上传文件至 kubernetes-MD

This commit is contained in:
wxin 2024-08-11 21:15:08 +08:00
parent 336512fced
commit ec7409babf
3 changed files with 655 additions and 0 deletions

View File

@ -0,0 +1,352 @@
<h1><center>kubernetes资源对象Secret</center></h1>
------
## 一Secret
Secret用来保存小片敏感数据的k8s资源例如密码token或者秘钥。这类数据当然也可以存放在Pod或者镜像中但是放在Secret中是为了更方便的控制如何使用数据并减少暴露的风险用户可以创建自己的secret系统也会有自己的secret。Pod需要先引用才能使用某个secret
#### 1.Pod使用secret的方式
作为volume的一个域被一个或多个容器挂载
在拉取镜像的时候被kubelet引用
#### 2.內建的Secrets
由ServiceAccount创建的API证书附加的秘钥,k8s自动生成的用来访问apiserver的Secret所有Pod会默认使用这个Secret与apiserver通信
#### 3.创建自己的Secret
方式1使用kubectl create secret命令
方式2yaml文件创建Secret
命令方式创建secret
假如某个Pod要访问数据库需要用户名密码分别存放在2个文件中username.txtpassword.txt
```shell
[root@master ~]# echo -n 'admin' > ./username.txt
[root@master ~]# echo -n '1f2d1e2e67df' > ./password.txt
```
kubectl create secret指令将用户名密码写到secret中并在apiserver创建Secret
```shell
[root@master ~]# kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
secret "db-user-pass" created
```
查看创建结果
```shell
[root@master ~]# kubectl get secrets
NAME TYPE DATA AGE
db-user-pass Opaque 2 51s
[root@master ~]# kubectl describe secret/db-user-pass
Name: db-user-pass
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password.txt: 12 bytes
username.txt: 5 bytes
```
get或describe指令都不会展示secret的实际内容这是出于对数据的保护的考虑如果想查看实际内容使用命令
```shell
[root@master ~]# kubectl get secret db-user-pass -o json
```
yaml方式创建Secret
创建一个secret.yaml文件内容用base64编码
```shell
[root@master ~]# echo -n 'admin' | base64
YWRtaW4=
[root@master ~]# echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm
```
yaml文件内容
```shell
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
```
创建
```shell
[root@master ~]# kubectl create -f ./secret.yaml
secret "mysecret" created
```
解析Secret中内容
```shell
[root@master ~]# kubectl get secret mysecret -o yaml
apiVersion: v1
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
kind: Secret
metadata:
creationTimestamp: 2016-01-22T18:41:56Z
name: mysecret
namespace: default
resourceVersion: "164619"
selfLink: /api/v1/namespaces/default/secrets/mysecret
uid: cfee02d6-c137-11e5-8d73-42010af00002
type: Opaque
```
base64解码
```shell
[root@master ~]# echo 'MWYyZDFlMmU2N2Rm' | base64 --decode
1f2d1e2e67df
```
#### 4.使用Secret
secret可以作为数据卷挂载或者作为环境变量暴露给Pod中的容器使用也可以被系统中的其他资源使用。比如可以用secret导入与外部系统交互需要的证书文件等
#### 5.在Pod中以文件的形式使用secret
创建一个Secret多个Pod可以引用同一个Secret
修改Pod的定义在spec.volumes[]加一个volume给这个volume起个名字spec.volumes[].secret.secretName记录的是要引用的Secret名字在每个需要使用Secret的容器中添加一项spec.containers[].volumeMounts[]指定spec.containers[].volumeMounts[].readOnly = truespec.containers[].volumeMounts[].mountPath要指向一个未被使用的系统路径
修改镜像或者命令行使系统可以找到上一步指定的路径。此时Secret中data字段的每一个key都是指定路径下面的一个文件名
#### 6.Pod中引用Secret的列子
```shell
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"  //这里是pod内部的目录
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
```
pod里面查看
```shell
[root@master ~]# kubectl exec -it mypod /bin/bash
root@mypod:/# cd /etc/foo/
root@mypod:/etc/foo# ls
password username
```
每一个被引用的Secret都要在spec.volumes中定义
映射secret key到指定的路径
可以控制secret key被映射到容器内的路径利用spec.volumes[].secret.items来修改被映射的具体路径
```shell
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
```
username被映射到了文件/etc/foo/my-group/my-username而不是/etc/foo/username
password没有变
从volume中读取secret的值
值得注意的一点是以文件的形式挂载到容器中的secret他们的值已经是经过base64解码的了可以直接读出来使用
```shell
[root@master ~]# ls /etc/foo/
username
password
[root@master ~]# cat /etc/foo/username
admin
[root@master ~]# cat /etc/foo/password
1f2d1e2e67df
```
被挂载的secret内容自动更新
也就是如果修改一个Secret的内容那么挂载了该Secret的容器中也将会取到更新后的值
#### 7.环境变量的形式使用Secret
创建一个Secret多个Pod可以引用同一个Secret
修改pod的定义定义环境变量并使用env[].valueFrom.secretKeyRef指定secret和相应的key
修改镜像或命令行,让它们可以读到环境变量
```shell
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
restartPolicy: Never
```
容器中读取环境变量已经是base64解码后的值了
```shell
[root@master ~]# echo $SECRET_USERNAME
admin
[root@master ~]# echo $SECRET_PASSWORD
1f2d1e2e67df
```
#### 8.案例
Pod中的ssh keys,创建一个包含ssh keys的secret
```shell
[root@master ~]# kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/path/to/.ssh/id_rsa --from-file=ssh-publickey=/path/to/.ssh/id_rsa.pub
```
创建一个Pod其中的容器可以用volume的形式使用ssh keys
```shell
kind: Pod
apiVersion: v1
metadata:
name: secret-test-pod
labels:
name: secret-test
spec:
volumes:
- name: secret-volume
secret:
secretName: ssh-key-secret
containers:
- name: ssh-test-container
image: daocloud.io/library/nginx
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
```
#### 9.k8s集群连接harbor私有仓库
使用命令创建一个secret
--docker-server 是私有仓库地址
--docker-username 是私有仓库用户名
--docker-password 是私有仓库对用用户名的密码
```shell
[root@master ~]# kubectl create secret docker-registry regcred --docker-server=10.11.67.119 --docker-username=diange --docker-password=QianFeng@123
```
创建pod的yaml文件
```shell
[root@master ~]# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: xingdian
labels:
app: xingdian
spec:
containers:
- name: diandian
image: 10.11.67.119/xingdian/nginx@sha256:2963fc49cc50883ba9af25f977a9997ff9af06b45c12d968b7985dc1e9254e4b
ports:
- containerPort: 80
imagePullSecrets:
- name: regcred
```
创建pod
```shell
[root@master ~]# kubectl create -f nginx.yaml
```
查看pod
```shell
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
xingdian 1/1 Running 0 10m
```
注意:
保证docker可以使用http连接下载默认是https
```shell
修改docker启动文件
[root@master ~]# vim /etc/systemd/system/multi-user.target.wants/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --insecure-registry 10.0.1.13 --containerd=/run/containerd/containerd.sock
[root@master ~]# systemctl daemon-reload
[root@master ~]# systemctl restart docker
```

View File

@ -0,0 +1,162 @@
<h1><center>Kubernetes资源对象service</center></h1>
------
## 一Service
将运行在一组 [Pods](https://v1-23.docs.kubernetes.io/docs/concepts/workloads/pods/pod-overview/) 上的应用程序公开为网络服务的抽象方法
使用 Kubernetes你无需修改应用程序即可使用不熟悉的服务发现机制Kubernetes 为 Pods 提供自己的 IP 地址,并为一组 Pod 提供相同的 DNS 名, 并且可以在它们之间进行负载均衡
Kubernetes Service 定义了这样一种抽象:逻辑上的一组 Pod一种可以访问它们的策略 —— 通常称为微服务
举个例子,考虑一个图片处理后端,它运行了 3 个副本。这些副本是可互换的 —— 前端不需要关心它们调用了哪个后端副本。 然而组成这一组后端程序的 Pod 实际上可能会发生变化, 前端客户端不应该也没必要知道,而且也不需要跟踪这一组后端的状态
#### 1.定义 Service
例如,假定有一组 Pod它们对外暴露了 9376 端口,同时还被打上 `app=MyApp` 标签:
```shell
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
```
上述配置创建一个名称为 "my-service" 的 Service 对象,它会将请求代理到使用 TCP 端口 9376并且具有标签 `"app=MyApp"` 的 Pod 上
Kubernetes 为该服务分配一个 IP 地址(有时称为 "集群IP"),该 IP 地址由服务代理使用
注意:
Service 能够将一个接收 `port` 映射到任意的 `targetPort`。 默认情况下,`targetPort` 将被设置为与 `port` 字段相同的值
#### 2.多端口 Service
对于某些服务,你需要公开多个端口。 Kubernetes 允许你在 Service 对象上配置多个端口定义
```shell
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
- name: https
protocol: TCP
port: 443
targetPort: 9377
```
## 二:发布服务
#### 1.服务类型
对一些应用的某些部分(如前端),可能希望将其暴露给 Kubernetes 集群外部 的 IP 地址
Kubernetes `ServiceTypes` 允许指定你所需要的 Service 类型,默认是 `ClusterIP`
`Type` 的取值以及行为如下:
`ClusterIP`:通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。 这也是默认的 `ServiceType`
![img](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/6R1zaHS1QM_i4c4W1k2ttg.png)
`NodePort`:通过每个节点上的 IP 和静态端口(`NodePort`)暴露服务。 `NodePort` 服务会路由到自动创建的 `ClusterIP` 服务。 通过请求 `<节点 IP>:<节点端口>`,你可以从集群的外部访问一个 `NodePort` 服务
![img](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/-E5GOvNElgId7mwjBs9elw.png)
[`LoadBalancer`](https://v1-23.docs.kubernetes.io/zh/docs/concepts/services-networking/service/#loadbalancer):使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的 `NodePort` 服务和 `ClusterIP` 服务上
你也可以使用Ingress来暴露自己的服务。 Ingress 不是一种服务类型,但它充当集群的入口点。 它可以将路由规则整合到一个资源中因为它可以在同一IP地址下公开多个服务
```shell
[root@master nginx]# kubectl expose deployment nginx-deployment --port=80 --type=LoadBalancer
```
#### 2.NodePort
如果你将 `type` 字段设置为 `NodePort`,则 Kubernetes 控制平面将在 `--service-node-port-range` 标志指定的范围内分配端口默认值30000-32767
例如:
```shell
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app: MyApp
ports:
# 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。
- port: 80
targetPort: 80
# 可选字段
# 默认情况下为了方便起见Kubernetes 控制平面会从某个范围内分配一个端口号默认30000-32767
nodePort: 30007
```
#### 3.案例
```shell
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-server
image: nginx:1.16
ports:
- containerPort: 80
```
```shell
apiVersion: v1
kind: Service
metadata:
name: nginx-services
labels:
app: nginx
spec:
type: NodePort
ports:
- port: 88
targetPort: 80
nodePort: 30010
selector:
app: nginx
```

View File

@ -0,0 +1,141 @@
<h1><center>Kubernetes资源对象Volumes</center></h1>
------
## 一Volumes
Container 中的文件在磁盘上是临时存放的,这给 Container 中运行的较重要的应用 程序带来一些问题。问题之一是当容器崩溃时文件丢失。kubelet 会重新启动容器, 但容器会以干净的状态重启。 第二个问题会在同一 Pod中运行多个容器并共享文件时出现。 Kubernetes 卷Volume 这一抽象概念能够解决这两个问题。
Docker 也有 卷Volume 的概念,但对它只有少量且松散的管理。 Docker 卷是磁盘上或者另外一个容器内的一个目录。 Docker 提供卷驱动程序,但是其功能非常有限。
Kubernetes 支持很多类型的卷。 Pod 可以同时使用任意数目的卷类型。 临时卷类型的生命周期与 Pod 相同,但持久卷可以比 Pod 的存活期长。 因此,卷的存在时间会超出 Pod 中运行的所有容器,并且在容器重新启动时数据也会得到保留。 当 Pod 不再存在时,卷也将不再存在。
卷的核心是包含一些数据的一个目录Pod 中的容器可以访问该目录。 所采用的特定的卷类型将决定该目录如何形成的、使用何种介质保存数据以及目录中存放的内容。
使用卷时, 在 .spec.volumes字段中设置为 Pod 提供的卷,并在.spec.containers[*].volumeMounts字段中声明卷在容器中的挂载位置。
#### 1.cephfs
cephfs卷允许你将现存的 CephFS 卷挂载到 Pod 中。 不像emptyDir那样会在 Pod 被删除的同时也会被删除cephfs卷的内容在 Pod 被删除 时会被保留,只是卷被卸载了。这意味着 cephfs 卷可以被预先填充数据,且这些数据可以在 Pod 之间共享。同一cephfs卷可同时被多个写者挂载。
详细使用官方链接:
```shell
https://github.com/kubernetes/examples/tree/master/volumes/cephfs/
```
#### 2.hostPath
hostPath卷能将主机节点文件系统上的文件或目录挂载到你的 Pod 中。 虽然这不是大多数 Pod 需要的,但是它为一些应用程序提供了强大的逃生舱。
| **取值** | **行为** |
| :---------------: | :----------------------------------------------------------: |
| | 空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。 |
| DirectoryOrCreate | 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755具有与 kubelet 相同的组和属主信息。 |
| Directory | 在给定路径上必须存在的目录。 |
| FileOrCreate | 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644具有与 kubelet 相同的组和所有权。 |
| File | 在给定路径上必须存在的文件。 |
| Socket | 在给定路径上必须存在的 UNIX 套接字。 |
| CharDevice | 在给定路径上必须存在的字符设备。 |
| BlockDevice | 在给定路径上必须存在的块设备。 |
hostPath 配置示例:
```shell
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# 宿主上目录位置
path: /data
# 此字段为可选
type: Directory
```
案例:
```shell
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-tomcat-1
labels:
app: tomcat-1
spec:
replicas: 2
selector:
matchLabels:
app: tomcat-1
template:
metadata:
labels:
app: tomcat-1
spec:
containers:
- name: tomcat-1
image: daocloud.io/library/tomcat:8-jdk8
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /usr/local/tomcat/webapps
name: xingdian
volumes:
- name: xingdian
hostPath:
path: /opt/apps/web
type: Directory
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-service-1
labels:
app: tomcat-1
spec:
type: NodePort
ports:
- port: 888
targetPort: 8080
nodePort: 30021
selector:
app: tomcat-1
```