k8s-07-存储

掌握多种存储类型的特点 并且能够在不同环境中选择合适的存储方案(有自己的见解)
一、ConfigMap
https://kubernetes.io/zh/docs/concepts/configuration/configmap/
在这里插入图片描述
1.2版本中引入,主要功能是为了解决应用程序会从配置文件、环境变量中获取配置信息,ConfigMap API为我们提供了向容器中注入配置信息的机制,ConfigMap可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制对象。ConfigMap 是为了方便的处理不含铭感信息的字符串,你可以将它理解为Linux系统中的/etc目录,专门用来存储配置文件的目录

注意: ConfigMap不是属性配置文件的代替品,只是作为多个properties文件的引用。

一、创建configmap

1.创建目录和配置文件
# mkdir configmap
# cd configmap/
# cat <<EOF > cm.properties
user.name=liuli
user.password=12345
EOF
1.使用目录创建
#kubectl create configmap cm-config-path --from-file /root/configmap
2.使用文件创建
#kubectl create configmap cm-config-file --from-file /root/configmap/cm.properties
3.使用字面值创建 (--from-literal)
#kubectl create configmap cm-config-kv --from-literal=user.name=liuli --from-literal=user.password=12345
4.资源清单形式创建  【 --- 多个文件放到一起】
# vim  vim configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.level: very
  special.type: charm
---   
apiVersion: v1
kind: ConfigMap
metadata:
  name: env-config
  namespace: default
data:
  log_level: INFO
查看
# kubectl get configmap
# kubectl get configmap cm-config-kv -o yaml

二、在Pod中使用 【# kubectl explain configmap.apiVersion 版本 v1】2种方式 (env /envFrom)

# vim pod.yaml  

apiVersion: v1
kind: Pod
metadata:
  name: configmap-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.level
        - name: SPECIAL_TYPE_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: special.type
      envFrom:
        - configMapRef:
            name: env-config
  restartPolicy: Never     
 # kubectl apply -f pod.yaml    
 服务启动会打印环境变量,查看日志,可以看到导入的环境变量               
 # kubectl logs configmap-pod  

在命令行中引用 :

command: ["/bin/sh","-c","echo $(SPECIAL_TYPE_KEY)"]

通过数据卷插件使用ConfigMap

# vim valume-pod.yaml  

apiVersion: v1
kind: Pod
metadata:
  name: valume-configmap-pod
spec:
  containers:
    - name: test-container
      image: nginx
      command: ["/bin/sh","-c","sleep 6000s"]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config
  restartPolicy: Never

 # kubectl apply -f valume-pod.yaml  
 进入容器查看
 # kubectl exec valume-configmap-pod -it -- /bin/bash
 -- 进入挂载目录 打印数据
root@valume-configmap-pod:/etc/config# cd /etc/config
root@valume-configmap-pod:/etc/config# ls
special.level  special.type
root@valume-configmap-pod:/etc/config# cat special.level
veryroot@valume-configmap-pod:/etc/config# 

configMap热更新

修改configMap
kubectl edit configMap special-config

修改信息:
在这里插入图片描述
等一会( 大约10s 就看到环境变量 改变了)

veryroot@valume-configmap-pod:/etc/config# cat special.level
very-hotroot@valume-configmap-pod:/etc/config# 

更新ConfigMap目前并不会触发相关pod的滚动更新,可以通过修改 pod annotaions 的方式强制触发滚动更新【TODO】
1.使用该ConfigMap挂载Env不会同步更新
2.使用该ConfigMap挂载的volume中的数据需要一段时间(大概10s)才能同步更新

二、Secret
https://kubernetes.io/zh/docs/concepts/configuration/secret/
在这里插入图片描述
解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴漏到镜像或者Pod Spec中。Secret可以以Vlolume或者环境变量的但是使用。

内置类型
kubernetes.io/service-account-token 服务账号令牌
kubernetes.io/dockercfg ~/.dockercfg 文件的序列化形式
kubernetes.io/dockerconfigjson ~/.docker/config.json 文件的序列化形式
kubernetes.io/basic-auth 用于基本身份认证的凭据
kubernetes.io/ssh-auth 用于 SSH 身份认证的凭据
kubernetes.io/tls 用于 TLS 客户端或者服务器端的数据
bootstrap.kubernetes.io/token 启动引导令牌数据

Service Account:用来访问k8s api,由系统自动创建,并且自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中
在这里插入图片描述
Opaque: base64编码格式的secret,用来存储密码、密钥等 ;是一个map类型的数据,要求value是base64编码格式

# 获取base64编码
[root@k8s ~]# echo -n "admin" |base64
YWRtaW4=
[root@k8s ~]# echo -n "12345" |base64
MTIzNDU=
# vim secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MTIzNDU=    
  
  # kubectl apply -f secret.yaml 
  # kubectl get secret 

1.将Secret挂载到volume中

# vim pod-secret.yaml

apiVersion: v1
kind: Pod
metadata:
  name: sercret-test  
  labels  
    name: sercret-test
spec:
   volumes:
    - name: secrets
     secret:
       secretName: mysecret  
  containers:
    -image:nginx 
     name: db
     volumeMounts:
     - name: secrets
       mountPath: ''
       readOnly: true    
       
# kubectl apply -f pod-secret.yaml    
# kubectl get pod  
# kubectl exec secret-test -it -- /bin/sh
查看效果 (使用时自己完成解密)
# cd /etc/secrets
# ls
password  username
# cat password
12345# cat username
admin#

2.将secret导出到环境变量

# vim pd-pod-secrets.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pod-deploment
spec:
   replicas: 2
   selector:
     matchLabels:
       app: pod-deploment
   template:
     metadata:
       labels:
         app: pod-deploment
     spec:
       containers:
       - name:  myapp
         image: nginx
         imagePullPolicy: IfNotPresent
         ports:
         - containerPort: 80
         env:
         - name: TEST_USER
           valueFrom:
             secretKeyRef:
               name: mysecret
               key: username
         - name: TEST_PASSWORD
           valueFrom:
             secretKeyRef:
               name: mysecret
               key: password
               
#kubectl apply -f  pd-pod-secrets.yaml       
# 查看结果    
[root@k8s secret]# kubectl get pod
NAME                            READY   STATUS    RESTARTS   AGE
pod-deploment-f69948d58-gqmlx   1/1     Running   0          6s
pod-deploment-f69948d58-vjfwh   1/1     Running   0          6s
[root@k8s secret]# kubectl exec pod-deploment-f69948d58-gqmlx -it -- bin/sh
# echo $TEST_USER
admin

kubernates.io/dockerconfigjson: 用来存储私有docker register 的认证信息

# kubectl create secret docker-registry myregistrykey \
--docker-server=DOCKER_REGISTER_SERVER \
--docker-username=DOCKER_USER \
--docker-password= DOCKER_PASSWORD \
--docker-email=DOCKER_EMAIL 

在创建pod的时候使用,通过imagePullSecrets来引用创建的 ‘myregistrykey ’

apiVersion: v1
kind: Pod
metadata:
   name: foo
spec:
  containers:
    - name: foo
      iamge: nginx
    imagePullSecrets:
     -name: myregistrykey      

basic-auth 、basic-auth (参考服务发现 ingress-nginx 应用)

三、volume
https://kubernetes.io/zh/docs/concepts/storage/
Container 中的文件在磁盘上是临时存放的,这给 Container 中运行的较重要的应用 程序带来一些问题。问题之一是当容器崩溃时文件丢失。kubelet 会重新启动容器, 但容器会以干净的状态重启。 第二个问题会在同一 Pod 中运行多个容器并共享文件时出现。 Kubernetes 卷(Volume) 这一抽象概念能够解决这两个问题。
在这里插入图片描述
olume是k8s数据卷,常见的数据卷有4种类型:EmptyDir,HostDir,NFS,Secret,gitRepo。Kubernetes支持Volume类型有:

emptyDir
hostPath
gcePersistentDisk
awsElasticBlockStore
nfs
iscsi
fc (fibre channel)
flocker
glusterfs
rbd
cephfs
gitRepo
secret
persistentVolumeClaim
downwardAPI
projected
azureFileVolume
azureDisk
vsphereVolume
Quobyte
PortworxVolume
ScaleIO
StorageOS
local

emptyDir
使用emptyDir,当Pod分配到Node上时,将会创建emptyDir,并且只要Node上的Pod一直运行,Volume就会一直存。当Pod(不管任何原因)从Node上被删除时,emptyDir也同时会删除,存储的数据也将永久删除。注:删除容器不影响emptyDir。
使用场景:

  • 暂存空间,例如用于基于磁盘的合并排序
  • 用做长时间计算崩溃恢复时的检查点
  • web服务器容器提供数据时,保存内容管理器容器提取的文件

hostPath
hostPath允许挂载Node上的文件系统到Pod里面去。如果Pod需要使用Node上的文件,可以使用hostPath。

  • 空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。
  • DirectoryOrCreate 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 kubelet 相同的组和属主信息。
  • Directory 在给定路径上必须存在的目录。
  • FileOrCreate 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 kubelet
    相同的组和所有权。
  • File 在给定路径上必须存在的文件。
  • Socket 在给定路径上必须存在的 UNIX 套接字。
  • CharDevice 在给定路径上必须存在的字符设备。
  • BlockDevice 在给定路径上必须存在的块设备。

当使用这种类型的卷时要小心,因为:
1.具有相同配置(例如基于同一 PodTemplate 创建)的多个 Pod 会由于节点上文件的不同 而在不同节点上有不同的行为。
2.下层主机上创建的文件或目录只能由 root 用户写入。你需要在 特权容器 中以 root 身份运行进程,或者修改主机上的文件权限以便容器能够写入 hostPath 卷。

实验

# vim emptydir.yaml

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: nginx
    name: myapp
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}
          
# kubectl apply -f  emptydir.yaml    
## 一个空目录
# kubectl exec test-pd -it  -- /bin/sh
# cd /cache

# vim hostpath.yaml

apiVersion: v1
kind: Pod
metadata:
  name: test-pod2
spec:
  containers:
  - image: nginx
    name: myapp2
    volumeMounts:
    - mountPath: /home
      name: mydir
    - mountPath: /home/a.txt
      name: myfile
  volumes:
  - name: mydir
    hostPath:
      path: /home
      type: DirectoryOrCreate
  - name: myfile
    hostPath:
      path: /home/a.txt
      type: FileOrCreate
# kubectl apply -f hostpath.yaml     
# kubectl exec test-pod2 -it -- /bin/sh  
查看挂载的文件
# cd /home
# ls

四、PV/PVC (实际中使用的较少 ,没有深入研究)
https://kubernetes.io/zh/docs/concepts/storage/persistent-volumes/
在这里插入图片描述
**持久卷(PersistentVolume,PV)**是集群中的一块存储,可以由管理员事先供应,或者 使用存储类(Storage Class)来动态供应。 持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样,也是使用 卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。 此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 还是特定于云平台的存储系统。

**持久卷申领(PersistentVolumeClaim,PVC)**表达的是用户对存储的请求。概念上与 Pod 类似。 Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以请求特定数量的资源(CPU 和内存);同样 PVC 申领也可以请求特定的大小和访问模式 (例如,可以要求 PV 卷能够以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 模式之一来挂载,参见访问模式)。

静态供应
集群管理员创建若干 PV 卷。这些卷对象带有真实存储的细节信息,并且对集群 用户可用(可见)。PV 卷对象存在于 Kubernetes API 中,可供用户消费(使用)。

动态供应 (实现比较繁琐,还不太有好)
如果管理员所创建的所有静态 PV 卷都无法与用户的 PersistentVolumeClaim 匹配, 集群可以尝试为该 PVC 申领动态供应一个存储卷。 这一供应操作是基于 StorageClass 来实现的:PVC 申领必须请求某个 存储类,同时集群管理员必须 已经创建并配置了该类,这样动态供应卷的动作才会发生。 如果 PVC 申领指定存储类为 “”,则相当于为自身禁止使用动态供应的卷。

绑定
PVC 申领与 PV 卷之间的绑定是一种一对一的映射

保护使用中的存储对象

确保仍被 Pod 使用的 PersistentVolumeClaim(PVC)对象及其所绑定的 PersistentVolume(PV)对象在系统中不会被删除,因为这样做可能会引起数据丢失。

访问模式

  • ReadWriteOnce – 卷可以被一个节点以读写方式挂载;
  • ReadOnlyMany – 卷可以被多个节点以只读方式挂载;
  • ReadWriteMany – 卷可以被多个节点以读写方式挂载。

在命令行接口(CLI)中,访问模式也使用以下缩写形式:

  • RWO - ReadWriteOnce
  • ROX - ReadOnlyMany
  • RWX - ReadWriteMany

重要提醒! 每个卷只能同一时刻只能以一种访问模式挂载,即使该卷能够支持 多种访问模式。
在这里插入图片描述


每个 PV 可以属于某个类(Class),通过将其 storageClassName 属性设置为某个 StorageClass 的名称来指定。 特定类的 PV 卷只能绑定到请求该类存储卷的 PVC 申领。 未设置 storageClassName 的 PV 卷没有类设定,只能绑定到那些没有指定特定 存储类的 PVC 申领。

早前,Kubernetes 使用注解 volume.beta.kubernetes.io/storage-class 而不是 storageClassName 属性。这一注解目前仍然起作用,不过在将来的 Kubernetes 发布版本中该注解会被彻底废弃。

回收策略

  • Retain – 手动回收
  • Recycle – 基本擦除 (rm -rf /thevolume/*) 【新版本已经废弃】
  • Delete – 诸如 AWS EBS、GCE PD、Azure Disk 或 OpenStack Cinder 卷这类关联存储资产也被删除

目前,仅 NFS 和 HostPath 支持回收(Recycle)。 AWS EBS、GCE PD、Azure Disk 和 Cinder 卷都支持删除(Delete)。

阶段
每个卷会处于以下阶段(Phase)之一:

  • Available(可用)-- 卷是一个空闲资源,尚未绑定到任何申领;
  • Bound(已绑定)-- 该卷已经绑定到某申领;
  • Released(已释放)-- 所绑定的申领已被删除,但是资源尚未被集群回收;
  • Failed(失败)-- 卷的自动回收操作失败。

PVC(PersistentVolumeClaims)
每个 PVC 对象都有 spec 和 status 部分,分别对应申领的规约和状态,申领可以通过为 storageClassName 属性设置 StorageClass 的名称来请求特定的存储类。 只有所请求的类的 PV 卷,即 storageClassName 值与 PVC 设置相同的 PV 卷, 才能绑定到 PVC 申领。

1.在(192.168.44.134) 安装nfs服务器
# yum install -y nfs-common nfs-utils rpcbind
# mkdir /nfs 
# chmod 777 /nfs/
# chown nfsnobody /nfs/
# vim /etc/exports
   /nfs *(rw,no_root_squash,no_all_squash,sync)
# systemctl start rpcbind
# systemctl start nfs
# exportfs -rv      //重新刷新共享(修改配置后找不到)
2.访问节点安装客户端(所有k8s节点)
# yum install -y nfs-utils rpcbind
# vim nfspv.yaml
测试挂载 ,验证后取消挂载
# mkdir /test
# showmount -e 192.168.44.134
    Export list for 192.168.44.134:
    /nfs *
# mount -t nfs 192.168.44.134:/nfs /test/
==== 可以测试文件访问+写入
# umount /test/
3.创建pv
# vim nfspv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /tmp
    server: 192.168.44.134
    
# kubectl apply -f nfspv.yaml    
# kubectl get pv
4.创建PVC
# vim pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc001
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  storageClassName: slow
  resources: 
    requests:
      storage: 5Gi
创建      
# kubectl apply -f pvc.yaml 
查看
# kubectl get pv
# kubectl get pvc
5.使用申请PVC   【该实验没成功,有时间在研究 TODO】
# vim pod-pvc.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pvc-pod
spec:
  volumes:
    - name: pvc-storage
      persistentVolumeClaim:
        claimName: pvc001
  containers:
    - name: pvc-container
      image: nginx
      ports:
        - containerPort: 80
      volumeMounts:
        - mountPath: /var/www/html
          name: pvc-storage
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值