kubernetes部署Volume数据卷

分两类,一类是本地数据卷,一类是网络数据卷,容器都是暂时的,他不会持久的在某个节点上,他的数据是默认保存在当前容器里的,容器没了啥都没了,所以就要使用Volume了,pod需要设置来源(spec.volume)和挂载点(spec.containers.volumeMounts)两个信息后就可以使用相应的Volume,先看看本地数据卷。

本地数据卷

主要用的两种,一个是emptyDir,另一个是hostPath,分别了解一下。

emptyDir

这个数据卷会在你的宿主机创建一个空目录,然后挂载到Pod容器,Pod删除这个卷也会被删除,这个应用场景就是Pod之间数据共享,说白了就是你想在容器中做数据共享就要用这个卷了,下面一个例子。

[root@k8s01 yml]# cat emptyDir.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-emptydir
spec: 
  containers: 
  - image: centos:latest
    name: write
    command: ["bash","-c","for i in {1..100};do echo $i >> /data/opesn;sleep 1;done"]
    volumeMounts: 
    - mountPath: /data
      name: data

  - name: read
    image: centos:latest
    command: ["bash","-c","tail -f /data/opesn"]
    volumeMounts: 
    - mountPath: /data
      name: data
  volumes:
  - name: data
    emptyDir: {}
[root@k8s01 yml]#

这个pod一共是启动了两个容器,第一个容器执行了一条命令,应该都能看懂,向/data/opesn文件写数据,一秒一次,第二个容器读取这个文件,注意这是读取的本地文件,不使用emptyDir的情况下各个容器之间的文件系统是隔离的。

后三行为数据卷来源,emptyDir用的格式就是{},定义一个空目录,这个空目录挂载容器的位置是由volumesMounts下的mountPath来定义的,我挂载到了/data,具体挂载哪个数据卷是通过名字来分辨的,数据卷名我用的是data,这里可以定义多个数据卷类型,通过名字去定义挂载哪一个,下面启动查看吧。

[root@k8s01 yml]# kubectl create -f emptyDir.yaml 
pod/my-emptydir created
[root@k8s01 yml]# kubectl get pods my-emptydir 
NAME          READY   STATUS    RESTARTS   AGE
my-emptydir   2/2     Running   0          41s
[root@k8s01 yml]# 
[root@k8s01 yml]# kubectl logs my-emptydir --tail=10 -c read 
87
88
89
90
91
92
93
94
95
96
[root@k8s01 yml]# kubectl exec -it my-emptydir -c write bash
[root@my-emptydir /]# tail -f /data/opesn 
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[root@my-emptydir /]#

一个在实时写,一个在实时读,大概就是这样

hostPath

这个就是挂载node节点宿主机目录到容器中,这个用的比较多

[root@k8s01 yml]# cat hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-hostpath
spec: 
  containers: 
  - image: centos:latest
    name: write
    command: ["bash","-c","for i in {1..100};do echo $i >> /data/opesn;sleep 1;done"]
    volumeMounts: 
    - mountPath: /data
      name: data
  volumes:
  - name: data
    hostPath: 
      path: /tmp
      type: Directory

意思是将宿主机的/tmp目录挂载到容器的/data目录,类型为目录,操作还是向/data/opesn写数据,启动之后看运行节点的/tmp/opesn文件就行了,开始创建。

[root@k8s01 yml]# kubectl create -f hostpath.yaml 
pod/my-hostpath created
[root@k8s01 yml]# kubectl get pods my-hostpath 
NAME          READY   STATUS    RESTARTS   AGE
my-hostpath   1/1     Running   0          61s
[root@k8s01 yml]# 

[root@k8s01 yml]# ansible 192.168.10.92 -m shell -a "tail /tmp/opesn"
192.168.10.92 | CHANGED | rc=0 >>
22
23
24
25
26
27
28
29
30
31

就是这种结果,容器没了文件还在,但要注意宿主机要挂在的目录一定要存在,否则Pod根本无法启动

NFS网络卷

既然是用NFS,现在还没有,所以需要安装一下,nfs01作为服务端

主机名

IP地址

服务

nfs01

192.168.10.41

nfs

[root@nfs01 ~]# yum -y install nfs-utils

所有的node节点要安装如上软件包以支持挂载NFS,但不用启动。

[root@k8s01 yml]# ansible nodes -m yum -a "name=nfs-utils state=installed"

下面要配置一下服务端的nfs配置完之后启动守护进程即可

[root@nfs01 ~]# cat /etc/exports
/data *(rw,no_root_squash)
[root@nfs01 ~]# systemctl start rpcbind.service   
[root@nfs01 ~]# systemctl start nfs
[root@nfs01 ~]# showmount -e localhost
Export list for localhost:
/data *
[root@nfs01 ~]#

现在可以通过编译YAML文件将NFS目录挂载到容器了,不需要你手动挂载,交给K8S去做就行了

[root@k8s01 yml]# cat nfs.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: web
spec:
  selector:
    matchLabels:
      app: web
  replicas: 3
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
        volumeMounts: 
        - name: wwwroot
          mountPath: /usr/share/nginx/html
      volumes:
      - name: wwwroot
        nfs:
          server: 192.168.10.41
          path: /data

---

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: default
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30010
  selector:
    app: web

[root@k8s01 yml]#

NFS数据卷使用方法是和本地数据卷一样的,设置了数据源和容器位置,我是挂到了nginx默认根目录,设置一下NFS服务地址和路径,当然得先把之前的删掉,然后在创建。

[root@k8s01 yml]# kubectl create -f nfs.yaml 
deployment.apps/nginx-deployment created
service/nginx-service created
[root@k8s01 yml]# kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-6446785f49-9hwbx   1/1     Running   0          3m9s
nginx-deployment-6446785f49-nndx8   1/1     Running   0          3m9s
nginx-deployment-6446785f49-pkq8v   1/1     Running   0          3m9s
[root@k8s01 yml]#

正常启动了,下面测试一下,这个Service绑定过域名,访问一下试试。

[root@k8s01 yml]# curl https://www.opesn.com
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.17.10</center>
</body>
</html>
[root@k8s01 yml]#

现在是没权限,暂定为找不到index.html,现在向nfs目录创建一个,写点数据进去,没意外的话就能访问到了

[root@nfs01 ~]# echo 'hello world' >>/data/index.html
[root@k8s01 yml]# curl https://www.opesn.com
hello world
[root@k8s01 yml]#

没问题,说明NFS挂载正常,这就是pod实现了远程存储