通过前面的架构概述,可以看出,若想手动部署一套高可用的Kubernetes集群,还是相当麻烦的。所以官方推出了快速建立Kubernetes集群的工具:Kubeadm。
Kubeadm是一个提供Kubeadm init 和 Kubeadm join命令,用于创建Kubernetes集群的最佳实践“快速路径”工具。
Kubeadm的目标是在不安装其他功能插件的基础上,建立一个通过Kubernetes一致性测试Kubernetes Conformance tests的最小可行集群。它在设计上并不会安装网络解决方案,而是需要用户自行安装第三方符合CNI的网络解决方案(如:flannel,calico,weave network等)。
准备工作
机器
这个太难了,好不容易从生产环境坑蒙拐骗挪出来3台能用的,总算能弄个一主两从的集群,系统都是CentOS:
机器角色 | IP |
---|---|
master | 10.128.2.53 |
node | 10.128.1.187 |
node | 10.11.7.94 |
配置host
三台机器均配置host,/etc/hosts
文件添加以下配置:
10.128.2.53 kubernetes-master01
10.128.1.187 kubernetes-node01
10.11.7.94 kubernetes-node02
hostnamectl
hostnamectl set-hostname kubernetes-master01
关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
systemctl status firewalld
关闭selinux
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config # 永久 需重启
setenforce 0 # 临时
关闭swap
swapoff -a
sed -i 's/^[^#].*swap/#&/' /etc/fstab
systemctl daemon-reload
若要启用swap设备,则需要在集群初始化时添加--ignore-preflight-errors=swap,意义为忽略因swap设备导致的报错
关闭ipv6
echo net.ipv6.conf.all.disable_ipv6=1 >> /etc/sysctl.conf
echo NETWORKING_IPV6=no >> /etc/sysconfig/network
sed -i 's/IPV6INIT=yes/IPV6INIT=no/g' /etc/sysconfig/network-scripts/ifcfg-ens33
sysctl -p
ip a # 查看ipv6是否关闭
将桥接的IPv4流量传递到iptables
cat >/etc/sysctl.d/kubernetes.conf << EOF
net.bridge.bridge-nf-call-ip6tables =1
net.bridge.bridge-nf-call-iptables =1
EOF
sysctl --system # 生效
这个不知道什么意思但是通过Kubeadm安装Kubenetes集群时会校验。这里也搜到一篇文章说明net.bridge.bridge-nf-call-iptables的作用
参数作用,但是我表示看不懂。
安装容器运行时
三台机器必须都安装容器运行时,这里我使用Dokcer,并且需要配置Docker的Cgroup Driver为systemd
:
vi /etc/docker/daemon.json
{
"exec-opts":["native.cgroupdriver=systemd"]
}
systemctl restart docker
什么是cgroups?
首先说下容器是什么?容器是一个视图隔离、资源可限制、独立文件系统的进程集合。cgroups(Control Groups) 是 linux 内核提供的一种机制,作用就是可以对资源进行限制。此外,视图隔离是通过namespace实现,而文件系统是通过chroot实现。
为什么要修改Cgroup Driver
Docker默认的Cgroup Driver是cgroupfs,而Kubernetes 推荐使用 systemd 来代替 cgroupfs。如果不修改,那么同时运行有两个cgroup控制管理器,当资源有压力的情况时,有可能出现不稳定的情况。并且在kubeadm init时也会出现警告。
master机器设置免登录node
ssh-keygen -t rsa # 一路默认回车即可
ssh-copy-id kubernetes-master01 # 过程中需要输入密码
ssh-copy-id kubernetes-node01
ssh-copy-id kubernetes-node02
ssh root@kubernetes-node01 # 测试是否成功,切记测试完exit,不然就像我一样捣鼓一下午不成功才发现问题。。
集群部署
安装kubeadm、kubelet、kubectl
以下操作在所有节点进行
- 添加阿里云YUM源
cat >/etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
- 指定版本安装软件,这里我安装的是1.19.8版本,1.20不再把Docker作为默认的容器运行时了,所以暂时选择1.19版本。
yum install -y kubelet-1.19.8 kubeadm-1.19.8 kubectl-1.19.8
systemctl enable kubelet
Master节点安装
kubeadm init --kubernetes-version=1.19.8 --image-repository=registry.aliyuncs.com/google_containers
按照提示执行下列命令:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
此处要记住打印出的下列命令,在添加Node节点时需要用到:
kubeadm join 10.128.2.53:6443 --token dvt5z4.sdf2rfwprp7byv62 \
--discovery-token-ca-cert-hash sha256:c2262789b43f4fae6a6ed42740abcf077e9f8da379713a0dee6c8d3a2de98fdb
若没注意,可通过kubeadm token list
查看当前的token,默认有效期为24小时,若忘记token或token过期,可使用命令kubeadm token create --print-join-command
重新生成,若初始有问题可通过命令kubeadm reset
重置。
启动kubelet并查看状态:
systemctl start kubelet
systemctl status kubelet
查看此时节点信息:
kubectl get nodes
可以看到master节点是NotReady状态。
部署CNI网络
在使用Docker时我们就发现,除非网络模式设为host
,否则会产生很多网络上的问题,当时也调研了一些容器跨主机网络通信的解决方案,最终还是选择了--net=host
共享宿主机网络。
在Kubernetes集群中或者说云原生中,网络同样存在容器跨主机网络通信的问题,一直以来,Kubernetes 并没有专门的网络模块负责网络配置,它需要用户在主机上已经配置好网络。kubernetes 对网络的要求是:
- 容器之间(包括同一台主机上的容器,和不同主机的容器)可以互相通信
- 容器和集群中所有的节点也能直接通信
Kubernetes 网络的发展方向是希望通过插件的方式来集成不同的网络方案,于是便出现了CNI的概念:
CNI(Container Network Interface)是 CNCF 旗下的一个项目,由一组用于配置 Linux 容器的网络接口的规范和库组成,同时还包含了一些插件。CNI 仅关心容器创建时的网络分配,和当容器被删除时释放网络资源。
CNI本身是一种标准的设计和概念,它只专注解决容器网络连接和容器销毁时的资源释放,提供一套框架,所以CNI可以支持大量不同的网络模式。更深入的在后续深入研究部分再详细学习。
网络插件选择,calico vs fannel
fannel和calico算是目前网络实现最热门的2个插件,经过简单的对比,calico在性能更好以外,还可以与服务网格 Istio 集成,所以毫不犹豫的选择calico。
安装calico
curl https://docs.projectcalico.org/manifests/calico.yaml -o calico.yaml
kubectl apply -f calico.yaml
这时kubectl get nodes
命令查看节点状态变为Ready
:
检查组件状态
下列文字于2021年3月16日修改废弃
# 都可
kubectl get cs
kubectl get componentstatus
可以看到scheduler与controller-manager是Unhealthy的,按端口提示检查10251及10252是否有监听
ss -ant|grep 10251
ss -ant|grep 10252
发现均未有监听,检查配置文件/etc/kubernetes/manifests/kube-scheduler.yaml
与/etc/kubernetes/manifests/kube-controller-manager.yaml
并将两个配置文件的配置项- --port=0
均注释掉,并重启kubelet,重新检查组件状态
2021年3月16日修改如下:
Kubectl get cs 命令由于安全原因在1.19+版本已废弃,查看组件状态使用以下命令
kubectl get po -n kube-system
Node节点安装
systemctl start kubelet
kubeadm join 10.128.2.53:6443 --token dvt5z4.sdf2rfwprp7byv62 \
--discovery-token-ca-cert-hash sha256:c2262789b43f4fae6a6ed42740abcf077e9f8da379713a0dee6c8d3a2de98fdb
检查节点:
集群检查
检查节点
[root@promote ~]# kubectl get cs Warning: v1 ComponentStatus is deprecated in v1.19+ NAME STATUS MESSAGE ERROR scheduler Healthy ok controller-manager Healthy ok etcd-0 Healthy {"health":"true"}
检查基础应用
[root@promote ~]# kubectl get po -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-6949477b58-mzpbf 1/1 Running 0 16m kube-system calico-node-4jlnb 1/1 Running 0 12m kube-system calico-node-mbxvg 1/1 Running 0 16m kube-system calico-node-r75dk 1/1 Running 0 3m28s kube-system coredns-6d56c8448f-sx9nk 1/1 Running 0 24m kube-system coredns-6d56c8448f-vkf9x 1/1 Running 0 24m kube-system etcd-kubernetes-master01 1/1 Running 0 24m kube-system kube-apiserver-kubernetes-master01 1/1 Running 0 24m kube-system kube-controller-manager-kubernetes-master01 1/1 Running 0 14m kube-system kube-proxy-b2jdp 1/1 Running 0 24m kube-system kube-proxy-fjvvs 1/1 Running 0 3m28s kube-system kube-proxy-gpwcn 1/1 Running 0 12m kube-system kube-scheduler-kubernetes-master01 1/1 Running 0 14m
至此集群就搭建完毕了。
集群测试
还记得前面文章本机mac搭建minikube的过程吗,集群测试我就照着前文来试了一遍,一切正常。附上上文链接。
下面的文章会对集群节点的操作以及多主多从的高可用集群做一些操作尝试。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。