Kubernetes v1.28.15集群搭建(亲测有效,每一步都是真实操作记录)

集群信息

1.节点规划

部署k8s集群的节点按照用途可以划分为如下2类角色:

  • master: 集群的master节点,集群的初始化节点,基础配置不低于2C2G

  • slave: 集群的slave节点,可以多台,基础配置不低于2C2G

本例为了演示slave节点的添加,会部署一台master+2台slave,节点规划如下:

主机名节点ip角色部署组件
master192.168.10.100masteretcd, kube-apiserver, kube-controller-manager, kubeadm, kubectl,kubelet, kube-proxy, flannel
node1192.168.10.101slavekubectl, kubelet, kube-proxy, flannel
node2192.168.10.102slavekubectl, kubelet, kube-proxy, flannel
2.组件版本
组件版本说明
CentOSCentOS Linux release 7.9.2009 (Core)cat /etc/redhat-release 可以查到
KernelLinux 3.10.0-1160.71.1.el7.x86_64hostnamectl |grep -I Kernel 可以查到
etcd3.5.15-0使用容器方式部署,默认数据挂载到本地路径
corednsv1.10.1
kubeadmv1.28.15
kubectlv1.28.15
kubeletv1.28.15
kube-proxyv1.28.15
flannelv0.26.4

安装前准备工作

1.创建虚拟机

光盘最后再选,不然让你设置虚拟机密码,太麻烦。

虚拟机的位置不要放在C盘,系统很容易占满。

磁盘大小我这设置40G,固态盘有点小,如果硬盘大的话可以设置大点。一般选这单个文件,方便虚拟机迁移,和格式转换。

这先自定义一下硬件,也可以直接完成,之后再修改。看个人习惯。

我这内存才8G,虚拟机内存就给2G,处理器内核数量选2,因为我的电脑是单个CPU,所以数量选1,虚拟化勾上。顺便移除USB、声卡、打印机。

Cdrom选一下ISO系统文件,然后点关闭、完成。

2.安装系统

直接选 Install CentOS7,选第二个是检查光盘,时间比较长,不般用,有错误时会用一下。

选择时区:

选基础设施服务,不用选最小安装,很多命令都不全。连命令补全都没有。

分区的话,这里测试就先自动分区好了

网卡先设置点亮,再点Configre...设置IP

选择IPv4、再选Manual,手动设置IP,把DNS也设置一下,用阿里的223.5.5.5 ,保存退出,点完成(Done)

开始安装。

在安装过程中设置一下 root 用户的密码,和普通用户。要等5分钟左右才完成安装。

完成。点重启

3.克隆虚拟机

用SSH 连上虚拟机,把网卡配置文件处理一下。

cp /etc/sysconfig/network-scripts/ifcfg-ens32 /etc/sysconfig/network-scripts/ifcfg-ens32.bak  
vim /etc/sysconfig/network-scripts/ifcfg-ens32

把标红的地方都删除了,退出保存。如下

执行命令 : poweroff    关机,开克隆:

拍下快照,方便回退。

第一台node完成,按照第一台的步骤再做一次,完成第二台,这样虚拟机就准备好了。

4.设置hosts解析

操作节点:所有节点(k8s-master,k8s-slave)均需执行

  • 修改hostname hostname必须只能包含小写字母、数字、","、"-",且开头结尾必须是小写字母或数字

  • 因为是克隆,所以要先从node1 或node2 开始,一台设置完再开另一台,防止IP冲突。

现在开启node2虚拟机,在node2上执行下面命令

# 在node2上执行下面命令
sed -i 's/10.100/10.102/g' /etc/sysconfig/network-scripts/ifcfg-ens32 
hostnamectl set-hostname node2 && bash

开启node1虚拟机,在node1上执行下面命令

# 在node1上执行下面命令
sed -i 's/10.100/10.101/g' /etc/sysconfig/network-scripts/ifcfg-ens32 
hostnamectl set-hostname node1 && bash

开启master虚拟机,在master上执行下面命令 ,这样三台虚拟机的IP和主机名都设置好了。

# 在master上执行下面命令
hostnamectl set-hostname master && bash

查看一下是否正确:

添加hosts解析  

 操作节点:所有的master和slave节点(master,node1,node2)都需要执行

cat >>/etc/hosts<<EOF
192.168.10.100 master 
192.168.10.100 cluster-endpoint
192.168.10.101 node1
192.168.10.102 node2
EOF
# 测试
ping -c3 master
ping -c3 cluster-endpoint
ping -c3 node1
ping -c3 node2
5.调整系统配置

 操作节点:所有的master和slave节点(master,node1,node2)都需要执行

设置yum源

rm -f /etc/yum.repos.d/CentOS-Base.repo 
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
yum clean all && yum makecache

时间同步

# 启动chronyd服务,设置chronyd服务开机自启
systemctl start chronyd && systemctl enable chronyd
# chronyd服务启动稍等几秒钟,使用date命令验证时间
date

关闭swap

不同的容器运行时(如 Docker, containerd, CRI-O 等)对 swap 的处理方式不同。例如,某些容器运行时可能默认不支持或不完全支持 swap。在这种情况下,禁用 swap 可以避免潜在的问题。swap 的使用可能导致性能问题,为了最佳的性能和稳定性,在 Kubernetes 节点上禁用 swap。

#临时关闭
swapoff -a
# 防止开机自动挂载swap 分区
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

关闭selinux和防火墙

# 关闭selinux
sed -ri 's#(SELINUX=).*#\1disabled#' /etc/selinux/config
setenforce 0
# 关闭防火墙
systemctl disable firewalld && systemctl stop firewalld
# 安装ipset和ipvsadm
yum install ipset ipvsadm -y
# 添加需要加载的模块写入脚本文件(加载五个模块)
cat <<EOF > /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
# 为脚本添加执行权限
chmod +x /etc/sysconfig/modules/ipvs.modules
# 执行脚本文件
bash /etc/sysconfig/modules/ipvs.modules

修改内核参数  

cat <<EOF> /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables =1
net.bridge.bridge-nf-call-iptables =1
net.ipv4.ip_forward=1
vm.max_map_count=262144
EOF
sysctl -p /etc/sysctl.d/k8s.conf
# 加载网桥过滤模块
modprobe br_netfilter

6.安装docker

 操作节点:所有的master和slave节点(master,node1,node2)都需要执行

# 安装必要的一些系统工具
yum install -y yum-utils
# 添加软件源信息
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 查看所有的可用版本
yum list docker-ce --showduplicates | sort -r
# 安装Docker
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
## 配置docker加速
mkdir -p /etc/docker
tee /etc/docker/daemon.json << EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registry-mirrors": ["https://docker.m.daocloud.io",
    "https://hub.urlsa.us.kg",
    "https://docker.urlsa.us.kg"]
}
EOF
# 开启Docker服务
systemctl daemon-reload && systemctl restart docker && systemctl enable docker
# 测试
docker version

安装cri-dockerd

cri-dockerd的主要作用是作为Kubernetes与Docker之间的桥梁,使得Kubernetes能够通过CRI(Container Runtime Interface)标准接口调用Docker的功能‌。在Kubernetes v1.24及以后的版本中,Kubernetes移除了内置的dockershim,这意味着它不再直接支持Docker。为了继续使用Docker作为容器运行时,需要安装cri-dockerd来实现这一功能‌。

下载并安装cri-docker

# 看了一下,好像最后一个针对centos7的版本是 cri-dockerd-0.3.14-3.el7.x86_64.rpm
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.14/cri-dockerd-0.3.14-3.el7.x86_64.rpm
# 安装
yum -y install cri-dockerd-0.3.14-3.el7.x86_64.rpm

 cri-docker.service 修改

在fd:// 后加入--pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9 看好了,//  后面有个空格的 。

vi /usr/lib/systemd/system/cri-docker.service

ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9

# 重新加载cri-docker
systemctl daemon-reload
systemctl enable cri-docker && systemctl start cri-docker

完成后重启所有虚拟机(也可以关机做快照,因为下面的集群设置容易出错,有快照方便回退),并检查设置,检查命令如下:

# 可以先查看selinux是否开启,Disabled是没有开。
getenforce
# 查看内存分配来检查seap是否已经禁用,0表示没有分配。
free -m | grep Swap
# 查看防火墙,Active: inactive (dead)表示没有开启。
systemctl status firewalld | grep  Active
# 查看对应模块是否加载成功
lsmod | grep -e ip_vs -e nf_conntrack_ipv4
# 查看网桥过滤模块是否加载成功
lsmod | grep br_netfilter

部署kubernetes

1.安装 kubeadm, kubelet 和 kubectl
  • 在Kubernetes集群中,kubeadm、kubectl 和 kubelet 是三个核心组件,它们在集群的初始化、管理和节点维护中扮演着不同的角色。

    • kubeadm‌ 用于集群的初始化,创建和配置主节点和工作节点

    • ‌kubectl‌ 是用户与集群交互的接口,用于管理和查询集群资源。

    • ‌kubelet‌ 在每个节点上运行,确保节点上的 Pod 按照期望的状态运行。

操作节点:所有的master和slave节点(master,node1,node2)都需要执行 

  • 添加kubernetes.repo

cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/rpm/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/rpm/repodata/repomd.xml.key
EOF
  • 安装kubeadm、kubelet和kubectl

yum install -y --nogpgcheck kubelet kubeadm kubectl
## 查看kubeadm 版本
kubeadm version
  • 配置kubelet的cgroup

# 配置kubelet的cgroup,编辑/etc/sysconfig/kubelet,执行下面命令会把原来这个文件所有内容替换

cat <<EOF | tee /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--fail-swap-on=true"
KUBELET_CGROUP_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"
EOF
# 设置kubelet开机自启
systemctl enable kubelet
# 这里仅设置了开机自启没有启动,是因为在kubernetes启动时会自动启动kubelet
# 修改一下 Cgroup
containerd config default > /etc/containerd/config.toml
sed -i -e 's/registry.k8s.io/registry.aliyuncs.com\/google_containers/g'  /etc/containerd/config.toml
sed -i -e 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
cat /etc/containerd/config.toml |egrep "sandbox_image|SystemdCgroup|disabled_plugins"
systemctl restart containerd

搭建k8s集群

提前下载镜像

操作节点:只在master节点(master)执行

  • 操作节点:只在master节点(master)执行

  • 查看要下载的镜像

kubeadm config images list | sed 's/^.*\///g'

命令结果如下 

  • 下载镜像

master虚拟下载镜像, imaweb是镜像源,images全部镜像。

# master下载镜像 imaweb是镜像源,阿里云镜像源,也可以换别的,images全部镜像列表
imaweb=registry.cn-hangzhou.aliyuncs.com/google_containers
images=(
kube-apiserver:v1.28.15
kube-controller-manager:v1.28.15
kube-scheduler:v1.28.15
kube-proxy:v1.28.15
pause:3.9
etcd:3.5.15-0
coredns:v1.10.1
)
for imageName in ${images[@]} ; do
docker pull $imaweb/$imageName  #从阿里云拉镜像
done

 下载完成,查看镜像  docker images -a

初始化master节点

# --apiserver-advertise-address配置k8s apiserver地址,用于监听、响应其他节点请求。此处配置为master节点ip地址
# --service-cidr=10.96.0.0/12 配置k8s Service的IP范围
# --pod-network-cidr=10.244.0.0/16 配置k8s pod的IP范围
# --cri-socket 用cri-dockerd.sock, 不用默认的containerd.sock

kubeadm init \
  --apiserver-advertise-address=192.168.10.100 \
  --image-repository=registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.28.15 \
  --service-cidr=10.96.0.0/12 \
  --pod-network-cidr=10.244.0.0/16 \
  --cri-socket=unix:///var/run/cri-dockerd.sock

当看到图下所示的显示时,说明集群初始化完成


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/

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

kubeadm join 192.168.10.100:6443 --token nlkc72.jv7si27k4etec0t0 \
        --discovery-token-ca-cert-hash --discovery-token-ca-cert-hash sha256:bf564fa1832cf6a5666f4b776945746747843a9ea33d81fe8c4ad2be3937c5ee
master执行命令

将刚刚画面出现的代码复制粘贴到master上运行

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

将刚刚界面出现的代码复制粘贴到node1node2上运行(记得结尾指定一下cri-socket),还有你不要直接复制我的,token和discovery-token-ca-cert-hash是系统生成的,每一次都有可能不一样,你要看自己部署成功后的提示。就是successfully!后面的话。

kubeadm join 192.168.10.100:6443 --token 3sj6sc.z8uhm59ejfna28dv \
        --discovery-token-ca-cert-hash sha256:bf564fa1832cf6a5666f4b776945746747843a9ea33d81fe8c4ad2be3937c5ee \       
        --cri-socket=unix:///var/run/cri-dockerd.sock
查看集群节点信息

master节点执行命令查看集群节点信息,但是当前STATUS都是NotReady

[root@master ~]# kubectl get nodes
NAME     STATUS     ROLES           AGE    VERSION
master   NotReady   control-plane   5m5s   v1.28.15
node1    NotReady   <none>          48s    v1.28.15
node2    NotReady   <none>          42s    v1.28.15

安装网络插件

  • 先拉取镜像

  • 操作节点:所有的master和slave节点(master,node1,node2)都需要执行 

 # 先拉取镜像,此过程,国内速度比较慢
 docker pull ghcr.io/flannel-io/flannel-cni-plugin:v1.6.2-flannel1
 docker pull ghcr.io/flannel-io/flannel:v0.26.4

下载kube-flannel.yml 配置文件

*下面步骤仅在master节点操作!!!*

wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

kubectl apply -f kube-flannel.yml

如果下载不了kube-flannel.yml ,下面贴出原文

apiVersion: v1
kind: Namespace
metadata:
  labels:
    k8s-app: flannel
    pod-security.kubernetes.io/enforce: privileged
  name: kube-flannel
---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: flannel
  name: flannel
  namespace: kube-flannel
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    k8s-app: flannel
  name: flannel
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes/status
  verbs:
  - patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    k8s-app: flannel
  name: flannel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: flannel
subjects:
- kind: ServiceAccount
  name: flannel
  namespace: kube-flannel
---
apiVersion: v1
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "EnableNFTables": false,
      "Backend": {
        "Type": "vxlan"
      }
    }
kind: ConfigMap
metadata:
  labels:
    app: flannel
    k8s-app: flannel
    tier: node
  name: kube-flannel-cfg
  namespace: kube-flannel
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: flannel
    k8s-app: flannel
    tier: node
  name: kube-flannel-ds
  namespace: kube-flannel
spec:
  selector:
    matchLabels:
      app: flannel
      k8s-app: flannel
  template:
    metadata:
      labels:
        app: flannel
        k8s-app: flannel
        tier: node
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/os
                operator: In
                values:
                - linux
      containers:
      - args:
        - --ip-masq
        - --kube-subnet-mgr
        command:
        - /opt/bin/flanneld
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: EVENT_QUEUE_DEPTH
          value: "5000"
        image: ghcr.io/flannel-io/flannel:v0.26.4
        name: kube-flannel
        resources:
          requests:
            cpu: 100m
            memory: 50Mi
        securityContext:
          capabilities:
            add:
            - NET_ADMIN
            - NET_RAW
          privileged: false
        volumeMounts:
        - mountPath: /run/flannel
          name: run
        - mountPath: /etc/kube-flannel/
          name: flannel-cfg
        - mountPath: /run/xtables.lock
          name: xtables-lock
      hostNetwork: true
      initContainers:
      - args:
        - -f
        - /flannel
        - /opt/cni/bin/flannel
        command:
        - cp
        image: ghcr.io/flannel-io/flannel-cni-plugin:v1.6.2-flannel1
        name: install-cni-plugin
        volumeMounts:
        - mountPath: /opt/cni/bin
          name: cni-plugin
      - args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        command:
        - cp
        image: ghcr.io/flannel-io/flannel:v0.26.4
        name: install-cni
        volumeMounts:
        - mountPath: /etc/cni/net.d
          name: cni
        - mountPath: /etc/kube-flannel/
          name: flannel-cfg
      priorityClassName: system-node-critical
      serviceAccountName: flannel
      tolerations:
      - effect: NoSchedule
        operator: Exists
      volumes:
      - hostPath:
          path: /run/flannel
        name: run
      - hostPath:
          path: /opt/cni/bin
        name: cni-plugin
      - hostPath:
          path: /etc/cni/net.d
        name: cni
      - configMap:
          name: kube-flannel-cfg
        name: flannel-cfg
      - hostPath:
          path: /run/xtables.lock
          type: FileOrCreate
        name: xtables-lock

验证

插件部署好之后等待若干分钟,查看集群pod信息STATUS都是Running

[root@master kubernetes]# kubectl get pod -o wide -A
NAMESPACE      NAME                             READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
kube-flannel   kube-flannel-ds-f6khf            1/1     Running   0          19s   192.168.10.100   master   <none>           <none>
kube-flannel   kube-flannel-ds-qcznr            1/1     Running   0          19s   192.168.10.102   node2    <none>           <none>
kube-flannel   kube-flannel-ds-xzzbw            1/1     Running   0          19s   192.168.10.101   node1    <none>           <none>
kube-system    coredns-66f779496c-d99gv         1/1     Running   0          69m   10.244.0.2       master   <none>           <none>
kube-system    coredns-66f779496c-srkrb         1/1     Running   0          69m   10.244.0.3       master   <none>           <none>
kube-system    etcd-master                      1/1     Running   0          69m   192.168.10.100   master   <none>           <none>
kube-system    kube-apiserver-master            1/1     Running   0          69m   192.168.10.100   master   <none>           <none>
kube-system    kube-controller-manager-master   1/1     Running   0          69m   192.168.10.100   master   <none>           <none>
kube-system    kube-proxy-57x8b                 1/1     Running   0          29m   192.168.10.101   node1    <none>           <none>
kube-system    kube-proxy-jzbrk                 1/1     Running   0          69m   192.168.10.100   master   <none>           <none>
kube-system    kube-proxy-x9szr                 1/1     Running   0          29m   192.168.10.102   node2    <none>           <none>
kube-system    kube-scheduler-master            1/1     Running   0          69m   192.168.10.100   master   <none>           <none>

不记得token、a证书sha256编码的hash值,可以查看 

查看 token

命令:kubeadm token list

[root@master kubernetes]# kubeadm token list
TOKEN                     TTL         EXPIRES                USAGES                   DESCRIPTION                                                ES
5v11rg.el3tv0w19q30v72y   23h         2025-02-17T11:59:39Z   authentication,signing   <none>                                                     sn
nlkc72.jv7si27k4etec0t0   22h         2025-02-17T11:22:35Z   authentication,signing   The default bootstrap token generated by 'kubeadm init'.   sn

生成新 token
命令:kubeadm token create

获取ca证书sha256编码的hash值,有时用的SSH客户端拉得太小也会显示不完整,可以用下面命令查看一下。
命令:openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

[root@master ~]# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
bf564fa1832cf6a5666f4b776945746747843a9ea33d81fe8c4ad2be3937c5ee

加入集群命令:把上面查到的代替 ... 即可。

kubeadm join master节点IP:6443 \
--token ... \
--discovery-token-ca-cert-hash sha256:...\
--cri-socket=unix:///var/run/cri-dockerd.sock

kubeadm join master节点IP:6443 \
--token nlkc72.jv7si27k4etec0t0 \
--discovery-token-ca-cert-hash sha256:bf564fa1832cf6a5666f4b776945746747843a9ea33d81fe8c4ad2be3937c5ee \
--cri-socket=unix:///var/run/cri-dockerd.sock

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值