k8s v1.30.1 高可用版本搭建

本文将介绍如何搭建 1.30.1 版本的 k8s。

在开始前需要先准备以下 5 台服务器,将搭建一个高可用版本的 k8s。

节点 IP Hostname OS
master01 192.168.8.148 master01 Centos7
master02 192.168.8.149 master02 Centos7
master03 192.168.8.150 master03 Centos7
worker01 192.168.8.151 worker01 Centos7
worker02 192.168.8.152 worker02 Centos7
VIP 192.168.8.153

初始化节点

在安装 k8s 之前,需要对每台服务器做以下操作:

  • 修改主机名称和修改 /etc/hosts 文件
  • 修改内核参数
  • 关闭防火墙和 selinux
  • 关闭 swap
  • 安装 containerd、nerdctl、kubeadm、kubelet 和 kubectl 软件
  • 配置 containerd 和 nerdctl

修改 hostname

在每台服务器上面分别执行以下命令来修改 hostname :

##每条命令在对应的服务器上单独执行
hostnamectl set-hostname master01 
hostnamectl set-hostname master02
hostnamectl set-hostname master03
hostnamectl set-hostname worker01
hostnamectl set-hostname worker02

验证命令如下:

cat /etc/hostname 

当 5 台节点对应输出如下时,代表 hostname 设置成功:

master01
master02
master03
worker01
worker02

修改 /etc/hosts 文件可以在每台服务器上执行下命令:

##在每台服务器上执行以下全部内容
echo "192.168.8.148 master01" | sudo tee -a /etc/hosts
echo "192.168.8.149 master02" | sudo tee -a /etc/hosts
echo "192.168.8.150 master03" | sudo tee -a /etc/hosts
echo "192.168.8.151 worker01" | sudo tee -a /etc/hosts
echo "192.168.8.152 worker02" | sudo tee -a /etc/hosts

执行 cat /etc/hosts 命令输出为以下内容,代表命令执行成功:

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.8.148 master01
192.168.8.149 master02
192.168.8.150 master03
192.168.8.151 worker01
192.168.8.152 worker02

关闭防火墙和 selinux

执行以下命名关闭 selinux 和 防火墙

##在每台服务器上执行以下全部内容
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
getenforce
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

验证防护墙是否关闭,可以执行 systemctl status firewalld,结果为以下内容代表命令执行成功:

● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)

Jun 09 15:28:05 localhost.localdomain systemd[1]: Starting firewalld - dynamic firewall daemon...
Jun 09 15:28:07 localhost.localdomain systemd[1]: Started firewalld - dynamic firewall daemon.
Jun 09 15:38:01 localhost.localdomain systemd[1]: Stopping firewalld - dynamic firewall daemon...
Jun 09 15:38:02 localhost.localdomain systemd[1]: Stopped firewalld - dynamic firewall daemon.

验证 selinux 是否关闭,执行 cat /etc/selinux/config,看到以下内容代表命令执行成功:

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

关闭 swap 和修改内核参数

执行以下命令注释掉 /etc/fstab 中有关 swap 的部分:

##在每台服务器上执行以下全部内容
swapoff -a
sed -i '/\/dev\/mapper\/centos-swap/s/^/#/' /etc/fstab

执行 cat /etc/fstab 输出内容如下代表命令执行成功:


#
# /etc/fstab
# Created by anaconda on Sun Jun  9 15:20:46 2024
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=94b19fa5-aabb-4af1-ad6b-766ab521f136 /boot                   xfs     defaults        0 0
#/dev/mapper/centos-swap swap                    swap    defaults        0 0

执行以下命令进行内核参数的修改:

modprobe ip_vs
modprobe nf_conntrack_ipv4
modprobe bridge
modprobe br_netfilter
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 >  /proc/sys/net/bridge/bridge-nf-call-iptables
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf
sysctl -p

执行以下命令进行验证:

lsmod | grep ip_vs
lsmod | grep ipv4
lsmod | grep bridge

输出以下内容代表内核加载成功:

[root@ ~]# lsmod | grep ip_vs
ip_vs                 145497  0
nf_conntrack          139224  2 ip_vs,nf_conntrack_ipv4
libcrc32c              12644  3 xfs,ip_vs,nf_conntrack
[root@ ~]# lsmod | grep ipv4
nf_conntrack_ipv4      15053  0
nf_defrag_ipv4         12729  1 nf_conntrack_ipv4
nf_conntrack          139224  2 ip_vs,nf_conntrack_ipv4
[root@ ~]# lsmod | grep bridge
bridge                151336  1 br_netfilter
stp                    12976  1 bridge
llc                    14552  2 stp,bridge

安装软件

除了要装 containerd、nerdctl、kubectl、kubeadm 和 kubelet 这些软件之外,还需要安装一下 net-tools、wget 和 vim 软件。

执行以下命令进行安装:

## 修改镜像源
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo

## 安装 containerd
yum install -y yum-utils device-mapper-persistent-data lvm2 vim net-tools wget
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
yum install containerd -y

## 安装 kubeadm kubelet 和 kubectl
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable kubelet
## 安装 nerdctl
wget https://github.com/containerd/nerdctl/releases/download/v1.7.6/nerdctl-1.7.6-linux-amd64.tar.gz
tar zxvf nerdctl-1.7.6-linux-amd64.tar.gz
cp nerdctl /usr/bin

配置 containerd 和 nerdctl

在安装软件之后,需要修改 containerd 的以下配置:

  • paus 镜像地址
  • containerd.sock 的位置

执行以下命令进行:

containerd config default > /etc/containerd/config.toml
sed -i 's|address = "\/run/containerd/containerd.sock"|address = "/var/run/containerd/containerd.sock"|' /etc/containerd/config.toml
sed -i 's|sandbox_image = ".*"|sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9"|' /etc/containerd/config.toml

查看 /etc/containerd/config.toml 文件相关字段内容如下代表修改成功:

[grpc]
  address = "/var/run/containerd/containerd.sock"

sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9

执行以下命令启动 containerd :

systemctl start containerd
systemctl enable containerd

修改 nerdctl 的配置:

mkdir -p /etc/nerdctl
cat > /etc/nerdctl/nerdctl.toml <<EOF
address        = "unix:///var/run/containerd/containerd.sock"
namespace      = "k8s.io"
EOF

高可用配置

在 k8s 的高可用配置中,通常使用 haproxy 和 keepalived 作为高可用的组件,对于 k8s 的高可用主要分为两个方面: apiserver 和 etcd。 apiserver 是 k8s 的入口,etcd 则为 k8s 的数据存储。

接下来主要讲述如何对 apiserver 进行高可用的配置,etcd 的高可用配置将在集群的生成的时候,由 kubeadm 进行自行配置。

软件安装及配置

在三台 master 节点执行以下命令安装 haproxy 和 keepalived:

yum install keepalived haproxy   -y 

修改三台 master haproxy 的配置文件,文件地址为 /etc/haproxy/haproxy.cfg 内容如下:

global
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

defaults
    log     global
    mode    tcp
    option  tcplog
    option  dontlognull
    timeout connect 5000
    timeout client  50000
    timeout server  50000

frontend https-in
    bind *:16443
    mode tcp
    option tcplog

    default_backend servers-backend

backend servers-backend
    mode tcp
    balance roundrobin
    option tcp-check

    server master01 192.168.8.148:6443 check
    server master02 192.168.8.149:6443 check
    server master03 192.168.8.150:6443 check

修改完成后启动 haproxy 命令如下:

systemctl start haproxy
systemctl enable haproxy 

执行命令 netstat -ntlp 查看 haproxy 端口是否已经启动,输出结果如下代表正常:

tcp        0      0 0.0.0.0:16443           0.0.0.0:*               LISTEN      12805/haproxy

修改 keepalived 的配置,配置文件的位置为 /etc/keepalived/keepalived.conf,修改为以下内容:

  • master01:
vrrp_instance VI_1 {
    state MASTER
    interface ens33 ## 修改网卡为电脑的网卡,可以使用 ifconfig 命令查看
    virtual_router_id 51
    priority 100
    advert_int 1
    unicast_peer {
        192.168.8.149
        192.168.8.150
    }
    virtual_ipaddress {
       192.168.8.153 
    }
}
  • master02:
vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 50
    advert_int 1
    unicast_peer {
        192.168.8.148
        192.168.8.149
    }
    virtual_ipaddress {
        192.168.8.153
    }
}
  • master03:
vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 20
    advert_int 1
    # 配置unicast_peers,指定其他两台服务器的IP
    unicast_peer {
        192.168.8.148
        192.168.8.150
    }
    virtual_ipaddress {
        192.168.8.153
    }
}

启动 keepalived 命令如下:

systemctl start keepalived
systemctl enable keepalived

在 master01 上执行 ip addr 命令看到以下输出就代表虚拟网卡启动成功:

 ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:f1:e2:f3 brd ff:ff:ff:ff:ff:ff
    inet 192.168.8.148/24 brd 192.168.8.255 scope global noprefixroute dynamic ens33
       valid_lft 81374sec preferred_lft 81374sec
    inet 192.168.8.153/32 scope global ens33
       valid_lft forever preferred_lft forever

创建 k8s 集群

在 master01 上执行以下命令创建 k8s 集群:

kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--control-plane-endpoint=192.168.8.153:16443 \
--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \
--upload-certs

看到以下结果代表集群初始化成功:

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/

You can now join any number of the control-plane node running the following command on each as root:

  kubeadm join 192.168.8.153:16443 --token csru9a.2bxorhv860uwz8w8 \
        --discovery-token-ca-cert-hash sha256:1993ac38e9f2e2f63deda436b04ae601fab038f2120343215f83c14e4429f956 \
        --control-plane --certificate-key 8ea5af444a382397626cd008c9814f5b9b71dbe978bbdfb7596a88276ca1213b

Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.8.153:16443 --token csru9a.2bxorhv860uwz8w8 \
        --discovery-token-ca-cert-hash sha256:1993ac38e9f2e2f63deda436b04ae601fab038f2120343215f83c14e4429f956

在生成集群之后,执行以下命令,配置 kubectl 认证:

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

然后分别在 master02 和 master03 上执行:

kubeadm join 192.168.8.153:16443 --token csru9a.2bxorhv860uwz8w8 \
      --discovery-token-ca-cert-hash sha256:1993ac38e9f2e2f63deda436b04ae601fab038f2120343215f83c14e4429f956 \
      --control-plane --certificate-key 8ea5af444a382397626cd008c9814f5b9b71dbe978bbdfb7596a88276ca1213b

在 worker01 和 worker02 上执行:

kubeadm join 192.168.8.153:16443 --token csru9a.2bxorhv860uwz8w8 \
        --discovery-token-ca-cert-hash sha256:1993ac38e9f2e2f63deda436b04ae601fab038f2120343215f83c14e4429f956

等待命令执行完毕后,在 master01 节点上执行 kubectl get node 命令,输出结果如下代表一个 3 主 2 从的 k8s 集群创建成功:

NAME       STATUS     ROLES           AGE     VERSION
master01   NotReady   control-plane   6m20s   v1.30.1
master02   NotReady   control-plane   2m57s   v1.30.1
master03   NotReady   control-plane   2m52s   v1.30.1
worker01   NotReady   <none>          98s     v1.30.1
worker02   NotReady   <none>          96s     v1.30.1

但是这时候 k8s 集群还不能进行工作,缺少了 cni 插件,无法进行网络通信,还需要安装 calico、flannel 或者 cilium 这种网络插件 k8s 集群才能正常运行。

执行以下命令进行安装 calico 网络插件:

curl https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/calico.yaml -O
kubectl apply -f calico.yaml

执行 kubectl get node 看到以下结果代表 k8s 已经准备就绪可以进行使用了:

NAME       STATUS   ROLES           AGE   VERSION
master01   Ready    control-plane   59m   v1.30.1
master02   Ready    control-plane   56m   v1.30.1
master03   Ready    control-plane   56m   v1.30.1
worker01   Ready    <none>          55m   v1.30.1
worker02   Ready    <none>          55m   v1.30.1

后续

  • 镜像拉取失败

    如果镜像拉取失败,可以考虑配置 contianerd 的镜像加速,参考链接

  • 集群加入命令忘记或者过期

    如果集群加入命令忘记或者过期,对于 worker 节点可以执行 kubeadm token create --print-join-command 获取新的加入命令,对于 master 节点需要先生成新的密钥,命令为 kubeadm init phase upload-certs --upload-certs,然后在 kubeadm token create --print-join-command 输出的命令的基础上添加 --control-plane --certificate-key 。完整的命令如下:

    ## worker
    kubeadm join 192.168.8.153:16443 --token csru9a.2bxorhv860uwz8w8 \
    sha256:1993ac38e9f2e2f63deda436b04ae601fab038f2120343215f83c14e4429f956
          
    ## master
    kubeadm join 192.168.8.153:16443 --token csru9a.2bxorhv860uwz8w8 \
        --discovery-token-ca-cert-hash sha256:1993ac38e9f2e2f63deda436b04ae601fab038f2120343215f83c14e4429f956 \
        --control-plane --certificate-key 8ea5af444a382397626cd008c9814f5b9b71dbe978bbdfb7596a88276ca1213b
    
  • etcd 集群

    集群默认生成的 etcd 配置文件在 /etc/kubernetes/manifests 下,主要关注 etcd.yaml 的以下内容:

    - --initial-cluster=master02=https://192.168.8.149:2380,master03=https://192.168.8.150:2380,master01=https://192.168.8.148:2380
    

    这个就已经代表 etcd 当前为集群模式,并且有三个节点。但是在 master01 节点和 master02 节点上可能看到只有一个地址和两个地址,这并不影响 etcd 节点之间的通信。etcd 本身是一个 P2P 网络,每个节点可以通过其他节点建立的连接来进行彼此发现。

  • kube-apiserver

    在默认生成的 kube-apiserver 配置的 etcd 为本地的 etcd 地址,文件地址为 /etc/kubernetes/manifests,相关内容为 kube-apiserver:

        - --etcd-servers=https://127.0.0.1:2379
    

    这样本身没有什么大问题,etcd 已经做好了数据同步,如果担心 etcd 会出现问题,这里可以追加其他 master 的地址,内容如下所示:

        - --etcd-servers=https://127.0.0.1:2379,https://192.168.8.148:2379
    

你可能感兴趣的:(k8s,kubernetes,容器,云原生,devops,linux)