比较

对比项目 Nexus3 Registry2
支持仓库类型 Maven,Docker等,比较多 仅Docker
支持镜像源 可对多个目标镜像源进行代理 仅支持一个目标镜像源进行代理
资源消耗 资源占用多,建议4核4G 资源占用少,1核1G
界面操作 界面UI和操作健全 需安装Registry UI镜像辅助,功能不强

简单来讲,Nexus3比Harbor轻比Registry重

特别强调
本方案主要目的是实现生产环境有一个本地仓库,从而加速在集群节点重启后发生节点调度变化又要去外部拉取镜像造成系统恢复变慢的问题。
开发或测试环境一旦使用就必需每次使用不同版本(即不能使用同一个版本号),否则需要手动去删除本地仓库中的镜像标签,不删除的话即使demployment配置了拉取策略为Always也是会从本地拿到旧的版本。

Nexus3代理

推荐设置为4000m(即4核)以上cpu

Available CPUs The host system is allocating a maximum of 1 cores to the application. A minimum of 4 is recommended.

---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s.kuboard.cn/name: nexus3
  name: nexus3
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s.kuboard.cn/name: nexus3
  template:
    metadata:
      labels:
        k8s.kuboard.cn/name: nexus3
    spec:
      containers:
        - env:
            - name: INSTALL4J_ADD_VM_PARAMS
              value: >-
                -Xms128m -Xmx512m -XX:MaxDirectMemorySize=512m
                -Djava.util.prefs.userRoot=/nexus-data/javaprefs
          image: 'sonatype/nexus3:3.37.3'
          imagePullPolicy: IfNotPresent
          name: nexus3
          ports:
            - containerPort: 8081
              name: web
              protocol: TCP
            - containerPort: 6001
              name: hosted
              protocol: TCP
            - containerPort: 6000
              name: group
              protocol: TCP
          volumeMounts:
            - mountPath: /nexus-data
              name: volume-data
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      volumes:
        - hostPath:
            path: /data/nexus
            type: ''
          name: volume-data

---
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s.kuboard.cn/name: nexus3
  name: nexus3
  namespace: default
spec:
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  ports:
    - name: web
      nodePort: 30906
      port: 8081
      protocol: TCP
      targetPort: 8081
    - name: hosted
      nodePort: 31884
      port: 6001
      protocol: TCP
      targetPort: 6001
    - name: group
      nodePort: 32762
      port: 6000
      protocol: TCP
      targetPort: 6000
  selector:
    k8s.kuboard.cn/name: nexus3
  type: NodePort

访问并登录

  • 浏览器访问 http://nodeIp:30906

  • 点击右上角 Sign in 开始登录,用户为 admin ,密码在 /nexus-data/admin.password 中:

    cat /data/nexus/admin.password
  • 登录成功后 点击 next ,需要修改密码,修改个自己的密码:

  • 下面弹出的是否启用匿名访问,我这里选是:

  • 最后点击 Finish 环境就搭建完成了,下面开始配置 docker 私有、代理仓库吧。

配置 docker 私有、代理 仓库

下面开始搭建上面的模式:

  1. 首先我们先创建三个 Blob Stores ,分别存放三种模式产生的文件:
    首先点击上方的设置图标,选择 Blob Stores,然后点击 右边的 Create Blob Stores

  • 创建 docker-hosted

  • 创建 docker-proxy

  • 创建 docker-group

  • 创建完成后在列表中可以看到

  1. 下面开始创建 hosted 模式私服仓库
    点击当前页的 Repositories ,然后点击 左上角的 Create repositories:

选中 docker(hosted) 模式:

指定基本信息及配置:

其中开放协议使用的 HTTP,端口就是上面安装时候释放的 6001 ,下面 Blob store 选择上面创建的:

最后点击最下面的 Create repositories完成创建。

  1. 接着创建 proxy 模式代理仓库
    选中 docker(proxy),代理模式可以不用开放协议端口,因为后面拉取镜像统一使用 group 模式进行拉取:

同样填写信息:

下面需要填写一个代理地址,可以指定为:https://registry-1.docker.io ,下面 Docker Index 可以使用 Docker Hub 的:

下面 Blob store 同样使用上面创建的:

最后点击最下面的 Create repositories完成创建。

由于需要代理凌云的仓库代理参考以上步骤

  • 名称为: docker-proxy-lingyun
  • 代理地址指定为:https://dev.flyrise.cn:8082
  • Docker Index则使用: Use proxy registry (specified above)
  1. 接着创建 group 模式代理仓库
    选中 docker(group):

同样填写信息,注意端口需要使用 6000 了:

下面 Blob store 同样使用上面创建的,注意下面的 group 需要选中上面创建好的两种模式:

注意:把docker-proxy-lingyun顺序调前一点

最后点击最下面的 Create repositories完成创建。

到这就已经创建好三种模式了,可以在列表中看到创建的仓库:

由于没有使用 SSL证书和域名,需要修改下 Realms 中的配置:

至此已基本配置完成,更多配置参考: https://blog.csdn.net/qq_43692950/article/details/125471729

Registry代理

经过验证发现
1、只能配置一个目标镜像代理
2、一旦启用proxy代理后将无法删除镜像,会报:{“errors”:[{“code”:”UNSUPPORTED”,”message”:”The operation is unsupported.”}]}

更多配置参数参考:https://distribution.github.io/distribution/about/configuration/#proxy

apiVersion: v1
kind: ConfigMap
metadata:
  name: registry-config
data:
  config.yml: |
    version: 0.1
    log:
      fields:
        service: registry
    storage:
      cache:
        blobdescriptor: inmemory
      filesystem:
        rootdirectory: /var/lib/registry
      delete:
        enabled: true
    http:
      addr: :5000
      headers:
        X-Content-Type-Options: [nosniff]
        Access-Control-Allow-Origin: ['*']
    health:
      storagedriver:
        enabled: true
        interval: 10s
        threshold: 3
    proxy:
      remoteurl: 'https://dev.flyrise.cn:8082'

---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s.kuboard.cn/name: registry
  name: registry
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s.kuboard.cn/name: registry
  template:
    metadata:
      labels:
        k8s.kuboard.cn/name: registry
    spec:
      containers:
        - image: 'registry:2.8.1'
          name: registry
          ports:
            - containerPort: 5000
              #hostPort: 5000
              name: api
              protocol: TCP
          volumeMounts:
            - mountPath: /etc/docker/registry
              name: registry-config
              readOnly: true
            - mountPath: /var/lib/registry
              name: registry-data
      volumes:
        - configMap:
            name: registry-config
          name: registry-config
        - hostPath:
            path: /data/registry
            type: DirectoryOrCreate
          name: registry-data

---
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s.kuboard.cn/name: registry
  name: registry
  namespace: default
spec:
  ports:
    - name: api
      port: 5000
      protocol: TCP
      targetPort: 5000
  selector:
    k8s.kuboard.cn/name: registry
  type: ClusterIP

UI
参考:https://github.com/Joxit/docker-registry-ui/tree/main/examples/ui-as-proxy

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s.kuboard.cn/name: registry-ui
  name: registry-ui
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s.kuboard.cn/name: registry-ui
  template:
    metadata:
      labels:
        k8s.kuboard.cn/name: registry-ui
    spec:
      containers:
        - env:
            - name: NGINX_PROXY_PASS_URL
              value: 'http://registry:5000'
            - name: SINGLE_REGISTRY
              value: 'true'
            - name: REGISTRY_TITLE
              value: My Private Docker Registry UI
          image: 'joxit/docker-registry-ui:2-debian'
          imagePullPolicy: IfNotPresent
          name: registry-ui
      dnsPolicy: ClusterFirst
      restartPolicy: Always

---
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s.kuboard.cn/name: registry-ui
  name: registry-ui
  namespace: default
spec:
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  ports:
    - name: web
      port: 80
      protocol: TCP
      targetPort: 80
  selector:
    k8s.kuboard.cn/name: registry-ui
  type: NodePort

K8s环境修改containerd配置文件

生成默认配置

containerd config default > /etc/containerd/config.toml

版本1 - sealos 3.x

sealos 3.x + kubernetes 1.16.9 的 containerd v1.2.6默认配置精减后如下,亲测有用

# 添加域名映射
echo 10.62.17.41 dev.flyrise.cn >> /etc/hosts

# 在 /etc/docker/daemon.json 增加 dev.flyrise.cn:8082
sed -i 's#\["127.0.0.1"\]#\["127.0.0.1", "dev.flyrise.cn:8082"\]#' /etc/docker/daemon.json

# 给 dockerd 发送 SIGHUP 信号,dockerd 收到信号后会 reload 配置
kill -SIGHUP $(pidof dockerd)

sealos 3.x + kubernetes 1.21.1 的 containerd v1.4.3默认配置精减后如下,亲测有用

version = 2

[plugins]
  [plugins."io.containerd.grpc.v1.cri"]
    max_container_log_line_size = -1
    max_concurrent_downloads = 20
    [plugins."io.containerd.grpc.v1.cri".registry]
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
          endpoint = ["http://10.62.17.41:32762"]
        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."dev.flyrise.cn:8082"]
          endpoint = ["http://10.62.17.41:32762"]

      [plugins."io.containerd.grpc.v1.cri".registry.configs]
        [plugins."io.containerd.grpc.v1.cri".registry.configs."10.62.17.41:32762".tls]
          insecure_skip_verify = true

版本2 - sealos 4.x

sealos 4.x + kubernetes v1.24.9 + containerd v1.6.19 可以使用 config_path 实现配置,示例如下:

version = 2

[plugins]
  [plugins."io.containerd.grpc.v1.cri"]
    max_container_log_line_size = -1
    max_concurrent_downloads = 20
    [plugins."io.containerd.grpc.v1.cri".registry]

      config_path = "/etc/containerd/certs.d"

/etc/containerd/certs.d/docker.io 添加 hosts.toml

server = "https://docker.io"

[host."http://10.62.17.41:32762"]
  capabilities = ["pull","resolve","push"]
  skip_verify = true

/etc/containerd/certs.d/dev.flyrise.cn:8082 添加 hosts.toml

server = "https://dev.flyrise.cn:8082"

[host."http://10.62.17.41:32762"]
  capabilities = ["pull","resolve","push"]
  skip_verify = true

http://10.62.17.41:32762 为加速服务器nexus3的nodeport地址

重启containerd

#重新加载配置并重启containerd
systemctl daemon-reload && systemctl restart containerd

注意:
1 这个配置文件是给crictl和kubelet使用,ctr是不可以用这个配置文件的,ctr 不使用 CRI,因此它不读取plugins.”io.containerd.grpc.v1.cri”配置。
2 经验证重启containerd服务时k3s环境的容器会重启,但K8s不会。

查看信息

crictl info

输出结果:

"registry": {
      "mirrors": {
        "dev.flyrise.cn:8082": {
          "endpoint": [
            "http://10.62.17.41:32762"
          ]
        },
        "docker.io": {
          "endpoint": [
            "http://10.62.17.41:32762"
          ]
        }
      },
      "configs": {
        "10.62.17.41:32762": {
          "auth": null,
          "tls": {
            "insecure_skip_verify": true,
            "caFile": "",
            "certFile": "",
            "keyFile": ""
          }
        }
      },
      "auths": null,
      "headers": null
    },

K3s环境修改containerd配置文件

K3s 默认的 containerd 配置文件目录为/var/lib/rancher/k3s/agent/etc/containerd/config.toml,但直接操作 containerd 的配置文件去设置镜像仓库或加速器相比于操作 docker 要复杂许多。K3s 为了简化配置 containerd 镜像仓库的复杂度,K3s 会在启动时检查/etc/rancher/k3s/中是否存在 registries.yaml 文件,如果存在该文件,就会根据 registries.yaml 的内容转换为 containerd 的配置并存储到/var/lib/rancher/k3s/agent/etc/containerd/config.toml,从而降低了配置 containerd 镜像仓库的复杂度。

使用 K3s 配置私有镜像仓库

K3s 镜像仓库配置文件由两大部分组成:mirrorsconfigs:

  • Mirrors 是一个用于定义专用镜像仓库的名称和 endpoint 的指令
  • Configs 部分定义了每个 mirror 的 TLS 和证书配置。对于每个 mirror,你可以定义auth和/或tls

containerd 使用了类似 K8S 中 svc 与 endpoint 的概念,svc 可以理解为访问名称,这个名称会解析到对应的 endpoint 上。 也可以理解 mirror 配置就是一个反向代理,它把客户端的请求代理到 endpoint 配置的后端镜像仓库。mirror 名称可以随意填写,但是必须符合IP或域名的定义规则。并且可以配置多个 endpoint,默认解析到第一个 endpoint,如果第一个 endpoint 没有返回数据,则自动切换到第二个 endpoint,以此类推。

比如以下配置示例:

mirrors:
  "172.31.6.200:5000":
    endpoint:
      - "http://172.31.6.200:5000"
  "dev.flyrise.cn:8082":
    endpoint:
      - "http://172.31.6.200:5000"
  "docker.io":
    endpoint:
      - "https://fogjl973.mirror.aliyuncs.com"
      - "https://registry-1.docker.io"

可以通过 crictl pull 172.31.6.200:5000/library/nginx:alpinecrictl pull dev.flyrise.cn:8082/library/nginx:alpine获取到镜像,但镜像都是从同一个仓库获取到的。

[root@localhost k3s]# systemctl restart k3s.service
[root@localhost k3s]# crictl pull 172.31.6.200:5000/library/alpine
Image is up to date for sha256:a24bb4013296f61e89ba57005a7b3e52274d8edd3ae2077d04395f806b63d83e
[root@localhost k3s]# crictl pull dev.flyrise.cn:8082/library/nginx:alpine
Image is up to date for sha256:a24bb4013296f61e89ba57005a7b3e52274d8edd3ae2077d04395f806b63d83e
文档更新时间: 2024-07-01 17:17   作者:姚连洲