1.4.2 使用HostPath挂载宿主机文件

hostPath 卷可将节点上的文件或目录挂载到 Pod 上,用于 Pod 自定义日志输出或访问 Docker 内部的容器等。

hostPath常用类型有如下:

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

hostPath注意事项有如下:

  • HostPath 卷可能会暴露特权系统凭据(例如 Kubelet)或特权 API(例如容器运行时套接字),可用于容器逃逸或攻击集群的其他部分。
  • 具有相同配置(例如基于同一 PodTemplate 创建)的多个 Pod 会由于节点上文件的不同而在不同节点上有不同的行为。
  • 下层主机上创建的文件或目录只能由 root 用户写入。 你需要在特权容器中以 root 身份运行进程,或者修改主机上的文件权限以便容器能够写入 hostPath 卷。

下面进行hostPath示例说明,将主机的/etc/timezone文件挂载到 Pod 的/etc/timezone:

1.定义一个yaml文件

[root@k8s-master01 practice]# vim emptydir-hostpath.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: default
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2 
        imagePullPolicy: IfNotPresent
        name: nginx
        volumeMounts:
        - mountPath: /opt
          name: share-volume
        - mountPath: /etc/timezone
          name: timezone
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2 
        imagePullPolicy: IfNotPresent
        name: nginx2
        command:
        - sh
        - -c
        - sleep 3600
        volumeMounts:
        - mountPath: /mnt
          name: share-volume
      volumes:
      - name: share-volume
        emptyDir: {}
          #medium: Memory
      - name: timezone
        hostPath:
          path: /etc/timezone
          type: File   

关键参数说明:

# hostPath下面挂载的目录为宿主机的目录
        hostPath:
          path: /etc/timezone

# volumeMounts下面mountPath挂载的目录为容器目录
        volumeMounts:
        - mountPath: /etc/timezone
          name: timezone

2.重新部署

[root@k8s-master01 practice]# kubectl apply -f emptydir-hostpath.yaml 

3.查看pod状态

[root@k8s-master01 practice]# kubectl get po
NAME                     READY   STATUS    RESTARTS      AGE
nginx-85fdffcd78-f9pwz           2/2     Running   0               12m

4.查看挂载情况,观察到设置的nginx已成功进行挂载;而未设置的nginx2未进行挂载

[root@k8s-master01 practice]# kubectl exec nginx-85fdffcd78-f9pwz  -c nginx -- cat /etc/timezone
Asia/Shanghai

[root@k8s-master01 practice]# kubectl exec nginx-85fdffcd78-f9pwz  -c nginx2 -- cat /etc/timezone 
cat: can't open '/etc/timezone': No such file or directory

1.4.3 挂载NFS至容器

在生产环境中,考虑到数据的高可用性,仍然不建议使用NFS作为后端存储。因为NFS存在单点故障,很多企业并非对其实现高可用,并且NFS的性能存在很大的瓶颈。所以生产中,建议使用分布式存储,在公有云中建议使用公有云提供的NAS存储来替代NFS,并且NAS性能更好,可用性更高。NFS作为一个比较流行的远端存储工具,在非生产环境中是一个比较好用的选择,可以快速地搭建使用。

首先我们需要安装一下NFS

1.每台机器安装NFS客户端

yum install nfs-utils -y

2.在k8s-node01(192.168.1.34)启动nfs

# 安装nfs
[root@k8s-node01 ~]# yum install nfs-utils rpcbind -y

# 启动nfs
[root@k8s-node01 ~]# systemctl start nfs-server

在k8s-node01(192.168.1.34)查看nfs支持的版本

[root@k8s-node01 ~]# cat /proc/fs/nfsd/versions 
-2 +3 +4 +4.1 +4.2

3.在k8s-node01(192.168.1.34)上创建一个共享目录

[root@k8s-node01 ~]# mkdir  -p  /data/nfs/test_nfs  

4.在k8s-node01(192.168.134)编辑授权文件,这里网段根据自己主机来定,我这里网段是192.168.1.0/24

[root@k8s-node01 ~]# vim /etc/exports
/data/nfs/ 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)

5.在k8s-node01(192.168.1.34)配置生效

[root@k8s-node01 ~]# exportfs -r

6.在k8s-node01(192.168.1.34)重新加载NFS

[root@k8s-node01 ~]# systemctl reload nfs-server

7.在k8s-master01上进行挂载测试

[root@k8s-master01 ~]# mount -t nfs 192.168.1.34:/data/nfs /mnt/
[root@k8s-master01 ~]# cd /mnt/
[root@k8s-master01 mnt]# touch test123

8.在k8s-node01(192.168.1.34)进行验证

[root@k8s-node01 ~]# cd /data/nfs/
[root@k8s-node01 nfs]# ls
test123  test_nfs

接下来,我们对上面的测试进行卸载

1.针对上诉测试进行卸载

[root@k8s-master01 ~]# umount /mnt/

最后,和emptyDir、HostPath的配置方法类似,NFS的Volume配置也是在Volumes字段中配置的,和emptyDir不同的是,NFS属于持久化存储的一种,在Pod删除或者重启后,数据依旧会存储在NFS节点上。

1.在k8s-master01上定义一个yaml文件

[root@k8s-master01 ~]# vim nfs.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: default
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2 
        imagePullPolicy: IfNotPresent
        name: nginx
        volumeMounts:
        - mountPath: /opt
          name: share-volume
        - mountPath: /etc/timezone
          name: timezone
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2 
        imagePullPolicy: IfNotPresent
        name: nginx2
        command:
        - sh
        - -c
        - sleep 3600
        volumeMounts:
        - mountPath: /mnt
          name: share-volume
        - mountPath: /opt
          name: nfs-volume       
      volumes:
      - name: share-volume
        emptyDir: {}
          #medium: Memory
      - name: timezone
        hostPath:
          path: /etc/timezone
          type: File   
      - name: nfs-volume
        nfs:
          server: 192.168.1.34
          path: /data/nfs/test_nfs  

2.在k8s-master01重新部署

[root@k8s-master01 ~]# kubectl replace -f nfs.yaml 

3.在k8s-master01查看pod状态

[root@k8s-master01 ~]# kubectl get po 
NAME                            READY   STATUS        RESTARTS       AGE
nginx-5f974586bc-wv89n          2/2     Running       0              29s

4.在k8s-master01以容器的方式进入pod,查看挂载已经成功

[root@k8s-master01 ~]# kubectl exec -it nginx-5f974586bc-wv89n  -c nginx2 -- sh 
/ # df -Th
Filesystem           Type            Size      Used Available Use% Mounted on
overlay              overlay        35.0G      4.5G     30.4G  13% /
tmpfs                tmpfs          64.0M         0     64.0M   0% /dev
tmpfs                tmpfs           3.9G         0      3.9G   0% /sys/fs/cgroup
/dev/mapper/centos-root
                     xfs            35.0G      4.5G     30.4G  13% /mnt
192.168.1.34:/data/nfs/test_nfs
                     nfs4           35.0G      3.6G     31.4G  10% /opt

5.在k8s-master01挂载目录中创建文件

[root@k8s-master01 ~]# kubectl exec -it nginx-5f974586bc-wv89n  -c nginx2 -- sh 
/ # cd /opt/
/opt # touch 11111

6.在k8s-node01上进行结果验证

[root@k8s-node01 ~]# cd /data/nfs/test_nfs
[root@k8s-node01 test_nfs]# ls
11111

注意:Kubernetes所有的节点都需要安装上nfs-utils才可以正常挂载NFS。