无法创建Kubernetes私有镜像仓库的问题咨询与排查
问题背景
已执行操作
- 生成自签名证书:
cd /opt sudo mkdir certs cd certs sudo touch registry.key cd /opt sudo openssl req -newkey rsa:4096 -nodes -sha256 -keyout \ ./certs/registry.key -x509 -days 365 -out ./certs/registry.crt ls -l certs/ # 创建registry目录 cd /opt mkdir registry
- 部署私有镜像仓库的Deployment配置文件
private-registry.yaml:
apiVersion: apps/v1 kind: Deployment metadata: name: private-repository-k8s labels: app: private-repository-k8s spec: replicas: 1 selector: matchLabels: app: private-repository-k8s template: metadata: labels: app: private-repository-k8s spec: volumes: - name: certs-vol hostPath: path: /opt/certs type: Directory - name: registry-vol hostPath: path: /opt/registry type: Directory containers: - image: registry:2 name: private-repository-k8s imagePullPolicy: IfNotPresent env: - name: REGISTRY_HTTP_TLS_CERTIFICATE value: "/certs/registry.crt" - name: REGISTRY_HTTP_TLS_KEY value: "/certs/registry.key" ports: - containerPort: 5000 volumeMounts: - name: certs-vol mountPath: /certs - name: registry-vol mountPath: /var/lib/registry
执行kubectl create -f private-registry.yaml后,Deployment已创建,但Pod始终处于0/1就绪状态:
kubernetes@kubernetes1:/opt/registry$ kubectl get deployments private-repository-k8s NAME READY UP-TO-DATE AVAILABLE AGE private-repository-k8s 0/1 1 0 12s
查看Pod日志提示:
kubernetes@kubernetes1:/opt/registry$ kubectl logs private-repository-k8s-6ddbcd9c45-s6dfq Error from server (BadRequest): container "private-repository-k8s" in pod "private-repository-k8s-6ddbcd9c45-s6dfq" is waiting to start: ContainerCreating
随后尝试创建PersistentVolume配置private-registry1.yaml:
apiVersion: v1 kind: PersistentVolume metadata: name: pv1 spec: capacity: storage: 256Mi # specify your own size volumeMode: Filesystem persistentVolumeReclaimPolicy: Retain local: path: /opt/registry # can be any path nodeAffinity: required: nodeSelectorTerms: - matchExpressions: # specify the node label which maps to your control-plane node. - key: kubernetes1 operator: In values: - controlplane-1 accessModes: - ReadWriteOnce # only 1 node will read/write on the path. # - ReadWriteMany # multiple nodes will read/write on the path
创建PV后,Pod仍处于ContainerCreating状态。
技术疑问
- 现有1个控制平面节点和2个工作节点,能否仅在控制平面节点的
/opt/registry目录存储镜像,无需共享文件夹即可在所有工作节点部署镜像? - 作为更具弹性的方案,能否让所有节点(控制平面+工作节点)的
/opt/registry目录自动同步数据,由Kubernetes管理镜像仓库的复制,无需手动创建共享文件夹? - 如何排查当前配置问题,解决Pod无法启动的问题?
解答
问题1解答
可以实现。核心逻辑是将私有镜像仓库通过Kubernetes Service暴露为集群内可访问的服务,工作节点通过该Service地址拉取镜像,无需在本地存储镜像文件:
- 为Deployment创建ClusterIP类型的Service,映射容器的5000端口
- 在所有节点上配置信任该私有仓库的自签名证书:将
registry.crt复制到/etc/docker/certs.d/<registry-service-ip>:5000/目录 - 工作节点拉取镜像时使用
<registry-service-ip>:5000/<image-name>:<tag>的地址,镜像文件仅存储在控制平面节点的/opt/registry,工作节点拉取后为本地缓存,并非直接共享存储。
问题2解答
Kubernetes本身不提供节点本地目录的自动同步能力,可通过以下两种方案实现类似效果:
- 使用分布式存储PV:放弃本地目录,采用支持ReadWriteMany(RWX)的分布式存储(如NFS、Ceph或云厂商共享存储),将镜像仓库数据挂载到该PV上,所有节点的Pod均可访问同一份数据,无需手动同步。
- 多副本仓库+外部同步工具:在多个节点部署registry实例,使用
registryctl或自定义定时任务实现不同实例间的镜像自动同步。此方案需额外配置同步逻辑,Kubernetes不直接管理镜像复制。
问题3解答
针对Pod处于ContainerCreating状态的问题,按以下步骤排查:
- 查看Pod事件详情:执行
kubectl describe pod <pod-name>,重点关注Events字段,会明确提示错误原因(如hostPath目录不存在、权限不足、节点亲和性不匹配等) - 检查hostPath目录权限:registry容器默认使用uid 10000运行,需确保控制平面节点上的
/opt/certs和/opt/registry目录对该用户有读写权限,执行sudo chown -R 10000:10000 /opt/certs /opt/registry - 验证节点亲和性配置:检查控制平面节点的实际标签(执行
kubectl get nodes --show-labels),确保PV的nodeAffinity中key和values与节点标签一致(当前PV中key: kubernetes1大概率不是节点实际标签,控制平面节点通常带有node-role.kubernetes.io/control-plane: ""标签) - 确认证书文件有效性:检查控制平面节点上
/opt/certs/registry.crt和/opt/certs/registry.key是否存在且内容完整,避免证书生成过程出错 - 检查节点资源:执行
kubectl top nodes确认控制平面节点有足够的CPU、内存资源运行registry容器
内容的提问来源于stack exchange,提问作者Peter Penzov
相关产品推荐
相关产品推荐

