问题形容

因为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服务的端口号。