kubernetes集群部署

常见的 k8s 部署方式包括:二进制包、kubeadm 工具、云服务提供商、或通过一些开源的工具搭建,例如:sealos、kuboard、Runcher、kubeSphere。

本文使用kubeadm的部署方式,部署k8s1.28版本

我本地安装资源规划如下:

IP地址主机名称角色操作系统主机配置参考
192.168.3.92master1masterrockylinux9.4(最小化安装)4核心CPU/4G内存/80G磁盘
192.168.3.93worker1workerrockylinux9.4(最小化安装)4核心CPU/4G内存/80G磁盘
192.168.3.94worker2workerrockylinux9.4(最小化安装)4核心CPU/4G内存/80G磁盘

初始化集群环境

**注意:**初始化集群环境,以下步骤在所有主机都需相应操作

修改相应主机的主机名称和host文件解析

hostnamectl set-hostname master1 && bash
hostnamectl set-hostname worker1 && bash
hostnamectl set-hostname worker2 && bash
cat <<EOF >> /etc/hosts
192.168.3.92 master1
192.168.3.93 worker1
192.168.3.94 worker2
EOF

配置相应主机的静态IP地址

vim /etc/NetworkManager/system-connections/ens160.nmconnection
[connection]
id=ens160
uuid=8fa4f8df-0d4d-3993-a38d-4de4f1af2382
type=ethernet
autoconnect-priority=-999
interface-name=ens160
timestamp=1725741990

[ethernet]

[ipv4]
method=manual
dns=114.114.114.114
address1=192.168.3.92/24,192.168.3.2

[ipv6]
addr-gen-mode=eui64
method=auto

[proxy]

安装常用软件包

yum install -y epel-release tree vim wget bash-completion lrzsz nfs-utils net-tools sysstat iotop unzip nc nmap telnet bc psmisc yum-utils ipvsadm git socat conntrack sshpass libseccomp device-mapper-persistent-data lvm2 gcc gcc-c++ make cmake libxml2-devel openssl-devel curl libaio-devel ncurses-devel autoconf automake zlib-devel epel-release telnet 

关闭selinux和防火墙

setenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
systemctl stop firewalld.service && systemctl disable firewalld.service

关闭swap缓存

swapoff -a && sed -ri 's/.*swap.*/#&/' /etc/fstab

配置免密登录

生成秘钥

ssh-keygen

拷贝秘钥到相应主机

ssh-copy-id 192.168.3.92

安装时间同步chrony软件

yum install chrony -y
systemctl enable chronyd.service --now
systemctl restart chronyd.service
vim /etc/chrony.conf

#修改以下位置
#pool 2.rocky.pool.ntp.org iburst
pool ntp1.aliyun.com
修改内核参数
#加载内核模块
modprobe br_netfilter
modprobe ip_conntrack
modprobe iptable_filter
modprobe iptable_nat
modprobe overlay

#查看是否加载
lsmod | grep -e ip_vs -e nf_conntrack
nf_conntrack          176128  1 nf_nat
nf_defrag_ipv6         20480  1 nf_conntrack
nf_defrag_ipv4         16384  1 nf_conntrack
libcrc32c              16384  3 nf_conntrack,nf_nat,xfs

lsmod | grep ip
iptable_nat            16384  0
nf_nat                 49152  1 iptable_nat
iptable_filter         16384  0
ip_tables              28672  2 iptable_filter,iptable_nat
nf_defrag_ipv6         20480  1 nf_conntrack
nf_defrag_ipv4         16384  1 nf_conntrack

#修改内核参数
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

#持久化加载内核模块
cat > /etc/modules-load.d/modules.conf << EOF
br_netfilter
ip_conntrack
iptable_filter
iptable_nat
overlay
EOF

systemctl restart systemd-modules-load.service

#解释:
#对网桥上的IPv6数据包通过iptables处理            net.bridge.bridge-nf-call-ip6tables = 1  
#对网桥上的IPv4数据包通过iptables处理            net.bridge.bridge-nf-call-iptables = 1   
#开启IPv4路由转发,来实现集群中的容器与外部网络的通信 net.ipv4.ip_forward = 1          
安装docker
yum install -y yum-utils
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#查看yum源中的docker版本
yum list docker-ce.x86_64 --showduplicates | sort -r
#安装指定版本
yum -y install docker-ce-26.1.1-1.el9.x86_64

安装好docker后containerd.io作为docker依赖也会被安装,在安装k8s前就无需再安装containerd.io了

[root@master1 ~]# rpm -qa | grep containerd
containerd.io-1.6.32-3.1.el9.x86_64

启用Docker Cgroup控制组,用于限制进程的资源使用量,如CPU、内存。再配置镜像加速器,harbor地址,方便后期拉取镜像。

mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
  "log-opts": {
    "max-size": "5m",
    "max-file":"3"
  },
  "exec-opts": ["native.cgroupdriver=systemd"],
  "insecure-registries": ["192.168.137.35","harbor.cn"],
  "registry-mirrors": [
        "https://jockerhub.com",
        "https://mirror.baidubce.com",
        "https://dockerproxy.com",
        "https://docker.laoex.link",
        "https://docker.nju.edu.cn"
    ]
}
EOF

启动Docker服务并设置开机自启动

systemctl enable docker --now

安装k8s

配置软件仓库和安装所需包

因上文安装好了docker所以在安装k8s前就无需再安装containerd.io了

**注意:**所有主机均需要操作

添加阿里云kubernetes仓库

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

新版k8s网络源地址 1.29+版本

cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.29/rpm/
enabled=1
gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/rpm/repodata/repomd.xml.key
EOF

安装集群所需软件包
●kubeadm:用于初始化集群,并配置集群所需的组件并生成对应的安全证书和令牌;
●kubelet:负责与 Master 节点通信,并根据 Master 节点的调度决策来创建、更新和删除 Pod,同时维护 Node 节点上的容器状态;
●kubectl:用于管理k8集群的一个命令行工具;

安装 kubeadm kubelet kubectl

dnf install -y kubeadm-1.28.2-0 kubelet-1.28.2-0 kubectl-1.28.2-0

设置kubelet开机自启,集群初始化时kubelet会随着集群启动

systemctl enable kubelet

生成且修改containerd的配置文件(原有的配置文件不可使用)

containerd config default > /etc/containerd/config.toml

#修改以下配置
vim /etc/containerd/config.toml
139             SystemdCgroup = true
67     sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"

#拷贝到其它主机
scp /etc/containerd/config.toml 192.168.3.93:/etc/containerd/config.toml
scp /etc/containerd/config.toml 192.168.3.94:/etc/containerd/config.toml

启动containerd并设置开机自启动

systemctl restart containerd
systemctl enable containerd

查看集群所需镜像文件(国外镜像我们无法下载的)

kubeadm config images list --kubernetes-version=v1.28.13

I0907 22:45:30.944332   40619 version.go:256] remote version is much newer: v1.31.0; falling back to: stable-1.28
registry.k8s.io/kube-apiserver:v1.28.13
registry.k8s.io/kube-controller-manager:v1.28.13
registry.k8s.io/kube-scheduler:v1.28.13
registry.k8s.io/kube-proxy:v1.28.13
registry.k8s.io/pause:3.9
registry.k8s.io/etcd:3.5.9-0
registry.k8s.io/coredns/coredns:v1.10.1
kubernetes集群初始化

注:在master节点初始化集群

生成集群初始化配置文件

kubeadm config print init-defaults > kubeadm.yaml

修改advertiseAddress,name,imageRepository,kubernetesVersion的值,

添加podSubnet字段,加入kube proxy模式为ipvs的配置字段

vim kubeadm.yaml 

apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.3.92 #控制节点IP
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///var/run/containerd/containerd.sock
  imagePullPolicy: IfNotPresent
  name: master1 #控制节点名称
  taints: null
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers #改为国内镜像
kind: ClusterConfiguration
kubernetesVersion: 1.28.13 #修改成1.28.13版本
networking:
  dnsDomain: cluster.local
  podSubnet: 10.244.0.0/16 #添加这个字段 指定pod网段
  serviceSubnet: 10.96.0.0/12
scheduler: {}

#加入以下配置使用ipvs转发规则
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd

准备镜像

kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=v1.28.13

导出所有镜像到其它主机,防止网络原因导致集群初始化失败

ctr -n=k8s.io images export all.tar.gz \
registry.aliyuncs.com/google_containers/coredns:v1.10.1 \
registry.aliyuncs.com/google_containers/etcd:3.5.9-0 \
registry.aliyuncs.com/google_containers/kube-apiserver:v1.28.13 \
registry.aliyuncs.com/google_containers/kube-controller-manager:v1.28.13 \
registry.aliyuncs.com/google_containers/kube-proxy:v1.28.13 \
registry.aliyuncs.com/google_containers/kube-scheduler:v1.28.13 \
registry.aliyuncs.com/google_containers/pause:3.9

scp k8sall.tar.gz 192.168.3.93:/root/
scp k8sall.tar.gz 192.168.3.94:/root/

#[root@worker1 ~] 
ctr -n=k8s.io images import k8sall.tar.gz
#[root@worker2 ~] 
ctr -n=k8s.io images import k8sall.tar.gz

执行初始化命令(控制节点执行)

kubeadm init --config=kubeadm.yaml --ignore-preflight-errors=SystemVerification

安装成功后会有以下提示信息

You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:

  kubeadm join 192.168.3.199:16443 --token abcdef.0123456789abcdef \
	--discovery-token-ca-cert-hash sha256:d53d64de26fe12db3fc01de53b3f8c7f281f465215b2c3bb34be6747c3db9870 \
	--control-plane 

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

kubeadm join 192.168.3.199:16443 --token abcdef.0123456789abcdef \
	--discovery-token-ca-cert-hash sha256:d53d64de26fe12db3fc01de53b3f8c7f281f465215b2c3bb34be6747c3db9870 

初始化成功后,按照提示准备集群管理员配置文件

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

配置tab键命令补全

yum install bash-completion
source /usr/share/bash-completion/bash_completion
echo 'source <(kubectl completion bash)' >>~/.bashrc
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -o default -F __start_kubectl k' >>~/.bashrc
source ~/.bashrc

查看集群状态

[root@master ~]# kubectl get nodes
NAME     STATUS     ROLES           AGE    VERSION
master   NotReady   control-plane   2m3s   v1.28.2

此时集群状态还是NotReady 状态,因为网络组件没有启动。

部署Pod网络插件Calico

Calico 和 Flannel 是两种流行的 k8s 网络插件,它们都为集群中的 Pod 提供网络功能,然而,它们在实现方式和功能上有一些重要区别:
模型的区别:
●Calico 使用 BGP(边界网关协议)作为其底层网络模型。它利用 BGP 为每个 Pod 分配一个唯一的 IP 地址,并在集群内部进行路由。Calico 支持网络策略,可以对流量进行精细控制,允许或拒绝特定的通信。
●Flannel 则采用了一个简化的覆盖网络模型。它为每个节点分配一个 IP 地址子网,然后在这些子网之间建立覆盖网络。Flannel 将 Pod 的数据包封装到一个更大的网络数据包中,并在节点之间进行转发。Flannel 更注重简单和易用性,不提供与 Calico 类似的网络策略功能。

性能的区别:
●由于 Calico 使用 BGP 进行路由,其性能通常优于 Flannel。Calico 可以实现直接的 Pod 到 Pod 通信,而无需在节点之间进行额外的封装和解封装操作。这使得 Calico 在大型或高度动态的集群中具有更好的性能。
●Flannel 的覆盖网络模型会导致额外的封装和解封装开销,从而影响网络性能。对于较小的集群或对性能要求不高的场景,这可能并不是一个严重的问题。

**注:**在线下载配置文件地址是: https://calico-v3-25.netlify.app/archive/v3.25/manifests/calico.yaml

在master1节点下载calico.yaml文件

wget https://docs.tigera.io/archive/v3.25/manifests/calico.yaml

vim calico.yaml
#修改pod网段ip ,把注释放开并修改vlaue值
...
- name: CALICO_IPV4POOL_CIDR
  value: "10.244.0.0/16"
...

若机器有多个网卡,需要在calico.yaml配置文件里指定可以联网的网卡。(若机器只有一个网卡也可以不配置此步)

增加指定网卡配置:(4513 4514 行 不同版本的calico行号位置略有不同)

4508                   name: calico-config
4509                   key: calico_backend
4510             # Cluster type to identify the deployment type
4511             - name: CLUSTER_TYPE
4512               value: "k8s,bgp"
4513             - name: IP_AUTODETECTION_METHOD   #加入这行
4514               value: "interface=ens160"       #加入这行
4515             # Auto-detect the BGP IP address.
4516             - name: IP
4517               value: "autodetect"

提前下载calico.yaml中所需要的镜像文件并导出至所有主机,防止网络原因导致集群初始化失败

docker pull docker.io/calico/kube-controllers:v3.25.0
docker pull docker.io/calico/node:v3.25.0
docker pull docker.io/calico/cni:v3.25.0
#这里我多下载一个nginx的镜像方便安装好后测试集群网络是否可用
docker pull docker.io/library/nginx:1.21

#导出所需要的镜像
docker save $(docker images | grep -v REPOSITORY | awk 'BEGIN{OFS=":";ORS=" "}{print $1,$2}') -o calicoimg.tar.gz

#所有主机都需要导入镜像
scp calicoimg.tar.gz 192.168.3.93:/root/
scp calicoimg.tar.gz 192.168.3.94:/root/
#[root@master1 ~]
ctr -n=k8s.io images import calicoimg.tar.gz
#[root@worker1 ~] 
ctr -n=k8s.io images import calicoimg.tar.gz
#[root@worker2 ~] 
ctr -n=k8s.io images import calicoimg.tar.gz

在master1节点创建Calico网络

kubectl apply -f calico.yaml

等待Calico相关的Pod状态为Running即可

[root@master ~]# kubectl get pod -n kube-system
NAME                                      READY   STATUS    RESTARTS   AGE
calico-kube-controllers-9d57d8f49-lk7sw   1/1     Running   0          10m
calico-node-drsmx                         1/1     Running   0          10m
coredns-6554b8b87f-6rjtd                  1/1     Running   0          39m
coredns-6554b8b87f-w5gzw                  1/1     Running   0          39m
etcd-master                               1/1     Running   0          39m
kube-apiserver-master                     1/1     Running   0          39m
kube-controller-manager-master            1/1     Running   0          39m
kube-proxy-cj5v8                          1/1     Running   0          39m
kube-scheduler-master                     1/1     Running   0          39m

查看集群节点状态是否为Ready

[root@master ~]# kubectl get nodes
NAME     STATUS   ROLES           AGE   VERSION
master   Ready    control-plane   39m   v1.28.2
将工作节点加入集群

在master1主机上查看加入节点的命令:

kubeadm token create --print-join-command

kubeadm join 192.168.3.92:6443 --token 27z1xd.143q77f4jqnt67r4 --discovery-token-ca-cert-hash sha256:48f4733f89787e74a07ac9a87d91782093a46190131ecfb20260a75968aa8166 

其它节点(worker1 worker2)执行加入命令

kubeadm join 192.168.3.92:6443 --token 27z1xd.143q77f4jqnt67r4 --discovery-token-ca-cert-hash sha256:48f4733f89787e74a07ac9a87d91782093a46190131ecfb20260a75968aa8166

创建nginx pod测试集群网络是否正常

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.21
    ports:
    - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080

浏览器访问 192.168.3.86:30080 nginx服务

完成部署

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐