前言
使用kubeadm搭建一套kubernetes集群很简单,但是一个单节点的master并不能满足我们在生产环境的需求。因此必须得解决单点的问题后才能考虑在生产环境大面积推广应用。
实践目标
- 至少2个以上的master节点可以同时管理集群;
- 集群的所有功能正常可用;
- 支持后续扩展;
环境准备
参考master单节点安装,此处不再具体描述。
系统参数 修改系统内核参数:
1 | setenforce 0 |
docker相关 安装docker。
1 | cat <<EOF > /etc/yum.repos.d/kubernetes.repo |
安装相关组件 安装kubeadm必须组件
1 | # 安装其他组件 |
配置NGINX代理
kube-apiserver高可用可以直接起多个节点,很多使用keepalive,haproxy来进行高可用配置,但是在大部分的公有云上无法使用vip。公有云上可以使用公有云提供的LoadBalance,这里我们使用nginx来代替.
nginx stream 四层协议的转发、代理或者负载均衡.
1 | yum -y install nginx nginx-mod-stream |
部署集群
获取默认配置文件 导出
1 | kubeadm config print init-defaults > kubeadm-config.yaml |
根据实际情况修改配置文件 注意修改
1 | apiVersion: kubeadm.k8s.io/v1beta3 |
配置说明:
- controlPlaneEndpoint:为集群apiserver监听端口16443
- imageRepository:由于国内无法访问google镜像仓库k8s.gcr.io,这里指定为私有仓库地址 registry.cn-hangzhou.aliyuncs.com/google_containers
- podSubnet:指定的IP地址段与后续部署的网络插件相匹配
执行初始化
1 | kubeadm init --config=kubeadm-config.yaml --upload-certs | tee kubeadm-init.log |
该命令指定了初始化时需要使用的配置文件,其中添加–upload-certs参数可以在后续执行加入节点时自动分发证书文件。
低版本注意使用–experimental-upload-certs。
kubeadm init主要执行了以下操作:
- [init]:指定版本进行初始化操作
- [preflight] :初始化前的检查和下载所需要的Docker镜像文件
- [kubelet-start]:生成kubelet的配置文件”/var/lib/kubelet/config.yaml”,没有这个文件kubelet无法启动,所以初始化之前的kubelet实际上启动失败。
- [certificates]:生成Kubernetes使用的证书,存放在/etc/kubernetes/pki目录中。
- [kubeconfig] :生成 KubeConfig 文件,存放在/etc/kubernetes目录中,组件之间通信需要使用对应文件。
- [control-plane]:使用/etc/kubernetes/manifest目录下的YAML文件,安装 Master 组件。
- [etcd]:使用/etc/kubernetes/manifest/etcd.yaml安装Etcd服务。
- [wait-control-plane]:等待control-plan部署的Master组件启动。
- [apiclient]:检查Master组件服务状态。
- [uploadconfig]:更新配置
- [kubelet]:使用configMap配置kubelet。
- [patchnode]:更新CNI信息到Node上,通过注释的方式记录。
- [mark-control-plane]:为当前节点打标签,打了角色Master,和不可调度标签,这样默认就不会使用Master节点来运行Pod。
- [bootstrap-token]:生成token记录下来,后边使用kubeadm join往集群中添加节点时会用到
- [addons]:安装附加组件CoreDNS和kube-proxy
无论是初始化失败或者集群已经完全搭建成功,你都可以直接执行kubeadm reset命令清理集群或节点,然后重新执行kubeadm init或kubeadm join相关操作即可。
注意清理
1
2
3
4
5
**配置网络插件** calico
```bash
kubectl apply -f https://docs.projectcalico.org/v3.21/manifests/calico.yaml
其他节点加入集群
master join
1 | kubeadm join 192.168.1.109:16443 --token abcdef.0123456789abcdef \ |
执行后会自动生成相关文件和目录
1 | [root@k8s-node-217 kubernetes]# ll |
如果在某些特殊情况下需要手动上传的话,注意传输以下文件即可:
admin.conf
pki/ca.
pki/front-proxy
pki/sa*
worker 新node
1 | kubeadm join 192.168.1.109:16443 --token abcdef.0123456789abcdef \ |
无论在master节点或node节点,要能够执行kubectl命令必须进行以下配置
1 | mkdir -p $HOME/.kube |
检查集群
两台master节点展示信息一致。
1 | [root@uat-109 ~]# kubectl get nodes |
其他
删除节点
在master节点上执行:1
2
3
当节点变成不可调度状态时候 SchedulingDisabled,执行
```kubectl delete node node-xxx
ipvs
IPVS简介:
尽管 Kubernetes 在版本v1.6中已经支持5000个节点,但使用 iptables 的 kube-proxy 实
际上是将集群扩展到5000个节点的瓶颈。 在5000节点集群中使用 NodePort 服务,如
果有2000个服务并且每个服务有10个 pod,这将在每个工作节点上至少产生20000个
iptable 记录,这可能使内核非常繁忙。
ipvs (IP Virtual Server) 实现了传输层负载均衡,也就是我们常说的4层LAN交换,作为
Linux 内核的一部分。ipvs运行在主机上,在真实服务器集群前充当负载均衡器。ipvs
可以将基于TCP和UDP的服务请求转发到真实服务器上,并使真实服务器的服务在单个
IP 地址上显示为虚拟服务。
我们知道kube-proxy支持 iptables 和 ipvs 两种模式, 在kubernetes v1.8 中引入了 ipvs
模式,在 v1.9 中处于 beta 阶段,在 v1.11 中已经正式可用了。iptables 模式在 v1.1 中
就添加支持了,从 v1.2版本开始 iptables 就是 kube-proxy 默认的操作模式,ipvs 和
iptables 都是基于netfilter的。ipvs 会使用 iptables 进行包过滤、SNAT、masquared。
具体来说,ipvs 将使用ipset来存储需要DROP或masquared的流量的源或目标地址,
以确保 iptables 规则的数量是恒定的,这样我们就不需要关心我们有多少服务了。
启动ipvs的要求:
k8s版本 >= v1.11
使用ipvs需要安装相应的工具来处理”yum install ipset ipvsadm -y“
确保 ipvs已经加载内核模块, ip_vs、ip_vs_rr、ip_vs_wrr、ip_vs_sh、
nf_conntrack_ipv4。如果这些内核模块不加载,当kube-proxy启动后,会退回到iptables模式。
先前基于iptables规则表的DNAT->SNAT方式来处理外部客户端到k8s集群pod内的流量
和集群内部流量(cluster-ip到pod ip),无需在宿主机上管理cluster-ip都由iptables来进行
管理。
使用IPVS后是需要对vs(虚拟服务也就是vip)进行管理,由于IPVS的DNAT钩子挂在
INPUT链上,因此必须要让内核识别 VIP(cluster-ip) 是本机的 IP。k8s 通过设置将
service cluster ip 绑定到虚拟网卡kube-ipvs0,其中下面的10.96.x.x都是VIP,也就
是cluster-ip。
kube-proxy 开启 ipvs
1 | yum install ipset ipvsadm -y |
修改ConfigMap的kube-system/kube-proxy中的config.conf,mode: “ipvs”
1 | [root@master k8s]# kubectl edit cm kube-proxy -n kube-system |
对于Kubernetes来说,可以直接将这三个Pod删除之后,会自动重建。
1 | [root@master k8s]# kubectl get pods -n kube-system|grep proxy |
批量删除 kube-proxy
1 | kubectl get pod -n kube-system | grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}' |
由于你已经通过ConfigMap修改了kube-proxy的配置,所以后期增加的Node节点,会直接使用ipvs模式。
1 | [root@master ~]# kubectl logs kube-proxy-hrjls -n kube-system |
日志中打印出了Using ipvs Proxier,说明ipvs模式已经开启。
使用ipvsadm测试,可以查看之前创建的Service已经使用LVS创建了集群。
1 | [root@master ~]# ipvsadm |