kind集群本地Registry

虽然使用 加载kind镜像 可以用于部署自己的定制镜像,但是使用上有一些不直观。通常我们都是习惯将制作好的镜像推送到Registry中,然后在 Kubernetes 的YAML中直接使用Registry地址。

kind也提供了一种符合我们使用习惯的的本地Registry方式,即在本地Docker中运行一个Local Registry,然后配置kind集群使用这个Local Registry。

创建Registry

kind User Guide: Local Registry 提供了一个脚本 kind-with-registry.sh 构建本地Registry并配置集群使用:

kind官方提供kind-with-registry.sh,可创建具备本地Registry的kind集群
#!/bin/sh
set -o errexit

# create registry container unless it already exists
reg_name='kind-registry'
reg_port='5001'
if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then
  docker run \
    -d --restart=always -p "127.0.0.1:${reg_port}:5000" --name "${reg_name}" \
    registry:2
fi

# create a cluster with the local registry enabled in containerd
cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
containerdConfigPatches:
- |-
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:${reg_port}"]
    endpoint = ["http://${reg_name}:5000"]
EOF

# connect the registry to the cluster network if not already connected
if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" = 'null' ]; then
  docker network connect "kind" "${reg_name}"
fi

# Document the local registry
# https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: local-registry-hosting
  namespace: kube-public
data:
  localRegistryHosting.v1: |
    host: "localhost:${reg_port}"
    help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
EOF

备注

推荐采用 本方法 替代 kind多节点集群

ARM架构Linux环境部署

我做了一些调整,以适配我在 ARM移动云计算构建 采用 kind多节点集群 部署的集群 dev :

  • kind-with-registry-arm.sh 脚本:

运行Registry适配kind集群(dev),ARM架构
#!/bin/sh
set -o errexit

# NOW kind node version(Kubernetes Version) is v1.25.3
VER=v1.25.3

cat << EOF > Dockerfile
FROM --platform=arm64 kindest/node:${VER}
RUN arch
EOF

docker build -t kindest/node:${VER}-arm64 .

# create registry container unless it already exists
reg_name='kind-registry'
reg_port='5001'
if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then
  docker run \
    -d --restart=always -p "127.0.0.1:${reg_port}:5000" --name "${reg_name}" \
    registry:2
fi

# create a cluster with the local registry enabled in containerd
cat <<EOF | kind create cluster --name dev --image kindest/node:${VER}-arm64 --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: control-plane
- role: control-plane
- role: worker
- role: worker
- role: worker
- role: worker
- role: worker
containerdConfigPatches:
- |-
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:${reg_port}"]
    endpoint = ["http://${reg_name}:5000"]
EOF

# connect the registry to the cluster network if not already connected
if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" = 'null' ]; then
  docker network connect "kind" "${reg_name}"
fi

# Document the local registry
# https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: local-registry-hosting
  namespace: kube-public
data:
  localRegistryHosting.v1: |
    host: "localhost:${reg_port}"
    help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
EOF
  • 执行 ./kind-with-registry.sh 创建集群 dev ,同时可以看到运行了一个 kind-registry 的容器提供服务

macOS 环境部署

在ARM架构的 macOS工作室 部署没有遇到ARM架构Linux环境的问题,所以

  • kind-with-registry-macos 脚本:

运行Registry适配kind集群(dev),macOS环境的Docker Desktop for macOS
#!/bin/sh
set -o errexit

CLUSTER_NAME='dev'
# create registry container unless it already exists
reg_name="${CLUSTER_NAME}-registry"
reg_port='5001'
if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then
  docker run \
    -d --restart=always -p "127.0.0.1:${reg_port}:5000" --name "${reg_name}" \
    registry:2
fi

# create a cluster with the local registry enabled in containerd
cat <<EOF | kind create cluster --name ${CLUSTER_NAME} --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: control-plane
- role: control-plane
- role: worker
- role: worker
- role: worker
- role: worker
- role: worker
containerdConfigPatches:
- |-
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:${reg_port}"]
    endpoint = ["http://${reg_name}:5000"]
EOF

# connect the registry to the cluster network if not already connected
if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" = 'null' ]; then
  docker network connect "kind" "${reg_name}"
fi

# Document the local registry
# https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: local-registry-hosting
  namespace: kube-public
data:
  localRegistryHosting.v1: |
    host: "localhost:${reg_port}"
    help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
EOF

使用Registry

Alpine Docker镜像 构建的本地 alpine-nginx 推送到Local Registry进行测试:

  • 检查镜像 docker images ,当前输出如下:

    REPOSITORY                    TAG                  IMAGE ID       CREATED         SIZE
    alpine-nginx                  latest               236634f9c6b8   3 hours ago     14.5MB
    
  • 将镜像打上tag,标记为local registry:

    docker tag alpine-nginx localhost:5001/alpine-nginx:latest
    
  • 此时检查 docker images 输出如下:

    REPOSITORY                    TAG                  IMAGE ID       CREATED         SIZE
    alpine-nginx                  latest               236634f9c6b8   3 hours ago     14.5MB
    localhost:5001/alpine-nginx   latest               236634f9c6b8   3 hours ago     14.5MB
    
  • 将镜像推入Local Reistry:

    docker push localhost:5001/alpine-nginx
    

此时输出信息类似:

Using default tag: latest
The push refers to repository [localhost:5001/alpine-nginx]
9992941a9f7b: Pushed
e9f76b9eead8: Pushed
e40a27ff8335: Pushed
ea0f922ba68b: Pushed
1f6b17cd478d: Pushed
17bec77d7fdc: Pushed
latest: digest: sha256:05e38376828b2d2279517c04e93c2a0b072abbaf0fcbc8e32422c047e9a2c03d size: 1578
  • 我们现在来模拟一个简单的Kubernetes部署:

    kubectl create deployment test-nginx --image=localhost:5001/alpine-nginx
    

提示:

deployment.apps/test-nginx created
  • 检查 kind 部署的这个pod:

    kubectl get pods -o wide
    

可以看到已经成功运行:

NAME                          READY   STATUS    RESTARTS   AGE   IP           NODE          NOMINATED NODE   READINESS GATES
test-nginx-84bcff4756-wszqn   1/1     Running   0          35s   10.244.3.2   dev-worker4   <none>           <none>

这只是第一步验证,实际上要访问部署在pod的服务,还需要一些步骤:

参考