1 存储机制分类

  1. k8s中的存储类型有以下四种:
    1.configMap: k8s中存储配置文件
    2.Secret: 需要加密的信息比如:秘钥,用户密码
    3.volume: 给Pod提供共享存储卷的能力
    4.Persistent Volume(简称PV): 服务持久卷的构建

2 ConfigMap

2.1 介绍

ConfigMap功能在K8s1.2版本中引入,许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。ConfigMap API 给我们提供了向容器中注入配置信息机制,ConfigMap可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制对象
在这里插入图片描述

2.2 创建方式

2.2.1 目录创建

game.properties

enemies=aliens
lives=3

ui.properties

color.good=purple
color.bad=yellow
allow.textmode=true
kubectl create configmap game-config --from-file=/root/k8s/configmap/dir

–from-file 指定在目录下的所有文件都会被用在ConfigMap里面创建一个键值对,键的名字就是文件名,值就是文件内容
在这里插入图片描述
kubectl get cm game-config -o yaml
在这里插入图片描述
kubectl describe cm game-config
在这里插入图片描述

2.2.2 文件创建

只要指定为一个文件就可以从单个文件中创建ConfigMap

kubectl create configmap game-config2 --from-file=/root/k8s/configmap/dir/ui.properties

在这里插入图片描述
–from-file 这个参数可以使用多次,你可以使用两次分别指定上个实例中的那两个配置文件,效果就跟指定整个目录是一样的。

2.2.3 字面值创建

使用文字值创建,利用 --from-literal 参数传递配置信息, 该参数可以使用多次,格式如下:

kubectl create configmap special-config --from-literal=special.type=charm 
kubectl get cm special-config -o yaml

在这里插入图片描述

2.3ConfigMap替代环境变量

special.yaml

apiVersion: v1
kind: ConfigMap
metadata:
     name: special-config
     namespace: default
data:
    special.how: very
    special.type: charm     

kubectl create -f special.yaml

env.yaml

apiVersion: v1
kind: ConfigMap
metadata:
     name: env-config
     namespace: default
data:
    log_level: INFO     

kubectl create -f env.yaml

注入上面俩个configMap的变量到Pod中.pod.yaml

vim pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: nginx
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: special.how
        - name: SPECIAL_TYPE_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: special.type
      envFrom:
        - configMapRef:
            name: env-config
  restartPolicy: Never

kubectl create -f pod.yaml
kubectl logs dapi-test-pod

#查看configMap中详细信息
kubectl describe cm env-config
创建测试pod-test
kubectl create -f pod-test.yaml
#查看日志, 确认导入环境变量成功
kubectl logs dapi-test-pod

2.4 ConfigMap之命令行参数

使用 ConfigMap 来替代环境变量。这里已经通过字面量创建方式创建完成。

apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
  special.type: charm

pod-test2.yaml配置文件

apiVersion: v1
kind: Pod
metadata:
  name: pod-test2
spec:
  containers:
  - name: test-container
    image: hub.qnhyn.com/library/myapp
    command: ["/bin/sh","-c","echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)"]
    env:
    - name: SPECIAL_LEVEL_KEY
      valueFrom:
        configMapKeyRef:
          name: special-config
          key: special.how
    - name: SPECIAL_TYPE_KEY
      valueFrom:
        configMapKeyRef:
          name: special-config
          key: special.type
  restartPolicy: Never

创建测试pod-test
kubectl create -f pod-test2.yaml
#查看日志, 确认导入环境变量成功 输出结果为(very charm)
kubectl logs pod-test2

2.5 ConfigMap之数据卷插件

使用 ConfigMap 来替代环境变量。这里已经通过字面量创建方式创建完成。

apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
  special.type: charm

在数据卷里面使用这个 ConfigMap,有不同的选项。最基本的就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容。

apiVersion: v1
kind: Pod
metadata:
  name: test-pod3
spec:
  containers:
  - name: test-container
    image: hub.qnhyn.com/library/myapp
    command: ["/bin/sh","-c","sleep 600s"]
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config
  volumes:
  - name: config-volume
    configMap:
      name: special-config
  restartPolicy: Never

实验查看基本操作

# 创建测试ptest-pod3
kubectl create -f test-pod3.yaml
# 交互到test-pod3容器中 容器中有储存的配置
kubectl exec test-pod3 -it -- /bin/sh
cd /etc/config
cat special.how

2.6 ConfigMap热更新

1)建立configMap和pod

apiVersion: v1
kind: ConfigMap
metadata:
  name: log-config
  namespace: default
data:
  log_level: INFO
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-deploy
  template:
    metadata:
      labels:
        app: nginx-deploy
    spec:
      containers:
      - name: nginx-deployment
        image: hub.qnhyn.com/library/myapp
        env:
        - name: GET_HOSTS_FROM
          value: dns
        ports:
        - containerPort: 80
        volumeMounts:
        - name: config-volume
          mountPath: /etc/config
      volumes:
      - name: config-volume
        configMap:
          name: log-config

2)实验查看基本操作

# 进入pod中容器查看configMap信息 
kubectl exec nginx-568bdc484c-vwzmv -it -- /bin/sh
cd /etc/config
# 热更新修改 ConfigMap
kubectl edit configmap log-config
# 修改log_level的值为DEBUG等待大概 10 秒钟时间,再次查看环境变量的值
kubectl exec nginx-568bdc484c-vwzmv -it cat /etc/config/log_level

3)ConfigMap 更新后滚动更新 Pod
更新 ConfigMap 目前并不会触发相关 Pod 的滚动更新,可以通过修改 pod annotations 的方式强制触发滚动更新

kubectl patch deployment my-nginx --patch’{“spec”: {“template”: {“metadata”: {“annotations”:{“version/config”: “20190411” }}}}}’

4)这个例子里我们在.spec.template.metadata.annotations中添加version/config,每次通过修该version/config来触发滚动更新
(1)!!!更新 ConfigMap 后:
(2)使用该 ConfigMap 挂载的 Env 不会同步更新
(3)使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概10秒)才能同步更新

3 存储机制-Secret

3.1 介绍

  1. Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 ssh key。敏感信息放在 secret 中比放在 Pod 的定义或者容器镜像中来说更加安全和灵活。
  2. Secret的类型:
    1.Service Account:用来访问Kubernetes API, 由Kubernetes 自动创建。对应的 secret 会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中
    2.Opaque:base64编码格式的Secret,用来存储密码、密钥等。使用base64编码存储信息,可以通过base64 --decode解码获得原始数据,因此安全性弱。
    3.kubernetes.io/dockerconfigjson: 用于存储docker registry的认证信息。

3.2 Service Account

  1. Service Account 创建时 Kubernetes 会默认创建对应的 secret。对应的 secret 会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中。
  2. 实验过程。这种实际应用中用的比较少。( 每个namespace下有一个名为default的默认的ServiceAccount对象 )
kubectl get sa
# 挑选一个可以访问Kubernetes API的pod,这里选kube-proxy-799ln
kubectl get pod -n kube-system
# 进去查看有三个文件 接口通过HTTPS双向认证
kubectl exec kube-proxy-799ln -n kube-system -it -- /bin/sh
cd  /run/secrets/kubernetes.io/serviceaccount

3.3 Opaque

  1. Opaque类型的数据是一个map类型,要求value是base64编码格式:
  2. 它实际上是表面上加密,很容易破解。
# 加密
echo -n "admin" | base64
echo -n "123456" | base64
# 解密
echo -n "YWRtaW4=" | base64 -d
  1. 创建一个Opaque类型的Secret: kubectl create -f So.yaml
kubectl get secret
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MTIzNDU2
  1. 将Secret挂载到Volume中
apiVersion: v1 
kind: Pod 
metadata:
  labels:
    name: secret-test 
  name: secret-test 
spec:
  volumes:
  - name: secrets 
    secret:
      secretName: mysecret 
  containers:
  - image: hub.qnhyn.com/library/myapp 
    name: db 
    volumeMounts:
    - name: secrets 
      mountPath: "/etc/secrets"
      readOnly: true
kubectl create -f secret-test.yaml
kubectl exec secret-test -it -- /bin/sh
cd /etc/secrets
  1. 将Secret设置为环境变量
apiVersion: v1
kind: Pod
metadata:
  name: secret-env
spec:
  containers:
  - name: nginx
    image: hub.qnhyn.com/library/myapp
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: username
      - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: password
kubectl get pod
# 查看环境变量
kubectl exec secret-env -- env

3.4 Secret的类型-kubernetes.io/dockerconfigjson

  1. harbor仓库中创建一个私有仓库并提镜像上去。对于私有仓库的拉取,需要登录认证否则无法成功拉取,登录认证信息存放在主机上(.docker/config.json)有安全隐患。
    1.docker logout hub.qnhyn.com
    2.因为不是公有再次拉取报验证错误,docker pull hub.qnhyn.com/test/myapp
  2. 使用kubectl创建docker registry认证的secret
kubectl create secret docker-registry myregistrykey --docker-server=hub.qnhyn.com --docker-username=admin --docker-password=123456 --docker-email=""
  1. 在创建Pod的时候,通过imagePullSecrets来引用刚创建的myregistrykey
apiVersion: v1
kind: Pod
metadata:
  name: foo
spec:
  containers:
    - name: foo
      image: hub.qnhyn.com/test/myapp
  imagePullSecrets:
    - name: myregistrykey

3 存储机制-Volume

3.1介绍

  1. 容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失,容器以干净的状态 (镜像最初的状态)重新启动。其次,在Pod中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes 中的Volume抽象就很好的解决了这些问题
  2. Kubernetes中的卷有明确的寿命,与封装它的Pod相同。所f以,卷的生命比Pod中的所有容器都长,当这个容器重启时数据仍然得以保存。当然,当Pod不再存在时,卷也将不复存在。也许更重要的是,Kubernetes支持多种类型的卷,Pod 可以同时使用任意数量的卷
  3. Kubernetes支持多种类型的卷
    awsElasticBlockStore、azureDisk、azureFile、cephfs、csi、downwgrdAPI、 emptyDir
    fc、flocker、 gcePersistentDisk、gitRepo、glusterfs、hostPath、iscsi、local、nfs
    persistentVolumeClaim、projected、 portworxVolume、quobyte、rbd、scaleI0 、secret
    storageos、vsphereVolume

3.2 emptyDir卷

  1. 当Pod被分配给节点时,首先创建emptyDir卷,并且只要该Pod在该节点上运行,该卷就会存在。正如卷的名字所述,它最初是空的。Pod中的容器可以读取和写入emptyDir 卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除Pod时,emptyDir中的数据将被永久删除
  2. emptyDir的用法有:
    1.暂存空间,例如用于基于磁盘的合井排序
    2.用作长时间计算前溃恢复时的检查点
    3.Web服务器容器提供数据时,保存内容管理器容器提取的文件
  3. 下面声明了一个名字叫cache-volume的volumes类型是emptyDir,把容器test-container中的/cache挂载在上面。em.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: hub.qnhyn.com/library/myapp
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  - image: busybox
    name: test-busybox
    command: ["/bin/sh","-c","sleep 6000s"]
    volumeMounts:
    - mountPath: /test
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}
  1. 到容器中查看,是否/cache下是一个空目录。
kubectl create -f em.yaml
# -c指定Pod中的容器
kubectl exec test-pd -c test-container  -it -- /bin/sh
# 在容器test-container的cache目录下
cd cache
date > index.html
exit
# 在容器test-busybox的test的目录下查看index.html文件
kubectl exec test-pd -c test-busybox  -it -- /bin/sh
cd test
exit

3.3 hostPath卷

  1. hostPath卷将主机节点的文件系统中的文件或目录挂载到集群中

  2. hostPath 的用途如下:

运行需要访问Docker内部的容器;使用 /var/lib/docker 的 hostPath
在容器中运行 cAdvisor;使用 /dev/cgroups 的 hostPath
3. 这种方法非常灵活。只要存储服务能被挂载到node所在的节点,我们就可以用hostPath方案让Pod使用
在这里插入图片描述
4. 除了所需的 path 属性之外,用户还可以为hostPath卷指定 type。

在这里插入图片描述
5. 使用这种卷类型是请注意,因为:
1.由于每个节点上的文件都不同,具有相同配置(例如从podTemplate创建的)的pod在不同节点上的行为可能会有所不同(没有你去挂能挂上吗?逗逼)
2.当Kubernetes 按照计划添加资源感知调度时,将无法考虑 hostPath 使用的资源(hostpath资源不归k8s管)
3.在底层主机上创建的文件或目录只能由 root写入。您需要在特权容器中以 root身份运行进程,或修改主机上的文件权限以便写入 hostPath 卷(没权限,去改)

apiVersion: v1 
kind: Pod 
metadata:
  name: test-pd 
spec:
  containers:
  - image: hub.qnhyn.com/library/myapp
    name: test-container 
    volumeMounts:
    - mountPath: /test-pd 
      name: test-volume 
  volumes:
  - name: test-volume 
    hostPath:
      # directory location on host 
      path: /data 
      # this field is optional 
      type: Directory

# 查看运行权限
ps aux | grep kubelete
# 创建文件夹 这里需要三个节点都创建文件夹哈 防止pod创建不成功
mkdir /data
kubectl create -f pod1.yaml
# 容器挂载目录下写入文件
kubectl exec test-pd -it -- /bin/sh
cd /test-pd
date > hello.txt
# 到对应节点下的/data下查看
cd /data

4 存储机制-持久卷PV和PVC

4.1 持久卷PV和PVC概念

在这里插入图片描述

  1. 假如没有PVC,你需要自己判断PV大小是否可用。非常耗时
  2. PersistentVolume(PV)是由管理员设置的存储,它是群集的一部分。就像节点是集群中的资源-样, PV也是集群中的资源。PV 是Volume之类的卷插件,但具有独立于使用PV的Pod的生命周期。此API对象包含存储实现的细节,即NFS、iSCSI或特定于云供应商的存储系统
  3. PersistentVolumeClaim(PVC)是用户存储的请求。它与Pod相似。Pod 消耗节点资源,PVC 消耗PV资源。Pod可以请求特定级别的资源(CPU和内存)。声明可以请求特定的大小和访问模式(例如,可以以读/写次或只读多次模式挂载)
  4. PV分类
    1.静态PV: 集群管理员创建一些PV。它们带有可供群集用户使用的实际存储的细节。它们存在于Kubernetes API中,可用于消费
    2.动态PV:(可以跟云存储上申请存储,以后的趋势,暂时并不友好,需要收费且麻烦,不太成熟。了解即可
    1)当管理员创建的静态PV都不匹配用户的PersistentVolumeClaim 时,集群可能会尝试动态地为PVC创建卷。此配置基于StorageClasses : PVC 必须请求[存储类],并且管理员必须创建并配置该类才能进行动态创建。声明该类为“ “可以有效地禁用其动态配置
    2)要启用基于存储级别的动态存储配置,集群管理员需要启用API server上的
    DefaultstorageClass[准入控制器]。例如,通过确保DefaultStorageClass位于API server组件的
    –admission-control标志,使用逗号分隔的有序值列表中,可以完成此操作
    3.绑定PV
    master中的控制环路监视新的PVC,寻找匹配的PV (如果可能) ,并将它们绑定在一 起。如果为新的PVC动态调配PV,则该环路将始终将该PV绑定到PVC。否则,用户总会得到他们所请求的存储,但是容量可能超出要求的数量。一旦PV和PVC绑定后,PersistentVolumeClaim绑定是排他性的, 不管它们是如何绑定的。PVC跟PV绑定是一对一的映射
  5. 持久化卷声明的保护
    1.PVC保护的目的是确保由pod正在使用的PVC不会从系统中移除,因为如果被移除的话可能会导致数据丢失
    2.当启用PVC保护alpha功能时,如果用户删除了一个pod正在使用的PVC,则该PVC不会被立即删除。PVC的删除将被推迟,直到PVC不再被任何pod使用
  6. 持久化卷的类型
    1.GCEPersistentDisk AWSElasticBlockStore AzureFile AzureDisk FC (Fibre Channel)
    2.FlexVolume Flocker NFS iSCSI RBD (Ceph Block Device) CephFS
    3.Cinder (OpenStack block storage) Glusterfs VsphereVolume Quobyte Volumes
    4.HostPath VMware Photon Portworx Volumes ScalelO Volumes StorageOS
apiVersion: v1 
kind: PersistentVolume 
metadata:
  name:pve003 
spec:
  capacity:
    # 卷的大小为5G
    storage: 5Gi 
  # 存储卷的类型为:文件系统
  volumeMode: Filesystem 
  # 访问策略:该卷可以被单个节点以读/写模式挂载
  accessModes:
    - ReadwriteOnce 
  # 回收策略:回收
  persistentVolumeReclaimPolicy: Recycle
  # 对应的具体底层存储的分级 存储类的级别
  # 比如有些固态或者其他存储类型比较快,就可以定义为strong
  storageClassName: slow
  # (可选的)挂载选项
  mountOptions:
    - hard 
    - nfsvers=4.1
  # 具体对应的真实底层存储类型为nfs
  # 挂载到172服务器下的/tmp目录
  nfs:
    path: /tmp 
    server: 172.17.0.2

4.2 PV访问模式(spec.accessModes)

  1. PersistentVolume可以以资源提供者支持的任何方式挂载到主机上。如下表所示,供应商具有不同的功能,每个PV的访问模式都将被设置为该卷支持的特定模式。例如,NFS可以支持多个读/写客户端,但特定的NFS PV可能以只读方式导出到服务器上。每个PV都有一套自己的用来描述特定功能的访问模式:
    1.ReadWriteOnce: 该卷可以被单个节点以读/写模式挂载
    2.ReadOnlyMany: 该卷可以被多个节点以只读模式挂载
    3.ReadWriteMany: 该卷可以被多个节点以读/写模式挂载
  2. 在命令行cli中,三种访问模式可以简写为:
    1.RWO - ReadWriteOnce
    2.ROX - ReadOnlyMany
    3.RWX - ReadWriteMany
  3. 但不是所有的类型的底层存储都支持以上三种,每种底层存储类型支持的都不一样。各种底层存储具体支持的访问模式如下:
Volume PluginReadWriteOnceReadOnlyManyReadWriteMany
AWSElasticBlockStore××
AzureFile
AzureDisk××
CephFS
Cinder××
FC×
FlexVolume×
Flocker××
GCEPersistentDisk×
Glusterfs
HostPath××
iSCSI×
PhotonPersistentDisk××
Quobyte
NFS
RBD×
VsphereVolume××
PortworxVolume×
ScaleIO×

4.3 PV的回收策略(spec.persistentVolumeReclaimPolicy)

  1. 回收策略的三种策略
    1.Retain(保留): pv被删除后会保留内存,手动回收
    2.Recycle(回收): 删除卷下的所有内容(rm-rf /thevolume/*)
    3.Delete(删除): 关联的存储资产(例如AWS EBS、GCE PD、Azure Disk 和OpenStack Cinder卷)将被删除。即直接把卷给删除了
  2. 回收策略注意事项
    1.当前,只有NFS和HostPath支持Recycle回收策略。 但是最新版本中的Recycle已被废弃,截图如下
    2.附:具体官网文档:https://kubernetes.io/docs/concepts/storage/persistent-volumes
    在这里插入图片描述

4.4 PV的状态

  1. PV可以处于以下的某种状态:
    1.Available(可用): 块空闲资源还没有被任何声明绑定
    2.Bound(已绑定): 卷已经被声明绑定, 注意:但是不一定不能继续被绑定,看accessModes而定
    3.Released(已释放): 声明被删除,但是资源还未被集群重新声明
    4.Failed(失败): 该卷的自动回收失败
  2. 命令行会显示绑定到PV的PVC的名称

5 持久化-NFS

5.1 安装NFS服务器

  1. 在hub仓库机器上创建NFS服务器
yum install -y nfs-common nfs-utils rpcbind 
mkdir /nfsdata
mkdir /nfsdata{1..3}
chmod 777 /nfsdata /nfsdata1 /nfsdata2 /nfsdata3
chown nfsnobody /nfsdata /nfsdata1 /nfsdata2 /nfsdata3
# 一下创建四个挂载目录
vim /etc/exports
	/nfsdata *(rw,no_root_squash,no_all_squash,sync)
	/nfsdata1 *(rw,no_root_squash,no_all_squash,sync)
	/nfsdata2 *(rw,no_root_squash,no_all_squash,sync)
	/nfsdata3 *(rw,no_root_squash,no_all_squash,sync)
systemctl start rpcbind 
systemctl start nfs
# 如果修改配置 重启生效
systemctl restart rpcbind
systemctl restart nfs
# 其他k8s节点安装客户端
yum install -y nfs-utils rpcbind

# 在任意节点测试是否能挂载成功
mkdir /test
# 查看共享目录
showmount -e 192.168.1.100
mount -t nfs 192.168.1.100:/nfsdata /test/
cd /test/
ls
vim index.html
# 解除挂载
cd -
umount /test/
rm -rf /test

5.2 部署PV

  1. 部署PV, 创建kubectl create -f pv.yaml.这里一下创建四个pv
    1.查看创建的pv: kubectl get pv
apiVersion: v1 
kind: PersistentVolume 
metadata:
 name: nfspv1 
spec:
 capacity:
   storage: 10Gi 
 accessModes:
   - ReadWriteOnce 
 persistentVolumeReclaimPolicy: Retain
 storageClassName: nfs
 nfs:
  path: /nfsdata
  server: 192.168.1.100
---
apiVersion: v1 
kind: PersistentVolume 
metadata:
 name: nfspv2 
spec:
 capacity:
   storage: 5Gi 
 accessModes:
   - ReadWriteOnce 
 persistentVolumeReclaimPolicy: Retain
 storageClassName: nfs
 nfs:
  path: /nfsdata1
  server: 192.168.1.100
---
apiVersion: v1 
kind: PersistentVolume 
metadata:
 name: nfspv3
spec:
 capacity:
   storage: 5Gi 
 accessModes:
   - ReadWriteOnce
 persistentVolumeReclaimPolicy: Retain
 storageClassName: slow
 nfs:
  path: /nfsdata2
  server: 192.168.1.100
---
apiVersion: v1 
kind: PersistentVolume 
metadata:
 name: nfspv4
spec:
 capacity:
   storage: 1Gi 
 accessModes:
   - ReadWriteOnce 
 persistentVolumeReclaimPolicy: Retain
 storageClassName: nfs
 nfs:
  path: /nfsdata3
  server: 192.168.1.100

5.3 创建服务并使用PVC

  1. 一般我们不会直接用PV,而是用PVC的方案去调度。创建服务并使用PVC。
    kubectl create -f pod.yaml
apiVersion: v1 
kind: Service 
metadata:
 name: nginx 
 labels:
   app: nginx 
spec:
 ports:
 - port: 80 
   name: web 
 clusterIP: None # 无头服务
 selector:
   app: nginx
---
apiVersion: apps/v1 
kind: StatefulSet # 要使用StatefulSet控制器,必须建立一个无头服务
metadata:
 name: web 
spec:
 selector:
   matchLabels:
     app: nginx 
 serviceName: "nginx" # 无头服务名称
 replicas: 3 
 template:
   metadata:
     labels:
       app: nginx 
   spec:
     containers:
     - name: nginx 
       image: hub.qnhyn.com/library/myapp
       ports:
       - containerPort: 80 
         name: web 
       volumeMounts: # 挂载下面声明的PVC
       - name: www 
         mountPath: /usr/share/nginx/html  # nginx的共享目录
 volumeClaimTemplates: # 声明一个PVC名称为www
 - metadata:
     name: www 
   spec:
     accessModes: [ "ReadWriteOnce" ] 
     storageClassName: "nfs"
     resources:
       requests:
         storage: 1Gi # 大小
  1. 上面创建pod时候会不成功。报错:没有匹配的volume,原因如下:
    1.既满足accessModes: [ “ReadWriteOnce” ]和 storageClassName: "nfs"的只有第一个PV
    2.而我们需要三个副本数。所以创建第二个时就卡住了。
    3.更改下PV的创建文件。重新创建PV即可。

5.4 关于 Statefulset

  1. StatefulSet为每个Pod副本创建了一个DNS域名,这个域名的格式为:S(podname).(headless servername),也就意味着服务间是通过Pod域名来通信而非PodIP,因为当Pod所在Node发生故障时,Pod会被飘移到其它 Node上,PodIP会发生变化,但是Pod域名不会有变化
  2. StatefulSet使用Headless服务来控制Pod的域名,这个域名的FQDN为:S(servicename).$(namespace).svc.cluster.local。其中,“cluster.local”指的是集群的域名
  3. 根据volumeClaimTemplates,为每个Pod 创建一个pvc,pvc的命名规则匹配模式:(volumeClaimTemplates.name)-(pod_name)
    1.比如上面的 volumeMounts.name=www,Podname-web-[0-2],因此创建出来的PVC是 www-web-0、www-web-1、 www-web-2
    2.在其他pod中可以直接访问:curl www-web-0 安装: yum install -y bind-utils
    3.kubectl get pod -o wide -n kube-system 查看coredns的pod的ip为:10.244.0.11
    4.dig -t A nginx.default.svc.cluster.local. @10.244.0.11 查看路由路径
  4. 删除 Pod 不会删除其pvc,手动删除pvc将自动释放pv
  5. Statefulset的启停顺序:
    1.有序部署:部罢Statefulset时,如果有多个Pod副本,它们会被顺序地创建**(从0到N-1)**并且,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态。
    2.有序删除:当Pod被删除时,它们被终止的顺序是从N-1到0。kubectl delete -f pod.yaml然后手动删除pv。
    3.有序扩展:当对Pod执行扩展操作时,与部署一样,它前面的Pod必须都处于Running和Ready状态。
  6. Statefulset使用场景:
    1.稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC 来实现。
    2.稳定的网络标识符,即Pod 重新调度后其iPodName 和 HostName不变。
    3.有序部署,有序扩展,基于init containers 来实现。
    4.有序收缩。
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐