背景
项目测试环境升级部署服务时,经常出现本地容器数据丢失,镜像仓库镜像数据丢失现象,经排查容器的数据目录/var/lib/docker,容器镜像仓库镜像数据目录/mnt/docker/registrydata以及k8s数据组目录/var/lib/kubelet和主机根文件系统共用同一块磁盘空间,有些团队的服务日志没有转储持续打印占用磁盘空间,导致整个根分区容量近乎占满,出现容器数据和镜像数据被系统删除,进而导致pod crash或k8s pod被频繁驱逐等问题发生。
解决措施
我们在生产环境上,需要将docker容器数据,镜像仓库数据,k8s本地数据目录挂盘转储。
集群中数据目录
docker-ce的默认工作目录是/var/lib/docker,会存放docker镜像文件、容器日志及写到容器临时目录的文件等。
kubelet的默认工作目录是/var/lib/kubelet,会存放volume文件(包括emptyDir volume)、plugin文件等。
数据目录挂盘转储
以下操作需要严格按照顺序在每个节点上操作,假如先在node01上操作:
- 寻找一块磁盘空间大的盘挂载的目录
等所有被驱逐的pod都runing后再做后续步骤
df -h
/dev/sdb1 3.7T 110G 3.6T 3% /data2
/dev/sdc1 3.7T 33G 3.7T 1% /data1
/dev/sdd1 3.7T 35G 3.7T 1% /data3
比如 /data1 挂载在sdc1 盘,而且空间为3.7T,只使用了1%,我们就将容器数据 和 k8s 数据存放在此目录下。
- 先在节点上打上污点,驱逐已有的pod
kubectl cordon node01
kubectl drain node01 --delete-emptydir-data --ignore-daemonsets --force
等所有被驱逐的pod都runing后再做后续步骤
- 容器数据转储
mkdir -p /data1/var/lib
cp -rf /var/lib/docker /var/lib/docker.bak
systemctl stop docker
mv /var/lib/docker /data1/var/lib/
ln -s /data1/var/lib/docker /var/lib/
systemctl restart docker
kubectl get pod -A -o wide | grep node01
当node01 节点上所有 pod 都running后
rm -rf /var/lib/docker.bak
- k8s 容器数据转储
systemctl stop kubelet
cp -rf /var/lib/kubelet /var/lib/kubelet.bak
mv /var/lib/kubelet /data1/var/lib/
ln -s /data1/var/lib/kubelet /var/lib/
systemctl restart kubelet
- 恢复节点可调度
kubectl uncordon node01
最后检查下所有pod都处于running状态
镜像数据目录挂盘转储
先查看镜像服务器所在节点地址
节点上敲命令docker images
登录 173.64.48.12 节点,查询docker-registry容器id
docker inspect 容器id
确认容器镜像挂载目录所映射的主机目录是否在一个空间比较大的盘,如果在一个空间比较大的盘(判断标准和容器数据目录挂载转储相同),以下步骤不需要操作。
将docker-registry容器删除
docker stop 容器 id
docker rm 容器id
挂载目录下创建子目录并同步镜像数据
mkdir - p /data1/docker/registry
mv /mnt/data/registry /data1/docker/
注意:/mnt/data/registry 为当前镜像服务器镜像文件所在路径
重启启动镜像服务器
docker run -d -p 5000:5000 -v /data1/docker/registry:/var/lib/registry registry:v1
查看镜像是否转储成功
curl -XGET 173.64.48.12:5000/v2/_catalog