利用kubeadm安装kubernetes(v1.19.2)集群详细指南

Kubernetes是如今最为火热的容器编排软件,是谷歌严格保密十几年的秘密武器Borg的开源版本。初学者部署Kubernetes集群,建议从以下两个方面入手:

  1. Minikube。Minikube是Kubernetes官方提供的单节点小型集群,可以轻松跑在普通的笔记本电脑上。Minikube其实就是一个虚拟机,用户可以根据官方指南进行安装。但是Minikube运行在虚拟机之上,性能有限,并且只支持单节点。如果你拥有超过一台的服务器可以使用,那么建议使用第二种方法。
  2. 使用kubeadm部署高可用集群。kubeadm是官方提供的快速部署Kubernetes集群的工具,目前总体上已经达到GA水平,基本满足生产使用,对于学习使用那更是绰绰有余。接下来本文对kubeadm部署集群的步骤进行详细地指南。

系统要求

  • CPU和内存:双核,2GB以上。
  • 操作系统:基于x86_64的各种Linux发行版,包括CentOS,Federa,Ubuntu等,但是内核要求在3.10及以上。这里我使用的是Centos7系统。
  • 容器运行时:一般情况,使用Docker作为容器运行时。

修改主机名和hosts文件

为了使机器之间能够相互通信,首先我们需要给机器提供合适的主机名,并且在hosts文件中添加相关映射。

修改主机名

  1. 首先修改主机名,centos中利用hostname server01可以修改主机名为server01;
  2. 然后打开/etc/sysconfig/network文件,写入HOSTNAME=server01
  3. 然后重新进入服务器,查看名称是否改变。

修改hosts文件

进入每一台机器的/etc/hosts文件,添加所有映射关系。例如,现在我有两台机器,一台叫做master,IP地址为192.168.0.1,一台叫做node-1,IP地址为192.168.0.2,那么我需要添加以下内容:

192.168.0.1 master
192.168.0.2 node-1

为了检验映射关系是否添加成功,我们可以利用ping命令。在master中执行ping node-1,在node-1中执行ping master,如果能够ping通,说明成功。

系统基本配置

在每一台机器上执行以下命令

# 关闭系统交换空间使用。(每次重启机器时都需要关闭,否则kubelet启动会报错)
swapoff -a 

# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld

# 设置SELinux
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

另外,一些Centos7用户报告了由于iptables被绕过而导致路由出错的问题,因此我们需要保证net.bridge.bridge-nf-call-iptables设置为1。具体来说,执行以下命令

cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system

为了保证br_netfilter模块加载,我们需要执行以下命令:

modprobe br_netfilter

安装Docker

如果没有安装过Docker,首先需要安装Docker作为容器运行时。

首先,尝试卸载旧版本的Docker,保证安装环境

yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

然后安装相关依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2

然后将docker仓库添加到yum的源中

yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

然后安装相应版本的Docker。这里我没有说最新版本,因为kubernetes往往没有来得及支持最新版本的Docker,所以在官网会推荐相应的版本,可以从这里查看。这里我安装的是最新的Kubernetes v1.15.0,官网推荐的Docker版本是docker-ce-18.06.2.ce,于是我用以下命令安装docker-ce-18.06.2.ce

yum update && yum install docker-ce-18.06.2.ce

安装完毕后,使用systemctl start docker来运行docker。然后我们可以用docker version命令查看是否成功安装,如果出现Client和Server两个版本信息,说明Docker已经成功安装并且运行。(如果只有Client的信息,说明docker没有成功运行,需要用systemctl status docker查看相关信息,寻找错误原因)。

安装kubeadm,kubelet和kubectl

  • kubeadm:快速创建集群的工具
  • kubelet:这是一个需要在所有集群中机器上安装的组件,它用于执行开启Pod和容器等操作。
  • kubectl:与集群通信的命令行工具,官方提供的CLI。

首先要在yum中添加Kubernetes的仓库源。官方源的地址为https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64,在国内无法访问,所幸阿里云为我们提供了镜像源(感谢阿里爸爸),使用以下命令添加阿里镜像源

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

然后运行yum install命令安装kubeadm和相关工具,并运行kubelet。

yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

systemctl enable --now kubelet

初始化主节点(Master)

成功安装kubeadm等一系列工具后,接下来就是正式部署Kubernetes集群了。首先我们需要在Master主机上执行kubeadm init相关命令,将Master节点配置成功,那么此时集群也就基本成功部署了。

具体来说,在master主机中执行以下命令

kubeadm init --image-repository=registry.aliyuncs.com/google_containers

其中--imge-repository指向阿里云的镜像仓库,显然还是因为google镜像仓库在国内无法访问;

以上命令执行可能需要几分钟的时间。执行完毕后,主机点就基本上初始化成功了!

如果初始化失败的话,根据提示寻找原因。第一次我初始化失败后,发现可能是由于在安装kubeadm之后才修改的主机名,造成kubeadm某些配置不正确。这种情况只需卸载并重新安装kubeadm,再次运行kubeadm init相关命令即可。
$ kubeadm reset
$ yum remove kubeadm
$ yum install kubeadm --disableexcludes=kubernetes

安装成功后,会显示一些重要信息。首先按照提示执行以下命令:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

这时利用kubectl get nodes命令,可以看到master还是Not Ready的状态,其实是因为我们还没有给集群安装Pod网络组件。所以现在我们需要给集群安装一个Pod网络组件。

这里可以看到,有多种组件可供选择。这里我使用Calico,按照官网文档,执行以下命令安装

curl https://docs.projectcalico.org/manifests/calico.yaml -O
kubectl apply -f calico.yaml

安装完毕后,执行kubectl get nodes命令,可以发现master的状态从NotReady变成了Ready。

安装好 Calico 后,有可能会出现主节点上的 calico-node 产生 Not Ready 状态,在查看 log 后发现,是 Calico BIRD is not ready: BGP not established with xxxx 的原因。此时是因为默认情况下,calico 会使用第一个找到的 network interface(往往是错误的 interface)里面的IP地址,导致 Calico 把 master 也算进 nodes,于是 master BGP 启动失败,而其他 workers 则启动成功。解决方案见下面

默认情况下,集群不会在Master节点上部署Pod,这意味着你的集群至少需要两个节点才能正常工作。如果你想要允许集群在Master上部署Pod,可以执行以下命令,这样即使只有一台机器,你也可以正常使用集群

kubectl taint nodes --all node-role.kubernetes.io/master-

另外,kubeadm init成功后会显示有关kubeadm join的命令,我们需要保存这个命令,以便后面为集群添加节点使用。

加入工作节点

首先仍然需要为工作节点安装docker,kubeadm等相关工具,具体步骤见上。然后执行上一步骤中保存的kubeadm join相关命令,就成功地将该节点添加进集群中了。

如果初始化时的token没有保存或者已经过期,可以在Master使用以下命令重新生成kubeadm join相关token及命令:

kubeadm token create --print-join-command

验证集群是否安装完成

执行以下命令,验证集群相关Pod是否都正常创建并运行:

kubectl get pods --all-namespaces

如果所有Pod都处于Running状态,说明集群正常运行。如果发现有状态错误的Pod,执行kubectl describe pod <pod_name> --namespace=kube-system查看错误原因,常见的错误一般是镜像没有下载完成。

至此,我们就通过kubeadm工具实现了Kubernetes集群的快速搭建。接下来可以愉快地使用了!

踩过的坑

Cgroup不支持pids子系统。

工作节点加入后,一直是NotReady状态。describe后发现报错如下:

Warning  FailedNodeAllocatableEnforcement  <invalid> (x1411 over 23h)     
kubelet, lbw-node-3   
Failed to update Node Allocatable Limits ["kubepods"]: failed to set supported cgroup subsystems for cgroup [kubepods]: Failed to find subsystem mount for required subsystem: pids

由错误日志可知是节点中的Cgroup不支持子系统pids所致。于是用uname -r查看内核版本:

[root@localhost ~]# uname -r 
3.10.0-327.el7.x86_64

然后查看该内核所支持的CGROUP,发现的确不支持PIDS。

[root@localhost ~]# cat /boot/config-3.10.0-327.el7.x86_64  | grep CGROUP
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=y
CONFIG_NETPRIO_CGROUP=m

然后在运行yum update -y后,使用yum list kernel命令查看当前安装的内核.

[root@lbw-master ~]# yum list kernel
Installed Packages
kernel.x86_64		3.10.0-327.el7			    @anaconda
kernel.x86_64		3.10.0-862.3.2.el7 		    @updates
kernel.x86_64		3.10.0-957.21.3.el7 	    @updates
kernel.x86_64		3.10.0-957.27.2.el7			@updates

查看新版内核所支持的CGOURP

[root@lbw-master ~]# cat /boot/config-3.10.0-957.27.2.el7.x86_64 | grep CGROUP
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=y
CONFIG_NETPRIO_CGROUP=y

发现的确有PIDS支持。于是接下来就是想办法将内核进行升级了。
用以下命令查看所有可用的内核

[root@lbw-master ~]# awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
0 : CentOS Linux (3.10.0-957.27.2.el7.x86_64) 7 (Core)
1 : CentOS Linux (3.10.0-957.21.3.el7.x86_64) 7 (Core)
2 : CentOS Linux (3.10.0-862.3.2.el7.x86_64) 7 (Core)
3 : CentOS Linux (3.10.0-327.el7.x86_64) 7 (Core)
4 : CentOS Linux (0-rescue-c4da2e677e384e85b9fd9f27eb3a9f8a) 7 (Core)

grub2-set-default命令设置默认启动内核。利用设为0表示使用上一个命令输出的第一个内核。

grub2-set-default 0

然后用grub2-mkconfig命令生成配置文件并应用在grub.config文件中。

grub2-mkconfig -o /boot/grub2/grub.cfg

执行完毕后,用reboot命令重启机器即可。

Calico BIRD is not ready: BGP not eatablished

安装好 Calico 后,有可能会出现主节点上的 calico-node 产生 Not Ready 状态,在查看 log 后发现,是 Calico BIRD is not ready: BGP not established with xxxx 的原因。此时是因为默认情况下,calico 会使用第一个找到的 network interface(往往是错误的 interface)里面的IP地址,导致 Calico 把 master 也算进 nodes,于是 master BGP 启动失败,而其他 workers 则启动成功。解决方案如下。

首先通过ifconfig来确认内网IP所对应的有效 network interface,例如我这里是ens160.

[root@k8s-master ~]# ifconfig
br-ce41472132af: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.0.0  broadcast 172.18.255.255
        inet6 fe80::42:21ff:fe58:7667  prefixlen 64  scopeid 0x20<link>
        ether 02:42:21:58:76:67  txqueuelen 0  (Ethernet)
        RX packets 783  bytes 56422 (55.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 10586  bytes 673574 (657.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

cali11853e474e7: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1440
        inet6 fe80::ecee:eeff:feee:eeee  prefixlen 64  scopeid 0x20<link>
        ether ee:ee:ee:ee:ee:ee  txqueuelen 0  (Ethernet)
        RX packets 18563438  bytes 4767603330 (4.4 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 18032865  bytes 4408327389 (4.1 GiB)
        TX errors 4  dropped 0 overruns 1  carrier 0  collisions 0

cali36b3fad4d20: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1440
        inet6 fe80::ecee:eeff:feee:eeee  prefixlen 64  scopeid 0x20<link>
        ether ee:ee:ee:ee:ee:ee  txqueuelen 0  (Ethernet)
        RX packets 18563441  bytes 4767603549 (4.4 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 18032866  bytes 4408327547 (4.1 GiB)
        TX errors 4  dropped 0 overruns 1  carrier 0  collisions 0

cali830c3c4a8f1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1440
        inet6 fe80::ecee:eeff:feee:eeee  prefixlen 64  scopeid 0x20<link>
        ether ee:ee:ee:ee:ee:ee  txqueuelen 0  (Ethernet)
        RX packets 18563441  bytes 4767603549 (4.4 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 18032869  bytes 4408328045 (4.1 GiB)
        TX errors 4  dropped 0 overruns 1  carrier 0  collisions 0

docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:70ff:feb9:dad1  prefixlen 64  scopeid 0x20<link>
        ether 02:42:70:b9:da:d1  txqueuelen 0  (Ethernet)
        RX packets 293546  bytes 19462521 (18.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 339924  bytes 523861651 (499.5 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.176.122.1  netmask 255.255.248.0  broadcast 10.176.127.255
        inet6 fe80::250:56ff:fea4:5d37  prefixlen 64  scopeid 0x20<link>
        ether 00:50:56:a4:5d:37  txqueuelen 1000  (Ethernet)
        RX packets 143985916  bytes 34603732815 (32.2 GiB)
        RX errors 307  dropped 1227523  overruns 0  frame 0
        TX packets 133027813  bytes 106262988429 (98.9 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

然后编辑 calico.yaml,找到 name: IP,在它上面加入:

           - name: CLUSTER_TYPE
             value: "k8s,bgp"
           # 新增部分
           - name: IP_AUTODETECTION_METHOD
             value: "interface=ens160"
           # 新增部分结束
           - name: IP
             value: "autodetect"
           - name: CALICO_IPV4POOL_IPIP
             value: "Always"

注意,如果是多次执行过kubectl apply -f calico.yaml,需要先清理cni文件。

rm -rf /var/lib/cni
kubectl apply -f calico.yaml
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值