问题描述
在Kubernetes集群(k3s)上运行着一个私有Docker注册表,并使用Let’s Encrypt证书对注册表进行了安全配置。在从Web浏览器访问注册表时,证书是有效的。然而,在尝试在Kubernetes中部署一个使用该私有注册表中镜像的应用程序时,遇到了与证书相关的错误。
Failed to pull image "192.168.42.50:5000/dev-backend:latest": rpc error: code = Unknown desc = failed to pull and unpack image "192.168.42.50:5000/dev-backend:latest": failed to resolve reference "192.168.42.50:5000/dev-backend:latest": failed to do request: Head "https://192.168.42.50:5000/v2/dev-backend/manifests/latest": x509: certificate signed by unknown authority
用户已在 “docker” 命名空间中创建了一个 Certificate 资源,并成功地从 Let’s Encrypt 获取了证书。可以使用以下命令查看证书请求及其对应的证书:
kubectl get certificaterequests -n docker
kubectl get certificates -n docker
私有注册表正确地使用了 Let’s Encrypt 证书,并且用户还将 Let’s Encrypt 根证书(ISRG Root X1)添加到了集群每个节点上容器运行时(Docker)的受信任证书存储中。
以下是部署的 YAML 文件:
apiVersion: apps/v1
kind: Deployment
metadata:
name: dev-backend
namespace: dev
spec:
replicas: 1
selector:
matchLabels:
app: dev-backend
template:
metadata:
labels:
app: dev-backend
spec:
containers:
- name: dev-backend
image: 192.168.42.50:5000/dev-backend:latest
ports:
- containerPort: 80
volumeMounts:
- name: dev-backend-storage
mountPath: /app/data
volumes:
- name: dev-backend-storage
persistentVolumeClaim:
claimName: dev-backend-pvc
imagePullSecrets:
- name: docker-registry-config
用户已创建了一个 Kubernetes 密钥(docker-registry-config),其中包含访问私有注册表所需的凭据。尽管进行了这些配置,Kubernetes 仍然报告证书由未知颁发机构签署。用户希望确保 Kubernetes 信任 Let’s Encrypt 证书并成功从私有注册表中拉取镜像。用户不想使用“不安全注册表”的方法。感谢您的帮助。
解决方案
以下解决方案可能涉及版本差异或者配置依赖。在实施操作前,务必备份您的数据,并在生产环境中谨慎操作。
为了确保 Kubernetes 信任 Let’s Encrypt 证书并能够成功从私有注册表中拉取镜像,您可以采取以下步骤:
-
使用域名访问:首先,确保您为 Let’s Encrypt 证书设置了一个域名。然后,修改您的部署 YAML 文件,将镜像的地址从 IP 地址改为该域名,如下所示:
yaml
containers:
- name: dev-backend
image: <your_domain>:5000/dev-backend:latest
# 其他配置... -
验证域名解析:确保集群中的节点可以正确解析该域名。您可以使用以下命令来验证:
bash
nslookup <your_domain> -
证书信任链:尽管您已将 Let’s Encrypt 根证书添加到容器运行时的受信任证书存储中,但某些情况下可能需要在 Kubernetes 中额外配置证书信任链。您可以创建一个
ConfigMap
,将根证书添加到其中,然后将该ConfigMap
挂载到您的应用程序 Pod 中。“`yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: trusted-ca-certs
namespace: dev
data:
tls.crt: |
—–BEGIN CERTIFICATE—–
# Let’s Encrypt 根证书内容
—–END CERTIFICATE—–
apiVersion: apps/v1
kind: Deployment
metadata:
name: dev-backend
namespace: dev
spec:
# 其他配置…
template:
spec:
volumes:
– name: trusted-ca-certs
configMap:
name: trusted-ca-certs
containers:
– name: dev-backend
image: :5000/dev-backend:latest
volumeMounts:
– name: trusted-ca-certs
mountPath: /etc/ssl/certs
“`以上示例中,创建了一个
ConfigMap
,其中包含 Let’s Encrypt 根证书内容。然后在您的应用程序 Pod 配置中,将该ConfigMap
挂载到/etc/ssl/certs
路径下,从而让容器能够信任该证书。
通过执行上述步骤,您可以确保 Kubernetes 信任 Let’s Encrypt 证书,并能够成功从私有注册表中拉取镜像,避免使用不安全的注册表方法。