
文章目录
- 环境要求
- 搭建虚拟机
- 克隆虚拟机
- [修改 DNS 配置](#修改 DNS 配置)
- 网络配置
- 防火墙配置
- selinux配置
- swap分区配置
- 设置hostname
- 设置hosts文件
- 桥接网络配置
- 时间同步
- 安装Docker
- [安装 containerd](#安装 containerd)
- [安装 kubelet、kubeadm、kubectl](#安装 kubelet、kubeadm、kubectl)
- 部署Kubernetes
- Kubernetes各个组件的关系
环境要求
以下是 搭建 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),即使一方故障仍能解析域名。
bash
# 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
我不想用谷歌的,想改成阿里云的,修改示例(三台全改)
bash
sudo vi /etc/resolv.conf
之所以用阿里的一个是更快,一个是隐私性(多虑的)
bash
# 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(三台全改)
bash
sudo vi /etc/NetworkManager/NetworkManager.conf
在 [main] 部分添加
bash
[main]
dns=none # 禁止 NetworkManager 管理DNS

使用 time 命令测量总耗时
bash
time dig +short www.baidu.com

我这里显示17毫秒,如果发现 dig 响应慢,可能是 DNS 服务器问题。测试本地 DNS 服务器的延迟:
bash
ping -c 4 192.168.211.2 # 替换为你的 DNS 服务器 IP
如果大于50毫秒建议你更换DNS服务器
网络配置
将 BOOTPROTO="dhcp" 改为 BOOTPROTO="static" 是为了将网络配置从自动获取IP(DHCP)改为手动指定静态IP
bash
sudo vi /etc/sysconfig/network-scripts/ifcfg-ens33
BOOTPROTO="dhcp" # 自动从路由器获取IP,每次重启可能变化
BOOTPROTO="static" # 手动指定IP,确保永久固定
修改UUID和IPADDR 则是为了避免网络冲突(尤其是克隆的虚拟机)(修改两台即可)
bash
uuidgen # 生成新UUID,替换配置文件中旧值

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

重启网络服务
bash
sudo systemctl restart NetworkManager # RHEL/CentOS 8+
# 或
sudo systemctl restart networking # Debian/Ubuntu
检查IP是否生效
bash
ip addr show ens33

测试网络连通性,可以很直观的看出谷歌跟阿里的速度差异
bash
ping 8.8.8.8
ping 223.5.5.5

防火墙配置
永久关闭防火墙(所有机器)
bash
systemctl stop firewalld && systemctl disable firewalld
查看防火墙状态
bash
firewall-cmd --state
#或者
systemctl status firewalld

selinux配置
永久关闭selinux(所有机器)
bash
sudo sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
SELinux(Security-Enhanced Linux) 是 Linux 的一个安全子系统,用于通过强制访问控制(MAC)增强系统安全性。但在 Kubernetes(K8s)等分布式系统中,通常建议关闭 SELinux
启用selinux命令:setenforce 0
查看selinux的状态
bash
getenforce
- Enforcing:SELinux 已启用并强制执行安全策略。
- Permissive:SELinux 仅记录违规行为,但不阻止(审计模式)。
- Disabled:SELinux 已完全禁用。
如果上述命令关不掉,如图
可手动修改etc/selinux/config配置文件
bash
vim /etc/selinux/config

修改后重启(三台机器都这样操作)
bash
reboot #或者手动重启
重启完再次查看
bash
getenforce

swap分区配置
永久禁止swap分区(所有机器)
bash
sudo sed -ri 's/.*swap.*/#&/' /etc/fstab
查看是否禁止成功
bash
free -h
如图,如果swap的空间还存在,说明禁止失败
需要重启后在看一下
bash
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
bash
sudo hostnamectl set-hostname master
#使用hostnamectl或hostname命令验证是否修改成功
hostnamectl

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

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

设置hosts文件
在hosts文件添加内容(仅master设置)
作用:在 master 节点的 /etc/hosts 文件中添加主机名解析,使 master 能通过主机名(如 master、node1)访问其他节点,而不需要依赖 DNS
bash
sudo cat >> /etc/hosts << EOF
192.168.211.129 master
192.168.211.130 node1
192.168.211.131 node2
EOF
查看是否修改成功
bash
cat /etc/hosts

桥接网络配置
将桥接的IPv4流量传递到iptables的链(所有机器)
bash
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立即生效
bash
sudo sysctl --system

时间同步
时间同步(所有机器)
如果没有ntpdate命令要安装一下,默认应该是有
bash
yum install -y ntpdate
安装好后执行同步时间命令
bash
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
- 更新你的包列表:
bash
sudo yum update
若:没有yum命令,安装yum,有的话直接跳过
bash
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2 --skip-broken
注意;到这里可能会有问题,如图所示(根本原因是 CentOS 7 已于 2024-06-30 停止维护,官方仓库 (mirrorlist.centos.org) 可能已关闭或迁移),如果没有这个问题的可跳过这部分

如果出现这个问题,需要更换镜像源,你完全不必担心刚才做的操作是否会消失(他仅影响 yum install、yum update 等命令的软件包下载来源,所以请放心按照如下步骤更换)
bash
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

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

- 添加Docker的存储库:
bash
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
如果失败试一下下面这个命令切换阿里云,未失败直接进行下一步
bash
# 设置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

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

安装 cri-dockerd(适配 Kubernetes 的 CRI 接口)
bash
# 添加 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

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

bash
sudo systemctl status docker

安装 containerd
安装 containerd(所有节点),containerd及docker二者选其一即可
安装 containerd
bash
# CentOS/RedHat
sudo yum install -y containerd
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y containerd
配置 containerd
bash
# 生成默认配置
# 生成默认配置
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
bash
sudo ctr version
确保 containerd 已安装并运行
bash
sudo systemctl status containerd
检查 containerd 的 CRI 插件是否启用
默认情况下,containerd 需要启用 cri 插件才能与 Kubernetes 通信。
编辑 /etc/containerd/config.toml:
bash
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
确保 disabled_plugins 里 没有 cri:
bash
[plugins."io.containerd.grpc.v1.cri"]
...
[plugins."io.containerd.grpc.v1.cri".containerd]
...
disable = false # 确保不是 true
如果修改了配置,重启 containerd:
bash
sudo systemctl restart containerd
如果这块一直会让你初始化报错链接cri失败,那就无需配置
bash
sudo rm -f /etc/containerd/config.toml
sudo systemctl restart containerd
验证 CRI 接口是否可用
bash
sudo ctr --address=/run/containerd/containerd.sock plugins ls | grep cri
安装 kubelet、kubeadm、kubectl
所有机器都要安装
组件 | 用途 | 安装位置 | 必要性 |
---|---|---|---|
kubelet |
节点代理,管理 Pod | 所有节点 | 必须安装 |
kubeadm |
集群初始化工具 | 控制平面+工作节点 | 非必须(但强烈推荐) |
kubectl |
集群管理 CLI | 管理员机器 | 必须安装 |
初始化 添加节点 管理 上报状态 kubeadm 控制平面 kubelet kubectl
先查看现在最新版本是多少
bash
yum list --showduplicates kubelet --disableexcludes=kubernetes

bash
sudo yum install -y kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2
如果没安装成功,说明没有Kubernetes 仓库
使用阿里云镜像源添加Kubernetes 仓库
bash
# 添加阿里云 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

重新安装执行
bash
sudo yum install -y kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2

设置开机启动和启动
bash
sudo systemctl enable kubelet && systemctl start kubelet

重启并验证
bash
# 重启 kubelet
sudo systemctl daemon-reload
sudo systemctl restart kubelet
# 检查版本
kubeadm version
kubectl version --client
kubelet --version

部署Kubernetes
注意:必须2核CPU,1.7g以上内存,不然会导致初始化失败
初始化Kubernetes(containerd方式)

bash
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 路径。
输出以下内容表示初始化成功
bash
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
如果你初始化失败,再次初始化,会有残留文件,会报一下错误的话(如图),按下述步骤进行
bash
# 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查看节点信息
bash
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节点不执行
bash
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文件
bash
---
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
bash
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状态
bash
systemctl restart kubelet
kubectl get pod -n kube-system
master执行
bash
kubectl get node
node1和node2节点处于Ready状态
bash
[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,这步很可能会报错】
bash
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)集群
bash
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get pod,svc
输出如下
bash
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启动失败,则进行删除
bash
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) 用户操作链
bash
kubectl run nginx --image=nginx
↓
kube-apiserver 接收请求
↓
调度器分配节点 → kubelet 接管任务
↓
kubelet 通过 CRI 调用 Containerd/Docker
↓
容器启动并加入 Pod 网络
(2) 初始化流程
bash
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: crictl
和 kubectl
区别
crictl
:直接调试容器运行时(需配置socket
路径)kubectl
:管理K8s集群资源(Pod/Deployment等)
此篇文章篇幅挺长了,通过Kubernetes搭建其他应用以及其他的Kubernetes知识,可查看主页其他Kubernetes相关文章