2 - 准备离线镜像


一、安装私有镜像仓库

参考: 私有镜像仓库

二、准备文件

Rancher HA安装需要使用来自3个源的镜像,将3个源合并到一个名为rancher-images.txt的文件中。

  • 使用可以访问Internet的计算机,访问我们的版本发布页面,找到需要安装的Rancher 2.xx版本。不要下载的版本标示rc或者Pre-release,因为它们不适用于稳定的生产环境。

Choose Release Version

  • 从发行版的Assets部分,下载以下三个文件,这些文件是在离线环境中安装Rancher所必需的:

文件描述rancher-images.txt此文件包含安装Rancher所需的所有镜像的列表。rancher-save-images.sh此脚本rancher-images.txt从Docker Hub中下载所有镜像并将所有镜像保存为rancher-images.tar.gzrancher-load-images.sh此脚本从rancher-images.tar.gz文件加载镜像,并将其推送到您的私有镜像仓库。

  • 确保rancher-save-images.sh可执行。
  1. chmod +x rancher-save-images.sh
  • 通过RKE生成镜像清单
  1. rke config --system-images -all >> ./rancher-images.txt
  • 获取cert-manager镜像,cert-manager版本查询。

    • 获取最新的cert-manager chart并解析模板以获取镜像详细信息。
  1. helm fetch stable/cert-manager
  2. helm template ./cert-manager-<version>.tgz | grep -oP '(?<=image: ").*(?=")' >> ./rancher-images.txt
  • 对镜像列表进行排序和去重,以去除重复的镜像。
  1. sort -u rancher-images.txt -o rancher-images.txt
  • 复制以下脚本保存为rancher-save-images.sh
  1. #!/bin/bash
  2. # 定义日志
  3. workdir=`pwd`
  4. log_file=${workdir}/sync_images_$(date +"%Y-%m-%d").log
  5. logger()
  6. {
  7. log=$1
  8. cur_time='['$(date +"%Y-%m-%d %H:%M:%S")']'
  9. echo ${cur_time} ${log} | tee -a ${log_file}
  10. }
  11. list="rancher-images.txt"
  12. #images="rancher-images.tar.gz"
  13. POSITIONAL=()
  14. while [[ $# -gt 0 ]]; do
  15. key="$1"
  16. case $key in
  17. -i|--images)
  18. images="$2"
  19. shift # past argument
  20. shift # past value
  21. ;;
  22. -l|--image-list)
  23. list="$2"
  24. shift # past argument
  25. shift # past value
  26. ;;
  27. -h|--help)
  28. help="true"
  29. shift
  30. ;;
  31. esac
  32. done
  33. usage () {
  34. echo "USAGE: $0 [--image-list rancher-images.txt] [--images rancher-images.tar.gz]"
  35. echo " [-l|--images-list path] text file with list of images. 1 per line."
  36. echo " [-l|--images path] tar.gz generated by docker save."
  37. echo " [-h|--help] Usage message"
  38. }
  39. if [[ $help ]]; then
  40. usage
  41. exit 0
  42. fi
  43. set -e -x
  44. mkdir -p rancher-images-$(date +"%Y-%m-%d")
  45. cd rancher-images-$(date +"%Y-%m-%d")
  46. for i in $(cat ${list});
  47. do
  48. docker pull ${i}
  49. if [ $? -ne 0 ]; then
  50. logger "${i} pull failed."
  51. else
  52. logger "${i} pull successfully."
  53. fi
  54. docker save ${i} | gzip > $(echo $i | sed "s#/#-#g; s#:#-#g").tgz
  55. if [ $? -ne 0 ]; then
  56. logger "${i} save failed."
  57. else
  58. logger "${i} save successfully."
  59. fi
  60. done
  • 复制以下脚本保存为rancher-load-images.sh
  1. #!/bin/bash
  2. # 定义日志
  3. workdir=`pwd`
  4. log_file=${workdir}/sync_images_$(date +"%Y-%m-%d").log
  5. logger()
  6. {
  7. log=$1
  8. cur_time='['$(date +"%Y-%m-%d %H:%M:%S")']'
  9. echo ${cur_time} ${log} | tee -a ${log_file}
  10. }
  11. POSITIONAL=()
  12. while [[ $# -gt 0 ]]; do
  13. key="$1"
  14. case $key in
  15. -i|--images-path)
  16. images_path="$2"
  17. shift # past argument
  18. shift # past value
  19. ;;
  20. -l|--image-list)
  21. list="$2"
  22. shift # past argument
  23. shift # past value
  24. ;;
  25. -h|--help)
  26. help="true"
  27. shift
  28. ;;
  29. esac
  30. done
  31. usage () {
  32. echo "USAGE: $0 [--image-list rancher-images.txt] [--images rancher-images.tar.gz]"
  33. echo " [-l|--images-list path] text file with list of images. 1 per line."
  34. echo " [-l|--images path] tar.gz generated by docker save."
  35. echo " [-h|--help] Usage message"
  36. }
  37. if [[ $help ]]; then
  38. usage
  39. exit 0
  40. fi
  41. set -e -x
  42. # 镜像压缩文件列表
  43. images=$(ls $images_path | grep ".tgz")
  44. cd $images_path
  45. # 导入镜像
  46. docker_load ()
  47. {
  48. for imgs in $(echo ${images});
  49. do
  50. gunzip -c ${imgs} | docker load
  51. if [ $? -ne 0 ]; then
  52. logger "${imgs} load failed."
  53. else
  54. logger "${imgs} load successfully."
  55. fi
  56. done
  57. }
  58. docker_load
  • 复制以下脚本保存为rancher-push-images.sh
  1. #!/bin/bash
  2. ## 镜像上传说明
  3. # 需要先在镜像仓库中创建 rancher 项目
  4. # 根据实际情况更改以下私有仓库地址
  5. # 定义日志
  6. workdir=`pwd`
  7. log_file=${workdir}/sync_images_$(date +"%Y-%m-%d").log
  8. logger()
  9. {
  10. log=$1
  11. cur_time='['$(date +"%Y-%m-%d %H:%M:%S")']'
  12. echo ${cur_time} ${log} | tee -a ${log_file}
  13. }
  14. images_hub() {
  15. while true; do
  16. read -p "输入镜像仓库地址(不加http/https): " registry
  17. read -p "输入镜像仓库用户名: " registry_user
  18. read -p "输入镜像仓库用户密码: " registry_password
  19. echo "您设置的仓库地址为: ${registry},用户名: ${registry_user},密码: xxx"
  20. read -p "是否确认(Y/N): " confirm
  21. if [ $confirm != Y ] && [ $confirm != y ] && [ $confirm == '' ]; then
  22. echo "输入不能为空,重新输入"
  23. else
  24. break
  25. fi
  26. done
  27. }
  28. images_hub
  29. echo "镜像仓库 $(docker login -u ${registry_user} -p ${registry_password} ${registry})"
  30. images=$(docker images -a | grep -v TAG | awk '{print $1 ":" $2}')
  31. namespace=rancher
  32. docker_push() {
  33. for imgs in $(echo ${images}); do
  34. n=$(echo ${imgs} | awk -F"/" '{print NF-1}')
  35. #如果镜像名中没有/,那么此镜像一定是library仓库的镜像;
  36. if [ ${n} -eq 0 ]; then
  37. img_tag=${imgs}
  38. #namespace=rancher
  39. #重命名镜像
  40. docker tag ${imgs} ${registry}/${namespace}/${img_tag}
  41. #删除原始镜像
  42. #docker rmi ${imgs}
  43. #上传镜像
  44. docker push ${registry}/${namespace}/${img_tag}
  45. #如果镜像名中有一个/,那么/左侧为项目名,右侧为镜像名和tag
  46. elif [ ${n} -eq 1 ]; then
  47. img_tag=$(echo ${imgs} | awk -F"/" '{print $2}')
  48. #namespace=$(echo ${imgs} | awk -F"/" '{print $1}')
  49. #重命名镜像
  50. docker tag ${imgs} ${registry}/${namespace}/${img_tag}
  51. #删除旧镜像
  52. #docker rmi ${imgs}
  53. #上传镜像
  54. docker push ${registry}/${namespace}/${img_tag}
  55. #如果镜像名中有两个/,
  56. elif [ ${n} -eq 2 ]; then
  57. img_tag=$(echo ${imgs} | awk -F"/" '{print $3}')
  58. #namespace=$(echo ${imgs} | awk -F"/" '{print $2}')
  59. #重命名镜像
  60. docker tag ${imgs} ${registry}/${namespace}/${img_tag}
  61. #删除旧镜像
  62. #docker rmi ${imgs}
  63. #上传镜像
  64. docker push ${registry}/${namespace}/${img_tag}
  65. else
  66. #标准镜像为四层结构,即:仓库地址/项目名/镜像名:tag,如不符合此标准,即为非有效镜像。
  67. echo "No available images"
  68. fi
  69. done
  70. }
  71. docker_push

三、同步镜像

  • 在可用访问Internet的主机中,使用rancher-save-images.shrancher-images.txt创建所有所需镜像的压缩包。

注意:镜像同步需要接近20GB的空磁盘空间。

  1. chmod +x rancher-save-images.sh && rancher-save-images.sh --image-list ./rancher-images.txt

结果: 在目录rancher-images-$(date +"%Y-%m-%d")生成所有镜像的压缩文件

  • 拷贝所有文件到内网环境中的Linux主机上,然后执行以下脚本去加载压缩包

注意 如果上一步下载镜像的主机可以连接内网的镜像仓库,那么此步骤可以跳过

  1. chmod +x rancher-load-images.sh && ./rancher-load-images.sh --images-path ./rancher-images-$(date +"%Y-%m-%d")
  • 使用rancher-push-images.sh把导入的docker镜像自动tag重命名,然后上传到私有镜像仓库

注意 镜像默认全部上传到镜像仓库的rancher项目下,如果镜像仓库不支持自动创建项目名(比如Harbor),需要提前手动去镜像仓库创建好项目。

  1. chmod +x rancher-push-images.sh && ./rancher-push-images.sh

执行脚本后会要求输入镜像仓库地址和用户名、用户密码