一、背景

当前总是会遇到拉取镜像失败,明明k8s 集群已经创建好了,镜像也放好了就是拉取不了!

在现代云原生架构中,Harbor 作为企业级私有镜像仓库,已成为 Kubernetes 集群不可或缺的一部分。本文将带你深入理解 Kubernetes 如何对接 Harbor 仓库,并详细讲解 拉取外部镜像 vs 内部镜像的配置区别,重点聚焦于 containerd 运行时的实际操作,涵盖 认证、安全、性能优化 等关键点.

二、目标

1. 实现自动化镜像拉取

2. 保障镜像传输安全

3. 统一内外镜像治理

4. 灵活适配多种场景

三 详细配置

3.1 Harbor 在 Kubernetes 中的角色

1. 集中管理镜像:构建、扫描、签名、复制

2. 权限控制:基于项目的 RBAC 访问控制

3. 高可用与同步:多数据中心镜像复制

4. 与 K8s 深度集成:通过 imagePullSecrets 或运行时配置自动拉取

3.2 前置准备:Harbor 仓库配置

1. 创建项目(Project)

  • 登录 Harbor Web UI

  • 创建项目:aadp(公开或私有均可)

2. 创建机器人账户(Robot Account)或用户

推荐使用 Robot Account(更安全、可自动过期):

  •      名称:robot$k8s-puller

  •      权限:pull(只读)

  •      生成 Token:lin.110778(示例)

3.3 Kubernetes 拉取镜像的两种方式对比

特性

拉取外部镜像(Docker Hub)

拉取内部 Harbor 镜像

认证需求

通常无需认证

必须认证(私有仓库)

镜像地址

nginx:latest

harbor.*.com/aadp/weaviate:1.18.0

安全性

低(公网暴露)

高(内网 + TLS + 认证)

网络延迟

高(跨公网)

低(内网直连)

配置方式

无需额外配置

需配置 imagePullSecrets 或运行时

3.4 方式一:使用 imagePullSecrets(推荐用于私有镜像)

这是最标准、最灵活的方式,适用于所有容器运行时(包括 containerd)。

步骤 1:创建 Docker Registry Secret

kubectl create secret docker-registry regcred-harbor \
  --docker-server=https://harbor.*.com \
  --docker-username=robot\$k8s-puller \
  --docker-password=lin.110778 \
  --docker-email=admin@lin.com \
  -n default

步骤 2:在 Pod 或 Deployment 中引用

apiVersion: apps/v1
kind: Deployment
metadata:
  name: weaviate
spec:
  replicas: 1
  selector:
    matchLabels:
      app: weaviate
  template:
    metadata:
      labels:
        app: weaviate
    spec:
      containers:
      - name: weaviate
        image: harbor.*.com/aadp/weaviate:1.18.0
        ports:
        - containerPort: 8080
      imagePullSecrets:
      - name: regcred-harbor

优点

    灵活:每个 Pod 可使用不同凭证

    安全:凭证与 Pod 绑定,最小权

    标准化:符合 Kubernetes 最佳

3.5 方式二:配置 containerd 运行时(全局认证)

适用于所有节点统一认证的场景,避免每个 Pod 都配置 imagePullSecrets

适用于:大规模集群、内网统一认证、减少配置冗余

步骤 1:编辑 containerd 配置文件

sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

步骤 2修改 /etc/containerd/conigg.toml        

在 [plugins."io.containerd.grpc.v1.cri".registry.configs] 下添加:

[plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.*.com".auth]
  username = "robot$k8s-puller"
  password = "lin.110778"

或者使用 Base64 编码的 auth 字段:

echo -n 'robot$k8s-puller:lin.110778' | base64
# 输出:cm9ib3QkazhzLXB1bGxlcjpKdWFuaGFpLjExMDc3OA==

配置:

[plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.lin.com".auth]
  auth = "cm9ib3QkazhzLXB1bGxlcKdWFuaGFpLjExMDc3OA=="

步骤 3:重启 containerd

sudo systemctl restart containerd

步骤 4:测试拉取镜像

crictl pull harbor.*.com/aadp/weaviate:1.18.0

优点

    全局生效:所有命名空间、Pod 自动使用

    减少配置:无需每个 Pod 写 imagePullSecrets

    性能更好:运行时缓存凭证

缺点

    安全性较低:凭证全局暴露

    灵活性差:不支持多租户多凭证

四 TLS 与证书配置(可选但推荐)

如果 Harbor 启用了自签名证书,需配置信任。

步骤 1:获取 Harbor 证书

openssl s_client -connect harbor.*.com:443 -showcerts < /dev/null 2>/dev/null | openssl x509 -outform PEM > harbor.crt

步骤 2:复制证书到 containerd

sudo mkdir -p /etc/containerd/certs.d/harbor.*.com
sudo cp harbor.crt /etc/containerd/certs.d/harbor.*.com/ca.crt

步骤 3:重启 containerd

sudo systemctl restart containerd

五 总结:选择最适合你的方案

方案

适用场景

推荐指数

imagePullSecrets

生产环境、多租户、安全敏感

⭐⭐⭐⭐⭐

containerd 全局配置

内网统一认证、简化运维

⭐⭐⭐⭐

两者结合

混合镜像源、灵活管理

⭐⭐⭐⭐⭐

对接 Harbor 不只是“能拉镜像”,更是 安全、效率、可维护性 的体现。选择正确的认证方式,让你的 Kubernetes 集群更强大、更可靠!

建议结合 

Harbor + Robot Account + imagePullSecrets + TLS,打造坚不可摧的镜像供应链安全体系。