文章目录

  • 前言
  • 一、配置要求
  • 二、环境配置
  • 1. 主机名解析
  • 2. 同步时间
  • 3. 关闭防火墙 firewalld
  • 4. 关闭selinux
  • 5. 禁用Swap分区
  • 6. 修改Linux内核参数
  • 7. 开启ipvs
  • 8. 重启机器
  • 三、安装集群所需组件
  • 1. 安装Docker
  • 2. 安装kubeadm,kubelet和kubectl
  • 四、启动Master Node
  • 五、加入Worker Node到集群
  • 六、配置CNI网络模块
  • 七、配置kubectl自动补全




前言

鉴于目前市面上的云服务提供商已经提供Kubernetes云托管服务,比如Google kubernetes Engine(GKE),Azure Kubernetes Service(AKS),Alibaba Kuberntes Service等等,直接使用他们的服务能够免去自己维护的工作,所以在实际工作中我们不一定需要自己搭建Kubernetes。

作为学习,这里我总结一下如何自己搭建一个简易的Kubernetes集群。搭建Kubernetes集群有两种方法:

  1. 使用Kuberadm工具。
  2. 直接下载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

重启完成以后,可以检查一下 selinuxswap 分区都已经关闭。

> 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

kubespere 搭建kafka kubernetes 搭建教程_linux


五、加入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)