环境介绍
最近手里闲置了两台云服务器,准备搭建一个公网环境下的 Kubenetes 集群,平时可以利用这个环境学习测试 k8s。公网搭建和本地搭建核心流程区别不大,要注意的是机器的公网IP以及在安全组里放行 kubenetes 组件必要的端口。
厂商 |
配置 |
k8s用途 |
阿里云 |
2c2g |
node |
京东云 |
2c4g |
master |
配置云服务器
配置公网 IP
云厂商的 ECS 都有分配一个公网 IP。这个公网 IP 在控制台上会显示,但是 IP 并不是直接配置在 ECS 机器上。
在机器上通过 ip a
命令只能看到内网 IP,我们需要在 ECS 设置一个虚拟网卡,将控制台的公网 IP 配置在 ECS 上。
将公网 IP 配置到 eth0 网卡上(master and node),
ip addr add x.x.x.x/24 dev eth0 label eth0:0 ip link set dev eth0:0 up
|
命令含义是为 eth0 网卡设置一个别名,eth0:0,将 ip 配置在这个别名上。
添加完成后,可以看到如下 eth0 下面多了 ipv4 的 IP。

Tips: 如果 IP 配置错了,等价删除命令 ip addr del x.x.x.x/24 dev eth0:0
放行端口
云服务器很多端口默认关闭的,需要在控制台打开
端口号 |
组件 |
理由 |
6443 |
apiserver |
放行 master apiserver 端口 |
端口是否开放可以通过 telnet [IP] [端口]
的方式测试,

关闭 firewalld
systemctl stop firewalld systemctl disable firewalld
|
安装 containerd
安装 containerd 并生成默认配置,
dnf config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install -y containerd
containerd config default > /etc/containerd/config.toml
sed -i 's|registry.k8s.io/pause|registry.aliyuncs.com/google_containers/pause|' /etc/containerd/config.toml
sed -i 's|SystemdCgroup = false|SystemdCgroup = true|' /etc/containerd/config.toml
systemctl restart containerd
|
注意:请确保你已经将 runc options SystemdCgroup 配置修改为 true
否则,你可能会在启用了 cgroupv2 操作系统上,遇到如下报错,导致 pod 被 kubelet 重建
Pod sandbox changed, it will be killed and re-created.
安装 kubenetes
安装 kubenetes 1.31,
cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.tuna.tsinghua.edu.cn/kubernetes/core:/stable:/v1.31/rpm/ enabled=1 gpgcheck=1 gpgkey=https://pkgs.k8s.io/core:/stable:/v1.31/rpm/repodata/repomd.xml.key EOF
yum install -y kubelet kubeadm kubectl
|
安装 crictl
安装 crictl 工具,crictl 是一个很方便的工具,
# 安装 crictl yum install cri-tools -y
# 生成 crictl 配置, cat > /etc/crictl.yaml << EOF runtime-endpoint: unix:///run/containerd/containerd.sock image-endpoint: unix:///run/containerd/containerd.sock timeout: 2 debug: false pull-image-on-create: false EOF
|
kubenetes 部署
从现在开始,部署 k8s 集群正式开始!
生成 init 配置
这里使用的是直接配置 yaml 的方式来部署集群,没有采用命令行,
kubeadm config print init-defaults > kubeadm-init.yaml
|
修改 init 配置,主要修改地方有 4 处,设置公网 IP,设置主机名,修改阿里云镜像源,新增一个 podSubnet 的条目,这里在后面的 CNI 网络要用到。
apiVersion: kubeadm.k8s.io/v1beta3 bootstrapTokens: - groups: - system:bootstrappers:kubeadm:default-node-token token: abcdef.0123456789abcdef ttl: 24h0m0s usages: - signing - authentication kind: InitConfiguration localAPIEndpoint: advertiseAddress: x.x.x.x bindPort: 6443 nodeRegistration: criSocket: unix:///var/run/containerd/containerd.sock imagePullPolicy: IfNotPresent name: k8s-master taints: null --- apiServer: timeoutForControlPlane: 4m0s apiVersion: kubeadm.k8s.io/v1beta3 certificatesDir: /etc/kubernetes/pki clusterName: kubernetes controllerManager: {} dns: {} etcd: local: dataDir: /var/lib/etcd imageRepository: registry.aliyuncs.com/google_containers kind: ClusterConfiguration kubernetesVersion: 1.28.0 networking: dnsDomain: cluster.local serviceSubnet: 10.96.0.0/12 podSubnet: 10.244.0.0/16 scheduler: {}
|
集群初始化
初始化集群之前,先加载 iptables 所需模块,开启 ip_forward,
modprobe br_netfilter echo 1 > /proc/sys/net/ipv4/ip_forward
|
通过如下方式,持久化配置,实现开机自动加载
tee /etc/modules-load.d/br_netfilter.conf <<EOF br_netfilter EOF
tee /etc/sysctl.d/99-ipv4-ip-forward.conf <<EOF net.ipv4.ip_forward = 1 EOF
|
加载完模块后后,初始化集群,
kubeadm init --config kubeadm-init.yaml --v 5
|
集群初始化完成后,将这条命令保存到 ~/.bashrc
中,方便后续通过 kubectl 命令管理集群。
export KUBECONFIG=/etc/kubernetes/admin.conf
|
执行完这一步,集群所需的关里面组件已经 up,此时集群依然是 not-ready 状态,应为我们还差集群网络没有配置,配置完毕后,集群状态会变为 ready。
[root@k8s-master ~]# kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system etcd-k8s-master 1/1 Running 9 14s kube-system kube-apiserver-k8s-master 1/1 Running 9 12s kube-system kube-controller-manager-k8s-master 1/1 Running 11 12s kube-system kube-scheduler-k8s-master 1/1 Running 10 12s
|
集群网络配置 flannel
使用 flannel 0.26.2 作为集群的网络方案
wget https://github.com/flannel-io/flannel/releases/download/v0.26.2/kube-flannel.yml
crictl pull m.daocloud.io/docker.io/flannel/flannel:v0.26.2 crictl pull m.daocloud.io/docker.io/flannel/flannel-cni-plugin:v1.6.0-flannel1
sed -i 's|docker.io|m.daocloud.io/docker.io|' kube-flannel.yml
kubectl apply -f kube-flannel.yml
|
Node 节点加入集群
kubeadm 创建集群完成后,会升成一条 join 命令用于节点加入集群,如果这条命令没保存也没有关系。让 master 重新生成一个 token 即可。
master 执行,
[root@k8s-master ~]# kubeadm token create --print-join-command kubeadm join x.x.x.x:6443 --token jpqqsk.ion4kc134qm2z8zv --discovery-token-ca-cert-hash sha256:f40dadc8070ff0218bcfe8530974937a95e3cd1e2d25cd5f865669ac3b40bdb1
|
node 执行(如果需要持久化,参考上文 master 部分),
modprobe br_netfilter echo 1 > /proc/sys/net/ipv4/ip_forward
kubeadm join x.x.x.x:6443 --token jpqqsk.ion4kc134qm2z8zv --discovery-token-ca-cert-hash sha256:f40dadc8070ff0218bcfe8530974937a95e3cd1e2d25cd5f865669ac3b40bdb1
|
FAQ
如何 debug flannel 启动失败问题?
当集群 apiserver 正常时,通过查看 flannel pod 的 日志确认错误
kubectl logs kube-flannel-ds-xxxxx -n kube-flannel

登录到问题节点,通过 crictl logs [flannel-container]
查看 flannel 容器日志

参考
1、https://github.com/kubernetes-sigs/cri-tools/blob/master/docs/crictl.md
2、https://juejin.cn/post/7383894854152405043