kubeadm部署k8s集群
k8s集群环境规划
主机名 | IP地址 | 节点作用 | k8s 相关组件 |
---|---|---|---|
k8s-master | 192.168.223.140 | k8s-master | kubeadmin,kube-apiserver,kube-controller-manager,kube-scheduler,etcd,kube-proxy,kubelet |
k8s-node1 | 192.168.223.142 | k8s-node1 | kubeadmin,kube-proxy,kubelet |
一、系统初始化配置
系统初始化配置在所有服务器上操作
设置主机名
1 | [root@k8s-master ~]# hostnamectl set-hostname k8s-master |
安装依赖包
1 | # yum -y install conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget git vim net-tools |
禁用firewalld
1 | # systemctl stop firewalld && systemctl disable firewalld |
关闭swap分区和SELINUX
如果不关闭,默认配置下kubelet将无法启动。使用free -m确认swap已经关闭。
1 | # swapoff -a && sed -ri 's/.*swap.*/#&/' /etc/fstab |
调整时区并关闭系统不需要的服务
1 | # timedatectl set-timezone Asia/Shanghai && timedatectl set-local-rtc 0 |
调整k8s内核参数
1 | # cat > /etc/sysctl.d/kubernetes.conf<<EOF |
升级Linux内核为4.44版本
1 | # rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org |
kube-proxy开启ipvs的前置条件
1 | # modprobe br_netfilter |
如果使用了较为高版本的内核这里可能会报错:modprobe: FATAL: Module nf_conntrack_ipv4 not found.
这是因为在高版本内核已经把 nf_conntrack_ipv4 替换为 nf_conntrack 了,改为 nf_conntrack 即可。
二、安装docker
一定要安装18.09版以上的docker,否则在初始化k8s master的时候会提示:[WARNING SystemVerification]: this Docker version is not on the list of validated versions: 19.03.3. Latest validated version: 18.09
所有服务器安装docker
1 | # yum install -y yum-utils |
修改docker cgroup driver为systemd
1 | # cat >/etc/docker/daemon.json <<EOF |
三、kubeadm安装k8s集群
配置k8s yum源
1 | # cat > /etc/yum.repos.d/kubernetes.repo <<EOF |
2.1 安装kubeadm,kubelet和kubectl
1 | # yum install -y kubelet-1.20.0 kubeadm-1.20.0 kubectl-1.20.0 |
1 | ##查看初始化需要的镜像 |
默认使用的镜像在国外仓库,后面我们可以改下载的仓库地址
2.2 初始化master节点
将默认的 init 初始化文件存放到指定位置
1 | [root@k8s-master ~]# kubeadm config print init-defaults > kubeadm-config.yml |
编辑kubeadm-config.yaml,修改本机服务器IP(advertiseAddress)、版本号(kubernetesVersion)、添加国内镜像仓库(imageRepository)、pod网段(podSubnet)
1 | [root@k8s-master ~]# cat kubeadm-config.yaml |
下载k8s-master节点镜像
1 | [root@k8s-master ~]# kubeadm config images pull --config kubeadm-config.yml |
初始化集群
建议将集群初始化日志保存起来
1 | [root@k8s-master ~]# kubeadm init --config kubeadm-config.yml |
添加 kubectl 集群认证文件
1 | [root@k8s-master ~]# mkdir -p $HOME/.kube |
查看node节点(状态显示notready是因为还未部署网络插件)
1 | [root@k8s-master ~]# kubectl get no |
2.3 部署网络插件
网络插件flannel 和 calico 二选一即可
2.3.1 部署网络插件 flannel
1 | [root@k8s-master ~]# wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml |
创建完成后查看pod的状态如下
1 | [root@k8s-master ~]# kubectl get po -nkube-system |
等两分钟之后pod状态变成Running
再查看node节点状态已经变成 ready
1 | [root@k8s-master ~]# kubectl get no |
开启ipvs转发模式
1 | [root@k8s-master ~]# kubectl edit configmaps -n kube-system kube-proxy |
最后再加入node节点,通过ipvsadm -Ln
查看
2.3.2 部署网络插件 calico
前往官网查看 calico和k8s 版本对应关系,安装对应版本的calico
1 | [root@k8s-master ~]# wget https://docs.projectcalico.org/v3.20/manifests/calico.yaml |
等两分钟之后pod状态变成Running
再查看node节点状态已经变成 ready
1 | [root@k8s-master ~]# kubectl get no |
开启ipvs转发模式
1 | [root@k8s-master ~]# kubectl edit configmaps -n kube-system kube-proxy |
最后再加入node节点,通过ipvsadm -Ln
查看
2.4 node 节点加入集群
使用初始化集群时生成的token,在node节点执行命令加入集群,默认token有效期为24小时,如果token过期了重新生成即可
1 | [root@k8s-node1 ~]# kubeadm join 192.168.223.140:6443 --token hpgvxz.q1iso7sfyoipqyp7 --discovery-token-ca-cert-hash sha256:1f06697abdb74cdfc9601d32a45fcf636084bc7ba3de7180dacf97f1403a98c2 |
去master节点查看是否已加入集群
1 | [root@k8s-master ~]# kubectl get no |
2.5 部署 nginx 测试
1 | [root@k8s-master ~]# kubectl create deploy nginx --image=nginx |
2.6 组件 Unhealthy 问题
Kubeadm部署完 k8s集群后,scheduler和controller-manager为Unhealthy
1 | [root@k8s-master ~]# kubectl get cs |
出现这种情况,是/etc/kubernetes/manifests/
下的kube-controller-manager.yaml
和kube-scheduler.yaml
设置的默认端口是0导致的,解决方式是注释掉对应的port即可,操作如下:
修改kube-controller-manager.yaml配置文件,将port=0注释
1 | [root@k8s-master ~]# vim /etc/kubernetes/manifests/kube-controller-manager.yaml |
修改kube-scheduler.yaml配置文件,将port=0注释掉
1 | [root@k8s-master ~]# vim /etc/kubernetes/manifests/kube-scheduler.yaml |
在master节点上重启kubelet
1 | [root@k8s-master ~]# systemctl restart kubelet |
2.7 其它问题
问题:如果node节点kubelet报错:Container runtime network not ready" networkReady="NetworkReady=false reason:NetworkPluginNotReady
解决:将master节点的容器网络配置拷贝到node节点即可 /etc/cni/net.d/*
问题:如果calico node节点活跃pod为0/1是因为calico-node容器获取到了错误的node节点IP
解决:修改calico.yaml在calico-node中添加以下参数
1 | - name: IP_AUTODETECTION_METHOD |
四、k8s高可用集群部署
k8s高可用集群环境规划,需要准备一个给高可用服务的虚拟IP
主机名 | IP地址 | 节点作用 | k8s 相关组件 | 高可用组件 |
---|---|---|---|---|
k8s-master1 | 192.168.223.140 | k8s-master | kubeadmin,kube-apiserver,kube-controller-manager,kube-scheduler,etcd,kube-proxy,kubelet | Haproxy,Keepalived |
k8s-master2 | 192.168.223.144 | k8s-master | kubeadmin,kube-apiserver,kube-controller-manager,kube-scheduler,etcd,kube-proxy,kubelet | Haproxy,Keepalived |
k8s-master3 | 192.168.223.145 | k8s-master | kubeadmin,kube-apiserver,kube-controller-manager,kube-scheduler,etcd,kube-proxy,kubelet | Haproxy,Keepalived |
k8s-node1 | 192.168.223.142 | k8s-node1 | kubeadmin,kube-proxy,kubelet | - |
系统初始化配置,按照一、系统初始化配置 进行配置
安装docker,按照二、安装docker 进行配置
4.1 安装kubeadm,kubelet和kubectl
3个master节点分别安装kubeadm,kubelet和kubectl
1 | # yum install -y kubelet-1.20.0 kubeadm-1.20.0 kubectl-1.20.0 |
4.2 部署etcd集群
cfssl下载 (选一台master 执行)
1 | [root@k8s-master1 ~]# wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/bin/cfssl |
生成etcd CA、etcd证书 (证书目录 在 /etc/etcd/ssl 下) (注意替换 -hostname= 里面IP地址 为所有masterIP地址)
1 | [root@k8s-master1 ~]# mkdir -p /etc/etcd/ssl && cd /etc/etcd/ssl |
将/etc/etcd/ssl 目录下所有文件拷贝到 剩余master 节点 相同目录下
1 | [root@k8s-master1 ssl]# scp /etc/etcd/ssl/* k8s-master2:/etc/etcd/ssl/ |
ETCD下载 (所有master节点执行)
1 | # wget https://github.com/etcd-io/etcd/releases/download/v3.3.12/etcd-v3.3.12-linux-amd64.tar.gz |
添加etcd服务 (所有master节点执行) (注意替换 IP地址 192.168 为本机IP,ETCD_NAME 改名)
1 | # cat > /etc/etcd/config << EOF |
启动3台master上的etcd,查看etcd集群状态
1 | ##启动ETCD |
到此部署完了etcd集群,使用kubeadm部署etcd集群可参考官网
4.3 配置apiserver 高可用VIP
高可用我们采用官方推荐的HAproxy + Keepalived
,HAproxy
和Keepalived
以守护进程的方式在所有Master
节点部署。
1 | # yum install -y keepalived haproxy |
配置 Haproxy 服务
所有master
节点的haproxy
配置相同,haproxy的配置文件是/etc/haproxy/haproxy.cfg
。master1
节点配置完成之后再分发给master2、master3
两个节点。
1 | [root@k8s-master1 ~]# cat /etc/haproxy/haproxy.cfg |
注意修改:server master1 k8s-master1:6443,中的k8s-master1
,换成master节点的IP或配置的hosts解析名称
配置Keepalived服务
keepalived中使用track_script机制来配置脚本进行探测kubernetes的master节点是否宕机,并以此切换节点实现高可用。
master1节点的keepalived配置文件如下所示,配置文件所在的位置/etc/keepalived/keepalived.cfg
1 | [root@k8s-master1 ~]# cat /etc/keepalived/keepalived.conf |
注:需要注意几点(记得修改):
interface:网卡名称
mcast_src_ip:配置多播源地址,此地址是当前主机的ip地址。
priority:keepalived根据此项参数的大小仲裁master节点。我们这里让master节点为kubernetes提供服务,其他两个节点暂时为备用节点。因此master1节点设置为100,master2节点设置为99,master3节点设置为98。
state:我们将master1节点的state字段设置为MASTER,其他两个节点字段修改为BACKUP。
上面的集群检查功能是关闭的,等到集群建立完成后再开启。
virtual_ipaddress:高可用虚拟IP
注:根据上面的注意事项配置master2、master3节点的keepalived服务。
配置健康检测脚本
这里将健康检测脚本放置在/etc/keepalived
目录下,check_kubernetes.sh
检测脚本如下
1 | [root@master1 keepalived]# cat check_kubernetes.sh |
启动Keeplived
和Haproxy
服务
1 | [root@k8s-master1 ~]# systemctl enable --now keepalived haproxy |
4.4 初始化k8s 集群
初始化kubeadm 使用的文件,修改以下几项参数
1 | [root@k8s-master1 ~]# kubeadm config print init-defaults > kubeadm-config.yaml |
注意:上面的advertiseAddress字段的值,这个值并非当前主机的网卡地址,而是高可用集群的VIP的地址。
注意:上面的controlPlaneEndpoint这里填写的是VIP的地址,而端口则是haproxy服务的8443端口,也就是我们在haproxy里面配置的这段信息
1 | frontend k8s-master |
这一段里面的8443端,如果你自定义了其他端口,这里请记得修改controlPlaneEndpoint
里面的端口。
提前拉取镜像
如果直接采用kubeadm init来初始化,中间会有系统自动拉取镜像的这一步骤,这是比较慢的,我建议分开来做,所以这里就先提前拉取镜像。其他两个master节点在初始化之前也尽量先把镜像拉取下来,这样子减少初始化时间(别忘了将初始化文件拷贝到其余master节点)。
1 | [root@k8s-master1 ~]# kubeadm config images pull --config kubeadm-config.yaml |
初始化kubenetes
的master1
节点
1 | [root@k8s-master1 ~]# kubeadm init --config=kubeadm-config.yaml --upload-certs |
添加kubectl config
1 | [root@k8s-master1 ~]# mkdir -p $HOME/.kube |
4.5 启用keepalived 检测功能
k8s集群初始化后kube-apiserver服务已运行,现在可以将3个master 节点keepalived配置文件的 track_script
字段取消注释,并重启keepalived 服务
4.6 Master 节点加入集群
根据提示添加其他master 节点 (master2、master3 上执行)
1 | [root@k8s-master2 ~]# kubeadm join 192.168.223.150:8443 --token abcdef.0123456789abcdef \ |
如果节点在加入集群时报错[ERROR Port-10250]: Port 10250 is in use
在报错的节点执行kubeadm reset
4.8 node 节点加入集群
根据提示添加 work 节点
1 | [root@k8s-node1 ~]# kubeadm join 192.168.223.150:8443 --token abcdef.0123456789abcdef \ |
到此高可用k8s集群部署基本完成,后续部署网络插件根据 2.3 部署网络插件 进行操作即可
五、集群 token 过期处理
默认token有效期为24小时,当过期之后,该token就不可用了。这时就需要重新创建token,可以直接使用命令快捷生成
1 | [root@k8s-master ~]# kubeadm token create --print-join-command |
如果已运行的集群出现token过期,kubelet、kube-apiserver,kube-controller-manager等服务都报token过期相关的错误,重新生成token后重启k8s相关服务即可恢复集群
六、卸载 flannel 网络插件
master节点删除flannel容器资源
1 | [root@k8s-master ~]# kubectl delete -f kube-flannel.yml |
在所有节点清理flannel网络插件留下的文件(如果没有创建pod那么cni0网桥只有master存在,意味着只要服务器上有cni0和flannel.l就需要执行下面命令)
1 | ifconfig cni0 down |
注意:如果有vteh设备的也要清理掉
1 | # ifconfig vethdc52a97e down |
清理完成后要重启kubelet
1 | # systemctl restart kubelet |
七、卸载 k8s 集群
1 | # kubeadm reset -f |
卸载k8s服务
1 | # modprobe -r ipip |
#Linux modprobe命令用于自动处理可载入模块。
#-r或–remove 模块闲置不用时,即自动卸载模块。
1 | # lsmod |
#lsmod 命令:用来显示文件、proc/modules的信息,也就是显示当前内核模块装载的模块。
1 | sudo systemctl stop kubelet kube-proxy flanneld kube-apiserver kube-controller-manager kube-scheduler |