K8S卷类型

Pod本地存储:emptyDir,hostPath
SAN:iSCSI,FC
NAS:nfs,cifs(samba)
分布式存储:glusterfs,rbd(ceph的块存储接口),cephfs(ceph的文件存储接口)
云存储:EBS, Azure Disk

在查看K8S集群Pod支持的卷类型

  1. [root@master ~]# kubectl explain pod.spec.volumes
  2. KIND: Pod
  3. VERSION: v1
  4. RESOURCE: volumes <[]Object>
  5. DESCRIPTION:
  6. List of volumes that can be mounted by containers belonging to the pod.
  7. More info: https://kubernetes.io/docs/concepts/storage/volumes
  8. Volume represents a named volume in a pod that may be accessed by any
  9. container in the pod.
  10. FIELDS:
  11. awsElasticBlockStore <Object>
  12. AWSElasticBlockStore represents an AWS Disk resource that is attached to a
  13. kubelet's host machine and then exposed to the pod. More info:
  14. https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore
  15. azureDisk <Object>
  16. AzureDisk represents an Azure Data Disk mount on the host and bind mount to
  17. the pod.
  18. azureFile <Object>
  19. AzureFile represents an Azure File Service mount on the host and bind mount
  20. to the pod.
  21. cephfs <Object>
  22. CephFS represents a Ceph FS mount on the host that shares a pod's lifetime
  23. cinder <Object>
  24. Cinder represents a cinder volume attached and mounted on kubelets host
  25. machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md
  26. configMap <Object>
  27. ConfigMap represents a configMap that should populate this volume
  28. csi <Object>
  29. CSI (Container Storage Interface) represents ephemeral storage that is
  30. handled by certain external CSI drivers (Beta feature).
  31. downwardAPI <Object>
  32. DownwardAPI represents downward API about the pod that should populate this
  33. volume
  34. emptyDir <Object>
  35. EmptyDir represents a temporary directory that shares a pod's lifetime.
  36. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir
  37. ephemeral <Object>
  38. Ephemeral represents a volume that is handled by a cluster storage driver
  39. (Alpha feature). The volume's lifecycle is tied to the pod that defines it
  40. - it will be created before the pod starts, and deleted when the pod is
  41. removed.
  42. Use this if: a) the volume is only needed while the pod runs, b) features
  43. of normal volumes like restoring from snapshot or capacity tracking are
  44. needed, c) the storage driver is specified through a storage class, and d)
  45. the storage driver supports dynamic volume provisioning through a
  46. PersistentVolumeClaim (see EphemeralVolumeSource for more information on
  47. the connection between this volume type and PersistentVolumeClaim).
  48. Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes
  49. that persist for longer than the lifecycle of an individual pod.
  50. Use CSI for light-weight local ephemeral volumes if the CSI driver is meant
  51. to be used that way - see the documentation of the driver for more
  52. information.
  53. A pod can use both types of ephemeral volumes and persistent volumes at the
  54. same time.
  55. fc <Object>
  56. FC represents a Fibre Channel resource that is attached to a kubelet's host
  57. machine and then exposed to the pod.
  58. flexVolume <Object>
  59. FlexVolume represents a generic volume resource that is
  60. provisioned/attached using an exec based plugin.
  61. flocker <Object>
  62. Flocker represents a Flocker volume attached to a kubelet's host machine.
  63. This depends on the Flocker control service being running
  64. gcePersistentDisk <Object>
  65. GCEPersistentDisk represents a GCE Disk resource that is attached to a
  66. kubelet's host machine and then exposed to the pod. More info:
  67. https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk
  68. gitRepo <Object>
  69. GitRepo represents a git repository at a particular revision. DEPRECATED:
  70. GitRepo is deprecated. To provision a container with a git repo, mount an
  71. EmptyDir into an InitContainer that clones the repo using git, then mount
  72. the EmptyDir into the Pod's container.
  73. glusterfs <Object>
  74. Glusterfs represents a Glusterfs mount on the host that shares a pod's
  75. lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md
  76. hostPath <Object>
  77. HostPath represents a pre-existing file or directory on the host machine
  78. that is directly exposed to the container. This is generally used for
  79. system agents or other privileged things that are allowed to see the host
  80. machine. Most containers will NOT need this. More info:
  81. https://kubernetes.io/docs/concepts/storage/volumes#hostpath
  82. iscsi <Object>
  83. ISCSI represents an ISCSI Disk resource that is attached to a kubelet's
  84. host machine and then exposed to the pod. More info:
  85. https://examples.k8s.io/volumes/iscsi/README.md
  86. name <string> -required-
  87. Volume's name. Must be a DNS_LABEL and unique within the pod. More info:
  88. https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
  89. nfs <Object>
  90. NFS represents an NFS mount on the host that shares a pod's lifetime More
  91. info: https://kubernetes.io/docs/concepts/storage/volumes#nfs
  92. persistentVolumeClaim <Object>
  93. PersistentVolumeClaimVolumeSource represents a reference to a
  94. PersistentVolumeClaim in the same namespace. More info:
  95. https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims
  96. photonPersistentDisk <Object>
  97. PhotonPersistentDisk represents a PhotonController persistent disk attached
  98. and mounted on kubelets host machine
  99. portworxVolume <Object>
  100. PortworxVolume represents a portworx volume attached and mounted on
  101. kubelets host machine
  102. projected <Object>
  103. Items for all in one resources secrets, configmaps, and downward API
  104. quobyte <Object>
  105. Quobyte represents a Quobyte mount on the host that shares a pod's lifetime
  106. rbd <Object>
  107. RBD represents a Rados Block Device mount on the host that shares a pod's
  108. lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md
  109. scaleIO <Object>
  110. ScaleIO represents a ScaleIO persistent volume attached and mounted on
  111. Kubernetes nodes.
  112. secret <Object>
  113. Secret represents a secret that should populate this volume. More info:
  114. https://kubernetes.io/docs/concepts/storage/volumes#secret
  115. storageos <Object>
  116. StorageOS represents a StorageOS volume attached and mounted on Kubernetes
  117. nodes.
  118. vsphereVolume <Object>
  119. VsphereVolume represents a vSphere volume attached and mounted on kubelets
  120. host machine

emptyDir

busybox容器负责产生数据,也就是我们常说的sidecar;myapp容器负责向外提供生产服务

  1. [root@master volumes]# cat pod-vol-demo.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: pod-demo
  6. spec:
  7. containers:
  8. - name: myapp
  9. image: ikubernetes/myapp:v1
  10. imagePullPolicy: IfNotPresent
  11. ports:
  12. - containerPort: 80
  13. volumeMounts:
  14. - name: html
  15. mountPath: /usr/share/nginx/html/
  16. - name: busybox
  17. image: busybox:latest
  18. imagePullPolicy: IfNotPresent
  19. volumeMounts:
  20. - name: html
  21. mountPath: /data/
  22. command: ["/bin/sh","-c","while true; do echo $(date) >>/data/index.html; sleep 2; done"]
  23. volumes:
  24. - name: html
  25. emptyDir: {}

hostPath

hostPath卷方式可以将数据持久化到宿主机本地,如下我们先在本地创建好/data/pod/volume1的目录,并在创建好可访问网页文件,但是这种方式如果要提供统一的内容访问,需要在每一个宿主机上创建相应的目录和网页内容发。
节点1:
[root@master volumes]# mkdir /data/pod/volume1 -p
[root@master volumes]# echo node01 >/data/pod/volume1/index.html
节点2:
[root@master volumes]# mkdir /data/pod/volume1 -p
[root@master volumes]# echo node02 >/data/pod/volume1/index.html

  1. [root@master volumes]# cat pod-hostpath-vol.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: pod-hostpath-vol
  6. namespace: default
  7. spec:
  8. containers:
  9. - name: myapp
  10. image: ikubernetes/myapp:v1
  11. volumeMounts:
  12. - name: html
  13. mountPath: /usr/share/nginx/html
  14. volumes:
  15. - name: html
  16. hostPath:
  17. path: /data/pod/volume1
  18. type: DirectoryOrCreate

nfs

通过nfs存储卷的方式可以实现将数据持久化的存储在远端存储上面,以防止数据丢失

  1. [root@master volumes]# cat pod-nfs-vol.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: pod-nfs-vol
  6. namespace: default
  7. spec:
  8. containers:
  9. - name: myapp
  10. image: ikubernetes/myapp:v1
  11. volumeMounts:
  12. - name: html
  13. mountPath: /usr/share/nginx/html
  14. volumes:
  15. - name: html
  16. nfs:
  17. path: /data/volumes
  18. server: 172.16.1.31

PV、PVC

让POD创建过程与底层存储解耦合,如下图PV,PVC,storageClass之间的逻辑关系
image.png
image.png
1、示例,创建pv

  1. [root@master volumes]# cat pv-nfs-demo.yaml
  2. apiVersion: v1
  3. kind: PersistentVolume
  4. metadata:
  5. name: pv001
  6. labels:
  7. name: pv001
  8. spec:
  9. nfs:
  10. path: /data/volumes/v1
  11. server: 172.16.1.31
  12. accessModes: ["ReadWriteMany", "ReadWriteOnce"]
  13. capacity:
  14. storage: 2Gi
  15. ---
  16. apiVersion: v1
  17. kind: PersistentVolume
  18. metadata:
  19. name: pv002
  20. labels:
  21. name: pv002
  22. spec:
  23. nfs:
  24. path: /data/volumes/v2
  25. server: 172.16.1.31
  26. accessModes: ["ReadWriteMany", "ReadWriteOnce"]
  27. capacity:
  28. storage: 4Gi

2、使用pvc创建pod,关联pv

  1. [root@master volumes]# cat pvc-demo.yaml
  2. apiVersion: v1
  3. kind: PersistentVolumeClaim
  4. metadata:
  5. name: mypvc
  6. namespace: default
  7. spec:
  8. accessModes: ["ReadWriteMany"]
  9. resources:
  10. requests:
  11. storage: 2Gi
  12. ---
  13. apiVersion: v1
  14. kind: Pod
  15. metadata:
  16. name: pod-pvc
  17. namespace: default
  18. spec:
  19. containers:
  20. - name: myapp
  21. image: ikubernetes/myapp:v1
  22. volumeMounts:
  23. - name: html
  24. mountPath: /usr/share/nginx/html
  25. volumes:
  26. - name: html
  27. persistentVolumeClaim:
  28. claimName: mypvc

configmap

配置容器化应用的方式
1、自定义命令行参数;command,args:[]
2、把配置文件直接备进镜像(但是此种方式耦合度过于紧密)
3、环境变量
1)Cloud Native的应用程序一般可以通过环境变量加载配置
2)Cloud enable,通过entrypoint脚本来预处理变量为配置文件中的配置信息
4、存储卷
怎么
命令行创建configmap

  1. 1、命令行创建
  2. [root@master manifests]# kubectl create configmap nginx-config --from-literal=nginx_port=8080 --from-literal=server_name=evn.xsc.com
  3. configmap/nginx-config created
  4. 2、查看
  5. [root@master manifests]# kubectl get cm
  6. NAME DATA AGE
  7. nginx-config 2 8s
  8. 3、查看详细描述
  9. [root@master manifests]# kubectl describe cm nginx-config
  10. Name: nginx-config
  11. Namespace: default
  12. Labels: <none>
  13. Annotations: <none>
  14. Data
  15. ====
  16. nginx_port:
  17. ----
  18. 8080
  19. server_name:
  20. ----
  21. evn.xsc.com
  22. Events: <none>

通过变量的方式注入配置

  1. [root@master configmap]# kubectl describe cm nginx-config
  2. Name: nginx-config
  3. Namespace: default
  4. Labels: <none>
  5. Annotations: <none>
  6. Data
  7. ====
  8. nginx_port:
  9. ----
  10. 8080
  11. server_name:
  12. ----
  13. evn.xsc.com
  14. Events: <none>
  15. pod通过env变量引用configmap的值
  16. [root@master configmap]# cat pod-configmap.yaml
  17. apiVersion: v1
  18. kind: Pod
  19. metadata:
  20. name: pod-cm-1
  21. spec:
  22. containers:
  23. - image: ikubernetes/myapp:v1
  24. name: myapp
  25. ports:
  26. - name: http
  27. containerPort: 80
  28. env:
  29. - name: NGINX_SERVER_PORT
  30. valueFrom:
  31. configMapKeyRef:
  32. name: nginx-config
  33. key: nginx_port
  34. - name: NGINX_SERVER_NAME
  35. valueFrom:
  36. configMapKeyRef:
  37. name: nginx-config
  38. key: server_name
  39. 容器内查看注入的变量值
  40. [root@master configmap]# kubectl exec -it pod-cm-1 -- /bin/sh
  41. / # printenv
  42. MYAPP_SVC_PORT_80_TCP_ADDR=10.98.57.156
  43. KUBERNETES_PORT=tcp://10.96.0.1:443
  44. KUBERNETES_SERVICE_PORT=443
  45. MYAPP_SVC_PORT_80_TCP_PORT=80
  46. HOSTNAME=pod-cm-1
  47. SHLVL=1
  48. MYAPP_SVC_PORT_80_TCP_PROTO=tcp
  49. HOME=/root
  50. NGINX_SERVER_PORT=8080
  51. NGINX_SERVER_NAME=evn.xsc.com

通过挂载configmap卷的方式传递值

  1. configmap的值
  2. [root@master configmap]# kubectl describe cm www.conf
  3. Name: www.conf
  4. Namespace: default
  5. Labels: <none>
  6. Annotations: <none>
  7. Data
  8. ====
  9. www.conf:
  10. ----
  11. server {
  12. server_name evn.xsc.com;
  13. listen 8088;
  14. root /data/web/html;
  15. }
  16. Events: <none>
  17. 创建pod
  18. [root@master configmap]# cat pod-configmap-3.yaml
  19. apiVersion: v1
  20. kind: Pod
  21. metadata:
  22. name: pod-cm-3
  23. spec:
  24. containers:
  25. - image: ikubernetes/myapp:v1
  26. name: myapp
  27. ports:
  28. - name: http
  29. containerPort: 80
  30. volumeMounts:
  31. - name: nginxconf
  32. mountPath: /etc/nginx/conf.d/
  33. readOnly: true
  34. volumes:
  35. - name: nginxconf
  36. configMap:
  37. name: www.conf
  38. 进入容器内部可以查看到挂载的值
  39. [root@master configmap]# kubectl exec -it pod-cm-3 -- /bin/sh
  40. / #
  41. / #
  42. / # cat /etc/nginx/conf.d/www.conf
  43. server {
  44. server_name evn.xsc.com;
  45. listen 8088;
  46. root /data/web/html;
  47. }
  48. 通过挂载configmap的方式可以实现动态修改,当configmap修改完之后,pod内的配置也会实现自动修改

secret

  1. [root@master ~]# kubectl create secret generic mysql-root-password --from-literal=password=abc123..
  2. secret/mysql-root-password created
  3. [root@master ~]# kubectl describe secret mysql-root-password
  4. Name: mysql-root-password
  5. Namespace: default
  6. Labels: <none>
  7. Annotations: <none>
  8. Type: Opaque
  9. Data
  10. ====
  11. password: 8 bytes
  12. 但是其实secret是通过base64进行编码的,因此其实是很容易解码的
  13. [root@master ~]# kubectl get secret mysql-root-password -o yaml
  14. apiVersion: v1
  15. data:
  16. password: YWJjMTIzLi4=
  17. kind: Secret
  18. metadata:
  19. creationTimestamp: "2021-06-18T08:23:43Z"
  20. managedFields:
  21. - apiVersion: v1
  22. fieldsType: FieldsV1
  23. fieldsV1:
  24. f:data:
  25. .: {}
  26. f:password: {}
  27. f:type: {}
  28. manager: kubectl-create
  29. operation: Update
  30. time: "2021-06-18T08:23:43Z"
  31. name: mysql-root-password
  32. namespace: default
  33. resourceVersion: "186277"
  34. uid: de4cadce-e3eb-430d-b7ea-c95e77e690cc
  35. type: Opaque
  36. You have new mail in /var/spool/mail/root
  37. [root@master ~]# echo YWJjMTIzLi4= | base64 -d
  38. abc123..