我在 K3s 内部署了一个 docker 注册表,但我无法在其上上传图像。
我有一个与 K3d 一起运行的 K3s 集群。在此集群上,我想部署一个 docker 注册表。 可通过端口 8090 在本地主机上访问集群。 为了部署注册表,我创建了一个名为 registry 的文件夹,其中包含以下清单:
1。部署.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: registry
namespace: registry
spec:
replicas: 1
selector:
matchLabels:
app: registry
template:
metadata:
labels:
app: registry
spec:
containers:
- name: registry
image: registry:2
ports:
- containerPort: 5000
name: web
protocol: TCP
readinessProbe:
httpGet:
port: web
path: /
2。 ingressroute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: registry
namespace: registry
spec:
entryPoints:
- web
routes:
- match: Host(`registry.test.local`)
kind: Rule
services:
- name: registry
port: 5000
3.命名空间.yaml
apiVersion: v1
kind: Namespace
metadata:
name: registry
4。 service.yaml
apiVersion: v1
kind: Service
metadata:
name: registry
namespace: registry
spec:
type: ClusterIP
selector:
app: registry
ports:
- protocol: TCP
port: 5000
5。 kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- deployment.yaml
- service.yaml
- ingressroute.yaml
然后我通过
kubectl apply -k registry
将此配置应用到我的集群
当我使用curl接收注册表的内容时,我得到了有效的响应:
$ curl http://registry.test.local:8090/v2/_catalog
{"repositories":[]}
当我尝试将图像推送到注册表时,我收到以下错误消息:
$ docker push registry.test.local:8090/hello-world
Using default tag: latest
The push refers to repository [registry.test.local:8090/hello-world]
ac28800ec8bb: Preparing
error parsing HTTP 404 response body: invalid character 'p' after top-level value: "404 page not found\n"
当我关闭 K3S 测试集群并通过 docker run 启动 docker 注册表时,它也正在工作:
# Start registry with:
docker run -p 8090:5000 registry:2
# Push Image with
docker push registry.test.local:8090/hello-world
Using default tag: latest
The push refers to repository [registry.test.local:8090/hello-world]
ac28800ec8bb: Layer already exists
latest: digest: sha256:d37ada95d47ad12224c205a938129df7a3e52345828b4fa27b03a98825d1e2e7 size: 524
上面的配置有什么问题,需要修改才能达到预期的效果?
非常感谢, 罗布
您需要 TLS,向您的入口添加新 TLS 路由
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: registry-https
namespace: registry
spec:
entryPoints:
- web
routes:
- match: Host(`registry.test.local`)
kind: Rule
services:
- name: registry
port: 5000
tls:
domains:
- main: registry.test.local
然后,如果您想使用
curl
进行测试,请使用 https
和 -k
忽略证书验证
curl -k https://registry.test.local:8090/v2/_catalog
Docker 不允许在没有任何加密的情况下推送图像,这就是为什么当你尝试推送时会失败,因为你的入口只能处理 HTTP。要使其正常工作,您需要通过添加
8090
部分来让您的端口 tls
侦听 HTTPS 连接,但这会使您根本无法使用 HTTP。
当没有
tls
而你打电话时
curl http://registry.test.local:8090/v2/_catalog
你会得到
{"repositories":[]}
(如你所写),但是当你这样做时
curl -k https://registry.test.local:8090/v2/_catalog
您将得到
404 page not found
与 docker push
命令在控制台中为您提供的内容
你可能会问
Why registry work for both cases?
,registry只是同时处于两种模式下,因为当它直接暴露在互联网上时,它将从Docker客户端获得HTTPS连接,但是当它位于反向代理后面时,通常将请求转发为普通 HTTP
要使其同时适用于 HTTP 和 HTTPS,您需要两条路由
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: registry-http
namespace: registry
spec:
entryPoints:
- web
routes:
- match: Host(`registry.test.local`)
kind: Rule
services:
- name: registry
port: 5000
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: registry-https
namespace: registry
spec:
entryPoints:
- web
routes:
- match: Host(`registry.test.local`)
kind: Rule
services:
- name: registry
port: 5000
tls:
domains:
- main: registry.test.local
secretName: ingress-local-tls
就是这样!