文章目录
前言
鉴于目前市面上的云服务提供商已经提供Kubernetes云托管服务,比如Google kubernetes Engine(GKE),Azure Kubernetes Service(AKS),Alibaba Kuberntes Service等等,直接使用他们的服务能够免去自己维护的工作,所以在实际工作中我们不一定需要自己搭建Kubernetes。
作为学习,这里我总结一下如何自己搭建一个简易的Kubernetes集群。搭建Kubernetes集群有两种方法:
- 使用Kuberadm工具。
- 直接下载binary文件搭建。
使用Kuberadm工具搭建比较快捷而使用binary文件搭建比较繁琐但能够加深对Kubernetes各个模块的理解,两种方法各有利弊,这里我介绍一下用Kubeadm方法怎么搭建,官方网站上也有具体的介绍:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/。
一、配置要求
我们搭建的这个简易Kubernetes集群包含一个Master Node和两个Worker Nodes。对于机器的最低要求是2核2G。机器少于两核,则节点无法启动。我在阿里云同一个账号上购买了3台机器,为期一周,用于学习搭建。在阿里云同一个账号下购买3台机器的好处在于,只要给这3台机器配置同一个安全组,就能够互相ping通,省去不少时间。
机器 | 配置要求 | 操作系统 |
---|---|---|
Master | 2核2G | CentOS 7.X |
Node1 | 2核2G | CentOS 7.X |
Node2 | 2核2G | CentOS 7.X |
二、环境配置
从Terminal中打开3个tab,分别ssh
连接到这3台机器。接下来我们首先配置环境,以下的环境配置都是需要在3台机器上完成的,为了节省时间,这里建议同步3个terminal tab以方便同时往3台机器输入指令。方法为同时按住Cmd
+ Shift
+ i
,再次按下即可取消同步。
1. 主机名解析
为了方便调用,这里先解析一下主机名。IP地址为阿里云中机器的私有IP。
> vim /etc/hosts
......
172.23.246.224 master
172.23.246.223 node1
172.23.246.222 node2
之后3台机器之间应该能用主机名相互ping通。(阿里云同一个账户下机器只要配置同一个安全组即可相互ping通,其他环境下需要额外的设置)。
> ping node1
PING node1 (172.23.246.223) 56(84) bytes of data.
64 bytes from node1 (172.23.246.223): icmp_seq=1 ttl=64 time=0.295 ms
64 bytes from node1 (172.23.246.223): icmp_seq=2 ttl=64 time=0.234 ms
64 bytes from node1 (172.23.246.223): icmp_seq=3 ttl=64 time=0.253 ms
......
2. 同步时间
因为Kubernetes内部机器之间安全通信涉及到证书(Certificate),如果机器之前时间不同步,可能会导致证书校验失败,所以我们要同步一下3台机器的时间。
> ntpdate 0.asia.pool.ntp.org
4 Apr 10:41:42 ntpdate[22577]: adjust time server 202.28.93.5 offset 0.059386 sec
> date
Sun Apr 4 10:41:50 CST 2021
3. 关闭防火墙 firewalld
> systemctl stop firewalld
> systemctl disable firewalld
4. 关闭selinux
selinux是Linux下一个安全服务,如果不关闭,则在安装过程中可能产生各种奇怪问题。
# 检查是否已经关闭
> getenforce
Disabled
# 如果未关闭,可以修改配置文件关闭
> cat /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
5. 禁用Swap分区
Swap是虚拟内存分区,是指在物理内存使用完以后,将磁盘空间当作内存使用,会极大地影响性能,所以Kubernetes建议关闭。检查一下 /etc/fstab
文件,如果有 swap
相关的行,全部注释掉。
> cat /etc/fstab
#
# /etc/fstab
# Created by anaconda on Thu Nov 29 03:34:10 2018
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=b98386f1-e6a8-44e3-9ce1-a50e59d9a170 / ext4 defaults 1 1
6. 修改Linux内核参数
# 添加网桥过滤和地址转发功能
> cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
vm.swappiness = 0
EOF
# 重新加载配置
> sysctl -p
vm.swappiness = 0
net.ipv4.neigh.default.gc_stale_time = 120
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_announce = 2
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 1024
net.ipv4.tcp_synack_retries = 2
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
kernel.sysrq = 1
# 加载br_netfilter 网桥过滤模块
> modprobe br_netfilter
# 检查br_netfilter模块是否加载成功
> lsmod | grep br_netfilter
br_netfilter 22256 0
bridge 146976 1 br_netfilter
7. 开启ipvs
Kubernetes中service有两种代理模型,一种是基于iptables的,另一种是基于ipvs的。相比之下,ipvs的性能要明显高一些,但是要使用ipvs的话,需要手动加载ipvs模块。
# 1. 安装ipset和ipvsadm
> yum install -y ipset ipvsadm
# 2. 添加需要加载的文件,写入脚本
> cat > /etc/sysconfig/modules/ipvs.modules <<EOF
> #!/bin/bash
> modprobe -- ip_vs
> modprobe -- ip_vs_rr
> modprobe -- ip_vs_wrr
> modprobe -- ip_vs_sh
> modprobe -- nf_conntrack_ipv4
> EOF
# 3. 添加脚本执行权限
> chmod +x /etc/sysconfig/modules/ipvs.modules
# 4. 执行脚本
> /bin/bash /etc/sysconfig/modules/ipvs.modules
# 5. 检查模块是否加载成功
> lsmod | grep -e ip_vs -e nf_conntrack_ipv4
nf_conntrack_ipv4 15053 0
nf_defrag_ipv4 12729 1 nf_conntrack_ipv4
ip_vs_sh 12688 0
ip_vs_wrr 12697 0
ip_vs_rr 12600 0
ip_vs 141473 6 ip_vs_rr,ip_vs_sh,ip_vs_wrr
nf_conntrack 133053 2 ip_vs,nf_conntrack_ipv4
libcrc32c 12644 2 ip_vs,nf_conntrack
8. 重启机器
上面步骤中selinux和swap的禁用是需要重启服务器的。如果有设置,那么重启这3台机器。
> reboot
重启完成以后,可以检查一下 selinux
和 swap
分区都已经关闭。
> getenforce
Disabled
> free -m
total used free shared buff/cache available
Mem: 1734 139 1446 0 148 1457
Swap: 0 0 0
三、安装集群所需组件
1. 安装Docker
# 1. 安装工具
> yum install -y yum-utils
# 2. 设置docker安装仓库为阿里云镜像
> sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 3. 更新cache
> yum makecache fast
# 4. 安装docker
> yum install docker-ce docker-ce-cli containerd.io
# 5. 添加阿里云的仓库镜像
# Docker默认使用的cgroup driver是cgroupfs,而kubernetes推荐使用systemd来代替cgroupfs
> sudo tee /etc/docker/daemon.json <<-'EOF'
> {
> "exec-opts": ["native.cgroupdriver=systemd"],
> "registry-mirrors": ["https://fxparv4c.mirror.aliyuncs.com"]
> }
> EOF
# 6. 重启docker
> systemctl daemon-reload
> systemctl restart docker
# 7. 设置docker开机启动
> systemctl enable docker
2. 安装kubeadm,kubelet和kubectl
# 1. 添加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
# 2. 安装kubelet,kubeadm和kubectl。需要制定版本号
> yum install -y kubelet-1.19.0 kubeadm-1.19.0 kubectl-1.19.0
# 3. 为了实现Docker使用的cgroup drvier和kubelet使用的cgroup drver一致,建议修改"/etc/sysconfig/kubelet"文件的内容:
> vim /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"
# 4. 设置kubelet开机自启动
> systemctl enable kubelet
四、启动Master Node
下面的指令只对Master机器输入。
# 1 启动Master节点
> kubeadm init \
--apiserver-advertise-address=172.23.246.224 \ # Master私网IP
--image-repository registry.aliyuncs.com/google_containers \ # 配置阿里云镜像
--kubernetes-version v1.19.0 \
--service-cidr=10.96.0.0/12 \ # 只要不和其他ip冲突即可
--pod-network-cidr=10.244.0.0/16
# 2. 配置Master节点的kubectl
> mkdir -p $HOME/.kube
> sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
> sudo chown $(id -u):$(id -g) $HOME/.kube/config
五、加入Worker Node到集群
Master节点启动完毕以后,terminal会显示加入集群的token kubeadm join xxxx
(如上图所示),分别在两个worker节点里面输入token即可加入集群:
> kubeadm join 172.23.246.224:6443 --token yymc24.cns6yk3x1akcbj60 \
--discovery-token-ca-cert-hash sha256:7f8611c424550efd650af17467c30cc2bfbdbc8d6c55b6abb525b33631adce41
上述token的有效期为24小时,token没了以后可以在Master节点上重新生成:
> kubeadm token create --print-join-command
W0404 12:21:27.962758 5394 configset.go:348] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
kubeadm join 172.23.246.224:6443 --token n310e4.ksvcu0m9ihwe8oah --discovery-token-ca-cert-hash sha256:7f8611c424550efd650af17467c30cc2bfbdbc8d6c55b6abb525b33631adce41
六、配置CNI网络模块
在Master节点上查看集群节点状态:
> kubectl get nodes
NAME STATUS ROLES AGE VERSION
master NotReady master 7m3s v1.19.0
node1 NotReady <none> 2m4s v1.19.0
node2 NotReady <none> 2m1s v1.19.0
三个节点都是 NotReady
状态,因为还没有正确配置网络模块。下面我们配置一下集群的网络模块。
CNI(Container Network Interface)是一个容器网络规范,Kubernetes网络就是采用这种CNI规范。K8s是一个扁平化网络,所有部署的网络组件都必须满足如下规范:
- 一个Pod一个IP。
- 所有的Pod可以与其他任何Pod直接通信。
- 所有节点可以与所有Pod通信。
- Pod内部获得的IP地址与其他Pod或者节点通信时的IP是同一个。
主流的网络组件有:Flannel和Calico
我们来安装Calico组件,详细步骤见:https://docs.projectcalico.org/getting-started/kubernetes/quickstart
# 1 下载calico配置文件
> wget https://docs.projectcalico.org/manifests/calico.yaml
# 2 修改
> vim calico.yaml
# 搜索 CALICO_IPV4POOL_CIDR, 修改为上面启动Master节点时配置的 --pod-network-cidr=10.244.0.0/16
# 3 安装Calico组件
> kubectl apply -f calico.yaml
# 4 稍等片刻,查看集群节点状态就绪
> kubectl get node
NAME STATUS ROLES AGE VERSION
master Ready master 39m v1.19.0
node1 Ready <none> 34m v1.19.0
node2 Ready <none> 34m v1.19.0
# 5 查看Calico组件状态
> kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-69496d8b75-r5445 1/1 Running 0 2m29s
calico-node-mbm6d 1/1 Running 0 2m29s
calico-node-nkpwk 1/1 Running 0 2m29s
calico-node-wg6tm 1/1 Running 0 2m29s
coredns-6d56c8448f-d42d2 1/1 Running 0 40m
coredns-6d56c8448f-vzz7x 1/1 Running 0 40m
etcd-master 1/1 Running 0 40m
kube-apiserver-master 1/1 Running 0 40m
kube-controller-manager-master 1/1 Running 0 40m
kube-proxy-8zctk 1/1 Running 0 35m
kube-proxy-lgcdd 1/1 Running 0 35m
kube-proxy-xl9hd 1/1 Running 0 40m
kube-scheduler-master 1/1 Running 0 40m
七、配置kubectl自动补全
# 1 安装自动补全
yum install -y bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo “source <(kubectl completion bash)” >> ~/.bashrc
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)