使用Kubespray离线部署kubernetes

这篇文章是记录一下目前homelab中kubernetes集群的部署方式,以及遇到的问题

在设计homelab的时候考虑到比较多的一个场景就是离线部署,是希望能够做到离线部署+离线升级。 将实际的生产网络进行隔离,因此在很多组建部署的时候都会考虑到优先考虑如何进行离线部署。

kubernetes有很多的发行版,当前还是用的kubespray来进行离线部署,在后续的文章中也会介绍其他发行版的离线部署。

这里一共有8个节点,分别是:

nameroledesc
mirrorsN/A离线包制作
nginxGateway离线包发布
node1master
node2master
node3worker
node4worker
node5worker
node6worker

所有节点均使用debian12。

💡 :以下操作是在可以上外网节点上执行

下载源码:

git clone https://github.com/kubernetes-sigs/kubespray

切换分支,这个也可以根据你实际需求来去使用不同的分支:

cd kubespray
git switch release-2.27

下载二进制文件:

cd contrib/offline
bash generate_list.sh
wget -x -P temp/files -i temp/files.list

保持这个目录结构 放到了nas上面 10.31.0.2

scp -r  temp/files/* root@10.31.0.2:/mirrors/k8s

除了二进制之外还需要将镜像也要下载下来,可以是harbor也可以是registry:

我这里准备了一个脚本可以用这个脚本批量将这些镜像搬运到内网的harbor:

#!/bin/bash

# 定义代理映射
declare -A proxies=(
    ["docker.io"]="docker-proxy.plz.ac"
    ["ghcr.io"]="ghcr.plz.ac"
    ["registry.k8s.io"]="k8s-io.plz.ac"
    ["quay.io"]="quay.plz.ac"
)

# 读取镜像列表文件
input_file="$1"
harbor_registry="harbor.plz.ac"

# 读取镜像列表文件
while IFS= read -r image; do
    # 提取镜像仓库和名称
    registry=$(echo $image | cut -d '/' -f 1)
    name=$(echo $image | cut -d '/' -f 2-)

    # 选择对应的代理
    proxy=${proxies[$registry]}
    if [ -z "$proxy" ]; then
        echo "No proxy found for $registry"
        continue
    fi

    # 构建代理镜像URL
    proxy_image="$proxy/$name"

    # 拉取镜像
    echo "Pulling image: $proxy_image"
    docker pull $proxy_image

    # 重新tag镜像
    echo "Tagging image: $proxy_image as $image"
    docker tag $proxy_image $image

    # 构建目标镜像URL(去掉域名前缀,如果没有仓库,使用library)
    if [[ $name == *"/"* ]]; then
        target_image="$harbor_registry/$name"
    else
        target_image="$harbor_registry/library/$name"
    fi

    # 使用skopeo拷贝镜像到Harbor
    echo "Copying image: $image to $target_image"
    skopeo copy docker-daemon:$image docker://$target_image

    # 删除中间镜像以节省空间
    docker rmi $proxy_image
    docker rmi $image

done < "$input_file"

执行:

~/tools/images_pull.sh temp/images.list

这里已经有了一个sample,我们可以直接复制对应的目录来做自己的环境:

cp -rv  inventory/sample inventory/basic

修改对应的配置文件如下 inventory/basic/group_vars/all/offline.yml,这里需要改一下对应的registry_hostfiles_repo还有对应工具地址这些是只需要取消注释即可:

registry_host: "harbor.plz.ac/k8s"
files_repo: "http://10.31.0.2/k8s"
kube_image_repo: "{{ registry_host }}"
gcr_image_repo: "{{ registry_host }}"
github_image_repo: "{{ registry_host }}"
docker_image_repo: "{{ registry_host }}"
quay_image_repo: "{{ registry_host }}"
github_url: "http://10.31.0.2/k8s/github.com"
kubeadm_download_url: "{{ files_repo }}/dl.k8s.io/release/{{ kube_version }}/bin/linux/{{ image_arch }}/kubeadm"

# 类似的其他的二进制也要修改对应的地址

创建虚拟环境:

python3 -m venv ~/kubespray-basic-pyenv

激活:

. ~/kubespray-basic-pyenv/bin/activate

设置国内的加速站点:

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

安装模块:

pip install -r  requirements.txt
pip install ruamel.yaml

设置ip

declare -a IPS=(10.31.0.110 10.31.0.111 10.31.0.112 10.31.0.113 10.31.0.114 10.31.0.115)
CONFIG_FILE=inventory/basic/hosts.yaml python3 contrib/inventory_builder/inventory.py ${IPS[@]}

修改额外的插件

这里可以启用类似lb,argo、helm等一系列的插件非常方便

vi inventory/basic/group_vars/k8s_cluster/addons.yml

修改网络插件

这里支持的插件是有很多可以根据需要去灵活的修改

inventory/basic/group_vars/k8s_cluster/k8s-cluster.yml

修改参数:

kube_network_plugin: cilium
# 这个开lb是需要的 ,但是会和cilium不太兼容因为cilium有其他的实现方案会把kube proxy代替掉
kube_proxy_strict_arp: true

部署:

ansible-playbook --private-key ~/chris-ssh/id_rsa -i inventory/basic/hosts.yaml --user=user  --become --become-user=root cluster.yml

清空集群:

ansible-playbook --private-key ~/chris-ssh/id_rsa -i inventory/basic/hosts.yaml --user=user --become --become-user=root reset.yml

目前这套方案已经在homelab里面运行了1年多了还没有出现什么问题,在后期的homelab专题里面我再去更新如何配合外部lb来进行服务访问、以及如何对集群进行升级。