部署容器镜像源
有的时候,需要频繁使用某个镜像,而为了节约本地空间,经常清理缓存。这就导致需要重复从互联网拉取,不仅慢还会造成带宽浪费。
所幸,有一个workaroud: 部署镜像代理,它将镜像存储到HDD中。一旦命中缓存,就能获得瞬间拉取的体验。
安装镜像仓库
推荐配置proxy.ttl: 0s,可以每次拉取都检查更新。
默认源
为默认源(Docker Hub)设置镜像比较简单,只需编辑配置 /etc/docker/daemon.json.
json
{
"insecure-registries": [
"localhost:5001",
],
"registry-mirrors": [
"http://localhost:5001"
]
}自用清理脚本
垃圾清理
sh
#!/bin/bash
# ================= 配置区域 =================
# NAS SSH 连接信息
NAS_SSH="nas"
# 公共基础路径 (末尾不要带 /)
NAS_BASE_PATH="/mnt/pool_1/Service/Runtime/container_cache"
# 服务配置列表
# 格式: "Docker容器名:NAS子目录名"
# 例如: "reg-docker-hub:dockerhub" 代表容器是 reg-docker-hub,路径是 .../dockerhub/data
TARGETS=(
"reg-docker-hub:dockerhub"
"reg-mcr:mcr"
)
# ===========================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd $SCRIPT_DIR && echo cd $SCRIPT_DIR
LOG_FILE="/var/log/registry_wipe.log"
log() {
local message="$1"
echo "$(date +"%Y-%m-%d %H:%M:%S") - ${message}" | tee -a "${LOG_FILE}"
}
log "=== 开始 TrueNAS 远程清理任务 ==="
# 遍历配置数组
for item in "${TARGETS[@]}"; do
# 使用 IFS (Internal Field Separator) 解析 "容器:目录" 字符串
IFS=':' read -r CONTAINER_NAME SUB_DIR <<<"$item"
# 自动拼接出完整的 NAS 路径
# 最终路径 = 基础路径 / 子目录 / data / docker
FULL_NAS_PATH="${NAS_BASE_PATH}/${SUB_DIR}/data/docker/*"
log "[处理任务] 容器: $CONTAINER_NAME"
log "目标路径: $FULL_NAS_PATH"
# ----------------------------------------------------
# 停止容器
# ----------------------------------------------------
if [ "$(docker ps -q -f name=^/${CONTAINER_NAME}$)" ]; then
docker stop "$CONTAINER_NAME" 2>&1
else
log "容器未运行,跳过停止步骤。"
fi
# ----------------------------------------------------
# SSH 远程删除
# ----------------------------------------------------
log "SSH 远程删除 TrueNAS 路径: $FULL_NAS_PATH"
ssh -o ConnectTimeout=5 "$NAS_SSH" "rm -rf '$FULL_NAS_PATH'" 2>&1
if [ $? -eq 0 ]; then
log "删除成功 (NAS Local execution)。"
else
log "错误: SSH 删除失败,请检查路径或权限!"
docker start "$CONTAINER_NAME"
continue
fi
# ----------------------------------------------------
# 启动容器
# ----------------------------------------------------
docker start "$CONTAINER_NAME" 2>&1
log "$CONTAINER_NAME 重置完成。"
done
docker compose up -d
log "=== 任务结束 ==="第三方仓库
Docker 的镜像源功能只对默认源有效。要实现从镜像源拉取,有2种方法:显式指定, 透明代理
shell
docker pull localhost:5000/azure-sdk/azure-mcp对于不能修改镜像源的地方,只能采取比较hack的方法:透明代理。基本原理
- 自定义DNS:指定被加速的域名的IP为反代的IP
- 反向代理:默认端口即可访问
- 添加信任:以上方法通常不被信任
反向代理
这里提供适用于 1Panel 用户的 OpenResty 的配置示例
假设项目的根目录是 /opt/1panel/www/sites/docker-proxy/.
nginx
server {
listen 80 ;
listen 5042 ;
listen 443 ssl ;
server_name home-cloud-manual.jfyy.xyz home.cloud.manual.jfyy.xyz hcm.jfyy.xyz 192.168.5.18;
index index.php index.html index.htm default.php default.htm default.html;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
access_log /www/sites/home-cloud-manual.jfyy.xyz/log/access.log main;
error_log /www/sites/home-cloud-manual.jfyy.xyz/log/error.log;
location ^~ /.well-known/acme-challenge {
allow all;
root /usr/share/nginx/html;
}
root /www/sites/home-cloud-manual.jfyy.xyz/index;
error_page 497 https://$host$request_uri;
ssl_certificate /www/sites/home-cloud-manual.jfyy.xyz/ssl/fullchain.pem;
ssl_certificate_key /www/sites/home-cloud-manual.jfyy.xyz/ssl/privkey.pem;
ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK:!KRB5:!SRP:!CAMELLIA:!SEED;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
proxy_set_header X-Forwarded-Proto https;
http2 on;
}/opt/1panel/www/sites/docker-proxy/proxy/proxy_params.conf
conf
# Docker Registry 代理通用参数
# 传递客户端原始请求的Host头给后端
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 告知后端客户端是通过HTTPS连接的
proxy_set_header X-Forwarded-Proto "https";
# 启用 WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 关闭缓冲,对拉取大镜像至关重要
proxy_buffering off;
proxy_request_buffering off;
# 允许上传任意大小的镜像层
client_max_body_size 0;
# 设置较长的超时时间 (15分钟)
proxy_connect_timeout 900s;
proxy_send_timeout 900s;
proxy_read_timeout 900s;添加信任
添加信任有2种方法:应用层配置,信任 CA 根证书。
应用层配置
编辑/etc/docker/daemon.json
json
{
"insecure-registries": [
"mcr.microsoft.com"
]
}shell
systemctl restart docker信任 CA 根证书
shell
Private_cert_Dir="/etc/TLS/my" # 私有证书目录
CA_PATH="${Private_cert_Dir}/ca"
CERTS_PATH="${Private_cert_Dir}/certs"
# 创建 CA 证书
docker run --rm -it -v ${CA_PATH}:/root/.local/share/mkcert alpine/mkcert mkcert -install
# 创建服务端证书
docker run --rm -it -v ${CA_PATH}:/root/.local/share/mkcert:ro -v ${CERTS_PATH}:/certs -w /certs alpine/mkcert mkcert mcr.microsoft.com registry.k8s.io k8s.gcr.io quay.io ghcr.io gcr.iosudo apt-get install -y mkcert
ln -s /etc/TLS/my/ca $(mkcert -CAROOT) # 链接CA证书到 mkcert 的默认位置
apt-get update && apt-get install -y mkcert # 安装 mkcert
mkcert -install # 使系统信任证书
# 卸载 mkcert(可选)
rm -rf "$(mkcert -CAROOT)"
apt-get remove mkcert自定义DNS
Debian系的hosts在/etc/hosts
bash
127.0.0.1 mcr.microsoft.com