01、使用kubeadm安装K8s-v1.23高可用集群

目录

K8s-v1.23 安装环境规划

kubeadm 和二进制安装 k8s 适用场景分析

一、初始化安装 k8s 集群的环境

1、 1初步的环境初始化;

1、 2配置主机之间无密码登录;

1、 3关闭交换分区swap提升性能;

1、 4修改机器内核参数;

1、 5配置阿里云的repo源;

1、 6配置安装k8s组件需要的阿里云的repo源;

1、 7配置时间同步;

1、 8开启ipvs;

1、 9安装基础软件包;

二、安装 docker 服务

2、 1安装docker-ce;

2、 2配置docker镜像加速器和驱动;

三、安装初始化 k8s 需要的软件包

四、kubeadm 初始化 k8s 集群

五、扩容 k8s 集群

5、 1添加第一个工作节点;

5、 2添加第二个工作节点;

六、安装 kubernetes 网络组件 Calico

七、测试在 k8s 创建 pod 是否可以正常访问网络

八、测试 coredns 是否正常


此次安装 k8s-v1.23 所用到的资料下载地址:

链接:https://caiyun.139.com/m/i?0A5CuauVgY8XY
提取码:F86C

K8s-v1.23 安装环境规划

  • 虚拟机操作系统:CentOS 7.6
  • 最低配置: 2Gib 内存/ 2v CPU/ 30G 硬盘
  • 网络:NAT 模式
  • podSubnet( pod 网段):10.244.0.0/16
  • serviceSubnet(service 网段):10.10.0.0/16
K8s 集群角色 IP 主机名 安装的组件
控制节点 192.168.78.143 k8s-master1 apiserver、controller-manager、scheduler、etcd、kube-proxy、docker、calico
工作节点 192.168.78.144 k8s-node1 kubelet、kube-proxy、docker、calico、coredns
工作节点 192.168.78.145 k8s-node2 kubelet、kube-proxy、docker、calico、coredns

kubeadm 和二进制安装 k8s 适用场景分析

kubeadm 是官方提供的开源工具,是一个开源项目,用于快速搭建 kubernetes 集群,目前是比较方便和推荐使用的。kubeadm init 以及 kubeadm join 这两个命令可以快速创建 kubernetes 集群。Kubeadm 初始化 k8s,所有的组件都是以 pod 形式运行的,具备故障自恢复能力。

kubeadm 是工具,可以快速搭建集群,也就是相当于用程序脚本帮我们装好了集群,属于自动部署,简化部署操作,证书、组件资源清单文件都是自动创建的,自动部署屏蔽了很多细节,使得对各个模块感知很少,如果对 k8s 架构组件理解不深的话,遇到问题比较难排查。

kubeadm 适合需要经常部署 k8s,或者对自动化要求比较高的场景下使用。

二进制:在官网下载相关组件的二进制包,如果手动安装,对 kubernetes 理解也会更全面。

Kubeadm 和二进制都适合生产环境,在生产环境运行都很稳定,具体如何选择,可以根据实际项目进行评估。

一、初始化安装 k8s 集群的环境

注意:没有特别说明指定虚拟机的,统一三台机器都要执行命令!

1.1 初步的环境初始化

给三台虚机进行初步的环境初始化,可以看我这篇文章:CentOS 7 初始化系统

1.2 配置主机之间无密码登录

#1. 配置 master1 到其他机器免密登录
# 生成秘钥文件
[root@k8s-master1 ~]# ssh-keygen                     # 输入三次回车即可(下面以此类推)

# 把本地生成的密钥文件和私钥文件拷贝到远程主机
[root@k8s-master1 ~]# ssh-copy-id k8s-master1        # 输入 yes 后再输入对应主机的密码(下面以此类推)
[root@k8s-master1 ~]# ssh-copy-id k8s-node1
[root@k8s-master1 ~]# ssh-copy-id k8s-node2

#2. 配置 node1 到其他机器免密登录
[root@k8s-node1 ~]# ssh-keygen 
[root@k8s-node1 ~]# ssh-copy-id k8s-master1
[root@k8s-node1 ~]# ssh-copy-id k8s-node1
[root@k8s-node1 ~]# ssh-copy-id k8s-node2

#3. 配置 node2 到其他机器免密登录
[root@k8s-node2 ~]# ssh-keygen 
[root@k8s-node2 ~]# ssh-copy-id k8s-master1
[root@k8s-node2 ~]# ssh-copy-id k8s-node1
[root@k8s-node2 ~]# ssh-copy-id k8s-node2

1.3 关闭交换分区 swap 提升性能

# 临时关闭
swapoff -a

# 永久关闭:注释 swap 挂载,给 swap 这行开头加一下 "#" 注释
sed -ri 's/.*swap.*/#&/' /etc/fstab

# 查看效果
free -m

为什么要关闭 swap 交换分区?
Swap 交换分区,如果机器内存不够,会使用 swap 分区,但是 swap 分区的性能较低,k8s 设计的时候为了能提升性能,默认是不允许使用交换分区的。Kubeadm 初始化的时候会检测 swap 是否关闭,如果没关闭,那就初始化失败。如果不想要关闭交换分区,安装k8s 的时候可以指定 --ignore-preflight-errors=Swap 来解决。

1.4 修改机器内核参数

modprobe br_netfilter

echo "modprobe br_netfilter" >> /etc/profile

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
EOF

sysctl -p /etc/sysctl.d/k8s.conf

问题 1 :sysctl 是做什么的?
在运行时配置内核参数 -p 从指定的文件加载系统参数,如不指定即从 /etc/sysctl.conf 中加载。

问题 2 :为什么要执行 modprobe br_netfilter ?
修改 /etc/sysctl.d/k8s.conf 文件,增加如下三行参数:
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1

sysctl -p /etc/sysctl.d/k8s.conf 出现报错:
sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-ip6tables: No such file or directory
sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-iptables: No such file or directory

解决方法:
modprobe br_netfilter

问题 3 :为什么开启 net.bridge.bridge-nf-call-iptables 内核参数?
在centos 下安装 docker,执行 docker info 出现如下警告:
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
解决办法:
vim /etc/sysctl.d/k8s.conf

net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1

问题 4 :为什么要开启 net.ipv4.ip_forward = 1 参数?
kubeadm 初始化 k8s 如果报错:

*

就表示没有开启 ip_forward,需要开启。

net.ipv4.ip_forward 是数据包转发:
出于安全考虑,Linux 系统默认是禁止数据包转发的。所谓转发即当主机拥有多于一块的网卡时,其中一块收到数据包,根据数据包的目的 ip 地址将数据包发往本机另一块网卡,该网卡根据路由表继续发送数据包。这通常是路由器所要实现的功能。
要让 Linux 系统具有路由转发功能,需要配置一个 Linux 的内核参数net.ipv4.ip_forward。这个参数指定了 Linux 系统当前对路由转发功能的支持情况;其值为 0时表示禁止进行 IP 转发;如果是 1,则说明 IP 转发功能已经打开。

1.5 配置阿里云的 repo 源

配置国内安装 docker 和 containerd 的阿里云的 repo 源

yum install yum-utils -y

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

1.6 配置安装 k8s 组件需要的阿里云的 repo 源

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
EOF

1.7 配置时间同步

# 安装 ntpdate 命令
yum install ntpdate -y

# 跟网络时间做同步
ntpdate cn.pool.ntp.org

# 把时间同步做成计划任务
crontab -e
* */1 * * * /usr/sbin/ntpdate cn.pool.ntp.org

1.8 开启 ipvs

# 编写 ipvs 脚本
vim /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
ipvs_modules="ip_vs ip_vs_lc ip_vs_wlc ip_vs_rr ip_vs_wrr ip_vs_lblc ip_vs_lblcr ip_vs_dh ip_vs_sh ip_vs_nq ip_vs_sed ip_vs_ftp nf_conntrack"
for kernel_module in ${ipvs_modules}; do
 /sbin/modinfo -F filename ${kernel_module} > /dev/null 2>&1
 if [ 0 -eq 0 ]; then
 /sbin/modprobe ${kernel_module}
 fi
done

# 执行脚本
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep ip_vs

问题 1 :ipvs 是什么?

ipvs (IP Virtual Server) 实现了传输层负载均衡,也就是我们常说的 4 层 LAN交换,作为 Linux 内核的一部分。ipvs 运行在主机上,在真实服务器集群前充当负载均衡器。ipvs 可以将基于 TCP 和 UDP 的服务请求转发到真实服务器上,并使真实服务器的服务在单个 IP 地址上显示为虚拟服务。

问题 2 :ipvs 和 iptable 对比分析

kube-proxy 支持 iptables 和 ipvs 两种模式, 在 kubernetes v1.8 中引入了 ipvs 模式,在 v1.9 中处于 beta 阶段,在 v1.11 中已经正式可用了。iptables 模式在 v1.1 中就添加支持了,从 v1.2 版本开始 iptables 就是 kube-proxy 默认的操作模式,ipvs 和 iptables 都是基于netfilter 的,但是 ipvs 采用的是 hash 表,因此当 service 数量达到一定规模时,hash 查表的速度优势就会显现出来,从而提高 service 的服务性能。那么 ipvs 模式和 iptables 模式之间有哪些差异呢?

  • ipvs 为大型集群提供了更好的可扩展性和性能
  • ipvs 支持比 iptables 更复杂的复制均衡算法(最小负载、最少连接、加权等等)
  • ipvs 支持服务器健康检查和连接重试等功能

1.9 安装基础软件包

yum install -y yum-utils device-mapper-persistent-data lvm2 wget net-tools nfs-utils lrzsz gcc gcc-c++ make cmake libxml2-devel openssl-devel curl curl-devel unzip sudo ntp libaio-devel wget vim ncurses-devel autoconf automake zlib-devel  python-devel epel-release openssh-server socat  ipvsadm conntrack ntpdate telnet ipvsadm

二、安装 docker 服务

docker 安装可以看我这篇文章更详细:[【云原生 | Docker 基础篇】02、CentOS 7 安装 Docker 详细图文教程_Stars.Sky的博客-CSDN博客_centos7安装docker][_ Docker _02_CentOS 7 _ Docker _Stars.Sky_-CSDN_centos7_docker]

2.1 安装 docker-ce

yum install docker-ce -y

systemctl enable docker.service --now

2.2 配置 docker 镜像加速器和驱动

docker 镜像加速器可以看我这篇文章更详细:[【云原生 | Docker 基础篇】03、Docker 阿里云镜像加速器_Stars.Sky的博客-CSDN博客_docker 镜像加速][_ Docker _03_Docker _Stars.Sky_-CSDN_docker]

# 修改 docker 文件驱动为 systemd,默认为 cgroupfs,kubelet 默认使用 systemd,两者必须一致才可
mkdir -p /etc/docker
vim  /etc/docker/daemon.json
{
 "registry-mirrors":["https://hlfcd01t.mirror.aliyuncs.com","https://registry.docker-cn.com","https://docker.mirrors.ustc.edu.cn","https://dockerhub.azk8s.cn","http://hub-mirror.c.163.com"],
  "exec-opts": ["native.cgroupdriver=systemd"]
}

systemctl daemon-reload  && systemctl restart docker

三、安装初始化 k8s 需要的软件包

yum install -y kubelet-1.23.1 kubeadm-1.23.1 kubectl-1.23.1

systemctl enable kubelet.service

# 设置 k8s 命令自动补全
yum install -y bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

# 清除 "您在 /var/spool/mail/root 中有新邮件"信息
echo "unset MAILCHECK" >> /etc/profile 

source /etc/profile

cat /dev/null > /var/spool/mail/root

注:每个软件包的作用

  • Kubeadm: kubeadm 是一个工具,用来初始化 k8s 集群的;
  • kubelet: 安装在集群所有节点上,用于启动 Pod 的;
  • kubectl: 通过 kubectl 可以部署和管理应用,查看各种资源,创建、删除和更新各种组件。

四、kubeadm 初始化 k8s 集群

把初始化 k8s 集群需要的离线镜像包 k8s-images-v1.23.1.tar.gz 上传到三台机器上,手动解压:

docker load -i k8s-images-v1.23.1.tar.gz

# 在 master 节点使用 kubeadm 初始化 k8s 集群
[root@k8s-master1 ~]# kubeadm init --kubernetes-version=1.23.1  --apiserver-advertise-address=192.168.78.143  --image-repository registry.aliyuncs.com/google_containers  --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=SystemVerification

# 注:--image-repository registry.aliyuncs.com/google_containers:手动指定仓库地址为registry.aliyuncs.com/google_containers。kubeadm 默认从 k8s.grc.io 拉取镜像,但是 k8s.gcr.io访问不到,所以需要指定从 registry.aliyuncs.com/google_containers 仓库拉取镜像。
--apiserver-advertise-address=192.168.78.143 为 master 节点主机 ip

显示如下,说明安装完成:

*

# 下面命令是把 node 节点加入集群,需要保存下来,每个人的都不一样
kubeadm join 192.168.78.143:6443 --token 3nm4yz.5towz6cx6ybx6ebm \
	--discovery-token-ca-cert-hash sha256:a3a937a1a8971a2a2b7fc73cef528bd0adaf36aa00be7ec88569394838600a17

# 配置 kubectl 的配置文件 config,相当于对 kubectl 进行授权,这样 kubectl 命令可以使用这个证书对k8s 集群进行管理
[root@k8s-master1 ~]# mkdir -p $HOME/.kube
[root@k8s-master1 ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@k8s-master1 ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 查看集群状态
[root@k8s-master1 ~]# kubectl get nodes
NAME          STATUS     ROLES                  AGE     VERSION
k8s-master1   NotReady   control-plane,master   4m23s   v1.23.1
# 此时集群状态还是 NotReady 状态,因为没有安装网络插件。

五、扩容 k8s 集群

5.1 添加第一个工作节点

# 在 master1 上查看加入节点的命令
[root@k8s-master1 ~]# kubeadm token create --print-join-command
kubeadm join 192.168.78.143:6443 --token 5zacv3.o4qmxknq2yx57pez --discovery-token-ca-cert-hash sha256:a3a937a1a8971a2a2b7fc73cef528bd0adaf36aa00be7ec88569394838600a17

# 把 node1 加入 k8s 集群
[root@k8s-node1 ~]# kubeadm join 192.168.78.143:6443 --token 5zacv3.o4qmxknq2yx57pez --discovery-token-ca-cert-hash sha256:a3a937a1a8971a2a2b7fc73cef528bd0adaf36aa00be7ec88569394838600a17

# 在 master1 上查看集群节点状况
[root@k8s-master1 ~]# kubectl get nodes
NAME          STATUS     ROLES                  AGE     VERSION
k8s-master1   NotReady   control-plane,master   9m36s   v1.23.1
k8s-node1     NotReady   <none>                 79s     v1.23.1

5.2 添加第二个工作节点

# 在 master1 上查看加入节点的命令。每添加一个工作节点都要执行一次此命令
[root@k8s-master1 ~]# kubeadm token create --print-join-command
kubeadm join 192.168.78.143:6443 --token rmoezg.0d5olntu2ynlyu74 --discovery-token-ca-cert-hash sha256:a3a937a1a8971a2a2b7fc73cef528bd0adaf36aa00be7ec88569394838600a17

# 把 node2 加入 k8s 集群
[root@k8s-node2 ~]# kubeadm join 192.168.78.143:6443 --token rmoezg.0d5olntu2ynlyu74 --discovery-token-ca-cert-hash sha256:a3a937a1a8971a2a2b7fc73cef528bd0adaf36aa00be7ec88569394838600a17

# 在 master1 上查看集群节点状况
[root@k8s-master1 ~]# kubectl get nodes
NAME          STATUS     ROLES                  AGE     VERSION
k8s-master1   NotReady   control-plane,master   11m     v1.23.1
k8s-node1     NotReady   <none>                 3m27s   v1.23.1
k8s-node2     NotReady   <none>                 52s     v1.23.1

可以看到 node1、 node2 的 ROLES 角色为空, 就表示这个节点是工作节点。可以把 node1 和 node2 的 ROLES 变成 work,按照如下方法给节点打上标签:

[root@k8s-master1 ~]# kubectl label nodes k8s-node1 node-role.kubernetes.io/worker=worker

[root@k8s-master1 ~]# kubectl label nodes k8s-node2 node-role.kubernetes.io/worker=worker

[root@k8s-master1 ~]# kubectl get nodes
NAME          STATUS     ROLES                  AGE     VERSION
k8s-master1   NotReady   control-plane,master   14m     v1.23.1
k8s-node1     NotReady   worker                 5m49s   v1.23.1
k8s-node2     NotReady   worker                 3m14s   v1.23.1

六、安装 kubernetes 网络组件 Calico

上传 calico.yaml 到 master1 上,使用 yaml 文件安装 calico 网络插件:

[root@k8s-master1 ~]# kubectl apply -f calico.yaml

# 查看 pod 状态
[root@k8s-master1 ~]# kubectl get pods -n kube-system 
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-677cd97c8d-6rwbh   1/1     Running   0          3m21s
calico-node-4j6wl                          1/1     Running   0          3m21s
calico-node-655v6                          1/1     Running   0          3m21s
calico-node-8zsrg                          1/1     Running   0          3m21s
coredns-6d8c4cb4d-jrhss                    1/1     Running   0          20m
coredns-6d8c4cb4d-mln79                    1/1     Running   0          20m
etcd-k8s-master1                           1/1     Running   0          20m
kube-apiserver-k8s-master1                 1/1     Running   0          20m
kube-controller-manager-k8s-master1        1/1     Running   0          20m
kube-proxy-4x6nq                           1/1     Running   0          20m
kube-proxy-cg5rt                           1/1     Running   0          9m38s
kube-proxy-pl6hz                           1/1     Running   0          12m
kube-scheduler-k8s-master1                 1/1     Running   0          20m

# 查看集群状态
[root@k8s-master1 ~]# kubectl get nodes
NAME          STATUS   ROLES                  AGE    VERSION
k8s-master1   Ready    control-plane,master   20m    v1.23.1
k8s-node1     Ready    worker                 11m    v1.23.1
k8s-node2     Ready    worker                 9m9s   v1.23.1

七、测试在 k8s 创建 pod 是否可以正常访问网络

把busybox-1-28.tar.gz 上传到 node1、node2 节点,手动解压:

[root@k8s-node1 ~]# docker load -i busybox-1-28.tar.gz
[root@k8s-node2 ~]# docker load -i busybox-1-28.tar.gz

[root@k8s-master1 ~]# kubectl run busybox --image busybox:1.28 --restart=Never --rm -it busybox -- sh
If you don't see a command prompt, try pressing enter.
/ # ping www.baidu.com
PING www.baidu.com (180.97.34.94): 56 data bytes
64 bytes from 180.97.34.94: seq=0 ttl=127 time=19.765 ms
64 bytes from 180.97.34.94: seq=1 ttl=127 time=18.713 ms
64 bytes from 180.97.34.94: seq=2 ttl=127 time=18.166 ms
^C
--- www.baidu.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 18.166/18.881/19.765 ms

通过上面可以看到能访问网络,说明 calico 网络插件已经被正常安装了。

八、测试 coredns 是否正常

[root@k8s-master1 ~]# kubectl run busybox --image busybox:1.28 --restart=Never --rm -it busybox -- sh
If you don't see a command prompt, try pressing enter.
/ # nslookup kubernetes.default.svc.cluster.local
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes.default.svc.cluster.local
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local

10、 96.0.10就是我们coreDNS的clusterIP,说明coreDNS配置好了解析内部Service的名称,是通过coreDNS去解析的;

注意:busybox 要用指定的 1.28 版本,不能用最新版本,最新版本,nslookup 会解析不到 dns 和ip。

至此,k8s-v1.23 安装完成!!!

上一篇文章:[【云原生 | Kubernetes 实战】01、K8s-v1.25集群搭建和部署基于网页的 K8s 用户界面 Dashboard_Stars.Sky的博客-CSDN博客_k8s1.25安装dashboard][_ Kubernetes _01_K8s-v1.25_ K8s _ Dashboard_Stars.Sky_-CSDN_k8s1.25_dashboard]

下一篇文章:【Kubernetes 企业项目实战】02、基于 Prometheus 和 K8s 构建智能化监控告警系统(上)_Stars.Sky的博客-CSDN博客