K3s docker 注册表服务:推送失败,解析 HTTP 404 响应正文时出错:顶级值后的字符“p”无效:“404 页面未找到”

问题描述 投票:0回答:1

我在 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

上面的配置有什么问题,需要修改才能达到预期的效果?

非常感谢, 罗布

kubernetes traefik docker-registry k3s
1个回答
0
投票

快速修复

您需要 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

就是这样!

© www.soinside.com 2019 - 2024. All rights reserved.