一、前言

1.1、准备三台虚拟机

主机名称 主机节点 IP地址 性能 系统及内核
k8s-master master 192.168.100.130 2H4G 25G CentOS7.x,内核版本至少为3.10及以上
k8s-node01 node01 192.168.100.131 2H2G 25G CentOS7.x,内核版本至少为3.10及以上
k8s-node02 node02 192.168.100.132 2H2G 25G CentOS7.x,内核版本至少为3.10及以上

此文档使用 kubeadm 部署

1.2、目前生产部署 k8s 集群主要有两种方式

1️⃣ kubeadm:kubeadm 是一个 k8s 部署工具,提供 kubeadmin init 和 kubeadm join,用于快速部署 k8s集群。
2️⃣ 二进制包:从 GitHub 下载发行版的二进制包,手动部署每个组件,组成 k8s 集群。
kubeadm 降低部署门槛,但是屏蔽了很多细节,遇到问题很难排查。如果想要更容易可控,推荐使用二级制包部署k8s集群,虽然手动部署麻烦点,期间可以学习很多工作原理,也有利于后期维护。

二、升级系统内核

为什么要升级内核?
提高对最新设备的兼容性、修补原有系统内核的漏洞、提高系统的稳定性等
注意内核升级是有一定风险的
你也可以选择不升级,直接跳过这一步

CentOS内核升级的官方文档:http://elrepo.org/tiki/tiki-index.php
Docker官方对OverlayFS 和 内核版本的要求说明:https://docs.docker.com/storage/storagedriver/overlayfs-driver/

2.1、查看当前 CentOS 的内核版本

1
2
3
4
5
//1、查看内核版本
uname -r

//2、显示内核版本信息如下
3.10.0-1160.el7.x86_64

可以看到 Centos7 的内核版本,虽然满足条件 (在3.10.0-514之上),但是其内核版本还是比较低的,为了更好的运行 docker 和 kubernetes,建议对 centos7 的内核进行升级

2.2、安装 ELRepo 和 kernel

1
2
3
4
5
6
7
8
//1、载入公钥
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org

//2、安装ELRepo
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm

//3、安装内核 kernel
yum --enablerepo=elrepo-kernel install -y kernel-ml-devel kernel-ml

2.3、查看新安装的内核完整名称

1
2
3
4
5
//1、查看已安装的内核版本
rpm -qa | grep -i kernel

//2、 查找新安装的内核完整名称
cat /boot/grub2/grub.cfg | grep menuentry

安装完成后,使用cat /boot/grub2/grub.cfg | grep menuentry命令,可以看到的第一行内容中包含新安装的内核完整名称信息,其名称为 CentOS Linux (6.0.0-1.el7.elrepo.x86_64) 7 (Core)

1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# cat /boot/grub2/grub.cfg | grep menuentry
if [ x"${feature_menuentry_id}" = xy ]; then
menuentry_id_option="--id"
menuentry_id_option=""
export menuentry_id_option
menuentry 'CentOS Linux (6.0.0-1.el7.elrepo.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-1160.el7.x86_64-advanced-bd3a0c48-c524-42ad-9578-d354eb74b407' {
menuentry 'CentOS Linux (3.10.0-1160.76.1.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-1160.el7.x86_64-advanced-bd3a0c48-c524-42ad-9578-d354eb74b407' {
menuentry 'CentOS Linux (3.10.0-1160.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-1160.el7.x86_64-advanced-bd3a0c48-c524-42ad-9578-d354eb74b407' {
menuentry 'CentOS Linux (0-rescue-9bc687058d174afead0494c18965406f) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-0-rescue-9bc687058d174afead0494c18965406f-advanced-bd3a0c48-c524-42ad-9578-d354eb74b407' {
[root@localhost ~]#

2.4、更改 CentOS7 默认的系统内核版本

1
2
3
4
5
6
7
8
//1、更改系统内核版本为最新安装版本
grub2-set-default 'CentOS Linux (6.0.0-1.el7.elrepo.x86_64) 7 (Core)'

//2、查看默认启动内核是否更换成功
grub2-editenv list

//3、重启系统
reboot
1
2
3
4
5
6
7
8
9
10
//1、更改系统内核版本为最新安装版本
grub2-set-default 0

//2、查看默认启动内核是否更换成功
grub2-editenv list

//3、重启系统
reboot

提示:由于升级后内核版本是往前面插入的,前面在查看新安装的内核完整名称时,我们也看到新安装的内核信息在第一行输出,所以设置启动顺序为0,即可更改为新内核版本

2.5、查看系统内核版本是否设置成功

1
uname -r

image.png

三、系统初始化 (三个节点都需要执行如下操作)

3.1、主机名

设置 mester 的主机名:hostnamectl set-hostname <hostname> 或者编辑 vim /etc/hostsname 文件内名称

设置192.168.100.130的主机名:hostnamectl set-hostname k8s-master
设置192.168.100.131的主机名:hostnamectl set-hostname k8s-node1
设置192.168.100.132的主机名:hostnamectl set-hostname k8s-node2

3.2、添加 hosts(此配置是方便与内网互通)

1
2
3
4
$ vim /etc/hosts
192.168.100.130 k8s-master
192.168.100.131 k8s-node1
192.168.100.132 k8s-node2

image.png

3.3、关闭 firewalld 防火墙

关闭防火墙:systemctl stop firewalld
禁止防火墙开机自启:systemctl disable firewalld

3.4、关闭 SElinux

临时关闭:setenforce 0
永久关闭(关闭后需重启):sed -i 's/enforcing/disabled/' /etc/selinux/config

3.5、关闭 swap 分区 (为了提高k8s的性能,建议关闭 swap 分区)

临时关闭 swap 分区:swapoff -a
永久关闭 swap 分区(关闭后需重启):sed -ri 's/.*swap.*/#&/' /etc/fstab

3.6、同步系统时间 (多个节点之间强烈建议同步时间)

1
2
yum install ntpdate -y 
ntpdate time.windows.com

3.7、修改网卡配置

作用:将桥接的 IPv4 流量传递到 iptables 的链

1
2
3
4
5
$ vim /etc/sysctl.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
$ sysctl -p

image.pngimage.png

3.8、开启 ipvs

从 kubernetes 的1.8版本开始,kube-proxy 引入了 ipvs 模式,ipvs 模式与 iptables 同样基于 Netfilter,但是 ipvs 模式采用的是 hash 表,因此当 service 数量达到一定规模时,hash 查表的速度优势就会显现出来,从而提高 service 的服务性能

这里需要注意有个坑,我们前面升级了系统内核,所以有个地方会和你去百度的有点不一样

3.8.1、安装 ipvsadm 和 ipset

1
yum -y install ipvsadm ipset

3.8.2、编辑 ipvs.modules 配置文件,使其永久生效

1
2
3
4
5
6
7
8
9
$ vim /etc/sysconfig/modules/ipvs.modules

//3、填写如下内容

modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack

image.png

3.8.3、授权、运行、检查是否加载:

1
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack

image.png

3.8.4、查看是否已经正确加载所需的内核模块

1
bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack

3.8.5、检查是否运行

1
cut -f1 -d " "  /proc/modules | grep -e ip_vs -e nf_conntrack

image.png

四、Docker 安装配置

k8s默认CRI(容器运行时)为Docker,因此需要先安装Docker

4.1、安装 docker

1
2
sudo yum remove docker docker-common docker-selinux docker-engine
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

4.1.1、下载 Repo 文件

1
wget -O /etc/yum.repos.d/docker-ce.repo https://repo.huaweicloud.com/docker-ce/linux/centos/docker-ce.repo

4.1.2、软件仓库地址替换为华为镜像

1
sudo sed -i 's+download.docker.com+repo.huaweicloud.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo

4.1.3、更新索引文件并安装

1
2
sudo yum makecache fast
sudo yum install docker-ce

4.2、配置 Docker 源

您可以通过修改 daemon 配置文件 /etc/docker/daemon.json 来使用加速器
使用 vim 编辑 vim /etc/docker/daemon.json 并在里面填入:👇👇👇

1
2
3
4
5
6
7
8
{
"registry-mirrors": [
"https://dockerproxy.com",
"https://qhrtxuc5.mirror.aliyuncs.com",
"https://docker.mirrors.ustc.edu.cn",
"http://f1361db2.m.daocloud.io"
]
}

4.2.1、重新加载 daemon.json 配置文件 并 重启 docker 服务

1
2
3
4
5
//1、重新加载daemon.json配置文件
systemctl daemon-reload

//2、重启服务器
systemctl restart docker

4.3、设置 Docker 开机自启和启动 Docker,并查看其版本

1
2
3
4
5
//1、设置docker开机自启 和 启动docker
systemctl enable docker && systemctl start docker

//2、查看docker版本
docker --version

五、部署前准备

5.1、配置阿里云的 Kubernetes 源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//1、编辑kubernetes.repo文件
vim /etc/yum.repos.d/kubernetes.repo

//2、添加如下内容
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
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


解释:
enable=1:表示启用这个源
gpgcheck=1:表示对这个源下载的rpm包进行校验
repo_gpgcheck=0:某些安全性配置文件会在 /etc/yum.conf 内全面启用 repo_gpgcheck,以便能检验软件库中数据的加密签署,如果repo_gpgcheck设置为1,会进行校验,就会出现报错[Errno -1] repomd.xml signature could not be verified for kubernetes,所以这里设为0

```shell

![image.png](https://f002.backblazeb2.com/file/choleimg/20221008_e/7.png)

### 5.2、安装kubeadm、kubelet 和 kubectl

> **提示:k8s 版本更新频繁,我们可以指定版本号部署,这里我默认安装最新版**
查看可安装版本:`yum list --showduplicates kubeadm --disableexcludes=kubernetes`
制定版本命令:yum -y install kubeadm-1.25.0 kubelet-1.25.0 kubectl-1.25.0
```shell
yum install -y kubelet kubeadm kubectl

5.2.1、设置开机启动 kubelet 服务

设置为开机自启动即可,由于没有生成配置文件,集群初始化后将会自动启动
开机自启 kubelet:systemctl enable kubelet
手动开启 kubelet:systemctl start kubelet
此时执行 systemctl status kubelet 查看服务状态,服务状态应为 Error(255), 如果是其他错误可使用journalctl -xe 查看错误信息。(如果是没有配置文件则忽略)

5.3、修改 kubelet 配置文件,关闭 swap

1
2
3
4
5
6
//1、编辑kubelet配置文件
vim /etc/sysconfig/kubelet

//2、添加 --fail-swap-on=false参数
KUBELET_EXTRA_ARGS="--fail-swap-on=false"

5.4、锁定版本

前面说了,k8s 更新非常频繁,但我们有时候会手残执行 yum update 以至于更新了这些组件和docker
为了避免版本问题导致的报错,我们安装好后将 docker和 kubeadm、kubelet kubectl 版本锁定

5.4.1、安装 yum-plugin-versionlock 插件

1
yum install -y yum-plugin-versionlock

5.4.2、锁定软件包

1
yum versionlock add docker-ce docker-ce-cli kubelet kubeadm kubectl

image.png

5.4.3、查看已锁定的软件包

1
yum versionlock list

image.png

此插件相关命令:
解锁指定的软件包:yum versionlock delete <软件包名称>
解锁所有的软件包:yum versionlock clear

!!!至此全节点配置安装完毕!!!

如果是用 VM 到这里后可以开始复制虚拟机制作 node 节点,然后分别配置好它们的 IP 和 主机名 即可

六、部署 Kubernetes Maste r节点 (在master节点上执行)

6.1、提前下载初始化 master 节点所需镜像

6.1.1、查看安装 kubernetes 需要哪些镜像

1
2
3
4
5
6
7
8
9
10
kubeadm config images list

输出:
registry.k8s.io/kube-apiserver:v1.25.2
registry.k8s.io/kube-controller-manager:v1.25.2
registry.k8s.io/kube-scheduler:v1.25.2
registry.k8s.io/kube-proxy:v1.25.2
registry.k8s.io/pause:3.8
registry.k8s.io/etcd:3.5.4-0
registry.k8s.io/coredns/coredns:v1.9.3

image.png

6.1.2、编写脚本下载

k8s 是谷歌的东西,由于国内网络无法直接拉取其镜像仓库,所以我们使用 阿里云来代理拉取,拉下来之后再重新打标签为 k8s 官方镜像名

①、创建并编辑脚本:vim k8simage-download.sh
脚本内容:👇👇👇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
if [ $# -ne 1 ];then
echo "The format is: ./`basename $0` kubernetes-version"
exit 1
fi

version=$1
images=`kubeadm config images list --kubernetes-version=${version} | awk -F '/' '{print $2}'`

for imageName in ${images[@]} ; do
docker pull registry.aliyuncs.com/google_containers/$imageName
docker tag registry.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
docker rmi registry.aliyuncs.com/google_containers/$imageName
done

②、为脚本设置可执行权限:chmod +x k8simage-download.sh
③、查看脚本是否已经拥有可执行权限:ll k8simage-download.sh
image.png

6.1.3、执行脚本获取镜像

下面需要填写 k8s 版本号
我们刚刚下的是最新版的组件,最新版版号为 1.25.0

1
./k8simage-download.sh v1.25.0

下载完成后我们使用 命令docker images 查看是否完成
image.png

6.2、初始化master节点

提示:–apiserver-advertise-address需要改成你自己master节点的ip地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
kubeadm init \
--apiserver-advertise-address=192.168.100.130 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version=v1.25.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16


解释:
--apiserver-advertise-address:指定用master节点的ip地址 与 Cluster的其他节点通信。
--image-repository:Kubenetes默认Registries地址是 k8s.gcr.io,一般在国内并不能访问 gcr.io, 可以将其指定为阿里云镜像地址:registry.aliyuncs.com/google_containers。
--kubernetes-version=v1.23.0:指定要安装kubernetes的版本号。
--service-cidr:指定Service网络的范围,即负载均衡VIP使用的IP地址段。
--pod-network-cidr:指定Pod网络的范围,即Pod的IP地址段。

6.2.1、第一次初始化失败

我们第一次初始化 master 节点可能会出错 “因未知服务kubeadm init而失败。runtime.v1alpha2.RuntimeService”(反正我好几次都这样)
报错信息如下:👇

1
2
3
4
5
6
7
8
9
10
11
12
[init] Using Kubernetes version: v1.25.0
[preflight] Running pre-flight checks
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR CRI]: container runtime is not running: output: E1007 15:56:10.546831 3659 remote_runtime.go:948] "Status from runtime service failed" err="rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.RuntimeService"
time="2022-10-07T15:56:10+08:00" level=fatal msg="getting status of runtime: rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.RuntimeService"
, error: exit status 1
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher
[root@k8s-master ~]# rm /etc/containerd/config.toml
rm: remove regular file ‘/etc/containerd/config.toml’? y
[root@k8s-master ~]# rm /etc/containerd/config.toml
rm: cannot remove ‘/etc/containerd/config.toml’: No such file or directory

解决方案:

1
2
rm /etc/containerd/config.toml
systemctl restart containerd

方案来源:https://github.com/containerd/containerd/issues/4581

6.2.2、再来一次!

我们解决上面那个麻烦之后再来一次,不出意外是可以了
当我们看到下面这一步,就说明在开始 获取 kubernetes相关组件的镜像,但是我们上面已经提前拉取了镜像,所以会很快进行下一步的

当我们看到这个,就说明在开始 获取 kubernetes相关组件的镜像

image.png
下面是控制台所输出的执行信息,各位可以对着看你如果有报错,在哪块开始的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
[root@k8s-master ~]# kubeadm init \
> --apiserver-advertise-address=192.168.100.130 \
> --image-repository registry.aliyuncs.com/google_containers \
> --kubernetes-version=v1.25.0 \
> --service-cidr=10.96.0.0/12 \
> --pod-network-cidr=10.244.0.0/16
[init] Using Kubernetes version: v1.25.0
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [k8s-master kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.100.130]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [k8s-master localhost] and IPs [192.168.100.130 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [k8s-master localhost] and IPs [192.168.100.130 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[apiclient] All control plane components are healthy after 11.503332 seconds
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
[mark-control-plane] Marking the node k8s-master as control-plane by adding the labels: [node-role.kubernetes.io/control-plane node.kubernetes.io/exclude-from-external-load-balancers]
[mark-control-plane] Marking the node k8s-master as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]
[bootstrap-token] Using token: c7y1ii.zzpnb7zxofdxjczp
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

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

Alternatively, if you are the root user, you can run:

export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.100.130:6443 --token c7y1ii.zzpnb7zxofdxjczp \
--discovery-token-ca-cert-hash sha256:5cc327c50ee63599b7aa1fab4509dd31621e48c4d5e7c32192996545e7e8428b
[root@k8s-master ~]#

6.2.3、安装成功

可以看到安装成功之后,图片上红色方框框起来的两部分内容,在后面的安装过程中需要用上

第一部分内容是用来配置 kubectl工具
第二部分内容是在node节点加入时需要此信息

image.png

6.2.4、CPU 问题报错

TIPS:master 节点的 cpu 数量要 >= 2,否则会报如下错误
[ERROR NumCPU]: the number of available CPUs 1 is less than the required 2

解决方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//方法一
修改master节点的cup数量要大于等于2

//方法二
添加 --ignore-preflight-errors==NumCPU 忽略运行时CPU错误

kubeadm init \
--apiserver-advertise-address=192.168.198.145 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version=v1.23.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
--ignore-preflight-errors==NumCPU


提示:
如果出现ERROR Swap错误,同样可以在后面添加 --ignore-preflight-errors==Swap 忽略运行时Swap错误

6.3 配置kubectl工具

根据上面终端输出的提示信息,在 Master 节点上使用 kubectl 工具:

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

6.4、添加网络插件

  1. 一键安装:
1
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
  1. 手动安装:
1
2
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml

查看已安装列表:kubectl get pods --all-namespaces
安装完成后查看此节点上的 pods,会发现多了几个 kube-flannel 节点
image.png
监听安装进度:watch kubectl get pods --all-namespaces 出现以下内容时为安装成功(所有 STATUS 为 Running 时)
image.png

七、部署 Kubernetes Node 节点 (在 node 节点上执行)

查看当前已加入的节点:kubectl get nodes -o wide(正常情况这里只有一个节点)
查看添加帮助:kubeadm token create --help(使用 –print-join-command 查看)

7.1、加入 Kubernetes 集群

查看添加节点命令:kubeadm token create --print-join-command
image.png
使用获取的添加命令在 node 节点机上执行
当看到如下输入信息时,则表示加入 Kubernetes 集群成功

This node has joined the cluster:

  • Certificate signing request was sent to apiserver and a response was received.
  • The Kubelet was informed of the new secure connection details.

Run ‘kubectl get nodes’ on the control-plane to see this node join the cluster.

提示:如果加入失败,可以使用 kubeadm reset 命令进行清理,然后再重新加入

在 master 节点上查看添加结果:watch kubectl get nodes -o wide
实时最后查看全部:watch kubectl get pods --all-namespaces -o wide
查看kubectl pods.png
在节点机上查看网络插件有没有被添加入 Docker 的镜像:docker images
节点机网络插件.png

八、集群状态监测与ipvs的开启 (在master节点上执行)

8.1、查看集群状态

1
kubectl get componentstatus

image.png

8.2、查看集群各个节点

1
kubectl get nodes

等会上图
可以看到此时,node 节点还处在 NotReady 状态 (这是由于启动 pod 需要时间,多等待一段时间即可)

8.3、查看所有pod是否已经启动成功

1
kubectl get pods -n kube-system

可以看到有一个名为 calico-node-nmbrg 的 pod 处于 Init 状态 (提示:其实等待一段时间就好了)
我们可以通过 kubectl describe pod calico-node-nmbrg -n kube-system 命令查看其详情,可以看到 upgrade-ipam 容器已经成功启动

8.4、再次查看集群各个节点状态 和 所有pod状态 (确保所有pod都处于Running状态)

1
2
3
4
5
//1、查看节点状态
kubectl get nodes

//2、查看pod状态
kubectl get pods -n kube-system

8.5、配置 kubectl 命令自动补全功能

8.5.1、安装 epel-release 和 bash-completion

1
yum install -y epel-release bash-completion

8.5.2、配置kubectl命令自动补全

1
2
3
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

8.5.3、测试配置是否成功

1
kubectl tab键

8.6、配置 kube-proxy 开启 ipvs

九、常见问题

9.1、忘记 token 或者 token 失效,后续节点如何重新加入集群

9.1.1、生成新的 token 并查看 token

1
2
3
4
5
6
7
8
//方式一:生成永久token,--ttl 0:表示设置永不过期 (不安全,不推荐)
kubeadm token create --ttl 0

//方式二:生成临时token,有效期为一天 (可以保证集群安全性,推荐)
kubeadm token create

//查看生成的token
kubeadm token list

9.1.2、获取 ca 证书的 sha256 编码 hash 值

1
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

9.1.3、组装生成有效的 kubeadm join 命令

通过新生成的 token 和 ca证书sha256编码的hash值 重新组装得到有效的 kubeadm join命令

1
2
kubeadm join 192.168.198.145:6443 --token gzxm5g.z2n80zos0ior1ln8 \
--discovery-token-ca-cert-hash sha256:9a39cca67b506c8c7b4e59bc9e8e934b1c779342ed159f2318ce9ca2533cf58f

9.2、master 节点安装过程失败,重置 kubeadm

1
2
3
4
5
6
kubeadm reset
ifconfig cni0 down
ip link delete cni0
ifconfig flannel.1 down
ip link delete flannel.1
rm -rf /var/lib/cni/

十、遇到的小问题

报错:url: (6) Could not resolve host: google.com; Name or service not known
解决:vim /etc/resolv.conf,加入 DNS

1
2
nameserver 8.8.8.8
nameserver 8.8.4.4

来源:https://stackoverflow.com/questions/24967855/curl-6-could-not-resolve-host-google-com-name-or-service-not-known


报错:与服务器 localhost:8080 的连接被拒绝 - 您是否指定了正确的主机或端口?
解决:配置 kubectl

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

原因:kubectl 你还没配置


使用 sysctl -p 提示报错:

1
2
sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-iptables: No such file or directory
sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-ip6tables: No such file or directory

解决:需要加载模块

1
modprobe br_netfilter       #加载模块

十一、常用命令

11.1、k8s需要重新初始化

master 节点

1
kubeadm reset

手动清除配置信息

1
2
3
4
5
rm -rf /root/.kube
rm -rf /etc/cni/net.d
yum install -y ipvsadm
ipvsadm -C
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X

删除 /etc/kubernetes/ $HOME/.kube /var/lib/etcd 文件夹

1
2
3
rm -rf /etc/kubernetes/*
rm -rf ~/.kube/*
rm -rf /var/lib/etcd/*

11.2、卸载k8s组件

在卸载 K8s 组件前,先执行 kubeadm reset 命令,清空 K8s 集群设置

1
kubeadm reset

卸载管理组件

1
yum erase -y kubelet kubectl kubeadm kubernetes-cni

再去 Docker 删除基础组件镜像