1

最近由于 Dockerhub 仓库被封导致常用的镜像无法拉取,好在网上已经有搭建镜像仓库的教程,比如使用 cloudflare-docker-proxy 基于 Cloudflare Workers 搭建镜像代理服务。虽然解决了镜像拉取的问题,但对于部署在 k8s 集群上的应用,管理员需要手动修改 YAML 文件中的镜像地址,如果集群上部署的应用较多这个工作量就会很大。更麻烦的是一些使用 Operator 管理的应用,甚至无法直接修改镜像地址。

image-operator 是基于 Admission Webhook 实现的一个 Operator,工作原理是在 Pod 创建时根据规则重写镜像地址,这个过程对使用者来说是透明的,无需手动修改 YAML 中的镜像地址。

安装 image-operator

image-operator 提供了 Helm Chart 方便安装,首先添加 Helm 仓库:

$ helm repo add image-operator https://yxwuxuanl.github.io/k8s-image-operator/

接着安装 image-operator

$ helm install image-operator image-operator/image-operator -n image-operator --create-namespace

稍等片刻后查看 image-operator 的状态:

$ kubectl get pods -n image-operator
NAME                             READY   STATUS    RESTARTS   AGE
image-operator-b8c8d5ddb-zkv6l   1/1     Running   0          2m

到这里 image-operator 就安装完成了。

重写镜像地址

image-operator 使用 Rule CRD 来配置重写规则,下面来看一个例子:

apiVersion: image.lin2ur.cn/v1
kind: Rule
metadata:
  name: dockerhub
spec:
  rewrite: # <- 重写规则,可以配置多个
    - registry: docker.io # <- 需要重写的镜像仓库
      replacement: docker.mymirror.com # <- 重写目标镜像仓库
    # 使用正则表达式重写,等效于上面的配置
    - regex: ^docker\.io/(.*)$
      replacement: docker.mymirror.com/$1

将上面的配置保存为 rule.yaml 并应用,然后使用 Dockerhub 仓库的镜像创建一个应用:

$ kubectl apply -f rule.yaml
rule/dockerhub created

$ kubectl run image-operator-test --image=nginx # <- 使用 Dockerhub 仓库的镜像
pod/image-operator-test created

$ kubectl get pod image-operator-test '-o=jsonpath={.spec.containers[0].image}'
docker.mymirror.com/library/nginx:latest # <- 镜像地址已被重写

此外 image-operator 还支持对特定的 Pod 进行重写:

apiVersion: image.lin2ur.cn/v1
kind: Rule
metadata:
  name: dockerhub
spec:
  namespaceSelector: # <- 选择需要重写的 Namespace
    matchExpressions:
    - key: kubernetes.io/metadata.name # <- 排除 kube-system 命名空间下的 Pods
      operator: NotIn
      values:
      - kube-system
  podSelector: # <- 选择需要重写的 Pod
    matchLabels: # <- 仅对包含 rewrite=true 标签的 Pod 进行重写
      rewrite: 'true' 

同步镜像

如果只是用到少量 Dockerhub 镜像并且不想大费周章搭建镜像仓库,可以使用 Mirror CRD 将 Dockerhub 上的镜像同步到自己的镜像仓库:

apiVersion: image.lin2ur.cn/v1
kind: Mirror
metadata:
  generateName: nginx-
spec:
  images:
    - source: nginx # <- 源镜像
      target: myregistry.com/nginx # <- 目标镜像
      tags: # <- 镜像标签
        - '1.27'
      platforms: # <- (可选) 镜像架构,默认为全部架构
        - linux/amd64
  dockerConfig: # <- (可选) Docker 配置,用于私有仓库的拉取和推送
    secretName: '' # <- 必须是 `kubernetes.io/dockerconfigjson` 类型的 Secret
  httpProxy: '' # <- (可选) 拉取镜像时使用 HTTP 代理
  parallelism: 1 # <- (可选) 并发数,默认为 1
  sizeLimit: 1Gi # <- (可选) 任务 Pod 的临时存储大小
  activeDeadlineSeconds: 300 # <- (可选) 任务 Pod 的超时时间

将上面的配置保存为 mirror.yaml 并应用:

$ kubectl create -f mirror.yaml 
mirror.image.lin2ur.cn/nginx-pq9dg created

image-operator 会创建一个 Job 来同步镜像,稍等片刻后查看任务状态:

$ kubectl get mirror nginx-pq9dg
NAME          IMAGES   RUNNING   FAILED   SUCCEEDED
nginx-pq9dg            0         0        2

同步完成后就可以使用 myregistry.com/nginx:1.27 这个镜像了。


lin2ur
71 声望1 粉丝

while(!die) {