基于 Devbox 搭建 IPv4/IPv6 双协议栈 Kubernetes 集群实践

前言

Kubernetes 是当下热门的容器编排系统,在 Devbox 上搭建 Kubernetes 集群是一种较为便捷的学习方式。目前网上资料以搭建 IPv4 集群为主,在公司大力推进 IPv6 改造的当下,本文提供了双协议栈集群的一种搭建方式。

通过本文你可以:

  • 快速搭建一个双协议栈 K8s 集群

  • 创建一个支持双协议栈的 Web 服务

准备工作

整个搭建过程均在 root 角色下进行的。

配置

本文使用的环境配置,可以作为参考。

两台开发机一台Master节点,一台工作节点 Debian 10系统8核16G
containerd 版本v1.6.8
K8s 版本v1.25
Flannel 版本v0.19.2
swap swap 会导致集群无法启动,建议永久关闭 sed -i '/swap/s/^/#/' /etc/fstab

安装 containerd

可参考官方安装指令:Install Docker Engine on Debian

Shell 复制代码
apt-get update
apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release \
    apt-transport-https
mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
apt-get update
apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin

因为 containerd 默认镜像拉取地址为国外仓库下载速度较慢,可能会报错"net/http: TLS handshake timeout",可以安装镜像加速器。在 /etc/docker/daemon.json 文件括号内添加下面的值。

Shell 复制代码
{
  "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"]
}

保存修改后重启 containerd 使配置生效。

Shell 复制代码
# 守护进程重启
systemctl daemon-reload
# 重启containerd服务
systemctl restart containerd

安装 K8s

从 1.21 版本开始,K8s 集群默认启用 IPv4/IPv6 双协议栈网络,以支持同时分配 IPv4 和 IPv6 地址。而官网建议使用 v1.23 版本之后的,这里选择安装了 K8s 的最新版本 v1.25 。

Shell 复制代码
apt-get update
curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
apt-get update -y
apt-get install -y kubelet kubeadm kubectl

搭建集群

启动 Master 节点

Shell 复制代码
kubeadm init --pod-network-cidr=10.244.0.0/16,2001:db8:42:0::/56 --service-cidr=10.96.0.0/16,2001:db8:42:1::/112 --image-repository=registry.aliyuncs.com/google_containers --ignore-preflight-errors=all

初始化成功后会返回下面内容,保存一下,这个命令用于其他节点加入到集群中,而且 Token 是有时效性的,过期时间一般是1天。

Shell 复制代码
kubeadm join *** --token *** \
        --discovery-token-ca-cert-hash ***

如果忘了保存,可以执行下面指令查看。

Shell 复制代码
kubeadm token create --print-join-command

安装网络通信插件

初始化集群后, Master 节点处于 Not-ready 的状态,需要安装网络通信插件,这里使用 Flannel 进行演示。从 kube-flannel.yml获取网页内容到本地,并在 ConfigMap.data.net-conf.json 字段新增"EnableIPv6"和"IPv6Network"表示支持双栈。

接着执行下面命令安装 Flannel 插件。

Shell 复制代码
kubectl apply -f kube-flannel.yml

可执行下面命令查看安装结果。

Shell 复制代码
cat /run/flannel/subnet.env

如图所示,新增了两个字段:

  • FLANNEL_IPV6_NETWORK

  • FLANNEL_IPV6_SUBNET

工作节点加入集群

首先在工作节点上根据以上步骤安装好 containerd 和 K8s 。执行以下命令,将工作节点加入到 Master 节点的集群中。

Shell 复制代码
kubeadm join *** --token *** \
        --discovery-token-ca-cert-hash ***

如下表示加入集群成功。

等待节点创建成功,分别执行以下命令查看 nodes 和 pods 状态。

Shell 复制代码
kubectl get nodes
kubectl get pod -A -o wide 

验证 IPv4 /IPv6 双****协议栈

验证寻址

每个双协议栈节点应分配一个 IPv4 块和一个 IPv6 块。 通过运行以下命令来验证是否配置了 IPv4/IPv6 Pod 地址范围。 将示例节点名称替换为集群中的有效双协议栈节点。 在此示例中,节点的名称为 n248-173-091。

Shell 复制代码
 kubectl get nodes n248-173-091 -o go-template --template='{{range .spec.podCIDRs}}{{printf "%s\n" .}}{{end}}'
Shell 复制代码
10.244.1.0/24
2001:db8:42:2::/64

验证服务支持双栈

下面通过创建一个 Nginx 服务验证双协议栈生效。

  1. 创建 nginx 的发布 deployment , K8s 通过 deployment 来部署应用

创建 nginx-dep.yml 文件并执行以下命令。

Shell 复制代码
kubectl apply -f nginx-dep.yml
YAML 复制代码
# nginx-dep.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80

执行以下命令查看 deployment 状态,可以看到3个 pod 均处于READY状态。

Shell 复制代码
kubectl get deploy -o wide
Shell 复制代码
NAME               READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES         SELECTOR
nginx-deployment   3/3     3            3           2d17h   nginx        nginx:alpine   app=nginx
  1. 创建 nginx 的服务 Service , K8s 使用 Service 来实现服务发现

创建 nginx-svc.yml 文件,执行以下命令。

Shell 复制代码
kubectl apply -f nginx-svc.yml
YAML 复制代码
# nginx-svc.yml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  ipFamilyPolicy: PreferDualStack 
  ipFamilies: 
  - IPv6
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30080
  type: NodePort

其中.spec.ipFamilyPolicy可设置为PreferDualStack或RequireDualStack以激活双栈支持,默认为SingleStack。

.spec.ipFamilies字段用来设置 IPv4 和 IPv6 的首选项顺序。

执行以下命令查看 Service 状态。

Shell 复制代码
kubectl get svc nginx-service -o wide

为了验证在外部正常访问 nginx,打开浏览器,输入工作节点的 ip+port ,可以看到 nginx 的欢迎页面,说明 nginx-service 创建成功。

常见问题

以下是我在搭建过程中遇到的一些问题,仅供参考。

  1. 当执行集群初始化命令时,出现 timed out waiting for the condition 的报错

执行journalctl -xeu kubelet查询日志,检查是不是 pause 镜像没有下载成功,因为阿里的kubernetes仓库虽然可以下载到 K8s v1.23+以上的镜像,但是有一个问题,其pause容器还是用的k8s.gcr.io/pause:3.6,该镜像在国内服务器下载不成功,需要手工下载。

Shell 复制代码
# 由于k8s.gcr.io 需要连外网才可以拉取到,导致 k8s 的基础容器 pause 经常无法获取。k8s docker 可使用代理服拉取,再利用 docker tag 解决问题
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6 k8s.gcr.io/pause:3.6

# 但是我们k8s集群中使用的CRI是containerd。所以只能通过 docker tag 镜像,再使用 ctr 导入镜像.
docker save k8s.gcr.io/pause -o pause.tar
ctr -n k8s.io images import pause.tar

# 重启
systemctl restart containerd
kubeadm reset

# 重新执行初始化命令
kubeadm init --pod-network-cidr=10.244.0.0/16,2001:db8:42:0::/56 --service-cidr=10.96.0.0/16,2001:db8:42:1::/112 --image-repository=registry.aliyuncs.com/google_containers --ignore-preflight-errors=all
  1. 当节点加入master后报错:Config not found: /etc/kubernetes/admin.conf

在工作节点的 /etc/kubernetes/ 位置创建 admin.conf ,把 master 节点的 admin.conf 内容复制进去,再新增环境变量。

Shell 复制代码
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile
  1. pod****中的coredns 一直重启

执行kubeadm reset 重置,并执行ifconfig,cni0 的IP地址段不属于 Flannel 的IP地址段里,需要清理一下网络,删除 cni0 ,之后会自动重建。

Shell 复制代码
ifconfig cni0 down    
ip link delete cni0

如果网卡 cni0 删除后没有重建时,重启 containerd 。

Shell 复制代码
systemctl daemon-reload
systemctl restart containerd

总结

本文演示了如何在 Devbox 上搭建一个双协议栈 Kubernetes 集群,并通过部署一个 Nginx 服务进行了验证。未来会提供更多实践类的文章,比如基于 Devbox 搭建一个高可用的 Kubernetes 集群。

参考资料

相关推荐
木鱼时刻1 天前
容器与 Kubernetes 基本概念与架构
容器·架构·kubernetes
chuanauc2 天前
Kubernets K8s 学习
java·学习·kubernetes
庸子2 天前
基于Jenkins和Kubernetes构建DevOps自动化运维管理平台
运维·kubernetes·jenkins
李白你好2 天前
高级运维!Kubernetes(K8S)常用命令的整理集合
运维·容器·kubernetes
Connie14512 天前
k8s多集群管理中的联邦和舰队如何理解?
云原生·容器·kubernetes
伤不起bb2 天前
Kubernetes 服务发布基础
云原生·容器·kubernetes
别骂我h3 天前
Kubernetes服务发布基础
云原生·容器·kubernetes
weixin_399380693 天前
k8s一键部署tongweb企业版7049m6(by why+lqw)
java·linux·运维·服务器·云原生·容器·kubernetes
斯普信专业组3 天前
K8s环境下基于Nginx WebDAV与TLS/SSL的文件上传下载部署指南
nginx·kubernetes·ssl
&如歌的行板&3 天前
如何在postman中动态请求k8s中的pod ip(基于nacos)
云原生·容器·kubernetes