当前位置 博文首页 > RtxTitanV的博客:kubeadm部署v1.18.5版Kubernetes集群
本文主要对使用kubeadm部署Kubernetes集群进行总结。使用三台虚拟机来部署一个单Master节点的Kubernetes集群,Kubernetes版本选择的是v1.18.5
。
控制平面节点:
协议 | 方向 | 端口范围 | 作用 | 使用者 |
---|---|---|---|---|
TCP | 入站 | 6443* | Kubernetes API服务器 | 所有组件 |
TCP | 入站 | 2379-2380 | etcd server client API | kube-apiserver,etcd |
TCP | 入站 | 10250 | Kubelet API | kubelet自身、控制平面组件 |
TCP | 入站 | 10251 | kube-scheduler | kube-scheduler自身 |
TCP | 入站 | 10252 | kube-controller-manager | kube-controller-manager自身 |
工作节点:
协议 | 方向 | 端口范围 | 作用 | 使用者 |
---|---|---|---|---|
TCP | 入站 | 10250 | Kubelet API | kubelet自身、控制平面组件 |
TCP | 入站 | 30000-32767 | NodePort服务 | 所有组件 |
注意事项:
*
标记的任意端口号都可以被覆盖,所以需要保证所定制的端口是开放的。准备三台网络互通并能上外网的主机,这里使用的是三台虚拟机。本文所使用的环境如下:
主机名 | ip | 操作系统 | Docker | kubernetes | kubeadm | kubectl | kubelet | flannel | 配置 | 备注 |
---|---|---|---|---|---|---|---|---|---|---|
k8s-master | 192.168.1.16 | CentOS Linux release 8.2.2004 | 19.03.12 | v1.18.5 | 1.18.5 | 1.18.5 | 1.18.5 | v0.12.0-amd64 | 4C4G | k8s控制平面节点(control plane) |
k8s-node1 | 192.168.1.17 | CentOS Linux release 8.2.2004 | 19.03.12 | v1.18.5 | 1.18.5 | 1.18.5 | 1.18.5 | / | 4C4G | k8s工作节点(worker node) |
k8s-node2 | 192.168.1.18 | CentOS Linux release 8.2.2004 | 19.03.12 | v1.18.5 | 1.18.5 | 1.18.5 | 1.18.5 | / | 4C2G | k8s工作节点(worker node) |
除特殊说明的地方外,在control plane和work节点都执行本部分操作。
cat /sys/class/net/ens160/address
cat /sys/class/dmi/id/product_uuid
k8s-master
主机:
k8s-node1
主机:
k8s-node2
主机:
各节点mac和uuid唯一。
设置主机名:
hostnamectl set-hostname <hostname>
退出重新登陆即可显示新设置的主机名。下面修改hosts
文件:
cat >> /etc/hosts << EOF
192.168.1.16 k8s-master
192.168.1.17 k8s-node1
192.168.1.18 k8s-node2
EOF
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
yum install -y wget
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-8.repo
systemctl stop firewalld && systemctl disable firewalld
临时禁用:
swapoff -a
永久禁需要在临时禁用后修改配置文件/etc/fstab
,注释swap:
sed -i.bak '/swap/s/^/#/' /etc/fstab
已禁用:
临时关闭:
setenforce 0
永久关闭需将SELinux设置为disabled:
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
重启系统,查看SELinux配置,成功关闭:
设置系统时区为亚洲/上海,如果安装时设置过,则跳过:
timedatectl set-timezone Asia/Shanghai
如未安装chrony,执行以下命令安装
yum install -y chrony
时间同步:
systemctl enable --now chronyd
查看同步状态:
timedatectl status
System clock synchronized: yes
表示时钟已同步,NTP service: active
表示开启了时钟同步服务:
将当前的UTC 时间写入硬件时钟:
timedatectl set-local-rtc 0
重启依赖于系统时间的服务:
systemctl restart rsyslog && systemctl restart crond
在修改下面的内核参数之前需确保加载了br_netfilter
模块。执行以下命令查看br_netfilter
模块:
lsmod | grep br_netfilter
如果系统没有br_netfilter
模块则执行下面的新增br_netfilter
模块的命令,有则跳过。执行以下命令临时新增br_netfilter
模块:
modprobe br_netfilter
该方式重启后会失效。想要永久新增br_netfilter
模块需执行以下命令:
cat > /etc/rc.sysinit << EOF
#!/bin/bash
for file in /etc/sysconfig/modules/*.modules ; do
[ -x $file ] && $file
done
EOF
cat > /etc/sysconfig/modules/br_netfilter.modules << EOF
modprobe br_netfilter
EOF
chmod 755 /etc/sysconfig/modules/br_netfilter.modules
重启后不会失效,永久新增了br_netfilter
模块。然后添加需要的内核参数,临时新增以下内核参数:
sysctl net.bridge.bridge-nf-call-iptables=1
sysctl net.bridge.bridge-nf-call-ip6tables=1
sysctl net.ipv4.ip_forward=1
永久新增以下内核参数:
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 --system
新增内核参数刷新生效:
验证是否生效:
sysctl -n net.bridge.bridge-nf-call-ip6tables
sysctl -n net.bridge.bridge-nf-call-iptables
sysctl -n net.ipv4.ip_forward
重启系统后验证是否生效,返回1
表示生效:
由于k8s已经支持了ipvs,为了kube-proxy开启ipvs需要加载以下模块,执行以下命令:
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
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
查看是否已经正确加载所需的内核模块:
lsmod | grep -e ipvs -e nf_conntrack_ipv4
所需模块已加载:
安装ipset软件包和管理工具ipvsadm:
yum install -y ipset ipvsadm
配置k8s-master主机到k8s-node1和k8s-node2主机的免密登录,本步骤只在k8s-master
上执行。首先创建秘钥:
ssh-keygen -t rsa
将公钥同步至k8s-node1
和k8s-node2
:
ssh-copy-id -i ~/.ssh/id_rsa.pub root@k8s-node1
ssh-copy-id -i ~/.ssh/id_rsa.pub root@k8s-node2
免密登录:
ssh root@k8s-node1
ssh root@k8s-node2
在control plane和work节点都执行本部分操作。
安装19.03.12
版本的Docker:
sudo yum update -y \
&& sudo yum install -y yum-utils device-mapper-persistent-data lvm2 \
&& sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo \
&& yum install -y https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/edge/Packages/containerd.io-1.2.13-3.2.el7.x86_64.rpm \
&& sudo yum install -y docker-ce-19.03.12 \
&& sudo systemctl start docker \
&& sudo systemctl enable docker
安装bash-completion:
yum install -y bash-completion
加载bash-completion:
source /etc/profile.d/bash_completion.sh
root用户可跳过,非root用户执行以下命令加入docker
用户组:
sudo usermod -aG docker $USER
newgrp docker
如下配置Docker:
cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://ncq2ty7z.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
}
}
EOF
重新加载配置并重启Docker:
sudo systemctl daemon-reload && sudo systemctl restart docker
验证Docker是否安装启动成功:
docker version
docker -v
systemctl status docker
安装成功:
启动成功:
在control plane和work节点都执行本部分操作。
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=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
[]
:中括号中是repository的id,唯一,用来标识不同仓库。name
:仓库名称。baseurl
:仓库地址。enable
:是否启用该仓库,默认为1表示启用。gpgcheck
:是否验证从该仓库获得程序包的合法性,1为验证。repo_gpgcheck
:是否验证元数据的合法性,1为验证。gpgkey
:数字签名的公钥所在位置,如果gpgcheck
值为1,此处就需要指定gpgkey
文件的位置,如果gpgcheck
值为0就不需要此项了。执行以下命令安装1.18.5
版kubeadm、kubelet和kubectl:
yum install -y kubeadm-1.18.5 kubelet-1.18.5 kubectl-1.18.5
设置kubelet开机自启:
systemctl enable kubelet
echo "source <(kubectl completion bash)" >> ~/.bash_profile
source .bash_profile
到这里可以拷贝一份虚拟机镜像保存,便于部署k8s集群。
除特殊说明的地方外,在k8s-master
节点执行本部分操作。
准备了科学上网可略过此步骤。由于国内网络原因,如果没有科学上网则无法直接从k8s.gcr.io拉取镜像。最简单的方式是初始化时通过
--image-repository registry.aliyuncs.com/google_container
指定阿里云镜像仓库,但是阿里云仓库暂时只更新到v1.18.3版本,指定阿里云仓库暂时只能使用v1.18.3及以下版本。本文使用v1.18.5版本,所以需要从国内镜像库或Docker Hub用户仓库提前拉取。
查看指定k8s版本需要的镜像:
kubeadm config images list --kubernetes-version v1.18.5
创建一个k8s目录并新建一个脚本:
mkdir -p /usr/local/k8s
vi /usr/local/k8s/k8s-images.sh
脚本内容如下:
#!/bin/bash
# 拉取镜像并打标签
KUBE_VERSION=v1.18.5
PAUSE_VERSION=3.2
ETCD_VERSION=3.4.3-0
COREDNS_VERSION=1.6.7
# 拉取镜像
docker pull kubeimage/kube-apiserver-amd64:$KUBE_VERSION
docker pull kubeimage/kube-controller-manager-amd64:$KUBE_VERSION
docker pull kubeimage/kube-scheduler-amd64:$KUBE_VERSION
docker pull kubeimage/kube-proxy-amd64:$KUBE_VERSION
docker pull registry.aliyuncs.com/google_containers/pause:$PAUSE_VERSION
docker pull registry.aliyuncs.com/google_containers/etcd:$ETCD_VERSION
docker pull registry.aliyuncs.com/google_containers/coredns:$COREDNS_VERSION
# 标签打上k8s.gcr.io前缀
docker tag kubeimage/kube-apiserver-amd64:$KUBE_VERSION k8s.gcr.io/kube-apiserver:$KUBE_VERSION
docker tag kubeimage/kube-controller-manager-amd64:$KUBE_VERSION k8s.gcr.io/kube-controller-manager:$KUBE_VERSION
docker tag kubeimage/kube-scheduler-amd64:$KUBE_VERSION k8s.gcr.io/kube-scheduler:$KUBE_VERSION
docker tag kubeimage/kube-proxy-amd64:$KUBE_VERSION k8s.gcr.io/kube-proxy:$KUBE_VERSION
docker tag registry.aliyuncs.com/google_containers/pause:$PAUSE_VERSION k8s.gcr.io/pause:$PAUSE_VERSION
docker tag registry.aliyuncs.com/google_containers/etcd:$ETCD_VERSION k8s.gcr.io/etcd:$ETCD_VERSION
docker tag registry.aliyuncs.com/google_containers/coredns:$COREDNS_VERSION k8s.gcr.io/coredns:$COREDNS_VERSION
# 删除打标签之前拉取的镜像
docker rmi kubeimage/kube-apiserver-amd64:$KUBE_VERSION
docker rmi kubeimage/kube-controller-manager-amd64:$KUBE_VERSION
docker rmi kubeimage/kube-scheduler-amd64:$KUBE_VERSION
docker rmi kubeimage/kube-proxy-amd64:$KUBE_VERSION
docker rmi registry.aliyuncs.com/google_containers/pause:$PAUSE_VERSION
docker rmi registry.aliyuncs.com/google_containers/etcd:$ETCD_VERSION
docker rmi registry.aliyuncs.com/google_containers/coredns:$COREDNS_VERSION
添加755权限并执行:
chmod 755 /usr/local/k8s/k8s-images.sh && /usr/local/k8s/k8s-images.sh
查看镜像:
kubeadm init \
--apiserver-advertise-address=192.168.1.16 \
--kubernetes-version v1.18.5 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
--apiserver-advertise-address
:指定与集群的其他节点通信的master的IP地址。--service-cidr
:指定Service网络的范围,即负载均衡使用的IP地址段。--pod-network-cidr
:指定Pod网络的范围,即Pod的IP地址段,使用flannel需指定为10.244.0.0/16
。--kubernetes-version
:指定kubernetes的版本号。初始化过程的输出如下:
输出内容主要有以下关键信息:
[init]
:指定版本进行初始化操作。[preflight]
:初始化前的检查和下载所需要的Docker镜像文件。[kubelet-start]
:生成kubelet的配置文件/var/lib/kubelet/config.yaml
,没有这个文件kubelet无法启动,所以初始化之前的kubelet启动会失败。[certs]
:生成Kubernetes使用的证书,存放在/etc/kubernetes/pki
目录。[kubeconfig]
:生成相关的KubeConfig 文件,存放在/etc/kubernetes
目录。[control-plane]
:使用/etc/kubernetes/manifests
目录中的yaml文件创建kube-apiserver、kube-controller-manager、kube-scheduler的静态pod。[etcd]
:使用/etc/kubernetes/manifest
目录中的yaml文件安装Etcd服务。[wait-control-plane]
:等待control-plan部署的Master组件启动。[apiclient]
:检查Master组件的健康状态。[uploadconfig]
:更新配置。[kubelet]
:使用configMap配置kubelet。[mark-control-plane]
:为当前节点打标签,打了角色Master和不可调度标签,这样默认就不会使用Master节点来运行Pod。[bootstraptoken]
:生成token记录下来,后面使用kubeadm join
往集群中添加节点时会用到。[addons]
:安装附加组件CoreDNS和kube-proxy。普通用户要运行kubectl,需要执行以下命令,这也是kubeadm init
输出的一部分:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
root
用户,执行以下命令:
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source .bash_profile
查看所有节点:
此时只有k8s-master
节点并且状态为NotReady,是因为还未安装网络插件,下面进行网络插件的安装,选择安装flannel插件。
由于raw.githubusercontent.com
无法访问,需先执行以下命令修改hosts
文件:
cat >> /etc/hosts << EOF
151.101.76.133 raw.githubusercontent.com
EOF
在k8s-master
上新建flannel网络,可以直接执行以下命令新建:
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
也可以先将flannel配置文件下载下来再新建,这里使用这种方式:
wget -P /usr/local/k8s https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f /usr/local/k8s/kube-flannel.yml
再次查看节点已经Ready:
如果使用了科学上网或指定的阿里云仓库部署的v1.18.3及以下版本的k8s,备份镜像是可选的。由于是使用的v1.18.5的k8s,work节点需要用到其中的部分镜像,由于网络原因无法拉取,需要导出镜像并传到work节点加载。
将镜像导出备份:
docker save -o /usr/local/k8s/k8s-images-v1.18.5.tar \
k8s.gcr.io/kube-proxy:v1.18.5 \
k8s.gcr.io/kube-apiserver:v1.18.5 \
k8s.gcr.io/kube-controller-manager:v1.18.5 \
k8s.gcr.io/kube-scheduler:v1.18.5 \
k8s.gcr.io/pause:3.2 \
k8s.gcr.io/coredns:1.6.7 \
k8s.gcr.io/etcd:3.4.3-0 \
quay.io/coreos/flannel:v0.12.0-amd64
导出成功:
在work节点创建目录用于存放镜像备份:
mkdir -p /usr/local/k8s
在k8s-master
执行以下命令将镜像备份拷贝到work节点:
scp -r /usr/local/k8s/k8s-images-v1.18.5.tar root@k8s-node1:/usr/local/k8s/
scp -r /usr/local/k8s/k8s-images-v1.18.5.tar root@k8s-node2:/usr/local/k8s/
然后在work节点加载镜像:
docker load -i /usr/local/k8s/k8s-images-v1.18.5.tar
加载成功:
除特殊说明的地方外,在work节点执行本部分操作。在work节点执行以下命令将其加入到k8s集群,该命令也是kubeadm init
输出的一部分:
kubeadm join 192.168.1.16:6443 --token f5d1i5.por52kags01avsz7 \
--discovery-token-ca-cert-hash sha256:15171b3d8414d244ef63759fbf2c3006ade34ff081f4a0381329ddc64f249b75
如果没有保存这个命令可以使用以下命令创建新的token并生成一个新的加入集群命令:
kubeadm token create --print-join-command
k8s-node1
加入集群成功:
k8s-node2
加入集群成功:
在master节点上查看集群状态。首先查看k8s组件健康状态,如下图所示,每个组件都处于healthy状态: