文章目录
一、Volume
- Kubernetes 支持很多类型的卷。Pod可以同时使用任意数目的卷类型。临时卷类型的生命周期与 Pod 相同, 但持久卷可以比 Pod 的存活期长。 当 Pod 不再存在时,Kubernetes 也会销毁临时卷;不过 Kubernetes 不会销毁持久卷。 对于给定 Pod 中任何类型的卷,在容器重启期间数据都不会丢失。
- 我们上面讲的都是持久卷相关的。
emptyDir
- 对于定义了emptyDir卷的 Pod,在 Pod 被指派到某节点时此卷会被创建。
- 就像其名称所表示的那样,emptyDir卷最初是空的。
- 当 Pod 因为某些原因被从节点上删除时,emptyDir卷中的数据也会被永久删除。
- 容器崩溃并不会导致 Pod 被从节点上移除,因此容器崩溃期间emptyDir卷中的数据是安全的。
emptyDir的一些用途:
- 缓存空间,例如基于磁盘的归并排序。
- 为耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行。
- 在 Web 服务器容器服务数据时,保存内容管理器容器获取的文件。
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir:
sizeLimit: 500Mi
hostpath
- 其实不推荐使用,因为宿主机不安全。
- hostPath宿主机路径,就是把pod所在的宿主机之上的脱离pod中的容器名称空间的之外的宿主机的文件系统的某一目录和pod建立关联关系,在pod删除时,存储数据不会丢失。
- hostpath的type相当重要,常用的如下:
因为FileOrCreate模式不会创建文件的父目录。如果挂载文件的父目录不存在,Pod 将启动失败。所以可以分别创建父目录和文件。如下:
apiVersion: v1
kind: Pod
metadata:
name: test-webserver
spec:
os: { name: linux }
nodeSelector:
kubernetes.io/os: linux
containers:
- name: test-webserver
image: registry.k8s.io/test-webserver:latest
volumeMounts:
- mountPath: /var/local/aaa
name: mydir
- mountPath: /var/local/aaa/1.txt
name: myfile
volumes:
- name: mydir
hostPath:
path: /var/local/aaa
type: DirectoryOrCreate
hostPath:
path: /var/local/aaa/1.txt
type: FileOrCreate
NFS
- nfs卷能将 NFS (网络文件系统) 挂载到你的 Pod 中。
- 不像emptyDir那样会在删除 Pod 的同时也会被删除,nfs卷的内容在删除 Pod 时会被保存,卷只是被卸载。
- 这意味着nfs卷可以被预先填充数据,并且这些数据可以在 Pod 之间共享。
- 我们需要提前在节点上安装NFS,并配置NFS服务。
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /my-nfs-data
name: test-volume
volumes:
- name: test-volume
nfs:
server: my-nfs-server.example.com
path: /my-nfs-volume
readOnly: true
PV
非常重要,见下面。
CSI
也很重要,主要是看不懂。。。
https://jimmysong.io/kubernetes-handbook/concepts/cri.html
二、持久卷相关
PV、PVC和SC
- PVC
- PersistentVolumeClaim (持久卷创建申请),当我们创建一个pod时,需要申请一块空间,这个申请就是PVC。
- PV
- PersistentVolume(持久卷)是集群中的一块存储资源,由管理员预先配置或通过动态 provisioner 自动创建,是物理资源。
- SC
- StorageClass(存储类型)为不同的存储后端提供了不同的类别。SC定义了存储的类型、性能参数、provisioner等信息,用于动态创建PV。
- 一般会定义PV的属性。比如,存储类型,Volume的大小等。
- 一般会定义创建这种PV需要用到的存储插件,即存储制备器。
PV、PVC、SC的协作流程
- 用户提交 PVC:
- 用户在 Kubernetes 集群中提交一个 PVC,声明所需的存储特性,如存储大小、访问模式等。
- 匹配 StorageClass:
- Kubernetes 查找与 PVC 匹配的StorageClass。
- 如果 PVC 指定了特定的StorageClass,则使用该StorageClass。
- 如果 PVC 没有指定StorageClass而集群有默认的StorageClass,则使用默认的StorageClass。
- 动态创建 PV:
- Kubernetes 调用StorageClass声明的存储插件(如nfs.csi.k8s.io)来动态创建一个新的 PV。
- 存储插件就是一个一个的pod,每个node上都有,各种类型的,nfs,s3等等
- 存储插件根据StorageClass的参数(如server和share)和挂载选项(如rw、hard)来配置存储资源。
- PV 和 PVC 绑定:
- Kubernetes 将新创建的 PV 绑定到 PVC。
- 绑定后,PV 将专门为该 PVC 服务,直到 PVC 被删除。
- Pod 使用存储:
- 用户的 Pod 通过 PVC 访问到绑定的 PV,从而使用存储资源。
- 存储回收:
- 当 PVC 被删除时,根据StorageClass的回收策略(如Retain),PV 可以被自动删除(数据丢失)或者保留(数据保留)。
当我创建数据源和代码源的时候,其实就是创建了sc。
当我创建任务的时候,就是创建了pvc,pvc找sc,sc找插件,插件创建pv,再绑定。
三、配置容器:CM和Secret
在k8s中,用户通过configmap和secret从集群外部向Pod内部的容器应用注入配置信息。
Secret
- Secret对象存储数据的方式是以键值方式存储数据。
- Secret对象的数据存储和打印格式为Base64编码的字符串,因此用户在创建Secret对象时,也需要提供该类型的编码格式的数据。在容器中以环境变量或存储卷的方式访问时,会自动解码为明文格式。
- 需要注意的是,如果是在Master节点上,Secret对象以非加密的格式存储在etcd中,所以需要对etcd的管理和权限进行严格控制。
- 四种类型:
- Service Account :用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中;
- Opaque :base64编码格式的Secret,用来存储密码、密钥、信息、证书等,类型标识符为generic;
- kubernetes.io/dockerconfigjson :用来存储私有docker registry的认证信息,类型标识为docker-registry。
- kubernetes.io/tls:用于为SSL通信模式存储证书和私钥文件,命令式创建类型标识为tls。
创建Sercret
[root@k8s-master ~]# kubectl create secret generic mysecret --from-literal=username=admin --from-literal=password=123456
secret/mysecret created
[root@k8s-master ~]# kubectl get secret
NAME TYPE DATA AGE
mysecret Opaque 2 6s
[root@k8s-master ~]# echo -n admin > ./username
[root@k8s-master ~]# echo -n 123456 > ./password
[root@k8s-master ~]# kubectl create secret generic mysecret --from-file=./username --from-file=./password
secret/mysecret created
[root@k8s-master ~]# kubectl get secret
NAME TYPE DATA AGE
mysecret Opaque 2 6s
#事先完成敏感数据的Base64编码
[root@k8s-master ~]# echo -n admin |base64
YWRtaW4=
[root@k8s-master ~]# echo -n 123456 |base64
MTIzNDU2
[root@k8s-master ~]# vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
data:
username: YWRtaW4=
password: MTIzNDU2
[root@k8s-master ~]# kubectl apply -f secret.yaml
secret/mysecret created
[root@k8s-master ~]# kubectl get secret #查看存在的 secret,显示有2条数据
NAME TYPE DATA AGE
mysecret Opaque 2 8s
[root@k8s-master ~]# kubectl describe secret mysecret #查看数据的 Key
Name: mysecret
Namespace: default
Labels: <none>
Annotations:
Type: Opaque
Data
====
username: 5 bytes
password: 6 bytes
[root@k8s-master ~]# kubectl edit secret mysecret #查看具体的value,可以使用该命令
apiVersion: v1
data:
password: MTIzNDU2
username: YWRtaW4=
kind: Secret
metadata:
......
[root@k8s-master ~]# echo -n MTIzNDU2 |base64 --decode #通过 base64 将 Value 反编码:
123456
[root@k8s-master ~]# echo -n YWRtaW4= |base64 --decode
admin
使用Sercret
以 Volume 方式使用的 Secret 支持动态更新:Secret 更新后,容器中的数据也会更新。
[root@k8s-master volumes]# vim pod-secret-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-secret
spec:
containers:
- name: pod-secret
image: busybox
args:
- /bin/sh
- -c
- sleep 10;touch /tmp/healthy;sleep 30000
volumeMounts: #将 foo mount 到容器路径 /etc/foo,可指定读写权限为 readOnly。
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes: #定义 volume foo,来源为 secret mysecret。
- name: foo
secret:
secretName: mysecret
[root@k8s-master volumes]# kubectl apply -f pod-secret-demo.yaml
pod/pod-secret created
[root@k8s-master volumes]# kubectl get pods
pod-secret 1/1 Running 0 1m
[root@k8s-master volumes]# kubectl exec -it pod-secret sh
/ # ls /etc/foo/
password username
/ # cat /etc/foo/username
admin/ #
/ # cat /etc/foo/password
123456/ #
可以看到,Kubernetes 会在指定的路径 /etc/foo 下为每条敏感数据创建一个文件,文件名就是数据条目的 Key,这里是 /etc/foo/username 和 /etc/foo/password,Value 则以明文存放在文件中。
可以自定义存放数据的文件名:
[root@k8s-master volumes]# cat pod-secret-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-secret
spec:
containers:
- name: pod-secret
image: busybox
args:
- /bin/sh
- -c
- sleep 10;touch /tmp/healthy;sleep 30000
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
items: #自定义存放数据的文件名
- key: username
path: my-secret/my-username
- key: password
path: my-secret/my-password
[root@k8s-master volumes]# kubectl delete pods pod-secret
pod "pod-secret" deleted
[root@k8s-master volumes]# kubectl apply -f pod-secret-demo.yaml
pod/pod-secret created
[root@k8s-master volumes]# kubectl exec -it pod-secret sh
/ # cat /etc/foo/my-secret/my-username
admin
/ # cat /etc/foo/my-secret/my-password
123456
以 环境变量 方式使用的 Secret 不支持动态更新。
[root@k8s-master volumes]# cp pod-secret-demo.yaml pod-secret-env-demo.yaml
[root@k8s-master volumes]# vim pod-secret-env-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-secret-env
spec:
containers:
- name: pod-secret-env
image: busybox
args:
- /bin/sh
- -c
- sleep 10;touch /tmp/healthy;sleep 30000
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
[root@k8s-master volumes]# kubectl apply -f pod-secret-env-demo.yaml
pod/pod-secret-env created
[root@k8s-master volumes]# kubectl exec -it pod-secret-env sh
/ # echo $SECRET_USERNAME
admin
/ # echo $SECRET_PASSWORD
abcdef
ConfigMap
- Configmap是让配置文件从镜像中解耦,让镜像的可移植性和可复制性。ConfigMap API给我们提供了向容器中注入配置信息的机制,ConfigMap可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制大对象。
- Configmap和Secret很类似,创建和使用几乎一致,不再展开。
四、引用文档
https://www.cnblogs.com/linuxk/p/9760363.html#tid-mDhj4d
官方文档