docker - 是否可以在 Kubernetes 中启动自签名 Docker 注册表,并让其他服务使用它作为注册表来获取其镜像?

标签 docker kubernetes kubectl docker-registry kubelet

问题陈述

  • 我想提供一个私有(private)注册表,其中捆绑了我的产品所需的所有图像(是的,这将是胖图像,但我对此很满意)
  • 我会以某种方式手动上传此图片
  • 我会将 docker 私有(private)注册表作为 Kubernetes 中的服务运行(可能在某个命名空间中)
  • 当其他服务/部署(与注册表在同一命名空间中)发生在 Kubernetes 中时,它们应该使用一致的名称引用此注册表

约束

  • 我们希望注册表仅暴露给集群而不是外部
  • 我们希望使用自签名证书而不是由 CA 签名

我按照这些链接中的一些说明进行操作(不知道这是否正确)

创建通过 Kubernetes 签名的证书

  1. 创建 server.key

  2. 创建 csr.info

[ req ]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn

[ dn ]
C = US
ST = oh
L = cincinnati
O = engg
OU = prod
CN = prateek.svc.cluster.local

[ req_ext ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = registry.prateek.svc.cluster.local

[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=@alt_names
  • 创建了 server.csr(openssl req -new -key server.key -out server.csr -config csr.conf)

  • 在 K8s 中创建 CertificateSigningRequest

  • cat <<EOF | kubectl apply -f -
    apiVersion: certificates.k8s.io/v1beta1
    kind: CertificateSigningRequest
    metadata:
    name: registry.prateek
    spec:
    groups:
    - system:authenticated
    request: $(cat server.csr | base64 | tr -d '\n')
    usages:
    - digital signature
    - key encipherment
    - server auth
    EOF
    
  • 检查 CSR 是否存在
  • kubectl describe csr registry.prateek
    Name: registry.prateek
    Labels: <none>
    Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"certificates.k8s.io/v1beta1","kind":"CertificateSigningRequest","metadata":{"annotations":{},"name":"registry.prateek","namespace":""},"spec":{"groups":["system:authenticated"],"request":"LS0sdfsfsdsfd=","usages":["digital signature","key encipherment","server auth"]}}
    
    CreationTimestamp: Thu, 11 Apr 2019 11:15:42 -0400
    Requesting User: docker-for-desktop
    Status: Pending
    Subject:
    Common Name: prateek.svc.cluster.local
    Serial Number:
    Organization: engg
    Organizational Unit: prod
    Country: US
    Locality: cincinnati
    Province: oh
    Subject Alternative Names:
    DNS Names: registry.prateek.svc.cluster.local
    Events: <none>
    
  • 批准了 CSR:kubectl 证书批准registry.prateek
  • 启动registry内部服务

  • 添加了证书和 key 类型:Secret
  • 注册表 secret .yml
    apiVersion: v1
    kind: Secret
    metadata:
      name: registry-credentials
    data:
      certificate: <CERTIFICATE in base64>
      key: <KEY in base64>
    
  • 创建注册表部署和服务(使用这些 secret ) 注册表部署.yml
  • apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: registry
      namespace: prateek
      labels:
          app: registry
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: registry
      template:
        metadata:
          labels:
            app: registry
        spec:
          containers:
            - name: registry
              image: prateek/registry
              imagePullPolicy: IfNotPresent
              ports:
                - containerPort: 443
              env:
                - name: REGISTRY_HTTP_ADDR
                  value: "0.0.0.0:443"
                - name: REGISTRY_HTTP_TLS_CERTIFICATE
                  value: "/certs/certificate"
                - name: REGISTRY_HTTP_TLS_KEY
                  value: "/certs/key"
              volumeMounts:
                - name: cert-files
                  mountPath: /certs
          volumes:
            - name: cert-files
              secret:
                secretName: registry-credentials
    

    注册表服务.yml

    apiVersion: v1
    kind: Service
    metadata:
      name: registry
      namespace: prateek
    spec:
      selector:
        app: registry
      ports:
      - protocol: TCP
        port: 443
        targetPort: 443
      type: LoadBalancer
    

    测试注册服务已启动

  • 尝试通过测试 Pod 访问注册表端点。我已经在 docker 中加载了这个测试容器的图像。
  • curl https://registry.prateek.svc.cluster.local/v2/_catalog -k
    {"repositories":["prateek/echo"]}
    

    使用注册表服务中的镜像进行部署

  • 尝试使用镜像进行部署:registry.prateek/prateek/echo:latest
  • apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello
      namespace: cequence
      labels:
          app: hello
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: hello
      template:
        metadata:
          labels:
            app: hello
        spec:
          containers:
          - name: hello
            image: registry.prateek/prateek/echo:latest
            imagePullPolicy: IfNotPresent
            ports:
             - containerPort: 5678
            args: ["-text=hello"]
    
  • 部署出现错误
  • Normal Pulling 10s (x2 over 25s) kubelet, docker-for-desktop pulling image "registry.prateek/prateek/echo:latest"
    Warning Failed 10s (x2 over 25s) kubelet, docker-for-desktop Failed to pull image "registry.prateek/prateek/echo:latest": rpc error: code = Unknown desc = Error response from daemon: Get https://registry.prateek/v2/: Service Unavailable 
    
  • 更改了部署以包含镜像:registry.prateek.svc.cluster.local/prateek/echo:latest
  • apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello
      namespace: cequence
      labels:
          app: hello
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: hello
      template:
        metadata:
          labels:
            app: hello
        spec:
          containers:
          - name: hello
            image: registry.prateek.svc.cluster.local/prateek/echo:latest
            imagePullPolicy: IfNotPresent
            ports:
             - containerPort: 5678
            args: ["-text=hello"]
    
  • 得到类似的错误
  • Warning Failed 1s kubelet, docker-for-desktop Failed to pull image "registry.prateek.svc.cluster.local/prateek/echo:latest": rpc error: code = Unknown desc = Error response from daemon: Get https://registry.prateek.svc.cluster.local/v2/: Service Unavailable
    

    我不认为这是可能的。将 Docker 注册表作为服务运行,并指向命名空间中的其他服务以在集群中使用该注册表部署。欢迎任何建议

    最佳答案

    容器守护进程在 kubernetes 之外运行。

    因此,如果要拉取镜像,需要确保可以从节点直接访问registry,而不是使用像服务这样的kubernetes机制。 (与您在步骤 9 中通过 pod 进行测试不同,您必须能够直接在节点上工作!)

    通常的选项是创建一个 DNS 条目或 ports.txt 条目来指向一个节点,该节点通过 hostPort(容器)或 nodePort(服务)注册表可访问或者您使用适当的入口。

    关于docker - 是否可以在 Kubernetes 中启动自签名 Docker 注册表,并让其他服务使用它作为注册表来获取其镜像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55732900/

    相关文章:

    nginx - 如何将 Dokku 应用程序指向 dokku 服务器的根域

    nginx - 带有 nginx 和正则表达式的 Kubernetes/Helm 入口路径

    nginx - Kubernetes NGINX 入口 : Disable external auth for specific path

    authorization - 为什么Kubernetes的 “kubectl”被 “Authorization error”中止?

    Docker 一个堆栈的服务与另一个堆栈的服务之间的通信

    deployment - 如何在开发/部署工作流程中使用 Docker?

    linux - kubectl 版本返回错误

    Kubernetes API - 获取特定节点上的 Pod

    macos - 如何在Docker容器中获得root特权?

    docker - Kubernetes:获取网络上其他 Pod 的 IP 地址