为什么要同步
安装 kubernetes 的时候,我们需要用到 gcr.io/google_containers
下面的一些镜像,在国内是不能直接下载的。如果用 Self Host 方式安装,Master 上的组件除开 Kubelet 之外都用容器运行,甚至 CNI 插件也是容器运行。比如 Flannel,在 quay.io/coreos
原理
Katacoda 是一个在线学习平台,在 Web 上提供学习需要的服务器终端,里面包含学习所需的环境,我们可以利用 Docker
课程的终端来同步,因为里面有 Docker
但是手工去执行命令很麻烦,如果要同步的镜像和 Tag 比较多,手工操作那就是浪费生命。我们可以利用程序代替手工操作,不过 Katacoda 为了安全起见,不允许执行外来的二进制程序,但是可以 Shell 脚本,我写好了脚本,大家只需要粘贴进去根据自己需要稍稍修改下,然后运行就可以了。
Let’s Do It
点击 这里[1] 进入 Docker 课程。
点击 START SCENARIO
安装脚本依赖的 jq
$ apt install jq
登录 Docker Hub
$ docker login
创建脚本并赋予执行权限
$ touch sync
$ chmod +x sync
编辑脚本,可以使用自带的 vim 编辑器
$ vim sync
将脚本粘贴进去
#! /bin/bash
docker_repo="k8smirror" # your docker hub username or organization name
registry="gcr.io" # the registry of original image, e.g. gcr.io, quay.io
repo="google_containers" # the repository name of original image
sync_one(){
docker pull ${registry}/${repo}/${1}:${2}
docker tag ${registry}/${repo}/${1}:${2} docker.io/${docker_repo}/${1}:${2}
docker push docker.io/${docker_repo}/${1}:${2}
docker rmi -f ${registry}/${repo}/${1}:${2} docker.io/${docker_repo}/${1}:${2}
}
sync_all_tags() {
for image in $*; do
tags_str=`curl https://${registry}/v2/${repo}/$image/tags/list | jq '.tags' -c | sed 's/\[/\(/g' | sed 's/\]/\)/g' | sed 's/,/ /g'`
echo "$image $tags_str"
src="
sync_one(){
docker pull ${registry}/${repo}/\${1}:\${2}
docker tag ${registry}/${repo}/\${1}:\${2} docker.io/${docker_repo}/\${1}:\${2}
docker push docker.io/${docker_repo}/\${1}:\${2}
docker rmi -f ${registry}/${repo}/\${1}:\${2} docker.io/${docker_repo}/\${1}:\${2}
}
tags=${tags_str}
echo \"$image ${tags_str}\"
for tag in \${tags[@]}
do
sync_one $image \${tag}
done;"
bash -c "$src"
done
}
sync_with_tags(){
image=$1
skip=1
for tag in $*; do
if [ $skip -eq 1 ]; then
skip=0
else
sync_one $image $tag
fi
done
}
sync_after_tag(){
image=$1
start_tag=$2
tags_str=`curl https://${registry}/v2/${repo}/$image/tags/list | jq '.tags' -c | sed 's/\[/\(/g' | sed 's/\]/\)/g' | sed 's/,/ /g'`
echo "$image $tags_str"
src="
sync_one(){
docker pull ${registry}/${repo}/\${1}:\${2}
docker tag ${registry}/${repo}/\${1}:\${2} docker.io/${docker_repo}/\${1}:\${2}
docker push docker.io/${docker_repo}/\${1}:\${2}
docker rmi -f ${registry}/${repo}/\${1}:\${2} docker.io/${docker_repo}/\${1}:\${2}
}
tags=${tags_str}
start=0
for tag in \${tags[@]}; do
if [ \$start -eq 1 ]; then
sync_one $image \$tag
elif [ \$tag == '$start_tag' ]; then
start=1
fi
done"
bash -c "$src"
}
get_tags(){
image=$1
curl https://${registry}/v2/${repo}/$image/tags/list | jq '.tags' -c
}
#sync_with_tags etcd 2.0.12 2.0.13 # sync etcd:2.0.12 and etcd:2.0.13
#sync_after_tag etcd 2.0.8 # sync tag after etcd:2.0.8
#sync_all_tags etcd hyperkube # sync all tags of etcd and hyperkube
脚本中有一些参数需要根据你自己情况修改,可以使用它自带的 vim
在脚本最后,可以调用写好的函数来实现镜像同步,举例:
sync_with_tags etcd 2.0.12 2.0.13
sync_after_tag etcd 2.0.8
同步一个或多个镜像的所有 Tag
sync_all_tags etcd hyperkube
最后执行脚本
$ ./sync
这就开始同步了,Katacoda 服务器在国外,下载 gcr.io 或 quay.io 上那些镜像都很快,上传 Docker Hub 也很快。如果断连了,可以在 Docker Hub 上查最新上传的 Tag 是哪个(如:https://hub.docker.com/r/k8smirror/hyperkube/tags/ 把 k8smirror 改为你的 Docker 用户名或组织名,hyperkube 改为镜像名),然后改脚本,用 sync_after_tag 这个函数继续上传。
这就开始同步了,Katacoda 服务器在国外,下载 gcr.io 或 quay.io 上那些镜像都很快,上传 Docker Hub 也很快。如果断连了,可以在 Docker Hub 上查最新上传的 Tag 是哪个(如:https://hub.docker.com/r/k8smirror/hyperkube/tags/ 把 k8smirror 改为你的 Docker 用户名或组织名,hyperkube 改为镜像名),然后改脚本,用 sync_after_tag 这个函数继续上传。
参考资料