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

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

节点IPHostnameOS
master01192.168.8.148master01Centos7
master02192.168.8.149master02Centos7
master03192.168.8.150master03Centos7
worker01192.168.8.151worker01Centos7
worker02192.168.8.152worker02Centos7
VIP192.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 <kubeadm init phase upload-certs --upload-certs 生成的内容>。完整的命令如下:

    ## 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
    
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐