深入浅出:K3s 和 RKE2 镜像仓库配置的完整指南

在本次线上 Meetup 中,我们将深入探讨 K3s 和 RKE2 镜像仓库的配置与优化技巧,帮助您提升 Kubernetes 集群的镜像拉取效率。无论是初学者还是经验丰富的开发者,都能从中获得实用的配置策略与最佳实践,助力更高效的容器管理和应用部署。

Posted by Ksd on November 18, 2024

章节介绍

  1. 如何在 K3s 中配置镜像仓库
  2. 如何在 Rancher 创建的 K3s 集群中配置镜像仓库
  3. 如何在 RKE2 中配置镜像仓库
  4. 如何在 Rancher 创建的 RKE2 集群中配置镜像仓库

Demo 环境

仓库域名/IP 证书类型 用户名/密码 镜像
https://public.kingsd.top/ 受信任证书 admin/Harbor12345 demo/nginx:1.27 demo/ubuntu:20.04
https://self-signed.kingsd.top/ 自签名证书 admin/Harbor12345 demo/nginx:1.27 demo/ubuntu:22.04
http://10.201.170.187/ admin/Harbor12345 demo/nginx:1.27 demo/ubuntu:24.04

在 K3s 中配置镜像仓库

配置文件说明

K3s registry 配置目录为: /etc/rancher/k3s/registries.yaml,K3s 会检查 /etc/rancher/k3s/ 中是否存在 registries.yaml 文件,并指示 containerd 使用文件中定义的镜像仓库。如果你想使用一个私有的镜像仓库,那么你需要在每个使用镜像仓库的节点上以 root 身份创建这个文件。

K3s 均使用 Containerd 作为默认容器运行时,而且均内置到 K3s 中。

请注意,server 节点默认是可以调度的。如果你没有在 server 节点上设置污点,那么将在它们上运行工作负载,请确保在每个 server 节点上创建 registries.yaml 文件。

镜像仓库配置文件

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:
  <REGISTRY>:
    endpoint:
      - https://<REGISTRY>/v2
configs:
  <REGISTRY>:
    auth:
      username: <BASIC AUTH USERNAME>
      password: <BASIC AUTH PASSWORD>
      token: <BEARER TOKEN>
    tls:
      ca_file: <PATH TO SERVER CA>
      cert_file: <PATH TO CLIENT CERT>
      key_file: <PATH TO CLIENT KEY>
      insecure_skip_verify: <SKIP TLS CERT VERIFICATION BOOLEAN>

示例 – 关联关系:

# /etc/rancher/k3s/registries.yaml
mirrors:
  docker.io:
    endpoint:
      - "https://fogjl973.mirror.aliyuncs.com/"
      - "https://registry-1.docker.io/"
  public.kingsd.top:
    endpoint:
      - "https://public.kingsd.top/"
  public-1.kingsd.top:
    endpoint:
      - "https://public.kingsd.top/"
configs:
  public.kingsd.top:
    auth:
      username: admin
      password: Harbor12345

crictl pull public.kingsd.top/demo/nginx:1.27

crictl pull public-1.kingsd.top/demo/nginx:1.27

root@demo-k3s:~# crictl pull public.kingsd.top/demo/nginx:1.27
Image is up to date for sha256:5ef79149e0ec84a7a9f9284c3f91aa3c20608f8391f5445eabe92ef07dbda03c
root@demo-k3s:~# crictl pull public-1.kingsd.top/demo/nginx:1.27
Image is up to date for sha256:5ef79149e0ec84a7a9f9284c3f91aa3c20608f8391f5445eabe92ef07dbda03c
root@demo-k3s:~# crictl images
IMAGE                                                                TAG                    IMAGE ID            SIZE
public-1.kingsd.top/demo/nginx                                       1.27                   5ef79149e0ec8       71MB
public.kingsd.top/demo/nginx                                         1.27                   5ef79149e0ec8       71MB

示例 – 配置 mirror:

# /etc/rancher/k3s/registries.yaml
mirrors:
  docker.io:
    endpoint:
      - "https://fogjl973.mirror.aliyuncs.com/"
      - "https://registry-1.docker.io/"

示例 – 配置受信任证书:

# /etc/rancher/k3s/registries.yaml
mirrors:
  public.kingsd.top:
    endpoint:
      - "https://public.kingsd.top/"
configs:
  public.kingsd.top:
    auth:
      username: admin
      password: Harbor12345

示例 – 自签名证书:

# /etc/rancher/k3s/registries.yaml
mirrors:
  self-signed.kingsd.top:
    endpoint:
      - "https://self-signed.kingsd.top/"
configs:
  self-signed.kingsd.top:
    auth:
      username: admin
      password: Harbor12345
    tls:
      ca_file: /opt/certs/ca.crt
# /etc/rancher/k3s/registries.yaml
mirrors:
  self-signed.kingsd.top:
    endpoint:
      - "https://self-signed.kingsd.top/"
configs:
  self-signed.kingsd.top:
    auth:
      username: admin
      password: Harbor12345
    tls:
      insecure_skip_verify: true

示例 – 配置非加密地址:

# /etc/rancher/k3s/registries.yaml
mirrors:
  10.201.170.187:
    endpoint:
      - "http://10.201.170.187/"
configs:
  10.201.170.187:
    auth:
      username: admin
      password: Harbor12345

示例 – 统一镜像仓库地址:

# /etc/rancher/k3s/registries.yaml
mirrors:
  docker.io:
    endpoint:
      - "https://fogjl973.mirror.aliyuncs.com/"
      - "https://public.kingsd.top/"
      - "https://self-signed.kingsd.top/"
      - "http://10.201.170.187/"
      - "https://registry-1.docker.io/"
configs:
  public.kingsd.top:
    auth:
      username: admin
      password: Harbor12345
  self-signed.kingsd.top:
    auth:
      username: admin
      password: Harbor12345
    tls:
      ca_file: /opt/certs/ca.crt
  10.201.170.187:
    auth:
      username: admin
      password: Harbor12345

完整示例:

# /etc/rancher/k3s/registries.yaml
mirrors:
  docker.io:
    endpoint:
      - "https://fogjl973.mirror.aliyuncs.com/"
      - "https://registry-1.docker.io/"
  public.kingsd.top:
    endpoint:
      - "https://public.kingsd.top/"
  self-signed.kingsd.top:
    endpoint:
      - "https://self-signed.kingsd.top/"
  10.201.170.187:
    endpoint:
      - "http://10.201.170.187/"
configs:
  public.kingsd.top:
    auth:
      username: admin
      password: Harbor12345
  self-signed.kingsd.top:
    auth:
      username: admin
      password: Harbor12345
    tls:
      ca_file: /opt/certs/ca.crt
  10.201.170.187:
    auth:
      username: admin
      password: Harbor12345

镜像重写

每个镜像都可以有一组重写,它们使用正则表达式来匹配和转换从镜像中提取到的镜像名称。如果私有镜像仓库中的组织/项目结构与其镜像的镜像仓库不同,这将非常有用。重写仅匹配和转换镜像名称,而不是标签。

例如,以下配置将透明地将镜像 docker.io/rancher/nginx:1.27 拉为 public.kingsd.top/demo/nginx:1.27

# /etc/rancher/k3s/registries.yaml
mirrors:
  docker.io:
    endpoint:
      - "https://public.kingsd.top/"
    rewrite:
      "^rancher/(.*)": "demo/$1"
configs:
  public.kingsd.top:
    auth:
      username: admin
      password: Harbor12345

请注意,使用镜像和重写时,镜像仍将以原始名称存储。例如,即使镜像是从具有不同名称的镜像中提取的,crictl image ls 也会显示 docker.io/rancher/nginx:1.27 在节点上可用。

更多关于镜像重写的说明,可参考:https://mp.weixin.qq.com/s/vyi8-X40P6GMxtAAtmRUIg

Containerd 日志位置

/var/lib/rancher/k3s/agent/containerd/containerd.log

通配符支持

mirrors 部分中可以使用 * 通配符来为所有镜像仓库提供默认配置。仅当该镜像仓库配置没有特定条目时才会使用默认配置。请注意,星号必须用引号引起来。

在以下示例中,除了从 http://10.201.170.187/ 仓库拉取镜像以外,都将从 https://public.kingsd.top/ 拉取镜像。

并且,由于 http://10.201.170.187/ 没有配置 configs,镜像将拉取失败。

# /etc/rancher/k3s/registries.yaml
mirrors:
  10.201.170.187:
    endpoint:
      - "http://10.201.170.187/"
  "*":
    endpoint:
      - "https://public.kingsd.top/"
configs:
  "public.kingsd.top":
    auth:
      username: admin
      password: Harbor12345

在 Rancher 创建的 K3s 集群中配置镜像仓库

Rancher UI 支持 K3s 镜像仓库的所需配置选项,直接从 UI 上配置镜像仓库即可,方法和直接编辑 K3s 配置文件一致。

在创建或者编辑集群时,可以导航到 Cluster Configuration –> Registries 来配置 MirrorsRegistry Authentication

示例 – 配置受信任证书:

  1. 创建 Authentication

导航到 Local 集群 –> Secrets ,在 fleet-default namespace 创建 HTTP Basic Auth 类型的 Secret

  1. 配置集群 Registries

在创建或者编辑集群时,可以导航到 Cluster Configuration –> Registries 来配置 MirrorsRegistry Authentication

示例 – 自签名证书:

  1. 创建 Authentication

导航到 Local 集群 –> Secrets ,在 fleet-default namespace 创建 HTTP Basic Auth 类型的 Secret

  1. 创建 TLS Certificate

导航到 Local 集群 –> Secrets,在 fleet-default namespace 创建 TLS Certificate 类型的 Secret

  1. 配置集群 Registries

在创建或者编辑集群时,可以导航到 Cluster Configuration –> Registries 来配置 MirrorsRegistry Authentication

方案 1:

方案 2:

示例 – 配置非加密地址:

  1. 创建 Authentication

导航到 Local 集群 –> Secrets ,在 fleet-default namespace 创建 HTTP Basic Auth 类型的 Secret

  1. 配置集群 Registries

在创建或者编辑集群时,可以导航到 Cluster Configuration –> Registries 来配置 MirrorsRegistry Authentication

在 RKE2 中配置镜像仓库

配置文件说明

RKE2 registry 配置目录为: /etc/rancher/rke2/registries.yaml,RKE2 会检查 /etc/rancher/rke2/ 中是否存在 registries.yaml 文件,并指示 containerd 使用文件中定义的镜像仓库。如果你想使用一个私有的镜像仓库,那么你需要在每个使用镜像仓库的节点上以 root 身份创建这个文件。

RKE2 均使用 Containerd 作为默认容器运行时,而且均内置到 RKE2 中。

请注意,server 节点默认是可以调度的。如果你没有在 server 节点上设置污点,那么将在它们上运行工作负载,请确保在每个 server 节点上创建 registries.yaml 文件。

镜像仓库配置文件

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

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

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

官方示例:

mirrors:
  <REGISTRY>:
    endpoint:
      - https://<REGISTRY>/v2
configs:
  <REGISTRY>:
    auth:
      username: <BASIC AUTH USERNAME>
      password: <BASIC AUTH PASSWORD>
      token: <BEARER TOKEN>
    tls:
      ca_file: <PATH TO SERVER CA>
      cert_file: <PATH TO CLIENT CERT>
      key_file: <PATH TO CLIENT KEY>
      insecure_skip_verify: <SKIP TLS CERT VERIFICATION BOOLEAN>

示例 – 关联关系:

# /etc/rancher/rke2/registries.yaml
mirrors:
  docker.io:
    endpoint:
      - "https://fogjl973.mirror.aliyuncs.com/"
      - "https://registry-1.docker.io/"
  public.kingsd.top:
    endpoint:
      - "https://public.kingsd.top/"
  public-1.kingsd.top:
    endpoint:
      - "https://public.kingsd.top/"
configs:
  public.kingsd.top:
    auth:
      username: admin
      password: Harbor12345

crictl pull public.kingsd.top/demo/nginx:1.27

crictl pull public-1.kingsd.top/demo/nginx:1.27

root@demo-rke2:~# crictl pull public.kingsd.top/demo/nginx:1.27
Image is up to date for sha256:5ef79149e0ec84a7a9f9284c3f91aa3c20608f8391f5445eabe92ef07dbda03c
root@demo-rke2:~# crictl pull public-1.kingsd.top/demo/nginx:1.27
Image is up to date for sha256:5ef79149e0ec84a7a9f9284c3f91aa3c20608f8391f5445eabe92ef07dbda03c
root@demo-rke2:~# crictl images
IMAGE                                                                TAG                    IMAGE ID            SIZE
public-1.kingsd.top/demo/nginx                                       1.27                   5ef79149e0ec8       71MB
public.kingsd.top/demo/nginx                                         1.27                   5ef79149e0ec8       71MB

示例 – 配置 mirror:

# /etc/rancher/rke2/registries.yaml
mirrors:
  docker.io:
    endpoint:
      - "https://fogjl973.mirror.aliyuncs.com/"
      - "https://registry-1.docker.io/"

示例 – 配置受信任证书:

# /etc/rancher/rke2/registries.yaml
mirrors:
  public.kingsd.top:
    endpoint:
      - "https://public.kingsd.top/"
configs:
  public.kingsd.top:
    auth:
      username: admin
      password: Harbor12345

示例 – 自签名证书:

# /etc/rancher/rke2/registries.yaml
mirrors:
  self-signed.kingsd.top:
    endpoint:
      - "https://self-signed.kingsd.top/"
configs:
  self-signed.kingsd.top:
    auth:
      username: admin
      password: Harbor12345
    tls:
      ca_file: /opt/certs/ca.crt
# /etc/rancher/rke2/registries.yaml
mirrors:
  self-signed.kingsd.top:
    endpoint:
      - "https://self-signed.kingsd.top/"
configs:
  self-signed.kingsd.top:
    auth:
      username: admin
      password: Harbor12345
    tls:
      insecure_skip_verify: true

示例 – 配置非加密地址:

# /etc/rancher/rke2/registries.yaml
mirrors:
  10.201.170.187:
    endpoint:
      - "http://10.201.170.187/"
configs:
  10.201.170.187:
    auth:
      username: admin
      password: Harbor12345

示例 – 统一镜像仓库地址:

# /etc/rancher/rke2/registries.yaml
mirrors:
  docker.io:
    endpoint:
      - "https://fogjl973.mirror.aliyuncs.com/"
      - "https://public.kingsd.top/"
      - "https://self-signed.kingsd.top/"
      - "http://10.201.170.187/"
      - "https://registry-1.docker.io/"
configs:
  public.kingsd.top:
    auth:
      username: admin
      password: Harbor12345
  self-signed.kingsd.top:
    auth:
      username: admin
      password: Harbor12345
    tls:
      ca_file: /opt/certs/ca.crt
  10.201.170.187:
    auth:
      username: admin
      password: Harbor12345

完整示例:

# /etc/rancher/rke2/registries.yaml
mirrors:
  docker.io:
    endpoint:
      - "https://fogjl973.mirror.aliyuncs.com/"
      - "https://registry-1.docker.io/"
  public.kingsd.top:
    endpoint:
      - "https://public.kingsd.top/"
  self-signed.kingsd.top:
    endpoint:
      - "https://self-signed.kingsd.top/"
  10.201.170.187:
    endpoint:
      - "http://10.201.170.187/"
configs:
  public.kingsd.top:
    auth:
      username: admin
      password: Harbor12345
  self-signed.kingsd.top:
    auth:
      username: admin
      password: Harbor12345
    tls:
      ca_file: /opt/certs/ca.crt
  10.201.170.187:
    auth:
      username: admin
      password: Harbor12345

镜像重写

每个镜像都可以有一组重写,它们使用正则表达式来匹配和转换从镜像中提取到的镜像名称。如果私有镜像仓库中的组织/项目结构与其镜像的镜像仓库不同,这将非常有用。重写仅匹配和转换镜像名称,而不是标签。

例如,以下配置将透明地将镜像 docker.io/rancher/nginx:1.27 拉为 public.kingsd.top/demo/nginx:1.27

# /etc/rancher/rke2/registries.yaml
mirrors:
  docker.io:
    endpoint:
      - "https://public.kingsd.top/"
    rewrite:
      "^rancher/(.*)": "demo/$1"
configs:
  public.kingsd.top:
    auth:
      username: admin
      password: Harbor12345

请注意,使用镜像和重写时,镜像仍将以原始名称存储。例如,即使镜像是从具有不同名称的镜像中提取的,crictl image ls 也会显示 docker.io/rancher/nginx:1.27 在节点上可用。

更多关于镜像重写的说明,可参考:https://mp.weixin.qq.com/s/vyi8-X40P6GMxtAAtmRUIg

Containerd 日志位置

/var/lib/rancher/rke2/agent/containerd/containerd.log

通配符支持

mirrors 部分中可以使用 * 通配符来为所有镜像仓库提供默认配置。仅当该镜像仓库配置没有特定条目时才会使用默认配置。请注意,星号必须用引号引起来。

在以下示例中,除了从 http://10.201.170.187/ 仓库拉取镜像以外,都将从 https://public.kingsd.top/ 拉取镜像。

并且,由于 http://10.201.170.187/ 没有配置 configs,镜像将拉取失败。

# /etc/rancher/rke2/registries.yaml
mirrors:
  10.201.170.187:
    endpoint:
      - "http://10.201.170.187/"
  "*":
    endpoint:
      - "https://public.kingsd.top/"
configs:
  "public.kingsd.top":
    auth:
      username: admin
      password: Harbor12345

在 Rancher 创建的 RKE2 集群中配置镜像仓库

Rancher UI 支持 RKE2 镜像仓库的所需配置选项,直接从 UI 上配置镜像仓库即可,方法和直接编辑 RKE2 配置文件一致。

在创建或者编辑集群时,可以导航到 Cluster Configuration –> Registries 来配置 MirrorsRegistry Authentication

示例 – 配置受信任证书:

  1. 创建 Authentication

导航到 Local 集群 –> Secrets ,在 fleet-default namespace 创建 HTTP Basic Auth 类型的 Secret

  1. 配置集群 Registries

在创建或者编辑集群时,可以导航到 Cluster Configuration –> Registries 来配置 MirrorsRegistry Authentication

示例 – 自签名证书:

  1. 创建 Authentication

导航到 Local 集群 –> Secrets ,在 fleet-default namespace 创建 HTTP Basic Auth 类型的 Secret

  1. 创建 TLS Certificate

导航到 Local 集群 –> Secrets,在 fleet-default namespace 创建 TLS Certificate 类型的 Secret

  1. 配置集群 Registries

在创建或者编辑集群时,可以导航到 Cluster Configuration –> Registries 来配置 MirrorsRegistry Authentication

方案 1:

方案 2:

示例 – 配置非加密地址:

  1. 创建 Authentication

导航到 Local 集群 –> Secrets ,在 fleet-default namespace 创建 HTTP Basic Auth 类型的 Secret

  1. 配置集群 Registries

在创建或者编辑集群时,可以导航到 Cluster Configuration –> Registries 来配置 MirrorsRegistry Authentication