在国内网络环境中创建集群

808 阅读3分钟

背景

k3d 启动集群的过程中,需要访问 ghcr.io、docker.io 等国外镜像仓库,基于运营商网络策略可能会遇到被墙导致镜像无法拉取的问题,本文简单介绍了如何通过国内镜像仓库规避创建集群时因无法拉取镜像导致的集群无法创建以及集群无法正常初始化问题。

场景一:创建集群报错

问题现象

当我们使用 k3d 命令行工具创建集群时,比如:

k3d cluster create mycluster

在集群创建过程中可能会出现错误,比如:

INFO[0000] Prep: Network                                
INFO[0000] Created network 'k3d-mycluster'              
INFO[0000] Created image volume k3d-mycluster-images    
INFO[0000] Starting new tools node...                   
INFO[0001] Creating node 'k3d-mycluster-server-0'       
INFO[0002] Pulling image 'ghcr.io/k3d-io/k3d-tools:5.7.4' 
ERRO[0016] failed Cluster Creation: failed setup of server/agent node k3d-mycluster-server-0: failed to create node: runtime failed to create node 'k3d-mycluster-server-0': failed to create container for node 'k3d-mycluster-server-0': docker failed to pull image 'docker.io/rancher/k3s:v1.30.4-k3s1': docker failed to pull the image 'docker.io/rancher/k3s:v1.30.4-k3s1': Error response from daemon: Get "https://registry-1.docker.io/v2/": context deadline exceeded 
ERRO[0016] Failed to create cluster >>> Rolling Back    
INFO[0016] Deleting cluster 'mycluster'                 
ERRO[0016] failed to get cluster: No nodes found for given cluster 
FATA[0016] Cluster creation FAILED, also FAILED to rollback changes!

问题分析

该问题是 k3d 工具通过 docker 启动集群实例相关容器时无法拉去镜像,具体原因大概率是网络阻塞导致的,无法访问 ghcr.io 镜像仓库拉取镜像。

解决方案

我们可以通过 docker registry mirrors 的功能,通过使用国内的镜像仓库解决无法拉取镜像的问题,例如使用:dockermirror.com 提供的镜像仓库。具体步骤如下:

1、编辑 Docker Daemon 配置文件,添加 registry-mirrors 配置项,例如:

{
  "registry-mirrors": ["https://registry.dockermirror.com"]
}

2、重启 docker daemon 服务 3、重新使用 k3d 创建集群

场景二:集群启动过程中无法拉取镜像

问题现象

当通过 k3d cluster create 命令创建集群后,docker 容器会启动集群相关虚拟节点,集群会进入初始化过程,这个过程中容器中的虚拟节点会通过 docker.io 拉取 mirrored-pausecorednslocal-path-provisionermetrics-server 等镜像,可通过以下命令查看:

kubectl get pod -n kube-system

通过持续查看 Pod 状态,我们会发现 Pod 始终处于 ContainerCreating 状态,通过 kubectl describe pod coredns-xxxxxxxxxx-xxxxx -n kube-system 命令可以具体查看 coredns 的 Pod 事件日志如下:

Events:
  Type     Reason                  Age   From               Message
  ----     ------                  ----  ----               -------
  Normal   Scheduled               24s   default-scheduler  Successfully assigned kube-system/coredns-576bfc4dc7-nmgfd to k3d-mycluster-server-0
  Warning  FailedCreatePodSandBox  2s    kubelet            Failed to create pod sandbox: rpc error: code = Unknown desc = failed to get sandbox image "rancher/mirrored-pause:3.6": failed to pull image "rancher/mirrored-pause:3.6": failed to pull and unpack image "docker.io/rancher/mirrored-pause:3.6": failed to resolve reference "docker.io/rancher/mirrored-pause:3.6": failed to do request: Head "https://registry-1.docker.io/v2/rancher/mirrored-pause/manifests/3.6": dial tcp 65.49.26.98:443: connect: connection refused

可以看到,也是因为拉取镜像存在问题,所以 Pod 无法正常启动。

问题分析

该问题是基于 Docker 容器运行的虚拟节点无法访问 docker.io 导致无法拉取到镜像,这个问题比较棘手一些,因为此时是在容器内独立运行的容器上下文要拉取镜像,通过给宿主机增加 mirrors 配置无法解决该问题。

解决方案

通过查看 k3d 相关文档 Using Config Files 我们发现可以通过预设配置文件的方式,在集群所有节点中应用 mirrors,具体步骤如下:

1、创建配置文件,比如 mycluster.yaml

apiVersion: k3d.io/v1alpha5
kind: Simple
metadata:
  name: mycluster
registries:
  config: |
    mirrors:
      "docker.io":
        endpoint:
          - https://registry.dockermirror.com

2、基于配置文件创建集群

k3d cluster create --config ./mycluster.yaml