Kubernetes集群搭建私有镜像仓库的方法,和K3S大同小异。

软件版本为Kubernetes 1.28.4 ,Debian 12。

一、安装私有镜像仓库

1.生成证书和认证文件

在master1节点上,运行

mkdir -p /registry && cd "$_"
mkdir certs
openssl req -x509 -newkey rsa:4096 -days 3650 -nodes -sha256 -keyout certs/tls.key -out certs/tls.crt -subj "/CN=docker-registry" -addext "subjectAltName = DNS:docker-registry"

apt install  apache2-utils
mkdir auth
htpasswd  -Bbn myuser mypasswd > auth/htpasswd

其中 myuser和mypasswd是访问仓库的用户名和密码,根据实际情况修改。

2.生成证书和认证密钥

kubectl create secret tls certs-secret --cert=/registry/certs/tls.crt --key=/registry/certs/tls.key
kubectl create secret generic auth-secret --from-file=/registry/auth/htpasswd

3.为私有镜像仓库准备PV和PVC

把下列内容保存到文件registry-volume.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: docker-repo-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /tmp/repository
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: docker-repo-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

运行下列命令生效

kubectl create -f registry-volume.yaml

4. 部署镜像仓库pod和service

把下列内容保存到文件docker-registry-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: docker-registry-pod
  labels:
    app: registry
spec:
  containers:
  - name: registry
    image: registry:2
    volumeMounts:
    - name: repo-vol
      mountPath: "/var/lib/registry"
    - name: certs-vol
      mountPath: "/certs"
      readOnly: true
    - name: auth-vol
      mountPath: "/auth"
      readOnly: true
    env:
    - name: REGISTRY_VALIDATION_DISABLED
      value: "true"
    - name: REGISTRY_AUTH
      value: "htpasswd"
    - name: REGISTRY_AUTH_HTPASSWD_REALM
      value: "Registry Realm"
    - name: REGISTRY_AUTH_HTPASSWD_PATH
      value: "/auth/htpasswd"
    - name: REGISTRY_HTTP_TLS_CERTIFICATE
      value: "/certs/tls.crt"
    - name: REGISTRY_HTTP_TLS_KEY
      value: "/certs/tls.key"
  volumes:
  - name: repo-vol
    persistentVolumeClaim:
      claimName: docker-repo-pvc
  - name: certs-vol
    secret:
      secretName: certs-secret
  - name: auth-vol
    secret:
      secretName: auth-secret
---
apiVersion: v1
kind: Service
metadata:
  name: docker-registry
spec:
  selector:
    app: registry
  ports:
    - port: 5000
      targetPort: 5000

运行下列命令生效

kubectl create -f docker-registry-pod.yaml

5. 修改每台主机的hosts文件,把证书文件复制到每个主机节点

首先,启用每台主机的ssh root登录。

登录到集群的每台主机上,修改/etc/ssh/sshd_config文件, 添加一行

PermitRootLogin yes

运行 systemctl restart sshd 生效。

在master1主机上,运行

kubectl get svc docker-registry

得到私有仓库service的IP地址。

然后运行

export REGISTRY_NAME="docker-registry"
export REGISTRY_IP="<docker-registry-service-ip>"

其中<docker-registry-service-ip>是私有仓库service的IP地址,根据实际情况修改。

运行

for x in $(kubectl get nodes -o jsonpath='{ $.items[*].status.addresses[?(@.type=="InternalIP")].address }'); do ssh root@$x "echo '$REGISTRY_IP $REGISTRY_NAME' >> /etc/hosts"; done

修改每台主机的hosts文件,把主机名docker-registry添加进去。

运行

for x in $(kubectl get nodes -o jsonpath='{ $.items[*].status.addresses[?(@.type=="InternalIP")].address }'); do scp /registry/certs/* root@$x:/usr/local/share/ca-certificates/; ssh root@$x "update-ca-certificates"; done

把证书文件复制到每台主机,更新主机的根证书。

6. 修改代理服务器设置(可选)

如果Kubernetes集群设置过代理服务器,需要修改配置文件。

在master1主机中,编辑/etc/systemd/system/containerd.service.d/http-proxy.conf,将docker-registry加入到NO_PROXY选项中,如下所示:

[Service]
Environment="HTTP_PROXY=http://username:password@proxy-server-ip:port"
Environment="HTTPS_PROXY=http://username:password@proxy-server-ip:port"
Environment="NO_PROXY=localhost,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0
/16,docker-registry,aliyuncs.com,.svc,.cluster.local,.ewhisper.cn,<nodeCIDR>,<AP
IServerInternalURL>,<serviceNetworkCIDRs>,<etcdDiscoveryDomain>,<clusterNetworkC
IDRs>,<platformSpecific>,<REST_OF_CUSTOM_EXCEPTIONS>"

运行

for x in $(kubectl get nodes -o jsonpath='{ $.items[*].status.addresses[?(@.type=="InternalIP")].address }'); do scp /etc/systemd/system/containerd.service.d/http-proxy.conf root@$x:/etc/systemd/system/containerd.service.d/;  done
 for x in $(kubectl get nodes -o jsonpath='{ $.items[*].status.addresses[?(@.type=="InternalIP")].address }'); do ssh root@$x "systemctl daemon-reload"; done
for x in $(kubectl get nodes -o jsonpath='{ $.items[*].status.addresses[?(@.type=="InternalIP")].address }'); do ssh root@$x "systemctl restart containerd.service"; done

把文件复制到每台主机上,重启containerd生效。

至此,私有镜像仓库安装部署完成。

二、测试

1. 把镜像文件上传到私有镜像仓库

运行

ctr image pull --platform linux/amd64 docker.io/library/nginx:latest
ctr image tag docker.io/library/nginx:latest docker-registry:5000/mynginx:v1
ctr image  push --platform linux/amd64  --user myuser:mypasswd docker-registry:5000/mynginx:v1

其中myuser和mypasswd是访问仓库的用户名和密码,根据实际情况修改。

2. 从私有镜像仓库拉取并运行镜像

运行

kubectl create secret docker-registry reg-cred-secret --docker-server=$REGISTRY_NAME:5000 --docker-username=myuser --docker-password=mypasswd

生成仓库访问密钥。其中myuser和mypasswd是访问仓库的用户名和密码,根据实际情况修改。

运行

kubectl run nginx-pod --image=docker-registry:5000/mynginx:v1 --overrides='{ "apiVersion": "v1", "spec": { "imagePullSecrets": [{"name": "reg-cred-secret"}] } }'

运行

kubectl get pods -o wide

观察nginx-pod的运行情况,记下它的内部IP地址。

运行

curl <nginx-pod-ip>:80

其中nginx-pod-ip是nginx-pod的内部IP,根据实际情况修改。

运行结果应该是返回nginx的HTML首页代码。

测试完成。

参考:

https://www.knowledgehut.com/blog/devops/private-docker-registry

https://docs.k3s.io/zh/installation/private-registry

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注