掘金 后端 ( ) • 2022-08-12 17:21

theme: nico

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情

前言

之前安装`k8s集群`都是在同一网段内,关闭防火墙后就不涉及到`网卡`跟`DNS`等网络对集群的影响,但是在`跨区域`的网络上进行安装`k8s集群`如果没有配置局域网络映射可能会遇到各种问题

比如以下几种问题

  • etcd无法启动
● etcd.service - etcd
   Loaded: loaded (/etc/systemd/system/etcd.service; disabled; vendor preset: disabled)
   Active: activating (auto-restart) (Result: exit-code) since 四 2022-08-11 14:17:50 CST; 7s ago
  Process: 52811 ExecStart=/usr/local/bin/etcd (code=exited, status=1/FAILURE)
 Main PID: 52811 (code=exited, status=1/FAILURE)

8月 11 14:17:50 master etcd[52811]: [WARNING] Deprecated '--logger=capnslog' flag is set; use '--logger=zap' flag instead
8月 11 14:17:50 master systemd[1]: etcd.service: main process exited, code=exited, status=1/FAILURE
8月 11 14:17:50 master systemd[1]: Failed to start etcd.
8月 11 14:17:50 master systemd[1]: Unit etcd.service entered failed state.
8月 11 14:17:50 master systemd[1]: etcd.service failed.
  • 非同区域节点无法加入集群
[init] Using Kubernetes version: v1.20.9
[preflight] Running pre-flight checks
[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/
[WARNING SystemVerification]: this Docker version is not on the list of validated versions: 20.10.7. Latest validated version: 19.03
[WARNING Hostname]: hostname "docker-master" could not be reached
[WARNING Hostname]: hostname "docker-master": lookup docker-master on 183.60.83.19:53: no such host
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR FileContent--proc-sys-net-ipv4-ip_forward]: /proc/sys/net/ipv4/ip_forward contents are not set to 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
  • 节点配置加入超时
[kubelet-check] Initial timeout of 40s passed.
  • iptables的代理设置要求为1
# [ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1
  • 节点为NotReady状态
[root@k8s-master ~]# kubectl get node
NAME         STATUS     ROLES    AGE     VERSION
master       Ready      <none>   7d22h   v1.18.6
node1        Ready      <none>   7d21h   v1.18.6
node2        NotReady   <none>   7d21h   v1.18.6

正常下我们的K8s集群都是在同网段部署的,我为什么有此需求,是因为我买服务器一台买到了`上海`,剩下的买到了`北京`\`(ㄒoㄒ)`,干什么事情总有一台孤零零的,太可怜,所以今天将它也加入k8s大家庭。

配置

服务器配置为:

名称 CPU 内存 硬盘 操作系统 网络(公网ip) master 2核 4GB 60GB Centos7.6 x.x.26.152 node1 2核 4GB 60GB Centos7.6 x.x.30.146 node2 2核 2GB 50GB Centos7.6 x.x.166.136 node3 2核 4GB 60GB Centos7.6 x.x.209.244

1. 基础环境配置(所有节点全部执行

1.1 关闭防火墙

systemctl stop firewalld

1.2 关闭 selinux

sed -i 's/enforcing/disabled/' /etc/selinux/config

1.3 关闭swap

echo "vm.swappiness = 0">> /etc/sysctl.conf 
swapoff -a && swapon -a
sysctl -p

1.4 设置主机名称

  • master节点
hostnamectl set-hostname k8s-master
  • node1节点
hostnamectl set-hostname k8s-node1
  • node2节点
hostnamectl set-hostname k8s-node2
  • node3节点
hostnamectl set-hostname k8s-node3

1.5 修改hosts(注意:修改自己的内网ip)

编辑hosts文件

vim /etc/hosts

在配置hosts配置文件最下方添加公网ip映射

x.x.26.152 k8s-master
x.x.30.146 k8s-node1
x.x.166.136 k8s-node2
x.x.209.244 k8s-node3

1.6 将桥接的 IPv4 流量传递到 iptables 的链

cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system # 刷新生效

1.7 时间同步

yum install ntpdate -y
 
ntpdate time.windows.com

1.2 安装docer (所有节点全部执行

下载docker源并安装docker

wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
 
yum -y install docker-ce-18.06.1.ce-3.el7
 
systemctl enable docker && systemctl start docker
 
docker --version

1.3 安装kubeadm、kubelet 、 kubectl(所有节点全部执行)

1.3.1 添加阿里云 YUM 软件源

cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
} 
EOF

1.3.2 添加 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

1.3.3 安装 kubeadm, kubelet 和 kubectl

yum install -y kubelet-1.17.3 kubectl-1.17.3 kubeadm-1.17.3 
 
systemctl enable kubelet

1.4 启动master节点

这一步只需要master节点执行即可,跨区域配置集群的重点就在这里,在初始化master的时候因为网卡问题会卡在etcd初始化的步骤,在出现超时提示时按照下面的解决办法进行修改配置,要在重试次数内完成,否则重试次数用尽会报失败退出初始化。

1.4.1 初始化master节点

参数解释

  • apiserver-advertise-address 是集群master节点的公网ip。
  • service-cidr 是service网段。
  • pod-network-cidr 是Pod网段。

执行以下命令使用kubeadm进行初始化

kubeadm init \
--apiserver-advertise-address=【公网ip】 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.17.3 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16

`执行完上面的初始化脚本后会卡在 etcd 初始化的位置,因为 etcd 绑定端口的时候使用外网 IP,而云服务器外网 IP 并不是本机的网卡,而是网关分配的一个供外部访问的 IP,从而导致初始化进程一直重试绑定,长时间卡住后失败。`

如下图示:

image.png

这时候就需要另开一个master的命令行窗口进行修改初始化生成的 `etcd.yaml` 文件,修改内容如下图`红框内的配置第一行跟第三行`,将ip配置修改为`0.0.0.0`,修改完成尽快保存进程会自动重试并初始化成功。

image.png

修改完成后切回执行初始化的命令行等待初始化完成后得到如下图的一个命令,这个命令在其他节点加入集群时使用

image.png

1.4.2 使用 kubectl 工具

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

1.4.4 安装pod网络插件

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

1.5 加入集群

1.5.1 加入集群

上面执行完成后得到了一行命令:

kubeadm join 0.0.0.0:6443 --token 6fx4v6.2urvjr85b22ftz5j \
    --discovery-token-ca-cert-hash sha256:eb6a611ce96435a849a1ac3d6bf9cab211e37f4279745729eb651df363bd4f0f 

别复制上面的命令,复制自己得到的命令在工作节点执行即可加入集群

1.5.2 重新获取join命令

如果忘记加入命令或者加入命令过期,在master节点重新执行以下命令获取新的join命令

kubeadm token create --print-join-command

得到如下图命令在其他节点执行

image.png

1.5.3 验证

工作节点执行命令后如下图

image.png

master节点执行以下命令获取节点状态

image.png

状态都为Ready即为加入成功

1.5.4 创建pod (master节点执行)

查询现有的pod:

kubectl get pod,svc

创建一个新的nginx的pod

kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get pod,svc

如下图,新建了一个pod,创建成功

image.png

部署成功后需要测试访问一下nginx,80对外映射的端口从图上看是30911,根据ip再找到节点,外部访问就是节点ip:30911端口,如果是云服务器一定要设置防火墙端口的开放。

如下图即访问成功,nginx部署成功


如果需要安装k8s官方的可视化页面dashboard,请看此篇文章的第二节:Linux傻瓜式安装k8s