问题形容
因为Kubernetes默认状况下只凋谢30000-32767这些端口,然而docker-registry在部署在Kubernetes中的时候conrainerd拜访就会呈现端口不匹配的问题,次要起因是containerd默认状况下HTTPS形式的拜访端口为443,然而依照Kubernetes默认的设置,docker-registry在部署的时候对外裸露的端口在30000-32767之间,因而要么批改Kubernetes默认的端口开启443端口,要么让containerd在拜访HTTPS的默认端口为30000-32767之间。
解决方案
一. 批改Kubernetes默认端口范畴
#解决办法为批改apiserver的启动参数vim /etc/kubernetes/manifests/kube-apiserver.yaml# 增加如下配置- --service-node-port-range=1-65535
上述配置为将默认端口都凋谢,然而这种解决方案存在安全性问题,因而不举荐应用。
二. 批改containerd源码使得HTTPS默认端口为指定值
1. 在Kubernetes中部署docker registry的时候向外裸露的端口设置为30443(也能够设置其余值)
部署过程看我另外一篇文章:https://blog.csdn.net/weixin_...
docker-registry.yaml
apiVersion: apps/v1kind: Deploymentmetadata: name: docker-registry namespace: defaultspec: selector: matchLabels: app: docker-registry spec: nodeSelector: kubernetes.io/hostname: master1 containers: - name: docker-registry image: docker.io/library/registry:2.7.1 imagePullPolicy: IfNotPresent ports: - containerPort: 8443 env: - name: REGISTRY_HTTP_ADDR value: "0.0.0.0:8443" - name: REGISTRY_HTTP_TLS_CERTIFICATE value: "/certs/Yuan.crt" - name: REGISTRY_HTTP_TLS_KEY value: "/certs/Yuan.key" - name: REGISTRY_AUTH value: "htpasswd" - name: REGISTRY_AUTH_HTPASSWD_PATH value: "/auth/htpasswd" - name: REGISTRY_AUTH_HTPASSWD_REALM value: "Registry Realm" volumeMounts: - name: reg-data mountPath: /vat/lib/registry - name: reg-auth mountPath: /auth - name: reg-certs mountPath: /certs volumes: - name: reg-data hostPath: path: /home/docker-registry/images - name: reg-auth hostPath: path: /home/docker-registry/auth - name: reg-certs hostPath: path: /home/docker-registry/certs---apiVersion: v1kind: Servicemetadata: name: docker-registry namespace: defaultspec: type: NodePort ports: - port: 8443 targetPort: 8443 nodePort: 30443 protocol: TCP selector: app: docker-registry
# 部署$ kubectl apply -f docker-registry.yaml# 查看Pod$ kubectl get po# 查看svc,这里就能够看到docker registry对外裸露的端口号为30443$ kubectl get svc
2. 尝试拉取镜像
通过命令:
# 批改containerd的配置文件中的端口号$ vim /etc/containerd/config.tomlendpoint = ["https://10.131.82.53:30443"]# 能够拉取到镜像的命令ctictl pull Yuan.com/nginx:v1 --creds Yuan:Abcd123456ctr i pull Yuan.com:30443/nginx:v1 --user Yuan:Abcd123456# 不能拉取镜像的命令ctictl pull Yuan.com:30443/nginx:v1 --creds Yuan:Abcd123456ctr i pull Yuan.com/nginx:v1 --user Yuan:Abcd123456
通过yaml部署文件
pod-pull-test.yaml
apiVersion: v1kind: Podmetadata: name: pod-pull-testspec: nodeSelector: kubernetes.io/hostname: master1 containers: - name: pod-pull-test image: Yuan.com/nginx:v1 imagePullPolicy: Always
部署测试
$ kubectl apply -f pod-pull-test.yaml$ kubectl describe po pull-podfailed to do request: Head "https://Yuan.com:443/v2/nginx:v1"# 通过以上输入信息能够看出containerd在拉取镜像的时候还是走的443端口,因而拉取镜像失败# 同时能够推断进去Kubernetes在拉取镜像的时候的命令与`ctr i pull Yuan.com/nginx:v1 --user Yuan:Abcd123456`成果相似
批改yaml文件再次拉取
pod-pull-test.yaml
apiVersion: v1kind: Podmetadata: name: pod-pull-testspec: nodeSelector: kubernetes.io/hostname: master1 containers: - name: pod-pull-test image: Yuan.com:30443/nginx:v1 imagePullPolicy: Always
部署测试
$ kubectl apply -f pod-pull-test.yaml$ kubectl describe po pull-podfailed to do request: Head "https://Yuan.com:443/v2/nginx:v1" x509: certificate signed by unknown authority# 通过以上输入信息能够看出containerd在拉取镜像的时候走的还是443端口# 同时还报了证书签名的问题导致镜像拉取失败
3.批改containerd源码HTTPS默认端口号
# 在containerd源码目录上面执行如下命令$ grep -rwnI "443"# 找到于Kubernetes的相干的代码,门路如下containerd/vendor/k8s.io/apimachinery/third_party/forked/golang/netutil/adr.go:16: https: 443# 将这一行批改为30443后编译部署containerd
4.批改证书信息
cd certs # 生成2048位的私钥,也能够生成4096位的,看本人需要 openssl genrsa -out Yuan.key 2048 # 生成证书申请文件 openssl req -new -key Yuan.key -subj "/CN=Yuan.com" -out Yuan.csr # 将DNS地址写入一个文件,为了解决上述所说的那个问题 echo subjectAltName = DNS:Yuan.com>extfile.cnf # 将IP地址写入一个文件,为了解决上述所说的那个问题 echo subjectAltName = IP:10.131.82.54>>extfile.cnf # 这里的ca我就应用了集群自带的,在/etc/kubernetes/pki/下 openssl x509 -req -in Yuan.csr -CA ca.crt -CAkey ca.key -CAcreateserial -extfile extfile.cnf -out Yuan.crt -days 5000 # 查看证书信息 openssl x509 -in Yuan.crt -noout -text # 将生存的证书信息追加到零碎的证书管理文件后 cat Yuan.crt >> /etc/pki/tls/certs/ca-bundle.crt
上述IP地址批改为你部署docker registry机器的IP地址
批改yaml文件再次拉取
pod-pull-test.yaml
apiVersion: v1kind: Podmetadata: name: pod-pull-testspec: nodeSelector: kubernetes.io/hostname: master1 containers: - name: pod-pull-test image: Yuan.com/nginx:v1 imagePullPolicy: Always
部署测试
$ kubectl apply -f pod-pull-test.yaml$ kubectl get po # 通过下面的命令就能够看到pod胜利拉起了
总结
为了合乎Kubernetes的端口要求并且能够通过containerd胜利部署业务镜像就必须要批改containerd的HTTPS默认端口号,在生成docker reigstry证书的时候须要将IP信息和DNS信息写入能力胜利拉取到镜像,这样批改完的益处是不必批改Kubernetes的相干默认配置,在公有仓库拉取镜像的时候不必指定docker registry服务的端口号。