本文为基于
kubeadm
搭建生产环境
级别高可用
的k8s集群。
1. 环境准备
1.0. master硬件配置
参考:
Kubernetes集群Master节点上运行着etcd、kube-apiserver、kube-controller等核心组件,对于Kubernetes集群的稳定性有着至关重要的影响,对于生产环境的集群,必须慎重选择Master规格。Master规格跟集群规模有关,集群规模越大,所需要的Master规格也越高。
说明 :可从多个角度衡量集群规模,例如节点数量、Pod数量、部署频率、访问量。这里简单的认为集群规模就是集群里的节点数量。
对于常见的集群规模,可以参见如下的方式选择Master节点的规格(对于测试环境,规格可以小一些。下面的选择能尽量保证Master负载维持在一个较低的水平上)。
节点规模 | Master规格 | 磁盘 |
---|---|---|
1~5个节点 | 4核8 GB(不建议2核4 GB) | |
6~20个节点 | 4核16 GB | |
21~100个节点 | 8核32 GB | |
100~200个节点 | 16核64 GB | |
1000个节点 | 32核128GB | 1T SSD |
注意事项:
由于Etcd的性能瓶颈,Etcd的数据存储盘尽量选择SSD磁盘。
为了实现多机房容灾,可将三台master分布在一个可用区下三个不同机房。(机房之间的网络延迟在10毫秒及以下级别)
申请LB来做master节点的负载均衡实现高可用,LB作为apiserver的访问地址。
1.1. 设置防火墙端口策略
生产环境设置k8s节点的iptables端口访问规则。
1.1.1. master节点端口配置
协议 | 方向 | 端口范围 | 目的 | 使用者 |
---|---|---|---|---|
TCP | 入站 | 6443 | Kubernetes API server | 所有 |
TCP | 入站 | 2379-2380 | etcd server client API | kube-apiserver, etcd |
TCP | 入站 | 10250 | Kubelet API | 自身, 控制面 |
TCP | 入站 | 10259 | kube-scheduler | 自身 |
TCP | 入站 | 10257 | kube-controller-manager | 自身 |
1.1.2. worker节点端口配置
协议 | 方向 | 端口范围 | 目的 | 使用者 |
---|---|---|---|---|
TCP | 入站 | 10250 | Kubelet API | 自身, 控制面 |
TCP | 入站 | 30000-32767 | NodePort Services | 所有 |
添加防火墙iptables规则
master节点开放6443、2379、2380端口。
1 | iptables -A INPUT -p tcp -m multiport --dports 6443,2379,2380,10250 -j ACCEPT |
1.2. 关闭swap分区
1 | [root@master ~]#swapoff -a |
1.3. 开启br_netfilter和bridge-nf-call-iptables
参考:https://imroc.cc/post/202105/why-enable-bridge-nf-call-iptables/
1 | # 设置加载br_netfilter模块 |
2. 安装容器运行时
在所有主机上安装容器运行时,推荐使用containerd为runtime
。以下分别是containerd与docker的安装命令。
2.1. Containerd
1、参考:安装containerd
1 | # for ubuntu |
2、生成默认配置
1 | containerd config default > /etc/containerd/config.toml |
3、修改CgroupDriver为systemd
k8s官方推荐使用systemd类型的CgroupDriver。
1 | [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] |
4、重启containerd
1 | systemctl restart containerd |
2.2. Docker
1 | # for ubuntu |
官方建议配置cgroupdriver为systemd。
1 | # 修改docker进程管理器 |
2.3. Container Socket
运行时 | Unix 域套接字 |
---|---|
Containerd | unix:///var/run/containerd/containerd.sock |
CRI-O | unix:///var/run/crio/crio.sock |
Docker Engine (使用 cri-dockerd) | unix:///var/run/cri-dockerd.sock |
3. 安装kubeadm,kubelet,kubectl
在所有主机上安装kubeadm,kubelet,kubectl。最好版本与需要安装的k8s的版本一致。
1 | # 以Ubuntu系统为例 |
离线下载安装
1 |
|
4. 配置kubeadm config
参考:
4.1. 配置项说明
4.1.1. 配置类型
kubeadm config支持以下几类配置。
1 | apiVersion: kubeadm.k8s.io/v1beta3 |
可以使用以下命令打印init和join的默认配置。
1 | kubeadm config print init-defaults |
4.1.2. Init配置
kubeadm init配置中只有InitConfiguration
和 ClusterConfiguration
是必须的。
InitConfiguration:
1 | apiVersion: kubeadm.k8s.io/v1beta3 |
- bootstrapTokens
- nodeRegistration
- criSocket:runtime的socket
- name:节点名称
- localAPIEndpoint
- advertiseAddress:apiserver的广播IP
- bindPort:k8s控制面安全端口
ClusterConfiguration:
1 | apiVersion: kubeadm.k8s.io/v1beta3 |
networking:
- podSubnet:Pod CIDR范围
- serviceSubnet: service CIDR范围
- dnsDomain
etcd:
- dataDir:Etcd的数据存储目录
apiserver
- certSANs:设置额外的apiserver的域名签名证书
imageRepository:镜像仓库
controlPlaneEndpoint:控制面LB的域名
kubernetesVersion:k8s版本
4.2. Init配置示例
在master节点生成默认配置,并修改配置参数。
1 | kubeadm config print init-defaults > kubeadm-config.yaml |
修改配置内容
1 | apiVersion: kubeadm.k8s.io/v1beta3 |
安装完成后可以查看kubeadm config
1 | kubectl get cm -n kube-system kubeadm-config -oyaml |
5. 安装Master控制面
提前拉取镜像:
1 | kubeadm config images pull |
5.1. 安装master
1 | sudo kubeadm init --config kubeadm-config.yaml --upload-certs --node-name <nodename> |
部署参数说明:
—control-plane-endpoint:指定控制面(kube-apiserver)的IP或DNS域名地址。
—apiserver-advertise-address:kube-apiserver的IP地址。
—pod-network-cidr:pod network范围,控制面会自动给每个节点分配CIDR。
—service-cidr:service的IP范围,default “10.96.0.0/12”。
—kubernetes-version:指定k8s的版本。
—image-repository:指定k8s镜像仓库地址。
—upload-certs :标志用来将在所有控制平面实例之间的共享证书上传到集群。
—node-name:hostname-override,作为节点名称。
执行完毕会输出添加master和添加worker的命令如下:
1 | ... |
5.2. 添加其他master
添加master
和添加worker
的差别在于添加master
多了--control-plane
参数来表示添加类型为master
。
1 | kubeadm join <control-plane-endpoint>:6443 --token <token> \ |
6. 添加Node节点
1 | kubeadm join <control-plane-endpoint>:6443 --token <token> \ |
7. 安装网络插件
1 | ## 如果安装之后node的状态都改为ready,即为成功 |
如果Pod CIDR的网段不是10.244.0.0/16
,则需要加flannel配置中的网段更改为与Pod CIDR的网段一致。
7.1. 问题
1 | Warning FailedCreatePodSandBox 4m6s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "300d9b570cc1e23b6335c407b8e7d0ef2c74dc2fe5d7a110678c2dc919c62edf": plugin type="flannel" failed (add): failed to delegate add: failed to set bridge addr: "cni0" already has an IP address different from 10.244.3.1/24 |
原因:
宿主机节点有cni0
网卡,且网卡的IP段与flannel的CIDR网段不同,因此需要删除该网卡,让其重建。
解决:
1 | ifconfig cni0 down |
8. 部署dashboard
1 | kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.0/aio/deploy/recommended.yaml |
镜像: kubernetesui/dashboard:v2.5.0
默认端口:8443
登录页面需要填入token或kubeconfig
参考:dashboard/creating-sample-user
1 | apiVersion: v1 |
创建用户
1 | kubectl -n kubernetes-dashboard create token admin-user |
9. 重置部署
1 | # kubeadm重置 |
删除flannel
1 | ifconfig cni0 down |
10. 问题排查
10.1. kubeadm token过期
问题描述:
添加节点时报以下错误:
1 | [discovery] The cluster-info ConfigMap does not yet contain a JWS signature for token ID "abcdef", will try again |
原因:token过期,初始化token后会在24小时候会被master删除。
解决办法:
1 | # 重新生成token |
基于新生成的token重新添加节点。
10.2. 修改kubeadm join的master IP或端口
kubeadm join
命令会去kube-public
命名空间获取名为cluster-info
的ConfigMap
。如果需要修改kubeadm join使用的master的IP或端口,则需要修改cluster-info的configmap。
1 | # 查看cluster-info |
修改配置文件中的server
字段
1 | clusters: |
执行kubeadm join的命令时指定新修改的master地址。
10.3. conntrack not found
1 | [preflight] Some fatal errors occurred: |
解决方法:
1 | apt -y install conntrack |
10.4. Kubelet: unable to determine runtime API version
1 | Error: failed to run Kubelet: unable to determine runtime API version: rpc error:code = Unavailable desc = connection error: desc = "transport: Error while dialing dial unix: missing address" |
解决方法:
检查kubelet的启动参数,可以用二进制直接添加参数debug
1 | # 查看启动参数是否遗漏,比如10-kubeadm.conf 文件参数缺失 |
参考:
- 利用 kubeadm 创建高可用集群 | Kubernetes
- 使用 kubeadm 创建集群 | Kubernetes
- 高可用拓扑选项 | Kubernetes
- kubeadm init | Kubernetes
- v1.24.2|kubeadm|v1beta3
- Installing kubeadm | Kubernetes
- Ports and Protocols | Kubernetes
- 容器运行时 | Kubernetes
- https://github.com/Mirantis/cri-dockerd
- 配置 cgroup 驱动|Kubernetes
- GitHub: flannel is a network fabric for containers
- 部署和访问 Kubernetes 仪表板(Dashboard) | Kubernetes
赞赏一下