摘要: 本文详细介绍了如何配置Containerd以使用Harbor作为私有仓库。首先解释了Containerd、Harbor及工具ctrcrictl的基本概念。接着,文章逐步指导如何上传Harbor证书至Kubernetes节点、更新Containerd配置并重启服务。最后,通过ctrcrictl验证配置是否成功,并展示了如何创建Harbor的Secret、将其添加到服务账号,并通过部署测试验证配置的有效性。此教程适合希望在Kubernetes环境中高效利用Harbor私有仓库的系统管理员和开发者。

目录

1 概念

1.1 什么是Containerd

Containerd 是一个高效的容器运行时,是 Kubernetes 生态中最常用的容器运行时接口(CRI)。Containerd 提供了从镜像管理、容器执行到存储和网络等容器生命周期的核心功能,是容器生态系统的基础组件。

Containerd 的优点:

  • 轻量、稳定、可扩展。
  • 提供了与镜像仓库对接的 API 支持。
  • 支持 OCI(Open Container Initiative)镜像格式。

1.2 什么是Harbor

Harbor 是一个开源的企业级容器镜像仓库,支持镜像的管理、安全扫描、复制和身份验证等高级功能。相比于简单的 Docker Registry,Harbor 提供了丰富的企业级特性,例如基于角色的访问控制(RBAC)、镜像复制、漏洞扫描以及镜像签名等功能。

Harbor 常用功能:

  • 存储 Docker 和 OCI 镜像。
  • 镜像的安全扫描和签名。
  • 审计日志和访问控制。

1.3 什么是ctr和crictl

  • ctr: Containerd 自带的命令行工具,用于直接与 Containerd 交互,可以管理镜像、容器、任务等资源。它是一个较为底层的工具,适合调试和开发使用。
  • crictl: 是一个更高级别的 CLI 工具,专门为 Kubernetes 设计,用于通过 CRI 与容器运行时交互。它简化了与容器运行时的交互,能够与 Kubernetes 紧密集成。

2 配置 Containerd 使用 Harbor 作为私有仓库

❔ 说明:上文《一文读懂Harbor以及部署实践攻略》中,在测试环境已经部署好带https协议的Harbor,但是如果kubernetes环境直接拉取Harbor的镜像会出现以下报错。

如果你在Kubernetes使用未认证的Harbor私有仓库,可能会出现x509: certificate signed by unknown authority错误,这是因为你没有将Harbor的自签名证书或CA证书添加到Containerd的信任镜像列表中。

Events:
  Type     Reason     Age              From               Message
  ----     ------     ----             ----               -------
  Normal   Scheduled  3s               default-scheduler  Successfully assigned default/nginx-84b646ffc7-4qz2d to k8s-worker2
  Normal   Pulling    2s               kubelet            Pulling image "harbor.zx/hcie/nginx:stable"
  Warning  Failed     2s               kubelet            Failed to pull image "harbor.zx/hcie/nginx:stable": failed to pull and unpack image "harbor.zx/hcie/nginx:stable": failed to resolve reference "harbor.zx/hcie/nginx:stable": failed to do request: Head "https://harbor.zx/v2/hcie/nginx/manifests/stable": tls: failed to verify certificate: x509: certificate signed by unknown authority
  Warning  Failed     2s               kubelet            Error: ErrImagePull
  Normal   BackOff    1s (x2 over 2s)  kubelet            Back-off pulling image "harbor.zx/hcie/nginx:stable"
  Warning  Failed     1s (x2 over 2s)  kubelet            Error: ImagePullBackOff

将Harbor相关证书上传到Kubernetes的节点上

在所有Kubernetes节点上创建证书目录,your-harbor-domain 代替为你证书的CN:

sudo mkdir -p /etc/containerd/certs.d/your-harbor-domain/
# 例如:
sudo mkdir -p /etc/containerd/certs.d/harbor.zx/


将Harbor的ca证书复制到该目录中:

sudo cp /path/to/harbor.crt /etc/containerd/certs.d/your-harbor-domain/

# 例如:
cp /data/harbor.crt /etc/containerd/certs.d/harbor.zx/


更新Containerd配置

在Containerd的配置文件添加harbor私有仓库和指定信任的证书目录。

编辑Containerd的配置文件(如果没有,执行以下命令生成一个默认配置):

sudo containerd config default | sudo tee /etc/containerd/config.toml

在配置文件中指定证书路径, 修改 /etc/containerd/config.toml

  [plugins."io.containerd.grpc.v1.cri".registry.configs]
  # 如果针对某个项目使用,可以在harbor里创建的用户,并授权访问指定项目
    [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.zx".auth]
      username = "project-admin"
      password = "xxxx"

    [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.zx".tls]
      # 是否跳过证书认证
      insecure_skip_verify = false
      # 指定harbor的CA证书
      ca_file = "/etc/containerd/certs.d/harbor.zx/ca.crt"
      # 如果是双向认证,需要添加客户端的公钥和私钥
      #cert_file = "/etc/containerd/certs.d/harbor.zx/client.cert"
      #key_file = "/etc/containerd/certs.d/harbor.zx/client.key"

    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."harbor.zx"]
     # 私有仓库地址
        endpoint = ["https://harbor.zx"]

重启Containerd服务

应用配置并重启Containerd:

systemctl daemon-reload
systemctl restart containerd

验证配置是否成功

2.4.1 使用 ctr 验证

可以使用 ctr 工具来验证 Containerd 是否能够成功与 Harbor 仓库交互,执行以下命令拉取私有镜像:

sudo ctr image pull harbor.zx/library/stress:latest

如果以下输出还是报错

INFO[0000] trying next host                              error="failed to do request: Head \"https://harbor.zx/v2/library/stress/manifests/latest\": x509: certificate signed by unknown authority" host=harbor.zx
harbor.zx/library/stress:latest: resolving      |--------------------------------------|
elapsed: 0.1 s                   total:   0.0 B (0.0 B/s)
ctr: failed to resolve reference "harbor.zx/library/stress:latest": failed to do request: Head "https://harbor.zx/v2/library/stress/manifests/latest": x509: certificate signed by unknown authority

执行以下命令,再拉取镜像

sudo ctr image pull -k harbor.zx/library/stress:latest

❔ 说明: -k参数是跳过ssl证书校验

拉取成功输出:

[root@k8s-master1 ~]# sudo ctr image pull -k harbor.zx/library/stress:latest
harbor.zx/library/stress:latest:                                                  resolved       |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:b6144f84f9c15dac80deb48d3a646b55c7043ab1d83ea0a697c09097aaad21aa: done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:8d43371bad93504d09422b0aadb993110ae5313aead99b2796e64124f456eda6:    done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:df58d15b053d1ac1378fa685cbc1f71a0a1716a4c6f6f105df9c4d7b7f1ee5bb:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:63bc94deeb2884fd684a72d356164664538ee55cd82a9e65afe300a432092744:    done           |++++++++++++++++++++++++++++++++++++++|
elapsed: 0.2 s                                                                    total:  739.0  (3.6 KiB/s)     
unpacking linux/amd64 sha256:b6144f84f9c15dac80deb48d3a646b55c7043ab1d83ea0a697c09097aaad21aa...
done: 1.411427987s

❔ 说明:如果镜像拉取成功,说明 Containerd 已成功配置 Harbor 仓库。

2.4.2 使用 crictl 验证:

如果 Kubernetes 使用的是 Containerd 作为CRI,可以通过 crictl 来验证配置,执行以下命令:

 crictl pull  harbor.zx/library/stress:latest

拉取成功输出:

Image is up to date for sha256:df58d15b053d1ac1378fa685cbc1f71a0a1716a4c6f6f105df9c4d7b7f1ee5bb

❔ 说明: 如果镜像成功下载并显示在结果中,则表明 Harbor 已正确配置为私有镜像仓库。

3 配置Harbor默认Secret并部署验证

❔ 说明: 以下是整个配置默认仓库的流程:

为了演示方便直接使用default命令空间和default用户, 第2、4步骤是k8s默认完成。

步骤操作
1创建一个 Secret 对象
2创建一个 ServiceAccount 对象
3将 ServiceAccount 与 Secret 对象关联
4在 Pod 使用 ServiceAccount 对象

3.1 创建私有仓库的Secret

创建docker-registry的secret,执行以下命令

kubectl create secret docker-registry myharbor --docker-server=https://harbor.zx \
--docker-username=admin \
--docker-password=admin12345 \
--docker-email=zengshingx@163.com

❔ 参数说明:

参数说明
docker-registryk8s内置参数,表示镜像仓库类型的secret
myharborsecret自定义名称
–docker-server镜像仓库地址
–docker-username镜像仓库登录用户
–docker-password镜像仓库登录密码
–docker-email通知email地址

3.2 将镜像仓库的 Secret 添加到服务账号

接下来更改默认命令空间的默认服务账号,将该 Secret 用作 imagePullSecret,执行以下命令。

kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myharbor"}]}'

3.3 部署Deployment测试是否配置成功

编辑test.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: tomcat
  name: tomcat
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tomcat
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: tomcat
    spec:
      nodeName: k8s-master1
      containers:
      - image: harbor.zx/hcie/tomcat:8.0
        name: tomcat
        ports:
        - containerPort: 80
          hostPort: 888
          name: http
        resources:
        imagePullPolicy: Always
      restartPolicy: Always

创建Deployment

kubectl apply -f test.yaml

查看详细信息

Events:
  Type     Reason   Age                    From     Message
  ----     ------   ----                   ----     -------
  Normal   Pulled   6m23s                  kubelet   Successfully pulled image "harbor.zx/hcie/tomcat:8.0" in 225m s (225ms including waiting)
  Normal   Pulled   6m14s                  kubelet  Successfully pulled image "harbor.zx/hcie/tomcat:8.0" in 162ms (162ms including waiting)
  Normal   Pulled   5m57s                  kubelet  Successfully pulled image "harbor.zx/hcie/tomcat:8.0" in 148ms (148ms including waiting)
  Normal   Created  5m22s (x4 over 6m23s)  kubelet  Created container tomcat
  Normal   Started  5m22s (x4 over 6m23s)  kubelet  Started container tomcat

❔ 说明: k8s事件说明可以通过secret直接拉取harbor私用仓库的镜像。

参考资料

【1】 Secrets
【2】Configure Image Registry

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐