k8s学习-存储

时间:2020-05-31 21:23:11   收藏:0   阅读:32

4.6、存储

4.6.1、ConfigMap

创建方式

文件夹/文件创建
mkdir dir
cd dir
cat > c1.properties <<EOF
c1.name=c1
EOF
cat > c2.properties <<EOF
c2.name=c2
EOF

cd ..
cat > c3.properties <<EOF
c3.name=c3
EOF

# configmap 简写为 cm
# 根据目录创建
kubectl create configmap cm-c1 --from-file=dir
# 根据文件创建
kubectl create configmap cm-c2 --from-file=c3.properties

# 查看
[root@k8s-master configmap]# kubectl get cm
NAME    DATA   AGE
cm-c1   2      12s
cm-c2   1      7s

# 查看内容
[root@k8s-master configmap]# kubectl get cm cm-c2 -o yaml
apiVersion: v1
data:
  c3.properties: |
    c3.name=c3
kind: ConfigMap
metadata:
  creationTimestamp: "2020-03-08T02:55:45Z"
  name: cm-c2
  namespace: default
  resourceVersion: "280079"
  selfLink: /api/v1/namespaces/default/configmaps/cm-c2
  uid: d35bfd4e-42bc-491f-b30a-488633d36653

字面量创建
# 使用 --from-literal=KEY=VALUE 
kubectl create cm cm-literal --from-literal=lt.name=bart --from-literal=lt.age=16
# 查看
[root@k8s-master configmap]# kubectl get cm cm-literal -o yaml
apiVersion: v1
data:
  lt.age: "16"
  lt.name: bart
kind: ConfigMap
metadata:
  creationTimestamp: "2020-03-08T02:59:41Z"
  name: cm-literal
  namespace: default
  resourceVersion: "280454"
  selfLink: /api/v1/namespaces/default/configmaps/cm-literal
  uid: 5bd18816-bfd9-4f5d-abd8-5fc20d4ead92
配置文件创建

vim cm.yml

apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-special-config
data:
  special.how: very
  special.type: charm
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-env-config
data:
  log_level: INFO
kubectl create -f cm.yml
[root@k8s-master configmap]# kubectl get cm
NAME                DATA   AGE
cm-c1               2      46m
cm-c2               1      45m
cm-env-config       1      13s # 刚创建的
cm-literal          2      41m
cm-special-config   2      13s # 刚创建的

Pod中使用ConfigMap

env使用

vim env.yml

apiVersion: v1
kind: Pod
metadata:
  name: cm-test-pod
spec:
  containers:
  - name: nginx
    image: habor-repo.com/library/nginx:v1
    command: ["/bin/sh", "-c", "env; echo -e $(SPECIAL_HOW)"] # 打印env和指定key
    env: # 容器添加环境变量
    - name: SPECIAL_HOW
      valueFrom: # 引用 configmap 的值
        configMapKeyRef:
          name: cm-special-config # configmap 的 name
          key: special.how # configmap 中的 key
    envFrom: # 环境变量导入
    - configMapRef:
        name: cm-env-config # configmap 的 name
  restartPolicy: Never # 不重启

kubectl create -f env.yaml
kubectl get pod
# 查看日志 
[root@k8s-master configmap]# kubectl logs cm-test-pod
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=cm-test-pod
HOME=/root
PKG_RELEASE=1~buster
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
NGINX_VERSION=1.17.9
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
NJS_VERSION=0.3.9
KUBERNETES_PORT_443_TCP_PROTO=tcp
log_level=INFO # fromEnv 中的值
SPECIAL_HOW=very
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
nvery # 打印的 env的value

挂载使用

vim volume.yaml

apiVersion: v1
kind: Pod
metadata:
  name: cm-test-pod2
spec:
  containers:
  - name: nginx
    image: habor-repo.com/library/nginx:v1
    command: ["/bin/sh", "-c", "cat /etc/config/special.how"] # 文件名就是key,内容就是value
    volumeMounts:
    - name: config-volume # 挂载位置绑定挂在卷名字
      mountPath: /etc/config
  volumes:
  - name: config-volume # 定义一个挂载卷为configmap的内容
    configMap: 
      name: cm-special-config
  restartPolicy: Never # 不重启
kubectl create -f volume.yml
kubectl get pod
# 查看日志 
[root@k8s-master configmap]# kubectl logs cm-test-pod2
very

热更新

vim hot.yml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: cm-test-pod3
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: cm-test-pod3
    spec:
      containers:
      - name: nginx
        image: habor-repo.com/library/nginx:v1
        volumeMounts:
        - name: config-volume # 挂载位置绑定挂在卷名字
          mountPath: /etc/config
      volumes:
      - name: config-volume # 定义一个挂载卷为configmap的内容
        configMap: 
          name: cm-special-config
      restartPolicy: Always # 不支持Never
kubectl create -f hot.yml
[root@k8s-master configmap]# kubectl get pod
NAME                            READY   STATUS      RESTARTS   AGE
cm-test-pod                     0/1     Completed   0          36m
cm-test-pod2                    0/1     Completed   0          22m
cm-test-pod3-75fbd58f94-v7rph   1/1     Running     0          5s
# 查看内容
kubectl exec cm-test-pod3-75fbd58f94-v7rph -it -- cat /etc/config/special.type

# 修改 cm-special-config 的值 
kubectl edit cm cm-special-config
# 再次查看 (大概10秒钟左右值会自动改变)
kubectl exec cm-test-pod3 -it -- cat /etc/config/special.type

# 修改pod内容强制触发滚动更新,适用于Env环境变量引用的configMap的情况
kubectl patch deployment cm-test-pod3 --patch ‘{"spec": {"template": {"metadata": {"annotations": {"version/config": "20200309"}}}}}‘

[root@k8s-master configmap]# kubectl get pod
NAME                          READY   STATUS      RESTARTS   AGE
cm-test-pod                   0/1     Completed   0          38m
cm-test-pod2                  0/1     Completed   0          24m
cm-test-pod3-59688486-xd5zs   1/1     Running     0          23s # pod 已经重启了

主意:!!!

4.6.2、Secret

Service Account

用来访问Kubernetes API,由Kubernetes自动创建,并会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount

# 假如有个pod为nginx
kubectl exec nignx -it -- ls /run/secrets/kubernetes.io/serviceaccount
ca.crt
namespace
token

OpqueSecret

使用base64来加密一些配置项

echo "admin" | base64 # YWRtaW4K
echo "YWRtaW4K" | base64 -d # admin

echo "123456" | base64 # MTIzNDU2Cg==
echo "MTIzNDU2Cg==" | base64 -d # 123456

vim secret.yml

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
data:
  name: YWRtaW4K
  password: MTIzNDU2Cg==
kubectl create -f secret.yml
# 查看内容
kubectl get secret mysecret -o yaml

vim pod.yml

apiVersion: v1
kind: Pod
metadata:
  name: secret-test-pod
spec:
  containers:
  - name: nginx
    image: habor-repo.com/library/nginx:v1
    env: # 容器添加环境变量
    - name: SEC_USER_NAME
      valueFrom: # 引用 secret 的值
        secretKeyRef:
          name: mysecret # mysecret 的 name
          key: name # mysecret 中的 key
    - name: SEC_USER_PASSWORD
      valueFrom: 
        secretKeyRef:
          name: mysecret 
          key: password 
    volumeMounts:
    - name: secret-volume # 挂载位置绑定挂在卷名字
      mountPath: /etc/config
  volumes:
  - name: secret-volume # 定义一个挂载卷为configmap的内容
    secret: 
      secretName: mysecret
  restartPolicy: Never # 不重启
kubectl create -f pod.yml
kubectl get pod
# 查看挂载文件
[root@k8s-master secret]# kubectl exec secret-test-pod -it -- ls /etc/config
name  password
# 查看环境变量(进入容器内部查看)
[root@k8s-master secret]# kubectl exec secret-test-pod -it -- /bin/bash
root@secret-test-pod:/# echo $SEC_USER_NAME $SEC_USER_PASSWORD
admin 123456

kubernetes.io/dockerconfigjson

使用kubectl创建docker registry认证的secret

kubectl create secret docker-registry <registrykey名字> --docker-server=<docker仓库域名> --docker-username=<仓库登录名> --docker-password=<登录密码> --docker-emai=<邮箱(随便给)>

# 使用 docker login登录也可以
docker login <docker仓库域名>

在创建Pod的时候指定imagePullSecrets参数

apiVersion: v1
kind: Pod
metadata:  
name: foo
spec:  
  containers:    
  - name: foo      
    image: roc/awangyang:v1  
  imagePullSecrets:     
  - name: myregistrykey # 对应上面创建的 <registrykey名字>

4.6.3、Volume

emptyDir

当 Pod 被分配给节点时,首先创建emptyDir卷,并且只要该 Pod 在该节点上运行,该卷就会存在。正如卷的名字所述,它最初是空的。Pod 中的容器可以读取和写入emptyDir卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除 Pod 时,emptyDir中的数据将被永久删除

emptyDir的用法有:

vim emptydir.yml

apiVersion: v1
kind: Pod
metadata:  
  name: test-pd
spec: 
  containers:
  - image: habor-repo.com/library/nginx:v1
    name: nginx
    volumeMounts:    
    - mountPath: /cache      
      name: cache-volume  
  - image: habor-repo.com/library/busybox:v1
    command: ["/bin/sh", "-c", "sleep 3600s;"]
    name: busybox    
    volumeMounts:    
    - mountPath: /cache      
      name: cache-volume  
  volumes:  
  - name: cache-volume 
    emptyDir: {}
kubectl create -f emptydir.yml
kubectl get pod 
kubectl describe pod test-pd
kubectl exec test-pd -c nginx -it -- /bin/bash
# date > /cache/a.txt 
kubectl exec test-pd -c nginx -it -- cat /cache/a.txt
# 查看另外一个 
kubectl exec test-pd -c busybox -it -- cat /cache/a.txt

hostPath

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

除了所需的path属性之外,用户还可以为hostPath卷指定type

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

使用这种卷类型是请注意,因为:

vim hostpath.yml

apiVersion: v1
kind: Pod
metadata:  
  name: test-pd2
spec: 
  containers:
  - image: habor-repo.com/library/nginx:v1
    name: nginx
    volumeMounts:    
    - mountPath: /cache      
      name: cache-volume  
  - image: habor-repo.com/library/busybox:v1
    command: ["/bin/sh", "-c", "sleep 3600s;"]
    name: busybox    
    volumeMounts:    
    - mountPath: /cache      
      name: cache-volume  
  volumes:  
  - name: cache-volume 
    hostPath: 
      path: /data # 本地路径
      type: Directory # 目录
# 在所有节点上创建 /data 目录
mkdir /data
kubectl create -f hostpath.yml
kubectl get pod -o wide 
# 假设在 k8s-node2 节点上
# date >/data/a.txt

kubectl exec test-pd2 -c nginx -it -- cat /cache/a.txt
# 查看另外一个 
kubectl exec test-pd2 -c busybox -it -- cat /cache/a.txt

# 发现有内容

4.6.4、PV&PVC

概念

PersistentVolume(PV)

是由管理员设置的存储,它是群集的一部分。就像节点是集群中的资源一样,PV 也是集群中的资源。 PV 是Volume 之类的卷插件,但具有独立于使用 PV 的 Pod 的生命周期。此 API 对象包含存储实现的细节,即 NFS、iSCSI 或特定于云供应商的存储系统

PersistentVolumeClaim(PVC)

是用户存储的请求。它与 Pod 相似。Pod 消耗节点资源,PVC 消耗 PV 资源。Pod 可以请求特定级别的资源(CPU 和内存)。声明可以请求特定的大小和访问模式(例如,可以以读/写一次或只读多次模式挂载)

持久化卷声明的保护

PVC 保护的目的是确保由 pod 正在使用的 PVC 不会从系统中移除,因为如果被移除的话可能会导致数据丢失当启用PVC 保护 alpha 功能时,如果用户删除了一个 pod 正在使用的 PVC,则该 PVC 不会被立即删除。PVC 的删除将被推迟,直到 PVC 不再被任何 pod 使用

PersistentVolume类型以插件形式实现。Kubernetes 目前支持以下插件类型:

PV 访问模式

PersistentVolume可以以资源提供者支持的任何方式挂载到主机上。如下表所示,供应商具有不同的功能,每个PV 的访问模式都将被设置为该卷支持的特定模式。例如,NFS 可以支持多个读/写客户端,但特定的 NFS PV 可能以只读方式导出到服务器上。每个 PV 都有一套自己的用来描述特定功能的访问模式:

在命令行中,访问模式缩写为:

Volume 插件 ReadWriteOnce ReadOnlyMany ReadWriteMany
AWSElasticBlockStoreAWSElasticBlockStore ? - -
AzureFile ? ? ?
AzureDisk ? - -
CephFS ? ? ?
Cinder ? - -
FC ? ? -
FlexVolume ? ? -
Flocker ? - -
GCEPersistentDisk ? ? -
Glusterfs ? ? ?
HostPath ? - -
iSCSI ? ? -
PhotonPersistentDisk ? - -
Quobyte ? ? ?
NFS ? ? ?
RBD ? ? -
VsphereVolume ? - - (pod 并列时有效)
PortworxVolume ? - ?
ScaleIO ? ? -
StorageOS ? - -

回收策略

当前,只有 NFS 和 HostPath 支持回收策略。AWS EBS、GCE PD、Azure Disk 和 Cinder 卷支持删除策略

状态

卷可以处于以下的某种状态:

命令行会显示绑定到 PV 的 PVC 的名称

例子

安装nfs

1)NFS 服务主要进程:

2)关键工具

3)NFS 服务端配置

在 NFS 服务器端的主要配置文件为 /etc/exports 时,通过此配置文件可以设置共享文件目录。每条配置记录由 NFS 共享目录、NFS 客户端地址和参数这 3 部分组成,格式如下:

[NFS 共享目录] [NFS 客户端地址 1 (参数 1, 参数 2, 参数 3……)] [客户端地址 2 (参数 1, 参数 2, 参数 3……)]

3.1)访问权限参数:

3.2)用户映射参数

3.3)其它配置参数

4)安装:

#创建一个目录作为共享文件目录
mkdir -p /usr/local/kubernetes/volumes

#给目录增加读写权限
chmod a+rw /usr/local/kubernetes/volumes

#**************** 安装 NFS 服务端 *******************
rpm -qa nfs-utils rpcbind
yum install -y nfs-utils rpcbind
systemctl start rpcbind #启动rpc服务 
systemctl status rpcbind #查看rpc服务状态 
systemctl start nfs #启动nfs服务 
systemctl status nfs #查看nfs服务状态 
# 注意:必须要先启动rpc服务,然后再启动NFS服务,如果先启动NFS服务,启动服务时会失败
# 检查开机是否自启动
# 1). chkconfig 配置开机自启动
chkconfig nfs on 
chkconfig rpcbind on 
chkconfig --list nfs 
#nfs  0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭 
chkconfig --list rpcbind 
#rpcbind 0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭 
# 2). /etc/rc.local 配置开机自启动
vim /etc/rc.local # 添加下面两行
systemctl start rpcbind
systemctl start nfs

#**************** 安装 NFS 客户端 *******************
# 安装客户端,实际上和服务端一样的
rpm -qa nfs-utils rpcbind
yum install -y nfs-utils rpcbind
systemctl start rpcbind #启动rpc服务 
systemctl status rpcbind #查看rpc服务状态 
systemctl start nfs #启动nfs服务 
systemctl status nfs #查看nfs服务状态

#**************** 分享目录 *******************
mkdir -p /usr/local/kubernetes/volumes
vi /etc/exports
/usr/local/kubernetes/volumes *(rw,sync,no_subtree_check)
# 说明:
# /usr/local/kubernetes/volumes:作为服务目录向客户端开放
# *:表示任何 IP 都可以访问
# rw:读写权限
# sync:同步权限
# no_subtree_check:表示如果输出目录是一个子目录,NFS 服务器不检查其父目录的权限 /usr/local/kubernetes/volumes *(rw,sync,no_subtree_check)
# 重启服务,使配置生效:
systemctl restart nfs

#**************** 客户端挂载分享目录 *******************
# 创建挂载目录
mkdir -p /usr/local/kubernetes/volumes-mount
# 将服务端的目录挂载到本地
mount 192.168.0.130:/usr/local/kubernetes/volumes /usr/local/kubernetes/volumes-mount
#使用 df 查看挂载
# 取消挂载
umount /usr/local/kubernetes/volumes-mount
测试

创建PV

vim pv.yml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv-test
spec:
  # 设置容量
  capacity:
    storage: 1Gi
  # 访问模式
  accessModes:
    # 该卷能够以读写模式被多个节点同时加载
    - ReadWriteMany
  # 回收策略,这里是基础擦除 `rm-rf/thevolume/*`
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: nfs
  nfs:
    # NFS 服务端配置的路径
    path: "/usr/local/kubernetes/volumes"
    # NFS 服务端地址
    server: 192.168.0.130
    readOnly: false
# 部署
kubectl create -f pv.yml

# 查看
[root@k8s-master pv]# kubectl get pv
NAME          CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
nfs-pv-test   1Gi        RWX            Recycle          Available           nfs                     2s
# 删除
kubectl delete pv --all

# 释放资源,删除对应的claimRef保存退出即可
kubectl edit pv nfs-pv-test

创建服务和PVC

1)使用spec.template.volumeClaimTemplates定义pvc

vim pvc.yml

apiVersion: v1
kind: Service
metadata:
  name: svc-pvc-nginx
  labels:
    app: svc-pvc-nginx
spec:
  selector:
    app: nginx
  ports:
  - name: web
    port: 8090
    targetPort: 80
  clusterIP: None # headless
---
apiVersion: apps/v1
kind: StatefulSet
metadata:  
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: svc-pvc-nginx
  replicas: 1 # 为什么给1因为上面创建了一个pv,但是pvc和是一一对应的关系,如果多了就会出问题
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: habor-repo.com/library/nginx:v1
        ports:
        - name: web
          containerPort: 80
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      #必须和要使用的pv的accessModes一致,根据accessModes和storageClassName去请求
      accessModes: ["ReadWriteMany"] 
      storageClassName: nfs
      resources:
        requests: # 请求使用资源
          #Ki、Mi、Gi、Ti、Pi、Ei(International System of units)
          #http://physics.nist.gov/cuu/Units/binary.html
          storage: 500Mi       
kubectl apply -f pvc.yml
kubectl get statefulset
kubectl get pvc
kubectl get pod

# 测试
# 进入 nfs 服务端的分享目录
cd /usr/local/kubernetes/volumes
date >index.html

# 请求测试
kubectl get pod -o wide
[root@k8s-master pv]# kubectl get pod -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
web-0   1/1     Running   0          33s   10.244.2.155   k8s-node2   <none>           <none>
[root@k8s-master pv]# curl 10.244.2.155
2020年 03月 08日 星期日 19:31:19 CST

# 删除
kubectl delete statefulset --all
kubectl delete pvc --all
kubectl delete pod --all

2)使用PersistentVolume定义pvc

vim pvc2.yml

apiVersion: v1
kind: Service
metadata:
  name: svc-pvc-nginx
  labels:
    app: svc-pvc-nginx
spec:
  selector:
    app: nginx
  ports:
  - name: web
    port: 8090
    targetPort: 80
  clusterIP: None # headless
---
apiVersion: apps/v1
kind: StatefulSet
metadata:  
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: svc-pvc-nginx
  replicas: 1 # 为什么给1因为上面创建了一个pv,但是pvc和是一一对应的关系,如果多了就会出问题
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: habor-repo.com/library/nginx:v1
        ports:
        - name: web
          containerPort: 80
        volumeMounts:
        - name: mypd
          mountPath: /usr/share/nginx/html
      volumes:
      - name: mypd
        persistentVolumeClaim:
          claimName: www
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: www
spec:
  #必须和要使用的pv的accessModes一致,根据accessModes和storageClassName去请求
  accessModes: ["ReadWriteMany"] 
  storageClassName: nfs
  resources:
    requests:
      storage: 100Mi
kubectl apply -f pvc2.yml
kubectl get statefulset
kubectl get pvc
kubectl get pod

# 测试
# 进入 nfs 服务端的分享目录
cd /usr/local/kubernetes/volumes
date >>index.html

# 请求测试
kubectl get pod -o wide
[root@k8s-master pv]# kubectl get pod -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
web-0   1/1     Running   0          33s   10.244.2.155   k8s-node2   <none>           <none>
[root@k8s-master pv]# curl 10.244.2.155
2020年 03月 08日 星期日 19:31:19 CST
2020年 03月 08日 星期日 20:00:38 CST

# 删除
kubectl delete statefulset --all
kubectl delete pvc --all
kubectl delete pod --all

原文:https://www.cnblogs.com/bartggg/p/13021377.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!