AWS EC2上Kubernetes集群使用自签名证书的私有容器Registry登录报错:x509 certificate signed by unknown authority
问题概述
我在3台AWS EC2服务器上运行着Kubernetes 1.30集群(1个主节点+2个工作节点),最近尝试用CNCF Distribution项目的registry:2.8.2镜像部署私有容器仓库。按照步骤操作后,执行docker login登录仓库时,一直碰到这个错误:"x509 certificate signed by unknown authority"。
注意:我使用的是自签名证书。
复现步骤
- 创建自签名证书和用户认证,TLS证书通过OpenSSL生成:
mkdir registry cd registry mkdir certs mkdir auth openssl req -x509 -newkey rsa:4096 -days 365 -nodes -sha256 -keyout certs/tls.key -out certs/tls.crt -subj "/CN=my-registry" -addext "subjectAltName = DNS:my-registry" - 使用htpasswd添加仓库访问的用户认证(后续步骤未完整展示)
问题分析与解决办法
这个错误的核心原因是:自签名证书没有被Docker和Kubernetes系统信任,所以它们拒绝和你的私有Registry建立TLS连接。下面是一步步的解决方案:
1. 给Docker添加证书信任
Docker默认会从/etc/docker/certs.d/<registry域名>/目录读取信任的证书,所以我们要把自签名证书放到这个位置:
# 先创建对应目录,这里你的Registry域名是my-registry sudo mkdir -p /etc/docker/certs.d/my-registry # 复制你的自签名证书到该目录,推荐命名为ca.crt(Docker会自动识别) sudo cp /path/to/registry/certs/tls.crt /etc/docker/certs.d/my-registry/ca.crt # 重启Docker服务让配置生效 sudo systemctl restart docker
2. 给系统添加根证书信任
Kubernetes的一些组件(比如kubelet)会读取系统的根证书列表,所以还要把证书加到系统信任库:
- 如果是Debian/Ubuntu系列的EC2实例:
sudo cp /path/to/registry/certs/tls.crt /usr/local/share/ca-certificates/my-registry.crt sudo update-ca-certificates - 如果是RHEL/CentOS/Amazon Linux系列的EC2实例:
sudo cp /path/to/registry/certs/tls.crt /etc/pki/ca-trust/source/anchors/my-registry.crt sudo update-ca-trust extract
3. 确保Registry部署时正确配置证书和认证
在Kubernetes中部署Registry时,要把证书和认证文件(htpasswd)挂载到Pod里,这里给你一个参考的Deployment配置:
apiVersion: apps/v1 kind: Deployment metadata: name: private-registry spec: replicas: 1 selector: matchLabels: app: private-registry template: metadata: labels: app: private-registry spec: containers: - name: registry image: registry:2.8.2 ports: - containerPort: 5000 volumeMounts: - name: certs-volume mountPath: /certs readOnly: true - name: auth-volume mountPath: /auth readOnly: true env: # 配置TLS证书路径 - name: REGISTRY_HTTP_TLS_CERTIFICATE value: /certs/tls.crt - name: REGISTRY_HTTP_TLS_KEY value: /certs/tls.key # 配置htpasswd认证 - name: REGISTRY_AUTH value: htpasswd - name: REGISTRY_AUTH_HTPASSWD_REALM value: "Private Registry Realm" - name: REGISTRY_AUTH_HTPASSWD_PATH value: /auth/htpasswd volumes: - name: certs-volume hostPath: path: /path/to/registry/certs # 替换成你EC2上存放证书的实际路径 - name: auth-volume hostPath: path: /path/to/registry/auth # 替换成你存放htpasswd文件的实际路径
另外需要创建一个Service让集群内部可以访问Registry:
apiVersion: v1 kind: Service metadata: name: private-registry-service spec: selector: app: private-registry ports: - port: 5000 targetPort: 5000
4. 验证登录
完成以上配置后,在任意EC2节点执行docker login my-registry:5000,输入你用htpasswd创建的用户名和密码,应该就能成功登录私有Registry了。
备注:内容来源于stack exchange,提问作者piyush sachdeva
相关产品推荐
相关产品推荐

