数据卷用于实现容器持久化数据, Kubernetes 对于数据卷重新定义, 提供了丰富强大的功能.
在 Kubernetes 系统中, 当 Pod 重建的时候, 数据卷会丢失, Kubernetes 也是通过数据卷来提供 Pod 数据的持久化的. Kubernetes 数据卷是对 Docker 数据库的扩展, Kubernetes 数据卷是 Pod 级别, 可以用来实现 Pod 中容器的文件共享.
通过命令查看支持的存储类型: kubectl explain pods.spec.volumes
本地数据卷有 2 种:
emptyDir: 临时目录
hostPath : 使用宿主机主机的路径
网络存储:
传统的设备存储: NAS,SAN
分布式存储: glusterfs,rbd,cephfs
云存储: EBS,Azure, 阿里云的
一, emptyDir 的类型
一个 pod 里面 2 个容器, 挂载同一个目录.
注意: emptyDir 的生命周期同 pod 周期, 简单来说, pod 删除了, emptyDir 也随之删除.
- apiVersion: v1
- kind: Pod
- metadata:
- name: pod-demo
- namespace: default
- labels:
- App: myapp
- tier: frontend
- spec:
- containers:
- - name: myapp
- image: ikubernetes/myapp:v1
- ports:
- - name: http
- containerPort: 80
- volumeMounts: #容器挂载
- - name: html
- mountPath: /data/web/HTML/
- - name: busybox
- image: busybox:latest
- command: ["/bin/sh" ,"-c","sleep 3600"]
- volumeMounts: #容器挂载
- - name: HTML
- mountPath: /data/
- volumes: #定义存储
- - name: HTML
- emptyDir: {}
进入 busybox 测试
- kubectl exec -it pod-demo -c busybox -- /bin/sh
- / # echo $(date)>>/data/index.HTML
- / # cat /data/index.HTML
- Sun Mar 17 08:20:03 UTC 2019
进入 myapp 查看数据共享
- kubectl exec -it pod-demo -c myapp -- /bin/sh
- / # cat /data/Web/HTML/index.HTML
- Sun Mar 17 08:20:03 UTC 2019
二, hostPath 类型存储
这种会把宿主机上的指定卷加载到容器之中, 当然, 如果 Pod 发生跨主机的重建, 其内容就难保证了.
这种卷一般和 DaemonSet 搭配使用, 用来操作主机文件, 例如进行日志采集的 FLK 中的 Fluentd https://www.centos.bz/tag/fluentd/ 就采用这种方式, 加载主机的容器日志目录, 达到收集本主机所有日志的目的.
- apiVersion: v1
- kind: Pod
- metadata:
- name: nginx-volume
- namespace: default
- spec:
- containers:
- - name: nginx
- image: nginx
- ports:
- - containerPort: 80
- volumeMounts:
- - name: HTML
- mountPath: /usr/share/nginx/HTML/
- volumes:
- - name: HTML
- hostPath:
- path: /data/nginx/v1/ #目录会在节点上自动创建
- type: DirectoryOrCreate
我们在节点的 / data/nginx/HTML / 创建一个文件
- [root@node01 HTML]# echo "hello nginx!!">>/data/nginx/HTML/index.HTML
- [root@master volumes]# curl 172.17.8.7
- hello nginxll
三, nfs 类型存储
NFS(Network File System) 即网络文件系统, 是 FreeBSD 支持的文件系统中的一种, 它允许网络中的计算机之间通过 TCP/IP 网络共享资源. 在 NFS 的应用中, 本地 NFS 的客户端应用可以透明地读写位于远端 NFS 服务器上的文件, 就像访问本地文件一样.
首先要准备好 nfs, 我在 192.168.247.144 的机器上安装 nfs, 到处的目录为 / nfs/data
- yum install nfs-utils -y
- VIM /etc/exports
- /data/volumes 192.168.247.0/16(rw,no_root_squash)
- systemctl start nfs
nfs 准备好了, 注意, 在 pod 的节点机器要一定确定可以挂载 nfs 类型的, 否则创建 pod 会出错. 执行 yum install nfs-utils -y 就可以挂载了
nfs pod 的 YAML 文件:
- apiVersion: v1
- kind: Pod
- metadata:
- name: nginx-volume-nfs
- namespace: default
- spec:
- containers:
- - name: nginx-nfs
- image: nginx
- ports:
- - containerPort: 80
- volumeMounts:
- - name: HTML
- mountPath: /usr/share/nginx/HTML/
- volumes:
- - name: HTML
- nfs:
- path: /data/volumes
- server: 192.168.247.144
在 nfs 上添加测试文件
- [root@node volumes]# echo "hello nfs">>/data/volumes/index.HTML
- [root@master volumes]# curl 172.17.8.7
- hello nfs
四, pv,pvc 的使用
PersistentVolume 和 PersistentVolumeClaim 提供了对存储支持的抽象, 也提供了基础设施和应用之间的分界, 管理员创建一系列的 PV 提供存储, 然后为应用提供 PVC, 应用程序仅需要加载一个 PVC, 就可以进行访问.
对于 pv 和 pvc, 首先要准备存储的, 我用的是 nfs, 在 192.168.247.144 的节点上划分了 5 个路径作为存储的设备.
- mkdir /data/volumes/{
- v1,v2,v3,v4,v5
- } -pv
- VIM /etc/exports
添加如下的内容:
- /data/volumes/v1 192.168.0.0/16(rw,no_root_squash)
- /data/volumes/v2 192.168.0.0/16(rw,no_root_squash)
- /data/volumes/v3 192.168.0.0/16(rw,no_root_squash)
- /data/volumes/v4 192.168.0.0/16(rw,no_root_squash)
- /data/volumes/v5 192.168.0.0/16(rw,no_root_squash)
保存, 导出下.
exportfs -avr
查看下是否正常.
nfs 的存储的好了. 下一步要先创建 pv,YAML 文件如下
- apiVersion: v1
- kind: PersistentVolume
- metadata:
- name: pv01
- labels:
- name: pv01
- spec:
- nfs:
- path: /data/v1/
- server: 192.168.247.144
- accessModes: ["ReadWriteOnce","ReadWriteMany"]
- capacity:
- storage: 5Gi
- ---
- apiVersion: v1
- kind: PersistentVolume
- metadata:
- name: pv02
- labels:
- name: pv02
- spec:
- nfs:
- path: /data/v2/
- server: 192.168.247.144
- accessModes: ["ReadWriteOnce","ReadWriteMany"]
- capacity:
- storage: 3Gi
- ---
- apiVersion: v1
- kind: PersistentVolume
- metadata:
- name: pv03
- labels:
- name: pv03
- spec:
- nfs:
- path: /data/v3/
- server: 192.168.247.144
- accessModes: ["ReadWriteOnce","ReadWriteMany"]
- capacity:
- storage: 5Gi
- ---
- apiVersion: v1
- kind: PersistentVolume
- metadata:
- name: pv04
- labels:
- name: pv04
- spec:
- nfs:
- path: /data/v4/
- server: 192.168.247.144
- accessModes: ["ReadWriteOnce","ReadWriteMany"]
- capacity:
- storage: 10Gi
- ---
- apiVersion: v1
- kind: PersistentVolume
- metadata:
- name: pv05
- labels:
- name: pv05
- spec:
- nfs:
- path: /data/v5/
- server: 192.168.247.144
- accessModes: ["ReadWriteOnce","ReadWriteMany"]
- capacity:
- storage: 10Gi
- #创建 pv
- kubectl apply -f pv-nfs.YAML
显示, pv 创建完成
接下来创建 pvc 和 pod,YAML 文件如下
- apiVersion: v1
- kind: PersistentVolumeClaim
- metadata:
- name: mypvc
- namespace: default
- spec:
- accessModes: ["ReadWriteMany"]
- resources:
- requests:
- storage: 5Gi #创建 pvc 的指定使用存储大小
- ---
- apiVersion: v1
- kind: Pod
- metadata:
- name: nginx-volume-pvc
- namespace: default
- spec:
- containers:
- - name: nginx-pvc
- image: nginx
- ports:
- - containerPort: 80
- volumeMounts:
- - name: HTML
- mountPath: /usr/share/nginx/HTML/
- volumes:
- - name: HTML
- persistentVolumeClaim: #指定 pvc 类型
- claimName: mypvc
添加文件测试:
- [root@node v1]# echo "hello pvc01">>index.HTML
- [root@master volumes]# curl 172.17.8.8
- hello pvc01
显示 pvc 创建好了, 同时 pvc 绑定了一个 pv, 到此 pv 和 pvc 的安装部署完成.
ps:pv 和 pvc 是一对一绑定的. 但是多个 pod 可以挂载同一个 pvc
通常使用的流程是, 首先创建存储, 在创建 pv, 接着创建 pvc,pod 挂载到相应的 pvc.
pv 与 pvc 的完整生命周期: 准备 -- 绑定 -- 使用 -- 释放 -- 回收
存在问题, pvc 申请时未必存在刚好符合需求的 pv, 因为设计了一种动态的申请 pv 叫 StroageClass.
不把配置写死在镜像中而是引入配置中心 configMap
configMap: 明文
配置容器化应用的方式:
1, 自定义命令行参数:
args: []
2, 把配置文件直接配进镜像.
3, 环境变量
(1)Cloud Mative 的应用程序一般可直接通过环境变量加载配置;
(2) 通过 entrypoint 脚本来预处理变量为配置文件中的配置信息;
4, 存储卷
configMap 使用
第一种方式:
- [root@master volumes]# kubectl create configmap nginx-config --from-literal=nginx_port=8080 --from-literal=server_name=myapp.com
- configmap/nginx-config created
- [root@master volumes]# kubectl get cm
- NAME DATA AGE
- nginx-config 2 9s
- [root@master volumes]# kubectl describe cm nginx-config
- Name: nginx-config
- Namespace: default
- Labels: <none>
- Annotations: <none>
- Data
- ====
- nginx_port:
- ----
- 8080
- server_name:
- ----
- myapp.com
- Events: <none>
第二种方式:
- [root@master configmap]# cat www.conf
- server {
- server_name myapp.com
- listen 80
- root /data/Web/HTML/;
- }
- [root@master configmap]# kubectl create configmap nginx-www --from-file=./www.conf
- configmap/nginx-www created
- [root@master configmap]# kubectl get cm
- NAME DATA AGE
- nginx-config 2 4m
- nginx-www 1 8s
- [root@master configmap]# kubectl get cm nginx-www -o YAML
- apiVersion: v1
- data:
- www.conf: "server {\n\tserver_name myapp.com\n\tlisten 80\n\troot /data/web/html/;\n}\n"
- kind: ConfigMap
- metadata:
- creationTimestamp: 2019-03-17T15:30:46Z
- name: nginx-www
- namespace: default
- resourceVersion: "276960"
- selfLink: /API/v1/namespaces/default/configmaps/nginx-www
- uid: a29267cb-48c9-11e9-9672-000c291e0db8
创建 pod
- [root@master configmap]# cat pod-configmap-demo.YAML
- apiVersion: v1
- kind: Pod
- metadata:
- name: pod-cm-1
- namespace: default
- labels:
- App: myapp
- tier: frontend
- spec:
- containers:
- - name: myapp
- image: ikubernetes/myapp:v1
- ports:
- - name: http
- containerPort: 80
- env:
- - name: NGINX_SERVER_PORT
- valueFrom:
- configMapKeyRef:
- name: nginx-config
- key: nginx_port
- - name: NGINX_SERVER_NAME
- valueFrom:
- configMapKeyRef:
- name: nginx-config
- key: server_name
- [root@master configmap]# kubectl exec -it pod-cm-1 -- /bin/sh
- / # printenv
- MYAPP_SVC_PORT_80_TCP_ADDR=10.98.57.156
- KUBERNETES_SERVICE_PORT=443
- KUBERNETES_PORT=tcp://10.10.10.1:443
- MYAPP_SVC_PORT_80_TCP_PORT=80
- HOSTNAME=pod-cm-1
- SHLVL=1
- MYAPP_SVC_PORT_80_TCP_PROTO=tcp
- HOME=/root
- NGINX_SERVER_PORT=8080
- EUREKA_SERVICE_HOST=10.10.10.192
- NGINX_SERVER_NAME=myapp.com
- [root@master configmap]# cat pod-configmap-2.YAML
- apiVersion: v1
- kind: Pod
- metadata:
- name: pod-cm-2
- namespace: default
- labels:
- App: myapp
- tier: frontend
- spec:
- containers:
- - name: myapp
- image: ikubernetes/myapp:v1
- ports:
- - name: http
- containerPort: 80
- volumeMounts:
- - name: nginx-config
- mountPath: /etc/nginx/config.d/
- readOnly: true
- volumes:
- - name: nginx-config
- configMap:
- name: nginx-config
来源: https://www.cnblogs.com/Dev0ps/p/10587598.html