自动转存Docker镜像脚本整理

由于种种原因,在国内从k8s.gcr.io或者us.gcr.io这些镜像仓库上拉取镜像都相当慢甚至就直接拉取失败。因此对于一些比较常用的镜像建议拉取后就推送到国内各镜像仓库(例如阿里云Docker Registry)上留存起来,方便后续使用。阿里云Docker Registry免费提供了个人容器镜像托管服务,虽然有限额(3个命名空间、300个仓库),但已足够使用,具体使用方法可见https://cr.console.aliyun.com/。本文主要对一些常用镜像的自动转存脚本进行整理和记录,包括支持情况和使用方法,脚本基本是我自己编写的,如有问题可通过评论反馈给我。

环境要求


  • 一台可同时访问源镜像仓库和目标镜像仓库的主机,可以是云主机也可以是本地虚拟机
  • 操作系统CentOS7.x以上
  • 安装有Docker环境,推荐18.09.9版本,安装方法可参考下面章节

安装Docker


清理原有Docker环境(如果有的话)

1
2
3
4
5
6
7
8
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine

配置docker-ce repository

1
2
3
4
5
6
7
8
9
# 安装所需要的包,yum-utils提供了yum-config-manager工具,device-mapper-persistent-data和lvm2是设备映射存储驱动所需要的
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2

# 设置稳定版的repo仓库
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo

说明
若无法访问国外网站,可配置国内阿里云的docker源

1
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo

配置好Docker仓库后,执行如下命令安装Docker v18.09.9

1
yum install docker-ce-18.09.9 docker-ce-cli-18.09.9 containerd.io -y

启动Docker并设置开机自启

1
2
3
systemctl start docker
systemctl enable docker
systemctl status docker

设置阿里云镜像加速器(可选)

1
2
3
4
5
6
7
8
9
10
mkdir -p /etc/docker
cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://lerc8rqe.mirror.aliyuncs.com"]
}
EOF

systemctl daemon-reload
systemctl restart docker
docker info

Kubernetes镜像转存脚本


背景

使用kubeadm部署Kubernetes集群时需要拉取各Kubernetes组件的Docker镜像,默认使用的是国外k8s.gcr.io仓库地址去拉取镜像启动容器,国外仓库访问不了的,可改为国内仓库比如registry.aliyuncs.com/google_containers,但至今为止我始终没找到这个仓库的访问地址,不知道这里面具体提供了哪些镜像及其镜像版本(如有大佬知道跪求共享!!)。因此我自己编写了下面的脚本将Kubernetes部署所需的所有镜像自动拉取并转存到我个人的阿里云Docker Registry中。

使用方法

说明
此脚本支持Kubernetes v1.12.x及以上版本(目前最新版本为1.22.1,理论上后续有版本更新也是支持的)

  1. 访问https://cr.console.aliyun.com/按照新手指引依次“设置访问密码”——“创建命名空间”——“创建镜像仓库”

说明
此步如果没做,推送镜像时也会自动创建

  1. 在任意路径创建脚本,脚本名称可自定义,例如sync_k8s_image_to_koenli_registry.sh,脚本内容如下。脚本中有几项配置请根据自己实际环境进行配置。

配置参数说明

  • ALI_ENABLED:配置为true则从registry.aliyuncs.com/google_containers拉取源镜像,配置为false则从k8s.gcr.io拉取源镜像
  • REGISTRY:配置阿里云Docker Registry访问地址
  • NAMESPACE:配置阿里云Docker Registry命名空间
  • USERNAME:配置阿里云Docker Registry用户名
  • PASSWORD:配置阿里云Docker Registry密码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/bin/bash
# 此脚本支持Kubernetes1.12及以上版本
WORKDIR=`pwd`
# 配置为true则从registry.aliyuncs.com/google_containers拉取源镜像,配置为false则从k8s.gcr.io拉取源镜像
ALI_ENABLED=true
# 配置阿里云Docker Registry访问地址
REGISTRY=registry.cn-hangzhou.aliyuncs.com
# 配置阿里云Docker Registry命名空间
NAMESPACE=koenli
# 配置阿里云Docker Registry用户名
USERNAME=123456789@qq.com
# 配置阿里云Docker Registry密码
PASSWORD=123456

# 清空日志文件
echo > ${WORKDIR}/logs

# 配置kubernetes repository
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

yum clean all
yum remove kubeadm -y

# 生成版本列表(1.12及以上版本)
yum list --showduplicates kubeadm --disableexcludes=kubernetes | awk '{print $2}' | egrep -e "1.*" | egrep -v -e "^1[.][6-9]" | egrep -v -e "^1[.][1][0-1]" > ${WORKDIR}/versions

# 登录阿里云Docker Registry
docker login --username=${USERNAME} --password=${PASSWORD} ${REGISTRY}

# 逐个版本拉取镜像推送镜像
for version in `cat ${WORKDIR}/versions`
do
# 安装对应版本的kubeadm
yum remove kubeadm -y
yum install kubeadm-${version} -y

version=${version//-0/}
version=${version//-1/}
major=`echo ${version} | awk -F '.' '{print $1}'`
minor=`echo ${version} | awk -F '.' '{print $2}'`

# 打印当前Kubernetes版本信息
echo -e "\033[44;37m ==== Kubernetes-${version} ==== \033[0m" | tee -a ${WORKDIR}/logs

# 获取当前版本Kubernetes所需的镜像列表
kubeadm config images list --kubernetes-version=${version} > ${WORKDIR}/imagelist
for image in `cat ${WORKDIR}/imagelist`
do
# 拉取源镜像
if [[ ${ALI_ENABLED} = "true" ]]
then
if [[ ${image} =~ 'coredns' ]] && [[ ${major} -eq 1 ]] && [[ ${minor} -ge 21 ]]
then
srcimage=${image//k8s.gcr.io\/coredns\//registry.aliyuncs.com\/google_containers\/}
srcimage=${srcimage//coredns:v/coredns:}
else
srcimage=${image//k8s.gcr.io\//registry.aliyuncs.com\/google_containers\/}
fi
else
srcimage=${image}
fi
echo -e "\033[44;37m ==== 拉取${srcimage} ==== \033[0m" | tee -a ${WORKDIR}/logs
docker pull ${srcimage}
if [[ $? -eq 0 ]]
then
echo -e "\033[32m 拉取${srcimage}成功 \033[0m" | tee -a ${WORKDIR}/logs
else
echo -e "\033[31m 拉取${srcimage}失败 \033[0m" | tee -a ${WORKDIR}/logs
fi

# 重新给镜像打tag
if [[ ${image} =~ 'coredns' ]] && [[ ${major} -eq 1 ]] && [[ ${minor} -ge 21 ]]
then
dstimage="${image//k8s.gcr.io\/coredns\//$REGISTRY/$NAMESPACE/}"
else
dstimage="${image//k8s.gcr.io\//$REGISTRY/$NAMESPACE/}"
fi
echo -e "\033[44;37m ==== 给${srcimage}镜像重新打tag ==== \033[0m" | tee -a ${WORKDIR}/logs
echo "docker tag ${srcimage} ${dstimage}" | tee -a ${WORKDIR}/logs
docker tag ${srcimage} ${dstimage}
if [[ $? -eq 0 ]]
then
echo -e "\033[32m 成功 \033[0m" | tee -a ${WORKDIR}/logs
else
echo -e "\033[31m 失败 \033[0m" | tee -a ${WORKDIR}/logs
fi

# 推送镜像
echo -e "\033[44;37m ==== 推送${dstimage} ==== \033[0m" | tee -a ${WORKDIR}/logs
echo "docker push $dstimage" | tee -a ${WORKDIR}/logs
docker push $dstimage
if [[ $? -eq 0 ]]
then
echo -e "\033[32m 推送${dstimage}成功 \033[0m" | tee -a ${WORKDIR}/logs
else
echo -e "\033[31m 推送${dstimage}失败 \033[0m" | tee -a ${WORKDIR}/logs
fi
done
echo -e "\033[44;37m ==== 分割线 ==== \033[0m" | tee -a ${WORKDIR}/logs
echo ""
done

配置完成后可执行以下命令执行脚本:

1
sh sync_k8s_image_to_koenli_registry.sh

说明
执行日志将输出到脚本所在路径下的logs文件中,执行过程中可通过tail -f logs进行实时查看