【Kubernetes】从零搭建K8s集群:虚拟机环境配置全指南(DNS/网络/防火墙/SELinux全解析一站式配置图文教程)

发布于:2025-06-22 ⋅ 阅读:(17) ⋅ 点赞:(0)

在这里插入图片描述


更多相关内容可查看

环境要求

以下是 搭建 Kubernetes (K8s) 集群的环境要求对比表,涵盖 开发测试生产环境 的硬件、软件及网络配置,方便快速查阅:


Kubernetes 环境要求对比表

类别 开发/测试环境 (Minikube/k3s/单节点) 生产环境 (多节点高可用) 备注
节点数量 1 个节点(All-in-One) 3 Master + 2+ Worker 生产环境需高可用,至少 3 个 Master。
CPU 2 核 4 核/节点(Master 8 核+) Master 节点需更高性能处理调度请求。
内存 2GB (Minikube) / 4GB (k3s) 8GB/节点(Master 16GB+) etcd 对内存敏感,建议 16GB+。
磁盘 20GB (系统盘) 100GB+/节点(SSD 优先) 需持久化存储时,建议额外挂载数据盘。
操作系统 Ubuntu 20.04+, CentOS 7/8, RHEL 同左(推荐 LTS 版本) 避免使用非稳定版(如 CentOS Stream)。
容器运行时 Docker 20.10+ 或 Containerd 1.5+ Containerd 1.5+(推荐) Docker 已弃用,生产建议 Containerd。
网络插件 Calico/Flannel(默认) Calico/Cilium(生产级) 需确保 Pod 跨节点通信和 NetworkPolicy 支持。
网络要求 节点间互通,开放端口:
- 6443 (API)
- 10250 (kubelet)
同左 + 高可用负载均衡(VIP) 防火墙需放行 K8s 端口列表
负载均衡 无需(单节点) 需外部 LB(如 Nginx/HAProxy) Master 高可用需 LB 分发流量到 6443
存储 本地卷或 hostPath 分布式存储(如 Ceph/NFS) 生产环境推荐 CSI 驱动对接云存储或独立存储集群。
镜像仓库 Docker Hub 或本地临时仓库 私有 Harbor/Nexus 生产环境需私有仓库保障安全性和速度。

搭建虚拟机

搭建一台虚拟机,如果现在还没有 Vmware及虚拟机,可查看此文进行搭建(注意搭建过程中给的内存大小建议给2g以上):

【Vmware】虚拟机安装、镜像安装、Nat网络模式、本地VM8、ssh链接保姆篇(图文教程)

克隆虚拟机

首先关闭虚拟机,右键管理-克隆

在这里插入图片描述
点击下一页

在这里插入图片描述
点击下一页

在这里插入图片描述
创建完整克隆

在这里插入图片描述
修改虚拟机名称,这里如果不修改,可以新建完虚拟机后 右键虚拟机-设置也可以修改

在这里插入图片描述
有这个提示 直接点继续就可以

在这里插入图片描述
克隆中

在这里插入图片描述
克隆完成

在这里插入图片描述
依次克隆 最少保证有三台虚拟机 后续会一台master 两台node

在这里插入图片描述

修改 DNS 配置

我的三台机器的DNS默认如下

高可用性:同时使用本地 DNS (192.168.211.2) 和 Google DNS (8.8.8.8),即使一方故障仍能解析域名。

# Generated by NetworkManager
search localdomain
nameserver 192.168.211.2 # 本地网关或内部DNS
nameserver 8.8.8.8 # Google 公共DNS
nameserver 8.8.8.4 # Google 备用DNS

我不想用谷歌的,想改成阿里云的,修改示例(三台全改)

sudo vi /etc/resolv.conf

之所以用阿里的一个是更快,一个是隐私性(多虑的)

# Generated by NetworkManager
search localdomain
nameserver 192.168.211.2
nameserver 223.5.5.5     # 阿里DNS
nameserver 223.6.6.6     # 阿里备用DNS

在这里插入图片描述

由于 NetworkManager 可能会动态修改DNS,所以要改一下NetworkManager 的配置 防止覆盖掉我们刚才改的DNS(三台全改)

sudo vi /etc/NetworkManager/NetworkManager.conf

在 [main] 部分添加

[main]
dns=none  # 禁止 NetworkManager 管理DNS

在这里插入图片描述
使用 time 命令测量总耗时​

time dig +short www.baidu.com

在这里插入图片描述
我这里显示17毫秒,如果发现 dig 响应慢,可能是 DNS 服务器问题。测试本地 DNS 服务器的延迟:

ping -c 4 192.168.211.2  # 替换为你的 DNS 服务器 IP

如果大于50毫秒建议你更换DNS服务器

网络配置

将 BOOTPROTO=“dhcp” 改为 BOOTPROTO=“static” ​​是为了将网络配置从自动获取IP(DHCP)改为手动指定静态IP​​

sudo vi /etc/sysconfig/network-scripts/ifcfg-ens33

BOOTPROTO="dhcp"  # 自动从路由器获取IP,每次重启可能变化

BOOTPROTO="static"  # 手动指定IP,确保永久固定

修改UUID和IPADDR​​ 则是为了避免网络冲突(尤其是克隆的虚拟机)(修改两台即可)

uuidgen  # 生成新UUID,替换配置文件中旧值

在这里插入图片描述
修改DNS值保证跟上述配置文件一直,都使用谷歌或者阿里,避免后续不必要的麻烦

在这里插入图片描述
重启网络服务

sudo systemctl restart NetworkManager  # RHEL/CentOS 8+
# 或
sudo systemctl restart networking     # Debian/Ubuntu

检查IP是否生效

ip addr show ens33 

在这里插入图片描述
测试网络连通性,可以很直观的看出谷歌跟阿里的速度差异

ping 8.8.8.8

ping 223.5.5.5 

在这里插入图片描述

防火墙配置

永久关闭防火墙(所有机器)

systemctl stop firewalld && systemctl disable firewalld

查看防火墙状态

firewall-cmd --state
#或者
systemctl status firewalld

在这里插入图片描述

selinux配置

永久关闭selinux(所有机器)

sudo sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config

SELinux(Security-Enhanced Linux)​​ 是 Linux 的一个安全子系统,用于通过强制访问控制(MAC)增强系统安全性。但在 Kubernetes(K8s)等分布式系统中,​​通常建议关闭 SELinux

启用selinux命令:setenforce 0

查看selinux的状态

getenforce
  • Enforcing:SELinux 已启用并强制执行安全策略。
  • Permissive:SELinux 仅记录违规行为,但不阻止(审计模式)。
  • Disabled:SELinux 已完全禁用。

如果上述命令关不掉,如图
在这里插入图片描述

可手动修改etc/selinux/config配置文件

vim /etc/selinux/config

在这里插入图片描述
修改后重启(三台机器都这样操作)

reboot #或者手动重启

重启完再次查看

getenforce

在这里插入图片描述

swap分区配置

永久禁止swap分区(所有机器)

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

查看是否禁止成功

free -h

如图,如果swap的空间还存在,说明禁止失败
在这里插入图片描述
需要重启后在看一下

reboot

在这里插入图片描述

Swap 对 K8s 的影响​​

​​(1)K8s 调度器无法正确管理资源​​

​​K8s 依赖 kubelet 监控节点资源(CPU、内存)​​,决定 Pod 的调度和驱逐策略。

​​Swap 会干扰内存统计​​:

  • 当内存不足时,Linux 会将部分内存数据写入 Swap,导致 kubelet 无法准确计算可用内存。
  • 可能导致 Pod 被错误驱逐(OOM Killer 误杀)或调度到资源不足的节点

​​(2)性能下降​​

  • ​​Swap 的本质是“用磁盘模拟内存”​​,但磁盘(即使是 SSD)比内存慢 100~1000 倍。

  • 频繁 Swap 会导致 I/O 瓶颈​​,拖慢节点性能,影响 Pod 响应速度

​​(3)K8s 官方明确要求​​

  • ​​Kubernetes 1.8+ 强制要求禁用 Swap​​,否则 kubelet 会启动失败(报错 Running with swap on is not supported)
  • 虽然可以通过 --fail-swap-on=false 绕过,但​​不推荐​​,可能导致集群不稳定。

设置hostname

三台机器分别为mster、node1、node2

sudo hostnamectl set-hostname master
#使用hostnamectl或hostname命令验证是否修改成功
hostnamectl

在这里插入图片描述

sudo hostnamectl set-hostname node1
#使用hostnamectl或hostname命令验证是否修改成功
hostnamectl

在这里插入图片描述

sudo hostnamectl set-hostname node2
#使用hostnamectl或hostname命令验证是否修改成功
hostnamectl

在这里插入图片描述

设置hosts文件

在hosts文件添加内容(仅master设置)

​​作用​​:在 master 节点的 /etc/hosts 文件中添加主机名解析,使 master 能通过主机名(如 master、node1)访问其他节点,而不需要依赖 DNS

sudo cat >> /etc/hosts << EOF
192.168.211.129 master
192.168.211.130 node1
192.168.211.131 node2
EOF

查看是否修改成功

cat /etc/hosts

在这里插入图片描述

桥接网络配置

将桥接的IPv4流量传递到iptables的链(所有机器)

sudo 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
vm.swappiness = 0
EOF

将桥接的IPv4流量传递到iptables的链(这句话可能有人不理解是啥意思)

解释说明:

  • 当数据包通过 ​​Linux 网桥(bridge)​​ 时,是否让 ​​iptables​​ 规则对其生效。
  • =1 表示 ​​允许 iptables 处理桥接流量​​。

为什么需要这个设置?​​

  • ​​Kubernetes 使用网桥(如 cni0、docker0)管理 Pod 网络​​,Pod 之间的通信会经过网桥。

  • 如果 bridge-nf-call-iptables=0,iptables 规则不会作用于桥接流量,导致:

    • ​​Kubernetes Service 的 kube-proxy 规则失效​​(依赖 iptables 做负载均衡)。
    • 网络策略(NetworkPolicy)无法生效​​(如 Calico/Cilium 依赖 iptables/nftables)。
  • ​​必须设为 1​​,否则 Kubernetes 网络可能无法正常工作。

vm.swappiness = 0​​

  • 控制内核使用 ​​Swap 分区的倾向​​。
  • =0 表示 ​​尽量不使用 Swap​​,除非内存严重不足。

在这里插入图片描述

使k8s.conf立即生效

sudo sysctl --system

在这里插入图片描述

时间同步

时间同步(所有机器)

如果没有ntpdate命令要安装一下,默认应该是有

yum install -y ntpdate

安装好后执行同步时间命令

sudo ntpdate time.windows.com

在这里插入图片描述

如果出现以下问题,则说明以下几个问题,需要按照上述步骤,排查一遍

在这里插入图片描述

  • DNS 服务器未配置​​(/etc/resolv.conf 中没有有效的 DNS)。
  • ​​网络连接问题​​(无法访问外网 DNS,如 8.8.8.8 或 114.114.114.114)。
  • ​​防火墙阻止了 DNS 查询​​(如 iptables/firewalld 拦截了 UDP 53 端口

安装Docker

可查看此篇文章,如果无法点击或者未来此文失效,请按照下面的步骤继续进行【CentOS7】Linux安装Docker教程(保姆篇)

安装docker(所有机器),注意,搭建k8s还可以通过containerd方式去部署,如果访问不了github,可以不使用docker

  1. 更新你的包列表:
sudo yum update

若:没有yum命令,安装yum,有的话直接跳过

yum install -y yum-utils \
           device-mapper-persistent-data \
           lvm2 --skip-broken

注意;到这里可能会有问题,如图所示(根本原因是 CentOS 7 已于 2024-06-30 停止维护​​,官方仓库 (mirrorlist.centos.org) 可能已关闭或迁移),如果没有这个问题的可跳过这部分

在这里插入图片描述
如果出现这个问题,需要更换镜像源,你完全不必担心刚才做的操作是否会消失(他仅影响 yum install、yum update 等命令的软件包下载来源,所以请放心按照如下步骤更换)

sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
sudo curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
sudo yum clean all && yum makecache

在这里插入图片描述

  1. 安装必要的包,这些包可以让yum使用HTTPS:
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

在这里插入图片描述

  1. 添加Docker的存储库:
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

如果失败试一下下面这个命令切换阿里云,未失败直接进行下一步

# 设置docker镜像源
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/g' /etc/yum.repos.d/docker-ce.repo

yum makecache fast

在这里插入图片描述

  1. 安装Docker:
sudo yum install docker-ce  #无脑输入y即可

在这里插入图片描述
安装 cri-dockerd(适配 Kubernetes 的 CRI 接口)

# 添加 Kubernetes 仓库
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

sudo yum install -y cri-dockerd

在这里插入图片描述

  1. 启动Docker服务:
sudo systemctl start docker
  1. 设置Docker服务开机自启:
sudo systemctl enable docker
  1. 验证Docker是否安装成功:
sudo docker --version

在这里插入图片描述

sudo systemctl status docker

在这里插入图片描述

安装 containerd

安装 containerd(所有节点),containerd及docker二者选其一即可

安装 containerd​

# CentOS/RedHat
sudo yum install -y containerd

# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y containerd

配置 containerd​

# 生成默认配置
# 生成默认配置
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

# 修改配置使用 systemd 作为 Cgroup 驱动
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

# 配置国内镜像加速(阿里云)
sudo sed -i 's|registry.k8s.io|registry.aliyuncs.com/google_containers|g' /etc/containerd/config.toml

# 启动 containerd
sudo systemctl enable --now containerd

验证 containerd​

sudo ctr version

确保 containerd 已安装并运行​

sudo systemctl status containerd

检查 containerd 的 CRI 插件是否启用​

默认情况下,containerd 需要启用 cri 插件才能与 Kubernetes 通信。
编辑 /etc/containerd/config.toml:

sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

确保 disabled_plugins 里 ​​没有​​ cri:

[plugins."io.containerd.grpc.v1.cri"]
  ...
  [plugins."io.containerd.grpc.v1.cri".containerd]
    ...
    disable = false  # 确保不是 true

如果修改了配置,重启 containerd:

sudo systemctl restart containerd

如果这块一直会让你初始化报错链接cri失败,那就无需配置

sudo rm -f /etc/containerd/config.toml
sudo systemctl restart containerd

验证 CRI 接口是否可用

sudo ctr --address=/run/containerd/containerd.sock plugins ls | grep cri

安装 kubelet、kubeadm、kubectl

所有机器都要安装

组件 用途 安装位置 必要性
kubelet 节点代理,管理 Pod 所有节点 必须安装
kubeadm 集群初始化工具 控制平面+工作节点 非必须(但强烈推荐)
kubectl 集群管理 CLI 管理员机器 必须安装
初始化
添加节点
管理
上报状态
kubeadm
控制平面
kubelet
kubectl

先查看现在最新版本是多少

yum list --showduplicates kubelet --disableexcludes=kubernetes

在这里插入图片描述

sudo yum install -y kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2

如果没安装成功,说明没有Kubernetes 仓库
在这里插入图片描述
使用阿里云镜像源添加Kubernetes 仓库

# 添加阿里云 Kubernetes 仓库
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

# 清理缓存并重新生成
sudo yum clean all
sudo yum makecache

# 安装(不指定版本,默认安装最新稳定版)
sudo yum install -y kubelet kubeadm kubectl

在这里插入图片描述
重新安装执行

sudo yum install -y kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2

在这里插入图片描述

设置开机启动和启动

sudo systemctl enable kubelet && systemctl start kubelet

在这里插入图片描述
重启并验证​

# 重启 kubelet
sudo systemctl daemon-reload
sudo systemctl restart kubelet

# 检查版本
kubeadm version
kubectl version --client
kubelet --version

在这里插入图片描述

部署Kubernetes

注意:必须2核CPU,1.7g以上内存,不然会导致初始化失败

初始化Kubernetes(containerd方式)

在这里插入图片描述

sudo kubeadm init \
  --pod-network-cidr=10.244.0.0/16 \
  --image-repository=registry.aliyuncs.com/google_containers \
  --cri-socket=unix:///run/containerd/containerd.sock

关键参数:

  • pod-network-cidr:Flannel 插件的默认网段。
  • image-repository:使用阿里云镜像源加速。
  • cri-socket:指定 containerd 的 socket 路径。

输出以下内容表示初始化成功

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

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.203.11:6443 --token 51c0rb.ehwwxemgec75r1g6 \
    --discovery-token-ca-cert-hash sha256:fad429370f462b36d2651e3e37be4d4b34e63d0378966a1532442dc3f67e41b4

如果你初始化失败,再次初始化,会有残留文件,会报一下错误的话(如图),按下述步骤进行
在这里插入图片描述

# 1. 重置集群配置
sudo kubeadm reset --force

# 2. 手动删除残留文件(关键步骤!)
sudo rm -rf /etc/kubernetes/manifests/ /var/lib/etcd/

#强制重装 Containerd
sudo yum remove -y containerd
sudo rm -rf /etc/containerd/
sudo yum install -y containerd
sudo systemctl enable --now containerd

根据上面的提示执行对应的To start using your cluster, you need to run the following as a regular user:命令

  • master节点执行,node节点不执行
  • kubectl get nodes查看节点信息
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes

node节点根据上面的提示执行对应的Then you can join any number of worker nodes by running the

  • following on each as root:命令
  • node节点执行,master节点不执行
kubeadm join 192.168.203.11:6443 --token 51c0rb.ehwwxemgec75r1g6 \
    --discovery-token-ca-cert-hash sha256:fad429370f462b36d2651e3e37be4d4b34e63d0378966a1532442dc3f67e41b4

node1和node2执行命令

  • 安装cni
  • kube-flannel-ds-amd.yml文件
---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: psp.flannel.unprivileged
  annotations:
    seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
    seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
    apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
    apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
spec:
  privileged: false
  volumes:
    - configMap
    - secret
    - emptyDir
    - hostPath
  allowedHostPaths:
    - pathPrefix: "/etc/cni/net.d"
    - pathPrefix: "/etc/kube-flannel"
    - pathPrefix: "/run/flannel"
  readOnlyRootFilesystem: false
  # Users and groups
  runAsUser:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  # Privilege Escalation
  allowPrivilegeEscalation: false
  defaultAllowPrivilegeEscalation: false
  # Capabilities
  allowedCapabilities: ['NET_ADMIN']
  defaultAddCapabilities: []
  requiredDropCapabilities: []
  # Host namespaces
  hostPID: false
  hostIPC: false
  hostNetwork: true
  hostPorts:
  - min: 0
    max: 65535
  # SELinux
  seLinux:
    # SELinux is unused in CaaSP
    rule: 'RunAsAny'
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: flannel
rules:
  - apiGroups: ['extensions']
    resources: ['podsecuritypolicies']
    verbs: ['use']
    resourceNames: ['psp.flannel.unprivileged']
  - apiGroups:
      - ""
    resources:
      - pods
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes/status
    verbs:
      - patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: flannel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: flannel
subjects:
- kind: ServiceAccount
  name: flannel
  namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: flannel
  namespace: kube-system
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: kube-flannel-cfg
  namespace: kube-system
  labels:
    tier: node
    app: flannel
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",
      "Backend": {
        "Type": "vxlan"
      }
    }
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-amd64
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: beta.kubernetes.io/os
                    operator: In
                    values:
                      - linux
                  - key: beta.kubernetes.io/arch
                    operator: In
                    values:
                      - amd64
      hostNetwork: true
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni
        image: quay.io/coreos/flannel:v0.13.0-rc2
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: quay.io/coreos/flannel:v0.13.0-rc2
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
            add: ["NET_ADMIN"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
        - name: run
          hostPath:
            path: /run/flannel
        - name: cni
          hostPath:
            path: /etc/cni/net.d
        - name: flannel-cfg
          configMap:
            name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-arm64
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: beta.kubernetes.io/os
                    operator: In
                    values:
                      - linux
                  - key: beta.kubernetes.io/arch
                    operator: In
                    values:
                      - arm64
      hostNetwork: true
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni
        image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-arm64
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-arm64
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
             add: ["NET_ADMIN"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
        - name: run
          hostPath:
            path: /run/flannel
        - name: cni
          hostPath:
            path: /etc/cni/net.d
        - name: flannel-cfg
          configMap:
            name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-arm
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: beta.kubernetes.io/os
                    operator: In
                    values:
                      - linux
                  - key: beta.kubernetes.io/arch
                    operator: In
                    values:
                      - arm
      hostNetwork: true
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni
        image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-arm
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-arm
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
             add: ["NET_ADMIN"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
        - name: run
          hostPath:
            path: /run/flannel
        - name: cni
          hostPath:
            path: /etc/cni/net.d
        - name: flannel-cfg
          configMap:
            name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-ppc64le
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: beta.kubernetes.io/os
                    operator: In
                    values:
                      - linux
                  - key: beta.kubernetes.io/arch
                    operator: In
                    values:
                      - ppc64le
      hostNetwork: true
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni
        image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-ppc64le
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-ppc64le
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
             add: ["NET_ADMIN"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
        - name: run
          hostPath:
            path: /run/flannel
        - name: cni
          hostPath:
            path: /etc/cni/net.d
        - name: flannel-cfg
          configMap:
            name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-s390x
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: beta.kubernetes.io/os
                    operator: In
                    values:
                      - linux
                  - key: beta.kubernetes.io/arch
                    operator: In
                    values:
                      - s390x
      hostNetwork: true
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni
        image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-s390x
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: quay-mirror.qiniu.com/coreos/flannel:v0.11.0-s390x
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
             add: ["NET_ADMIN"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
        - name: run
          hostPath:
            path: /run/flannel
        - name: cni
          hostPath:
            path: /etc/cni/net.d
        - name: flannel-cfg
          configMap:
            name: kube-flannel-cfg

docker pull quay.io/coreos/flannel:v0.13.0-rc2
kubectl apply -f kube-flannel-ds-amd.yml

kubectl get pod -n kube-system 查看kube-flannel-ds-XXX 是否为runnin状态

systemctl restart kubelet
kubectl get pod -n kube-system

master执行

kubectl get node

node1和node2节点处于Ready状态

[root@master ~]# kubectl get node
NAME     STATUS   ROLES    AGE   VERSION
master   Ready    master   50m   v1.18.0
node1    Ready    <none>   49m   v1.18.0
node2    Ready    <none>   49m   v1.18.0

master部署CNI网络插件【如果前面没有把–network-plugin=cni移除并重启kubelet,这步很可能会报错】

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl get pods -n kube-system
kubectl get node

master执行测试Kubernetes(k8s)集群

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

输出如下

NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        21m
service/nginx        NodePort    10.108.8.133   <none>        80:30008/TCP   111s

如果nginx启动失败,则进行删除

kubectl delete service nginx

Kubernetes各个组件的关系

可能有很多朋友,实际对Kubernetes了解不深,或者不了解,上述的操作过程可能云里雾里,复制粘贴命令行都很顺利,但是不知道自己在干了啥,可以看下面一些组件的关系介绍

1. 组件关系图

控制命令
初始化
运行容器
调度指令
调用CRI接口
底层操作
kubectl
kube-apiserver
kubeadm
Master组件
Container Runtime
Pod
kubelet
Containerd/Docker
容器

2. 核心组件功能说明

组件 作用 典型工作场景
kubectl Kubernetes 命令行工具 用户通过它部署应用 (kubectl create)、查看资源 (kubectl get pods)
kubeadm 集群初始化工具 快速搭建集群 (kubeadm init)、添加节点 (kubeadm join)
kubelet 节点代理 接收API Server指令,管理Pod生命周期,定期上报节点状态
Container Runtime 容器运行时引擎 实际创建/运行容器(通过CRI接口与K8s交互)
Containerd 轻量级容器运行时 默认CRI实现,直接管理容器(无Docker守护进程)
Docker 完整容器平台 包含Docker引擎+containerd,需通过cri-dockerd适配K8s

3. 关键交互流程

(1) 用户操作链

kubectl run nginx --image=nginx
  ↓
kube-apiserver 接收请求
  ↓
调度器分配节点 → kubelet 接管任务
  ↓
kubelet 通过 CRI 调用 Containerd/Docker
  ↓
容器启动并加入 Pod 网络

(2) 初始化流程

kubeadm init
  ↓
生成证书、配置 etcd/kube-apiserver 等控制平面组件
  ↓
每个节点启动 kubelet
  ↓
kubelet 自动注册到集群

4. 版本适配关系

Kubernetes版本 推荐容器运行时 特殊要求
v1.24+ Containerd (默认) 需启用CRI插件
v1.20+ Docker 需安装cri-dockerd适配层
所有版本 CRI-O 需配置/etc/crictl.yaml

5. 常见问题场景
Q1: 为什么需要CRI?

  • 解耦设计:Kubernetes 通过 CRI (Container Runtime Interface) 标准接口支持多种容器运行时,避免绑定Docker。

Q2: Containerd vs Docker

特性 Containerd Docker
架构 仅运行时 引擎+API+CLI
资源占用 较高
K8s兼容性 原生支持CRI cri-dockerd转换

Q3: crictlkubectl 区别

  • crictl:直接调试容器运行时(需配置socket路径)
  • kubectl:管理K8s集群资源(Pod/Deployment等)

此篇文章篇幅挺长了,通过Kubernetes搭建其他应用以及其他的Kubernetes知识,可查看主页其他Kubernetes相关文章


网站公告

今日签到

点亮在社区的每一天
去签到