背景
在某些网络环境中,直接访问 Docker Hub 可能会很慢或不稳定。通过在您的 Kubernetes 集群中使用 Ingress Nginx 作为反向代理,您可以缓存镜像并加快拉取速度。
本文档将指导您如何配置 Ingress Nginx 来代理对 Docker Hub 的请求。
先决条件
- 一个正在运行的 Kubernetes 集群。
- 已经安装并配置了 Ingress Nginx Controller。
- 拥有一个可以配置的域名。
配置步骤
1. 创建 ExternalName Service
首先,我们需要创建一个 ExternalName 类型的 Service,它将作为 Docker Hub 注册中心的内部 DNS 别名。
1
2
3
4
5
6
7
8
| apiVersion: v1
kind: Service
metadata:
name: docker-hub-registry
namespace: default
spec:
type: ExternalName
externalName: registry-1.docker.io
|
这个 Service 会将 docker-hub-registry.default.svc.cluster.local 解析为 registry-1.docker.io。
2. 创建 Ingress 规则
接下来,我们创建一个 Ingress 规则,将来自特定域名的流量路由到我们刚刚创建的 ExternalName Service。
请将 dockerhub.yourdomain.com 替换为您自己的域名。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: docker-hub-proxy
namespace: default
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
spec:
ingressClassName: nginx
rules:
- host: dockerhub.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: docker-hub-registry
port:
number: 443
tls:
- hosts:
- dockerhub.yourdomain.com
secretName: your-domain-tls # 替换为您的 TLS 证书
|
2.1 (可选) 使用 cert-manager 自动生成 TLS 证书
如果您在集群中安装了 cert-manager,则可以自动管理 TLS 证书。
首先,请确保您已经安装了 cert-manager。然后,创建一个 Issuer 或 ClusterIssuer 来指定证书颁发机构。例如,使用 Let’s Encrypt:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: kbsonlong@gmail.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
|
然后,修改 Ingress 资源,添加 cert-manager.io/cluster-issuer 注解,并让 cert-manager 自动创建和管理 secretName:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: docker-hub-proxy
namespace: default
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod" # 指定 Issuer
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
spec:
ingressClassName: nginx
rules:
- host: dockerhub.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: docker-hub-registry
port:
number: 443
tls:
- hosts:
- dockerhub.yourdomain.com
secretName: your-domain-tls # cert-manager 会自动创建和管理这个 secret
|
注解解释:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS": 告诉 Ingress Nginx 后端服务使用 HTTPS。nginx.ingress.kubernetes.io/proxy-body-size: "0": 允许上传任意大小的镜像层。nginx.ingress.kubernetes.io/proxy-read-timeout: "600": 延长代理读取超时时间。nginx.ingress.kubernetes.io/proxy-send-timeout: "600": 延长代理发送超时时间。
3. 配置 Docker 客户端
最后,您需要在 Docker 客户端上配置镜像仓库地址,以使用您的代理。
编辑 Docker 的配置文件 (/etc/docker/daemon.json 或在 Docker Desktop 的设置中),添加您的代理地址。
如果您为 Ingress 配置了有效的 TLS 证书,则无需将其添加到 insecure-registries。
重启 Docker 服务后,您就可以通过您的代理拉取和推送镜像了。
例如:
1
| docker pull dockerhub.yourdomain.com/library/ubuntu
|
4. 镜像地址转换示例
当您配置好代理后,可以将原始的 Docker Hub 镜像地址转换为通过您的代理访问的地址。假设您的代理域名是 regis.kbsonlong.com。
原始地址:
1
| docker.io/nginx/nginx-ingress:edge-alpine
|
转换后地址:
1
| regis.kbsonlong.com/docker.io/nginx/nginx-ingress:edge-alpine
|
您可以使用转换后的地址来拉取镜像:
1
| docker pull regis.kbsonlong.com/docker.io/nginx/nginx-ingress:edge-alpine
|