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。