最近由于 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
这个镜像了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。