「伸手摘星,即使一无所获,亦不致满手污泥」。
「请关注公众号:星河之码」
K8S作为主流的容器编排工具,搭建一个完整的K8S集群的方式也是有很多种,包括第三方的一些工具:
「使用minikube安装单节点集群,用于测试」 「采用工具kubeadm」 「使用kubespray,google官方提供的工具。」 「全手动:二进制方式安装」 「全自动安装:rancher 、kubesphere」
在官网中也提供了两种方式给我们在线学习的方式部署集群,就是外网有点慢
https://kubernetes.io/zh-cn/docs/tutorials/kubernetes-basics/create-cluster/cluster-interactive/
复制

其实搭建一个Kubernetes集群本身并不复杂,主要分为以下四个步骤
「centos7.9操作系统配置」
这个在安装centos7.9的时候,就可以配置,推荐使用centos7.7以上版本
「k8s集群镜像下载」
由于是外网的,镜像下载很慢,最好提前下载
「搭建k8s集群」
「k8s集群网络配置」
接下来我就以一个干净的centos7.9,完成以上几个步骤,搭建一个Kubernetes集群
一、 Kubernetes集群安装要求
「硬件要求」
硬件 | 要求 |
---|---|
CPU | 至少2核 |
内存 | 至少3G |
硬盘 | 至少50G |
「集群节点」
主机名 | 主机IP | 说明 |
---|---|---|
k8s-master-01-150 | 192.168.204.150 | 主节点,管理节点 |
k8s-node-01-151 | 192.168.204.151 | 工作节点01 |
k8s-node-02-152 | 192.168.204.152 | 工作节点02 |
harbor-130 | 192.168.204.130 | 私服 |
二、centos7的安装与系统配置
centos7的安装与系统配置在之前的文章《centos安装》有详细的介绍与步骤,
centos安装在我的个人CSDN【星河之码】中已发布,可以自行搜索
这里就不再赘述,参考之前的文章即可,这里安装K8S需要再加一些配置,如下
「开启IPVS」
K8S的负载均衡是通过Ip做的
#安装IPVS
yum -y install ipset ipvsdm
#编译ipvs.modules文件
vi 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
#赋予权限并执行
chmod 755 etc/sysconfig/modules/ipvs.modules && bash etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack
#重启电脑,检查是否生效
reboot
#查看是否生效
lsmod | grep ip_vs_rr复制

注意:
在网上很多教程安装K8S需要配置ipvs功能,但是在进行配置时会报错:modprobe: FATAL: Module nf_conntrack_ipv4 not found.
这是因为网上教程中大多使用的3.X版本的内核,上述配置中「最后一个使用的是nf_conntrack_ipv4」,但是现在内核版本都比较高,我的就是5.x
「在高版本内核已经把nf_conntrack_ipv4替换为nf_conntrack了」。所以正确配置应该跟我上面哪个一样
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack复制
「同步时间」
#安装软件
yum -y install ntpdate
#向阿里云服务器同步时间
ntpdate time1.aliyun.com
#删除本地时间并设置时区为上海
rm -rf etc/localtime
ln -s usr/share/zoneinfo/Asia/Shanghai etc/localtime
#查看时间
date -R || date复制

「命令补全」
#安装bash-completion
yum -y install bash-completion bash-completion-extras
#使用bash-completion
source etc/profile.d/bash_completion.sh复制
「关闭swap分区」
#临时关闭:
swapoff -a
#永久关闭:
vi etc/fstab
#将文件中的/dev/mapper/centos-swap这行代码注释掉
#/dev/mapper/centos-swap swap swap defaults 0 0
#高版本的 可能显示一个UUID 如下
#UUID=29eb2c2f-15cb-4a7d-a76f-f6b5fc18bae0 swap swap defaults 0 0
#确认swap已经关闭:若swap行都显示 0 则表示关闭成功
free -m
#如果free -m查看没有变为0可以重启一下服务器试试
reboot复制

「到这里centos就配置好了,配置好以上内容以后,建议打个镜像,留着以后作为基础镜像使用」
三、安装docker
Docker的安装在另外一篇文章也有详细的介绍与步骤,参考之前的文章即可,同样的,这里安装K8S也需要再加一些配置,如下
「修改Cgroup Driver」
#修改daemon.json,新增:
sudo vim etc/docker/daemon.json
"exec-opts": ["native.cgroupdriver=systemd"]
#重启docker服务:
systemctl daemon-reload
systemctl restart docker
#查看修改后状态:
docker info | grep Cgroup复制
修改cgroup driver可以消除安装k8s集群时的告警:
[WARNING IsDockerSystemdCheck]: detected “cgroupfs” as the Docker cgroup driver. The recommended driver is “systemd”. Please follow the guide at https://kubernetes.io/docs/setup/cri/......
「添加私服地址」
「没有私服可以不添加,这一步骤非必要」
#编辑配置文件
vi etc/docker/daemon.json
#增加仓库配置信息
# 在daemon.json中添加以下 key,保存退出。此步用于让 docker 信任私有仓库地址 192.168.242.130:5000是harbor的地址
{"insecure-registries":["192.168.242.130:5000"]}复制「开启转发配置」
这是让外网访问,在之前的文章《Docker-compose》中有讲过为啥要配置这个,可以参考看看篇文章
#编辑sysctl.conf
vi etc/sysctl.conf
#配置转发
net.ipv4.ip_forward=1
#保存退出就可以了
#重启服务,让配置生效
systemctl restart network
#查看是否成功,如果返回为“net.ipv4.ip_forward = 1”则表示成功
sysctl net.ipv4.ip_forward
#重启docker
sudo systemctl start docker复制
「到这里docker就安装好了,安装好以上内容以后,建议在打个镜像,留着以后作为docker基础镜像使用」
四、使用kubeadm安装K8S
kubeadm是官方推荐的一种安装k8S 的方式,接下来就用kubeadm来安装一个K8S集群,集群包含一个master节点和三个工作节点
主机名 | 主机IP | 说明 |
---|---|---|
k8s-master-01-150 | 192.168.204.150 | 主节点,管理节点 |
k8s-node-01-151 | 192.168.204.151 | 工作节点01 |
k8s-node-02-152 | 192.168.204.152 | 工作节点02 |
k8s-node-03-153 | 192.168.204.153 | 工作节点03 |
先从上述的基础节点中克隆出一个新的虚拟机 k8s-master-01-150 。工作节点可以等我们配置好master之后再从master节点克隆。

由于我们上述表格中固定了几个ip,所以我们可以先修改一下虚拟机的IP和hostname,这样方便后面的区分
4.1 修改虚拟机的IP和hostname
「修改虚拟机的hostname」
hostnamectl set-hostname k8s-master-01-150
bash复制「修改虚拟机的Ip」
#编辑ifcfg-ens33
vi etc/sysconfig/network-scripts/ifcfg-ens33
#修改参数
BOOTPROTO=static #dhcp:自动分配ip ,static:静态ip
ONBOOT=yes #开启启动必须是yes
#设置IP和掩码
IPADDR=192.168.204.150 # 要设置的Ip地址
NETMASK=255.255.255.0 # 掩码
GATEWAY=192.168.204.2 # 子网网关
DNS1=192.168.204.2 # 跟子网网关就行复制「GATEWAY 获取的方式」
「重启网络」
systemctl restart network
复制
4.2 安装yum源
「新建repo文件」
#新建一个repo文件
vi etc/yum.repos.d/kubernates.repo
#给repo文件中追加以下内容
[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复制「更新缓存」
yum clean all
yum -y makecache复制「验证源是否可用」
yum list | grep kubeadm
复制「查看k8s版本」
有很多版本,推荐使用1.17.5
yum list kubelet --showduplicates | sort -r
复制「安装k8s-1.17.5」
1.18版本相对于1.17更新了不少很多东西,我这里选择的是更新之前的版本
yum install -y kubelet-1.17.5 kubeadm-1.17.5 kubectl-1.17.5
复制
4.3 设置kubelet
「kubelet用于接收api-server指令」
「增加配置信息」
如果不配置kubelet,可能会导致K8S集群无法启动。为实现docker使用的cgroup driver与kubelet 使用的cgroup的一致性。
#编辑kubelet
vi etc/sysconfig/kubelet
#追加一下配置信息 配置中KUBELET_EXTRA_ARGS= 默认是空的
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"复制「设置开机启动」
systemctl enable kubelet
复制
4.4 初始化镜像
「查看安装集群需要的镜像」
kubeadm config images list
#最好使用这种带版本的,不带版本有时候会显示不准确,不知道为啥
kubeadm config images list --kubernetes-version v1.17.5复制「编写执行脚本」
编写脚本,将k8s.gcr.io替换成阿里云的镜像地址
mkdir -p data
cd data
#创建并且编辑脚本文件
vi init.sh
#在文件中追加一下内容
#!/bin/bash
# 下面的镜像应该去除"k8s.gcr.io"的前缀,版本换成kubeadm config images list命令获取到的版本
images=(
kube-apiserver:v1.17.5
kube-controller-manager:v1.17.5
kube-scheduler:v1.17.5
kube-proxy:v1.17.5
pause:3.1
etcd:3.4.3-0
coredns/coredns:1.6.5
)
for imageName in ${images[@]};
do
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
done复制「执行脚本」
#给脚本授权
chmod 777 data/init.sh
#进入/data执行脚本
./init.sh复制「或者换一种方式」
直接使用kubeadm拉取指定仓库的镜像
kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.17.5
复制下列脚本与以上不同的地方在于修改了镜像tag
#!/bin/bash
# Script For Quick Pull K8S Docker Images
# by Hellxz Zhang <hellxz001@foxmail.com>
# please run kubeadm for get version msg. e.g `kubeadm config images list --kubernetes-version v1.18.3`
# then modified the Version's ENV, Saved and Run.
KUBE_VERSION=v1.17.5
PAUSE_VERSION=3.1
CORE_DNS_VERSION=1.6.5
ETCD_VERSION=3.4.3-0
# pull aliyuncs mirror docker images
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:$KUBE_VERSION
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:$KUBE_VERSION
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:$KUBE_VERSION
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:$KUBE_VERSION
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:$PAUSE_VERSION
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:$CORE_DNS_VERSION
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:$ETCD_VERSION
# retag to k8s.gcr.io prefix
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:$KUBE_VERSION k8s.gcr.io/kube-proxy:$KUBE_VERSION
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:$KUBE_VERSION k8s.gcr.io/kube-controller-manager:$KUBE_VERSION
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:$KUBE_VERSION k8s.gcr.io/kube-apiserver:$KUBE_VERSION
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:$KUBE_VERSION k8s.gcr.io/kube-scheduler:$KUBE_VERSION
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:$PAUSE_VERSION k8s.gcr.io/pause:$PAUSE_VERSION
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:$CORE_DNS_VERSION k8s.gcr.io/coredns:$CORE_DNS_VERSION
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:$ETCD_VERSION k8s.gcr.io/etcd:$ETCD_VERSION
# untag origin tag, the images won't be delete.
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:$KUBE_VERSION
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:$KUBE_VERSION
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:$KUBE_VERSION
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:$KUBE_VERSION
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/pause:$PAUSE_VERSION
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:$CORE_DNS_VERSION
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:$ETCD_VERSION复制「保存镜像」
由于K8S在下载比较慢,而且在集群中每个节点都需要进行K8S的安装,所以我们可以将镜像备份,然后导入到其他节点,这点跟之前搭建Docker-Swarm集群的时候差不多,有兴趣可以参考一下之前的文章《Docker-Swarm集群管理》。
「执行下面命令,将K8S 的脚本打成一个tar包」,打包的时候可以区分一下,因为K8S中master节点和worker节点需要的镜像是不一样的
「master节点需要的镜像」
master节点需要全部镜像
docker save -o k8s.1.17.5.master.tar \
k8s.gcr.io/kube-proxy:v1.17.5 \
k8s.gcr.io/kube-apiserver:v1.17.5 \
k8s.gcr.io/kube-controller-manager:v1.17.5 \
k8s.gcr.io/kube-scheduler:v1.17.5 \
k8s.gcr.io/coredns:1.6.5 \
k8s.gcr.io/etcd:3.4.3-0 \
k8s.gcr.io/pause:3.1 \复制「worker节点需要的镜像」
worker节点需要kube-proxy:v1.17.5和pause:3.1两个镜像,当然也可以全部导入进去
docker save -o k8s.1.17.5.worker.tar \
k8s.gcr.io/kube-proxy:v1.17.5 \
k8s.gcr.io/pause:3.1 \复制「导入镜像tar包」
docker load -i k8s.1.17.5.worker.tar
复制由于我们这里是使用的虚拟机克隆,worker也是从master克隆来的,所以这里不需要使用这个tar包,上述的保存镜像只是为以后做一个备份
4.4 初始化集群
「配置k8s集群网络」
#官网下载地址:
https://docs.projectcalico.org/v3.14/manifests/calico.yaml
#github地址:
https://github.com/projectcalico/calico复制「calico.yaml」
从上述两个网站中下载一个calico.yaml,上传至服务器
calico要注意和K8s的版本想匹配,不匹配会报错,可以通过以下官网地址查看版本信息
https://projectcalico.docs.tigera.io/archive/v3.20/getting-started/kubernetes/requirements
复制以下是我执行了不匹配的calico.yaml产生的报错信息
configmap/calico-config created
clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrole.rbac.authorization.k8s.io/calico-node created
clusterrolebinding.rbac.authorization.k8s.io/calico-node created
Warning: spec.template.metadata.annotations[scheduler.alpha.kubernetes.io/critical-pod]: non-functional in v1.16+; use the "priorityClassName" field instead
daemonset.apps/calico-node created
serviceaccount/calico-node created
deployment.apps/calico-kube-controllers created
serviceaccount/calico-kube-controllers created
unable to recognize "calico.yml": no matches for kind "CustomResourceDefinition" in version "apiextensions.k8s.io/v1beta1"
unable to recognize "calico.yml": no matches for kind "CustomResourceDefinition" in version "apiextensions.k8s.io/v1beta1"
unable to recognize "calico.yml": no matches for kind "CustomResourceDefinition" in version "apiextensions.k8s.io/v1beta1"
unable to recognize "calico.yml": no matches for kind "CustomResourceDefinition" in version "apiextensions.k8s.io/v1beta1"
unable to recognize "calico.yml": no matches for kind "CustomResourceDefinition" in version "apiextensions.k8s.io/v1beta1"
unable to recognize "calico.yml": no matches for kind "CustomResourceDefinition" in version "apiextensions.k8s.io/v1beta1"
unable to recognize "calico.yml": no matches for kind "CustomResourceDefinition" in version "apiextensions.k8s.io/v1beta1"
unable to recognize "calico.yml": no matches for kind "CustomResourceDefinition" in version "apiextensions.k8s.io/v1beta1"
unable to recognize "calico.yml": no matches for kind "CustomResourceDefinition" in version "apiextensions.k8s.io/v1beta1"
unable to recognize "calico.yml": no matches for kind "CustomResourceDefinition" in version "apiextensions.k8s.io/v1beta1"
unable to recognize "calico.yml": no matches for kind "CustomResourceDefinition" in version "apiextensions.k8s.io/v1beta1"
unable to recognize "calico.yml": no matches for kind "CustomResourceDefinition" in version "apiextensions.k8s.io/v1beta1"
unable to recognize "calico.yml": no matches for kind "CustomResourceDefinition" in version "apiextensions.k8s.io/v1beta1"
unable to recognize "calico.yml": no matches for kind "CustomResourceDefinition" in version "apiextensions.k8s.io/v1beta1"
unable to recognize "calico.yml": no matches for kind "CustomResourceDefinition" in version "apiextensions.k8s.io/v1beta1"复制「镜像下载」
docker pull calico/cni:v3.14.2
docker pull calico/pod2daemon-flexvol:v3.14.2
docker pull calico/node:v3.14.2
docker pull calico/kube-controllers:v3.14.2复制
「到这里集群初始化就完成了,我们可以给此时的虚拟机打一个快照,留作备份,然后基于这个服务器克隆两个工作节点,然后通过当前的服务器和两个工作节点启动集群」
4.5 启动K8S集群
「配置工作节点」
从K8S- master-01-150节点中克隆出两个工作节点,分别按照上述方法修改虚拟机的IP和hostname。
「初始化集群信息:calico网络」
在master节点的calico.yaml问价所在目录下执行以下命令,初始化集群
#注意 192.168.204.180 是master的Ip v1.23.3 是上面安装的K8s的版本
kubeadm init --apiserver-advertise-address=192.168.204.180 --kubernetes-version v1.17.5 --service-cidr=10.1.0.0/16 --pod-network-cidr=10.81.0.0/16复制如果执行报错/proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1
「解决方法」
echo "1" >/proc/sys/net/bridge/bridge-nf-call-iptables
#如果执行上面的命令后提示没有这个文件,则继续执行下面的命令:modprobe br_netfilter
#执行后再执行上面的echo命令复制「master节点执行配置命令」
这是存放秘钥鉴权的东西的,master用来管理集群,颁发证书
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config复制「node节点加入集群信息」
分别在152 152两个节点执行以下命令,将他们加入集群
kubeadm join 192.168.204.150:6443 --token oaz0tj.1440sfhpjnabnfhj \
--discovery-token-ca-cert-hash sha256:0ad526160551eff1dbbab5467fe53658a872671e50fb1c0ce500474cced2d7f5复制如果加入节点报错,
一般第一次部署不会出现这个错误,只有在同一个服务器重复安装K8S的的时候,才会报这个错,解决方法如下
#删除k8s配置文件
rm -f /etc/kubernetes/kubelet.conf
#删除K8S证书
rm -f /etc/kubernetes/pki/ca.crt
#重启docker
systemctl restart docker
#重启kubeadm
kubeadm reset
#重启服务,也可以不重启试试
reboot
#然后重新加入master节点
kubeadm join 192.168.204.150:6443 --token oaz0tj.1440sfhpjnabnfhj \
--discovery-token-ca-cert-hash sha256:0ad526160551eff1dbbab5467fe53658a872671e50fb1c0ce500474cced2d7f5复制「查看集群节点」
#master节点执行
kubectl get nodes复制「初始化集群网络」
# 进入刚才上传calico.yaml的目录,初始化集群网络 master节点执行
kubectl apply -f calico.yaml
#或者直接执行,注意版本 v3.20要跟K8s的版本相匹配
curl https://docs.projectcalico.org/v3.20/manifests/calico.yaml -O复制「再次查看集群节点」
#master节点执行 执行网络初始化后等个一两分钟,再次查看
kubectl get nodes复制
4.6 加餐
「kubectl命令自动补全」
echo "source <(kubectl completion bash)" >> ~/.bash_profile
source ~/.bash_profile复制