前置知识点
目前生产部署Kubernetes 集群主要有两种方式:
kubeadm
Kubeadm 是一个K8s 部署工具,提供kubeadm init 和kubeadm join,用于快速部署Kubernetes 集群。
官方地址:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/
二进制包
从github 下载发行版的二进制包,手动部署每个组件,组成Kubernetes 集群。
Kubeadm 降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。如果想更容易可控,推荐使用二进制包部署Kubernetes 集群,虽然手动部署麻烦点,期间可以学习很多工作原理,也利于后期维护。

kubeadm 部署方式介绍
kubeadm 是官方社区推出的一个用于快速部署kubernetes 集群的工具,这个工具能通过两条指令完成一个kubernetes 集群的部署:
- 创建一个Master 节点kubeadm init
- 将Node 节点加入到当前集群中$ kubeadm join <Master 节点的IP 和端口>
安装要求
在开始之前,部署Kubernetes 集群机器需要满足以下几个条件:
- 一台或多台机器,操作系统CentOS7.x-86_x64,版本需要大于7.5,否则会出现问题,例如节点加入不到集群
- 硬件配置:2GB 或更多RAM,2 个CPU 或更多CPU,硬盘30GB 或更多
- 集群中所有机器之间网络互通
- 可以访问外网,需要拉取镜像
- 禁止swap 分区
2.4 最终目标
- 在所有节点上安装Docker 和kubeadm
- 部署Kubernetes Master
- 部署容器网络插件
- 部署Kubernetes Node,将节点加入Kubernetes 集群中
- 部署Dashboard Web 页面,可视化查看Kubernetes 资源
准备环境

| 角色 |
IP地址 |
组件 |
| master |
192.168.79.100 |
docker,kubectl,kubeadm,kubelet |
| node1 |
192.168.79.101 |
docker,kubectl,kubeadm,kubelet |
| node2 |
192.168.79.102 |
docker,kubectl,kubeadm,kubelet |
虚拟机准备和网络设置参考:[6-环境搭建–主机安装_哔哩哔哩_bilibili]
系统初始化
1
2
|
#先查看版本,必须要大于centos7.5
cat /etc/redhat-release
|
设置 Host 文件的相互解析(所有节点都要操作)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
cat <<EOF>> /etc/hosts
192.168.79.100 master
192.168.79.101 node1
192.168.79.102 node2
EOF
#执行完后可以查看一下
vi /etc/hosts
# 出现如下提示则成功
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.79.100 master
192.168.79.101 node1
192.168.79.102 node2
|
然后在任意一台机器上ping master或者ping node1或者ping node2都能通
禁用 Iptables 和firewalld服务(所有节点都要操作)
k8和docker运行过程中会产生大量Iptables规则,避免与系统规则混淆,先禁用
1
2
3
4
5
6
7
|
#禁用
systemctl stop firewalld
#关闭开机自启动
systemctl disable firewalld
#本系统其实没有iptables
systemctl stop iptables
systemctl disable iptables
|
禁用 SELINUX 和swap分区(所有节点都要操作)
linux的一个安全服务,如果不关闭容易遇到奇葩问题
1
2
|
#setenforce 0只能暂时关闭,需要将/etc/selinux/config中的SELINUX选项改为disabled
setenforce 0 && sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
|
swap分区指的是虚拟内存分区,它的作用是在物理内存使用完之后,将磁盘空间虚拟成内存来使用
启用swap设备会对系统的性能产生非常负面的影响,因此kubernetes要求每个节点都要禁用swap设备
但是如果因为某些原因确实不能关闭swap分区,就需要在集群安装过程中通过明确的参数进行配置说明
1
2
|
#swapoff -a只能暂时关闭,需要注释掉/etc/fstab中最后一行
swapoff -a && sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
|
修改linux内核参数(所有节点都要操作)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#加载网桥过滤模块
modprobe br_netfilter
#在当前路径下生成kubernetes.conf文件,编辑内核参数,添加网桥过滤和地址转发功能,
cat <<EOF> kubernetes.conf
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
EOF
#拷贝文件到指定目录
cp kubernetes.conf /etc/sysctl.d/kubernetes.conf
#重新加载配置
sysctl -p /etc/sysctl.d/kubernetes.conf
|
时间同步(所有节点都要操作)
- Kubernetes 要求集群中的节点时间必须精确一致,所以在每个节点上添加时间同步,这里直接用chronyd服务从网络同步时间
1
2
3
4
5
6
7
8
9
|
#启动服务
systemctl start chronyd
#设置开机自启
systemctl enable chronyd
#验证
date
|
配置ipvs(所有节点都要操作)
在 Kubernetes 中 service 有两种代理模型,一种是基于 iptables ,另一种是基于 ipvs 的。ipvs 的性能要高于 iptables 的,但是如果要使用它,需要手动载入 ipvs 模块。
●在三台机器安装 ipset 和 ipvsadm :
1
2
|
#安装 ipset 和 ipvsadm
yum -y install ipset ipvsadm
|
1
2
3
4
5
6
7
8
9
10
11
|
#生成脚本文件
cat <<EOF> /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
#授权脚本文件,执行,然后查看结果
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
|
重启机器
1
2
3
4
5
6
7
|
reboot
#重启后查看配置是否生效,出现disable则ok
getenforce
#swap分区相关都是0则ok
free -m
|
安装 Docker 版本20.10.8(所有节点都要操作)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#先配置阿里云的镜像源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#查看存储库中 Docker 的版本
yum list docker-ce --showduplicates | sort -r
#安装指定版本的 Docker(v20.10)
yum -y install docker-ce-3:20.10.8-3.el7.x86_64 docker-ce-cli-1:20.10.8-3.el7.x86_64 containerd.io
## 创建 /etc/docker 目录
mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": ["https://7u7aivp6.mirror.aliyuncs.com"]
}
EOF
# 由于没有启动过docker,所以无需重载配置文件 systemctl daemon-reload
#启动docker并设置开机自启动
systemctl start docker && systemctl enable docker
|
安装 kubelet kubeadm kubectl 指定版本1.21.10 (所有节点都要操作)
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
|
#配置kubernetes镜像源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
#安装kubelet kubeadm kubectl 指定版本
yum install -y kubelet-1.21.10 kubeadm-1.21.10 kubectl-1.21.10
#为了实现 Docker 使用的 cgroup drvier 和 kubelet 使用的 cgroup drver 一致,
#建议修改 /etc/sysconfig/kubelet 文件的内容:
vim /etc/sysconfig/kubelet
# 修改
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"
#设置开机自启,由于没有生成配置文件,集群初始化后自动启动:
systemctl enable kubelet
|
下载 Kubernetes 所需镜像
查看 Kubernetes 安装所需镜像:
1
|
kubeadm config images list
|
:::color2
从阿里云拉取所需的七个镜像
:::
1
2
3
4
5
6
7
|
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.21.10
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.21.10
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.21.10
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.21.10
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.4.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.13-0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.0
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#查看镜像,这时可以看到镜像的tag不对,需要改为kubernetes的tag,方便后续使用
docker images
#给镜像重新打tag
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.21.10 k8s.gcr.io/kube-apiserver:v1.21.10 &&
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.21.10 k8s.gcr.io/kube-controller-manager:v1.21.10 &&
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.21.10 k8s.gcr.io/kube-scheduler:v1.21.10 &&
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.21.10 k8s.gcr.io/kube-proxy:v1.21.10 &&
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.4.1 k8s.gcr.io/pause:3.4.1 &&
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.13-0 k8s.gcr.io/etcd:3.4.13-0 &&
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.0 k8s.gcr.io/coredns:v1.8.0
#可以移除老镜像,也可以不移除
|
部署Kubernetes Master
初始化主节点(主节点操作)
注意:
- apiserver-advertise-address 一定要是master主机的 IP 地址。当然,你可以在任意一台机器上执行下面的命令,它就是主节点
- apiserver-advertise-address 、service-cidr 和 pod-network-cidr 不能在同一个网络范围内。
- 不要使用 172.17.0.1/16 网段范围,因为这是 Docker 默认使用的。
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
|
#第一个参数为master节点的地址,由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里需要指定阿里云镜像仓库地址
kubeadm init \
--apiserver-advertise-address=192.168.79.100 \
--image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers \
--kubernetes-version=v1.21.10 \
--service-cidr=10.96.0.0/16 \
--pod-network-cidr=10.244.0.0/16
#安装成功后可以看到
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.79.100:6443 --token kpoksa.a5dhuqu4ccbap85o \
--discovery-token-ca-cert-hash sha256:e070c812307c6aaaccb328790001ce5bad043a994106b0949c4930b81e93eadc
#然后按照指示执行如下操作
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 如果是 root 用户,还可以执行如下命令
export KUBECONFIG=/etc/kubernetes/admin.conf
#此时如果执行kubectl get nodes,可以看到没有任何工作节点
kubectl get nodes
|
默认的 token 有效期为 24 小时,当过期之后,该 token 就不能用了,这时可以使用如下的命令创建 token :
1
|
kubeadm token create --print-join-command
|
生成一个永不过期的token
1
|
kubeadm token create --ttl 0 --print-join-command
|
其余工作节点加入主节点
按照上一步的指示,将其余的工作节点加入到主节点
1
2
|
kubeadm join 192.168.79.100:6443 --token kpoksa.a5dhuqu4ccbap85o \
--discovery-token-ca-cert-hash sha256:e070c812307c6aaaccb328790001ce5bad043a994106b0949c4930b81e93eadc
|
然后再在master节点运行kubectl get nodes可以看到相应的工作节点了

部署网络
1
2
3
4
5
6
|
kubectl apply -f https://projectcalico.docs.tigera.io/v3.19/manifests/calico.yaml
#网络不好将calico.yaml文件上传到root目录下然后执行
kubectl apply -f /root/calico.yaml
#网络这一步的等待时间可能比较久,中间可能会出现部分节点就绪,部分未就绪的情况
|
然后查看节点状态
1
2
3
4
5
6
7
8
|
kubectl get nodes
#结果如下
[root@master /]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane,master 27m v1.21.10
node1 Ready <none> 21m v1.21.10
node2 Ready <none> 21m v1.21.10
|
至此,Kubernetes安装完成
让工作节点也能使用kubectl
kubectl的运行是需要进行配置的,它的配置文件是$HOME/.kube,如果想要在node节点运行此命令,需要将
master上的.kube文件复制到node节点上,即在master节点上执行下面操作:
1
|
scp -r $HOME/.kube node1:$HOME/ && scp -r $HOME/.kube node2:$HOME/
|
测试kubernetes 集群
部署nginx 测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#在控制节点执行安装nginx
kubectl create deployment nginx --image=nginx:1.14-alpine
#暴露80端口
kubectl expose deployment nginx --port=80 --type=NodePort
#查看pod和service
kubectl get pod,svc
#结果如下
NAME READY STATUS RESTARTS AGE
pod/nginx-65c4bffcb6-knqpr 1/1 Running 0 2m20s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 37m
service/nginx NodePort 10.96.129.185 <none> 80:32100/TCP 100s
|
此时可以使用master节点的ip加nginx的端口访问,例如 192.168.79.100:32100