Shell脚本如何配置私有镜像仓库

wen 实用脚本 1

Shell脚本如何配置私有镜像仓库:企业级自动化部署实战指南

目录导读

  1. 私有镜像仓库的核心价值 – 为什么你需要自建镜像仓库?
  2. 环境准备与仓库选型 – Harbor、Registry、Nexus对比
  3. Shell脚本实现仓库配置 – 从Docker守护进程到认证交互
  4. 自动化推送与拉取镜像 – 脚本中的HTTPS与安全策略
  5. 常见故障与问答 – 403错误、证书问题、Cgroup驱动冲突

私有镜像仓库的核心价值

在容器化开发流程中,私有镜像仓库是连接CI/CD流水线的枢纽,通过Shell脚本配置私有镜像仓库,你可以实现以下目标:

Shell脚本如何配置私有镜像仓库

  • 加速镜像拉取:公网仓库可能因限流、地域延迟影响部署效率。
  • 安全合规:敏感业务镜像无需上传至公网,规避数据泄露风险。
  • 版本控制:结合Git标签自动生成镜像版本,避免“latest”混乱。

关键场景:某金融科技公司通过内网Harbor仓库,将镜像部署时间从25秒降至2秒(基于1Gbps内网带宽测试)。


环境准备与仓库选型

主流方案对比

仓库类型 推荐场景 资源占用 认证方式 脚本友好度
Harbor 企业级,需要UI、多租户 2C4G起步 LDAP/OAuth/基础认证 中(API复杂)
Registry 2.0 轻量级、测试环境 256MB内存足够 基础认证 高(纯命令行)
Nexus Repository Java生态、通用制品 4C8G起步 集成LDAP 低(XML配置)

推荐选择:如果你需要Shell脚本自动化配置,Registry 2.0 结合 nginx 反向代理是最灵活的方式,以下脚本示例默认使用Registry v2


Shell脚本实现仓库配置

1 基础配置脚本(一键搭建)

#!/bin/bash
# 文件名: setup-private-registry.sh
# 用途: 在 CentOS 7.9+/Ubuntu 20.04 上部署私有镜像仓库
REGISTRY_NAME="myregistry.internal"
REGISTRY_PORT="5000"
DATA_DIR="/data/registry"
CERT_DIR="/etc/ssl/registry"
# 第1步:创建目录与自签名证书(生产环境请使用CA签发)
mkdir -p ${DATA_DIR} ${CERT_DIR}
openssl req -newkey rsa:4096 -nodes -sha256 -keyout ${CERT_DIR}/domain.key \
  -x509 -days 3650 -out ${CERT_DIR}/domain.crt \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=${REGISTRY_NAME}"
# 第2步:配置Docker守护进程信任私仓证书
if [ -d /etc/docker/certs.d ]; then
  mkdir -p /etc/docker/certs.d/${REGISTRY_NAME}:${REGISTRY_PORT}
  cp ${CERT_DIR}/domain.crt /etc/docker/certs.d/${REGISTRY_NAME}:${REGISTRY_PORT}/ca.crt
fi
# 第3步:启动Registry容器(内置基本认证)
docker run -d --restart=always --name registry \
  -v ${DATA_DIR}:/var/lib/registry \
  -v ${CERT_DIR}:/certs \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
  -e REGISTRY_AUTH=htpasswd \
  -e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
  -v ${DATA_DIR}/auth:/auth \
  -p ${REGISTRY_PORT}:5000 \
  registry:2.8.3
# 第4步:创建初始用户(admin/密码:Admin123!)
docker exec registry htpasswd -Bbn admin Admin123! > ${DATA_DIR}/auth/htpasswd
echo "私有仓库已就绪:https://${REGISTRY_NAME}:${REGISTRY_PORT}"
echo "用户:admin / 密码:Admin123!"

2 客户端登录脚本(自动交互)

#!/bin/bash
# login-private-registry.sh
REGISTRY_URL="myregistry.internal:5000"
USER="admin"
PASS="Admin123!"
CERT_FILE="/etc/docker/certs.d/${REGISTRY_URL}/ca.crt"
# 首次登录前先将证书加入系统信任
if [ ! -f "${CERT_FILE}" ]; then
  echo "错误:未找到证书文件,请先执行 setup-private-registry.sh"
  exit 1
fi
# 使用 expect 或 docker login 结合变量(非交互式)
echo "${PASS}" | docker login ${REGISTRY_URL} -u ${USER} --password-stdin
if [ $? -eq 0 ]; then
  echo "登录成功!可通过 ${REGISTRY_URL} 推送/拉取镜像。"
else
  echo "登录失败,请检查用户名密码或HTTPS证书。"
fi

自动化推送与拉取镜像

批量推送脚本(支持多镜像)

#!/bin/bash
# push-images.sh - 将本地镜像批量推送至私有仓库
PRIVATE_REGISTRY="myregistry.internal:5000"
IMAGE_LIST=("nginx:1.25" "postgres:16" "alpine:3.19")
DEST_PREFIX="${PRIVATE_REGISTRY}/myteam"
for img in "${IMAGE_LIST[@]}"; do
  echo "正在处理:${img}..."
  # 步骤1:拉取公网镜像(若本地不存在)
  docker pull ${img} 2>/dev/null || echo "本地已有:${img}"
  # 步骤2:打标签并推送
  docker tag ${img} ${DEST_PREFIX}/${img}
  docker push ${DEST_PREFIX}/${img}
  # 步骤3:清理临时标签(保留原始镜像)
  docker rmi ${DEST_PREFIX}/${img}
done
echo "所有镜像推送完成!"
echo "可以通过以下命令验证:"
echo "curl -k https://${PRIVATE_REGISTRY}/v2/_catalog | jq ."

常见故障与问答

Q1:为什么 docker push 返回 “403 Forbidden”?

A:最常见的原因是认证失效令牌(Token)过期
解决

  1. 重新执行 docker login 脚本。
  2. 检查htpasswd文件是否生成正确:docker exec registry cat /auth/htpasswd
  3. 若使用 Harbor,需检查用户是否有“推送”角色。

Q2:配置后仍提示“x509: certificate signed by unknown authority”?

A:Docker守护进程未信任自签名证书。
解决

  • 确保 /etc/docker/certs.d/仓库地址/ 目录下 ca.crt 存在。
  • 重启Docker服务:systemctl restart docker
  • 如果使用Rootless模式,证书路径需改为 ~/.config/docker/certs.d/

Q3:脚本执行后 curl 访问能通过,但 docker pull 失败?

A:检查是否使用了私有仓库的内部域名,Docker会跳过DNS解析,直接尝试IP连接。
验证:在 /etc/hosts 添加映射:
echo "192.168.1.100 myregistry.internal" >> /etc/hosts

Q4:如何从脚本中更新已有镜像的标签?

A:使用 docker tag 配合循环:

for tag in v1.0 v1.1; do
  docker tag myapp:${tag} ${PRIVATE_REGISTRY}/myapp:${tag}
  docker push ${PRIVATE_REGISTRY}/myapp:${tag}
done

最佳实践要点

通过以上Shell脚本,你可以快速配置一个生产级私有镜像仓库,记住三个核心原则:

  1. 证书先行 – 无论是否生产环境,永远使用HTTPS(自签名至少比明文安全)。
  2. 认证隔离 – 每个团队应使用独立htpasswd或集成LDAP,避免“超级管理员”通行所有仓库。
  3. 垃圾回收 – 定期执行 docker exec registry /bin/registry garbage-collect /etc/docker/registry/config.yml 清理废弃层。

扩展建议:在CI/CD流水线中,将 setup-private-registry.sh 作为初始化步骤,配合Ansible管理多节点证书分发,可实现5分钟部署一套完整的私有仓库集群。

抱歉,评论功能暂时关闭!