文章目录
- 集群类型
- 主机规划
- 环境初始化
- 检查操作系统版本
- 关闭防火墙
- 设置主机名
- 主机名解析
- 时间同步
- 关闭 SELinux
- 关闭 swap 分区
- 将桥接的IPv4流量传递到iptables的链
- 开启ipvs
- 安装容器运行时(Docker)
- 卸载Docker旧版本:
- 安装 gcc 相关
- 安装Docker
- 设置阿里云镜像加速
- 安装kubernetes基础环境
- 添加阿里云的YUM软件源
- 安装 kubelet 、kubeadm 和 kubectl
- 下载 Kubernetes 安装所需镜像
- 部署Master节点
- 部署Node节点
- 部署CNI网络插件
- 查看节点状态
- 完全卸载Kubectl环境
- 常见问题解决方案
kubernetes有多种部署方式,目前主流的方式有kubeadm、minikube、二进制包。本文基于kubeadm安装。
集群类型
- Kubernetes集群大致分为两类:一主多从和多主多从。
- 一主多从:一个Master节点和多个Node节点,搭建简单,但是有单机故障风险(Master),适合测试环境。
- 多主多从:多台Master节点和多台Node节点,搭建复杂,安全性高,适用于生产环境。
主机规划
本次环境搭建需要三台CentOS服务器(一主二从),然后在每台服务器中分别安装Docker(20.10.0)、kubeadm(1.21.10)、kubectl(1.21.10)和kubelet(1.21.10)。
角色 | IP地址 | 操作系统 | 配置 |
---|---|---|---|
Master | 172.16.11.12 | CentOS7.8+,基础设施服务器 | 72核CPU,62G内存,1TB硬盘 |
node1 | 172.16.11.13 | CentOS7.8+,基础设施服务器 | 72核CPU,62G内存,1TB硬盘 |
node2 | 172.16.11.14 | CentOS7.8+,基础设施服务器 | 72核CPU,62G内存,1TB硬盘 |
环境初始化
检查操作系统版本
- 检查操作系统版本
cat /etc/redhat-release
- 要求操作系统的版本至少在7.5以上,如果版本低于7.5,需要升级系统内核。
关闭防火墙
- 关闭防火墙:
systemctl stop firewalld
- 禁止防火墙开机启动:
systemctl disable firewalld
设置主机名
hostnamectl set-hostname <hostname>
# 设置 172.16.11.12 的主机名
hostnamectl set-hostname Master
# 设置 172.16.11.13 的主机名
hostnamectl set-hostname node1
# 设置 172.16.11.14 的主机名
hostnamectl set-hostname node2
主机名解析
- 集群节点间的直接调用,需要在hosts (/etc/hosts)配置一下主机名解析。
cat >> /etc/hosts << EOF
172.16.11.12 master
172.16.11.13 node1
172.16.11.14 node2
EOF
时间同步
- kubernetes要求集群中的节点时间必须精确一致,所以在每个节点上添加时间同步:
yum install ntpdate -y
ntpdate time.windows.com
关闭 SELinux
SELinux(Security-Enhanced Linux) 是美国国家安全局(NSA)对于强制访问控制的实现,是 Linux历史上最杰出的新安全子系统。
- 查看selinux是否开启:
getenforce
- 永久关闭 SELinux ,需要重启:
sed -i 's/enforcing/disabled/' /etc/selinux/config
- 临时关闭selinux,重启之后,无效:
setenforce 0
关闭 swap 分区
- 永久关闭 swap ,需要重启:
sed -ri 's/.*swap.*/#&/' /etc/fstab
- 关闭当前会话的 swap ,重启之后无效:
swapoff -a
将桥接的IPv4流量传递到iptables的链
- 修改 /etc/sysctl.conf 文件:
# 如果有配置,则修改
sed -i "s#^net.ipv4.ip_forward.*#net.ipv4.ip_forward=1#g" /etc/sysctl.conf
sed -i "s#^net.bridge.bridge-nf-call-ip6tables.*#net.bridge.bridge-nf-call-ip6tables=1#g" /etc/sysctl.conf
sed -i "s#^net.bridge.bridge-nf-call-iptables.*#net.bridge.bridge-nf-call-iptables=1#g" /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.all.disable_ipv6.*#net.ipv6.conf.all.disable_ipv6=1#g" /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.default.disable_ipv6.*#net.ipv6.conf.default.disable_ipv6=1#g" /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.lo.disable_ipv6.*#net.ipv6.conf.lo.disable_ipv6=1#g" /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.all.forwarding.*#net.ipv6.conf.all.forwarding=1#g" /etc/sysctl.conf
# 可能没有,追加
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.lo.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.conf
# 加载br_netfilter模块
modprobe br_netfilter
# 查看是否加载
lsmod | grep br_netfilter
# 生效
sysctl --system
开启ipvs
-
在kubernetes中service有两种代理模型,一种是基于iptables,另一种是基于ipvs的。ipvs的性能要高于iptables的,但是如果要使用它,需要手动载入ipvs模块。
-
安装ipset和ipvsadm:
yum -y install ipset ipvsadm
- 执行如下脚本:
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
EOF
- 授权、运行、检查是否加载:
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
安装容器运行时(Docker)
卸载Docker旧版本:
sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine
安装 gcc 相关
yum -y install gcc
yum -y install gcc-c++
- 安装所需要的软件包
yum -y install yum-utils
安装Docker
- 设置 stable 镜像仓库
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 更新 yum 软件包索引
yum makecache fast
- 查看存储库中 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
- 启动 Docker
# 启动 Docker
systemctl start docker
# 开启自动启动
systemctl enable docker
- 验证 Docker 是否安装成功
docker version
设置阿里云镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{"exec-opts": ["native.cgroupdriver=systemd"], "registry-mirrors": ["https://du3ia00u.mirror.aliyuncs.com","https://hub-mirror.c.163.com","https://mirror.baidubce.com"],"live-restore": true,"log-driver":"json-file","log-opts": {"max-size":"500m", "max-file":"3"},"max-concurrent-downloads": 10,"max-concurrent-uploads": 5,"storage-driver": "overlay2"
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
安装kubernetes基础环境
添加阿里云的YUM软件源
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
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
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 文件的内容:
vi /etc/sysconfig/kubelet
# 修改
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"
- 设置为开机自启动即可,由于没有生成配置文件,集群初始化后自动启动:
systemctl enable kubelet
下载 Kubernetes 安装所需镜像
- 查看k8s所需镜像
kubeadm config images list
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
- coredns 镜像重新打 tag :
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.0 registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.0
注意:以上步骤kubernetes集群中的每个节点都需要执行,下面的步骤按节点执行。
部署Master节点
- 在 172.16.11.12 (Master)机器上部署 Kubernetes 的 Master 节点:
# 由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里需要指定阿里云镜像仓库地址
kubeadm init \--apiserver-advertise-address=172.16.11.12 \--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
注意:
- apiserver-advertise-address 一定要是主机的 IP 地址。
- apiserver-advertise-address 、service-cidr 和 pod-network-cidr 不能在同一个网络范围内。
- 不要使用 172.17.0.1/16 网段范围,因为这是 Docker 默认使用的。
根据提示消息,在Master节点上使用kubectl工具:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
部署Node节点
- 在 172.16.11.13 和 172.16.11.14 执行如下命令:
# 需要根据Master初始化完成后生成
kubeadm join 172.16.11.12:6443 --token tluojk.1n43p0wemwehcmmh \--discovery-token-ca-cert-hash sha256:c50b25a5e00e1a06cef46fa5d885265598b51303f1154f4b582e0df21abfa7cb
- 默认的 token 有效期为 2 小时,当过期之后,该 token 就不能用了,这时可以使用如下的命令在Master创建 token :
kubeadm token create --print-join-command
# 生成一个永不过期的token
kubeadm token create --ttl 0 --print-join-command
部署CNI网络插件
- Kubernetes 支持多种网络插件,比如 flannel、calico、canal 等,任选一种即可,本次选择 calico(在 172.16.11.12 Master节点上执行)。
wget https://projectcalico.docs.tigera.io/v3.19/manifests/calico.yaml
kubectl apply -f calico.yaml
- 查看部署 CNI 网络插件进度:
kubectl get pods -n kube-system
watch kubectl get pods -n kube-system
查看节点状态
kubectl get nodes
默认情况下,只有 Master 节点才有 kubectl 命令。
如果上述操作完成后,还存在某个节点处于 NotReady 状态,可以在 Master 将该节点删除。
# 将 node1 节点删除 【master 节点上操作】
kubectl delete node node1# 将 node1 节点进行重置【在 node1 节点上操作】
kubeadm reset
# 将 node1 节点加入集群【在 node1 节点上操作】
kubeadm join 172.16.11.12:6443 --token tluojk.1n43p0wemwehcmmh \--discovery-token-ca-cert-hash sha256:c50b25a5e00e1a06cef46fa5d885265598b51303f1154f4b582e0df21abfa7cb
完全卸载Kubectl环境
sudo yum remove -y kubelet kubeadm kubectl
kubeadm reset -f
modprobe -r ipip
lsmod
sudo rm -rf ~/.kube/
sudo rm -rf /etc/kubernetes/
sudo rm -rf /etc/systemd/system/kubelet.service.d
sudo rm -rf /etc/systemd/system/kubelet.service
sudo rm -rf /usr/bin/kube*
sudo rm -rf /etc/cni
sudo rm -rf /opt/cni
sudo rm -rf /var/lib/etcd
sudo rm -rf /var/etcd
常见问题解决方案
- 查看kubelet状态
systemctl status kubelet
- 查看kubelet系统日志
journalctl -xefu kubelet
错误一
- 在给 node1 节点使用
kubeadm join
命令的时候,出现以下错误
error execution phase preflight: [preflight] Some fatal errors occurred:[ERROR Swap]: running with swap on is not supported. Please disable swap
- 错误原因是我们需要关闭 swap【可能是永久关闭 swap 时没有重启生效】
# 关闭 swap
# 临时关闭【立即生效】
swapoff -a
# 永久关闭【重启生效】
sed -ri 's/.*swap.*/#&/' /etc/fstab
错误二
- 在给 node 节点使用
kubeadm join
命令的时候,出现以下错误
The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get http://localhost:10248/healthz: dial tcp [::1]:10248: connect: connection refused
- Docker是用yum安装的,docker的cgroup驱动程序默认设置为system。默认情况下Kubernetes cgroup为systemd,我们需要更改Docker cgroup驱动。
vim /etc/docker/daemon.json{"exec-opts": ["native.cgroupdriver=systemd"]
}
# 重启docker
systemctl restart docker
错误三
- 部署CNI网络插件之后,使用
kubectl get pod -n kube-system
发现有calico的pod启动不成功。使用kubectl describe pod calico-node-gdkvg -n kube-system
查看pod,发现pod出现以下错误。
calico/node is not ready: BIRD is not ready: BGP not established withxxx
- 使用
ifconfig
查看集群机器台机器的网卡分别是 enp6s0, eno1 发现都是 en开头 然后修改 calico 的配置文件:
kubectl edit daemonset calico-node -n kube-system
- 对应位置,增加以下配置:(注意这儿需要根据自己的网卡前缀具体修改)
- name: IP_AUTODETECTION_METHODvalue: interface=ens*
- 修改后的配置文件为:
-
稍等一两分钟,calico的pod也就处于ready状态了。
-
持续补充中…
你知道的越多,你不知道的越多。