原文链接:https://fuckcloudnative.io/posts/docker-registry-proxy/

在使用 Docker 和 Kubernetes 时,我们经常需要访问 gcr.ioquay.io 镜像仓库,由于众所周知的原因,这些镜像仓库在中国都无法访问,唯一能访问的是 Docker Hub,但速度也是奇慢无比。gcr.azk8s.cngcr.io 镜像仓库的代理站点,原来可以通过 gcr.azk8s.cn 访问 gcr.io 仓库里的镜像,但是目前 *.azk8s.cn 已经仅限于 Azure 中国的 IP 使用,不再对外提供服务了。国内其他的镜像加速方案大多都是采用定时同步的方式来缓存,这种方法是有一定延迟的,不能保证及时更新,ustc 和七牛云等镜像加速器我都试过了,非常不靠谱,很多镜像都没有。

为了能够顺利访问 gcr.io 等镜像仓库,我们需要在墙外自己搭建一个类似于 gcr.azk8s.cn 的镜像仓库代理站点。利用 Docker 的开源项目 registry 就可以实现这个需求,registry 不仅可以作为本地私有镜像仓库,还可以作为上游镜像仓库的缓存,也就是 pull through cache

先来感受下速度:

1. 前提条件


  • 一台能够施展魔法的服务器(你懂得,可以直接访问 gcr.io)
  • 一个域名和域名相关的 SSL 证书(docker pull 镜像时需要验证域名证书),一般用 Let's Encrypt 就够了。

2. 核心思路


registry 可以通过设置参数 remoteurl 将其作为远端仓库的缓存仓库,这样当你通过这个私有仓库的地址拉取镜像时,regiistry 会先将镜像缓存到本地存储,然后再提供给拉取的客户端(有可能这两个步骤是同时的,我也不太清楚)。我们可以先部署一个私有 registry,然后将 remoteurl 设为需要加速的镜像仓库地址,基本上就可以了。

3. 定制 registry

为了能够支持缓存 docker.iogcr.iok8s.gcr.ioquay.ioghcr.io 等常见的公共镜像仓库,我们需要对 registry 的配置文件进行定制,Dockerfile 如下:

FROM registry:2.6
LABEL maintainer="registry-proxy Docker Maintainers https://fuckcloudnative.io"
ENV PROXY_REMOTE_URL="" 
    DELETE_ENABLED=""
COPY entrypoint.sh /entrypoint.sh

其中 entrypoint.sh 用来将环境变量传入配置文件:

{{< expand "entrypoint.sh" >}}

#!/bin/sh

set -e

CONFIG_YML=/etc/docker/registry/config.yml

if [ -n "$PROXY_REMOTE_URL" -a `grep -c "$PROXY_REMOTE_URL" $CONFIG_YML` -eq 0 ]; then
    echo "proxy:" >> $CONFIG_YML
    echo "  remoteurl: $PROXY_REMOTE_URL" >> $CONFIG_YML
    echo "  username: $PROXY_USERNAME" >> $CONFIG_YML
    echo "  password: $PROXY_PASSWORD" >> $CONFIG_YML
    echo "------ Enabled proxy to remote: $PROXY_REMOTE_URL ------"
elif [ $DELETE_ENABLED = true -a `grep -c "delete:" $CONFIG_YML` -eq 0 ]; then
    sed -i '/rootdirectory/a  delete:' $CONFIG_YML
    sed -i '/delete/a    enabled: true' $CONFIG_YML
    echo "------ Enabled local storage delete -----"
fi

sed -i "/headers/a    Access-Control-Allow-Origin: ['*']" $CONFIG_YML
sed -i "/headers/a    Access-Control-Allow-Methods: ['HEAD', 'GET', 'OPTIONS', 'DELETE']" $CONFIG_YML
sed -i "/headers/a    Access-Control-Expose-Headers: ['Docker-Content-Digest']" $CONFIG_YML

case "$1" in
    *.yaml|*.yml) set -- registry serve "$@" ;;
    serve|garbage-collect|help|-*) set -- registry "$@" ;;
esac

exec "$@"

{{< /expand >}}

4. 启动缓存服务

构建好 Docker 镜像之后,就可以启动服务了。如果你不想自己构建,可以直接用我的镜像:yangchuansheng/registry-proxy

一般来说,即使你要同时缓存 docker.iogcr.iok8s.gcr.ioquay.ioghcr.io,一台 1C 2G 的云主机也足够了(前提是你不在上面跑其他的服务)。我的博客、评论服务和其他一堆乱七八糟的服务都要跑在云主机上,所以一台是不满足我的需求的,我直接买了两台腾讯云香港轻量级服务器。

既然买了两台,肯定得组个 k3s 集群啦,看主机名就知道我是用来干啥的。其中 2C 4G 作为 master 节点,1C 2G 作为 node 节点。

docker.io 为例,创建资源清单:

{{< expand "dockerhub.yaml" >}}

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dockerhub
  labels:
    app: dockerhub
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dockerhub
  template:
    metadata:
      labels:
        app: dockerhub
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - dockerhub
              topologyKey: kubernetes.io/hostname
            weight: 1
      dnsPolicy: None
      dnsConfig:
        nameservers:
          - 8.8.8.8
          - 8.8.4.4
      containers:
      - name: dockerhub
        image: yangchuansheng/registry-proxy:latest
        env:
        - name: PROXY_REMOTE_URL
          value: https://registry-1.docker.io
        - name: PROXY_USERNAME
          value: yangchuansheng
        - name: PROXY_PASSWORD
          value: ********
        ports:
        - containerPort: 5000
          protocol: TCP
        volumeMounts:
        - mountPath: /etc/localtime
          name: localtime
        - mountPath: /var/lib/registry
          name: registry
      volumes:
      - name: localtime
        hostPath:
          path: /etc/localtime
      - name: registry
        hostPath:
          path: /var/lib/registry
---
apiVersion: v1
kind: Service
metadata:
  name: dockerhub
  labels:
    app: dockerhub
spec:
  selector:
    app: dockerhub
  ports:
    - protocol: TCP
      name: http
      port: 5000
      targetPort: 5000

{{< /expand >}}

使用资源清单创建对应的服务:


    

  
内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/ryanyangcs/p/14451427.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!