一、环境准备
1.1 系统要求
| 项目 | 最低要求 | 推荐配置 |
|---|---|---|
| 操作系统 | openEuler 24.03 LTS | openEuler 24.03 LTS |
| 内核版本 | ≥ 5.10 | 6.6.x (openEuler默认) |
| CPU | 2核 | 4核+ |
| 内存 | 4GB | 8GB+ |
| 磁盘空间 | 50GB | 100GB+ |
| 网络 | 千兆网络 | 千兆+网络 |
openEuler 24.03 特有说明:openEuler 24.03 基于 Linux 6.6 内核,默认已支持 cgroup v2、overlayfs、iptables 等 Kubernetes 所需特性,无需额外升级内核。
1.2 节点规划
本文以 1 Master + 2 Worker 架构为例,读者可根据实际情况调整节点数量。
| 主机名 | IP地址 | 角色 | 说明 |
|---|---|---|---|
| k8s-master | 192.168.33.30 | Master | 控制平面节点 |
| k8s-node1 | 192.168.33.31 | Worker | 计算节点1 |
| k8s-node2 | 192.168.33.32 | Worker | 计算节点2 |
1.3 网络规划
| 网络类型 | CIDR | 说明 |
|---|---|---|
| Pod 网络 | 10.244.0.0/16 | Flannel 默认网段 |
| Service 网络 | 10.96.0.0/12 | Kubernetes Service 网段 |
1.4 软件版本选型
| 组件 | 版本 | 说明 |
|---|---|---|
| Kubernetes | 1.29.x | LTS 版本,稳定可靠 |
| containerd | 1.6.22+ | openEuler 默认源版本 |
| CNI 插件 | Flannel 或 Calico | 二选一,本文使用 Flannel |
二、前置配置(所有节点执行)
以下配置需要在 所有节点 上执行,请使用 root 权限或 sudo 提权操作。
2.1 配置网络
2.1.1 设置静态 IP
bash
# 查看当前网络接口
ip addr
# 假设网卡名为 ens33,使用 nmcli 配置静态 IP (Master节点)
nmcli connection modify "ens33" \
ipv4.method manual \
ipv4.addresses 192.168.33.30/24 \
ipv4.gateway 192.168.33.1 \
ipv4.dns "223.5.5.5,114.114.114.114,8.8.8.8" \
&& nmcli connection down "ens33" && nmcli connection up "ens33"
# Worker节点1
nmcli connection modify "ens33" \
ipv4.method manual \
ipv4.addresses 192.168.33.31/24 \
ipv4.gateway 192.168.33.1 \
ipv4.dns "223.5.5.5,114.114.114.114,8.8.8.8" \
&& nmcli connection down "ens33" && nmcli connection up "ens33"
# Worker节点2
nmcli connection modify "ens33" \
ipv4.method manual \
ipv4.addresses 192.168.33.32/24 \
ipv4.gateway 192.168.33.1 \
ipv4.dns "223.5.5.5,114.114.114.114,8.8.8.8" \
&& nmcli connection down "ens33" && nmcli connection up "ens33"
# 验证网络连通性
ping -c 3 www.baidu.com
2.1.2 设置主机名
bash
# Master 节点
hostnamectl set-hostname k8s-master
# Worker 节点1
hostnamectl set-hostname k8s-node1
# Worker 节点2
hostnamectl set-hostname k8s-node2
2.1.3 配置 hosts 解析
bash
# 所有节点执行,添加以下内容到 /etc/hosts
cat >> /etc/hosts << EOF
192.168.33.30 k8s-master
192.168.33.31 k8s-node1
192.168.33.32 k8s-node2
EOF
# 将 hosts 文件同步到其他节点(Master 节点执行)
scp /etc/hosts k8s-node1:/etc/hosts
scp /etc/hosts k8s-node2:/etc/hosts
2.2 关闭防火墙
bash
# 所有节点执行
systemctl disable --now firewalld
# 验证防火墙状态
firewall-cmd --state
# 预期输出:not running
openEuler 24.03 注意事项:
- 如果需要保留防火墙,请参考 openEuler 官方文档 开放必要端口
- 核心端口:6443 (API Server)、2379-2380 (etcd)、10250-10259 (kubelet)
2.3 禁用 SELinux
bash
# 所有节点执行
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
# 验证
sestatus
# 预期输出:SELinux status: disabled
⚠️ 重要 :修改 SELinux 配置后 必须重启系统 才能完全生效。
2.4 关闭 Swap
bash
# 所有节点执行
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
# 验证
free -h | grep Swap
# 预期输出:Swap: 0B
说明:Kubernetes 调度器依赖准确的内存信息判断,启用 swap 会导致调度不准确。
2.5 时间同步
bash
# 所有节点执行
# 设置时区
timedatectl set-timezone Asia/Shanghai
# 启用并启动 chronyd
systemctl enable --now chronyd
# 同步时间
chronyc -a makestep
# 验证
timedatectl status
2.6 内核参数调优
bash
# 所有节点执行
# 配置内核模块自动加载
cat > /etc/modules-load.d/k8s.conf << EOF
overlay
br_netfilter
EOF
# 加载模块
modprobe overlay
modprobe br_netfilter
# 配置内核参数
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
# 应用配置
sysctl --system
sysctl -p /etc/sysctl.d/k8s.conf
# 验证
cat /proc/sys/net/ipv4/ip_forward
# 预期输出:1
2.7 安装 IPVS 相关工具(可选,推荐)
bash
# 所有节点执行
yum install -y ipvsadm ipset conntrack sysstat
# 配置 IPVS 模块自动加载
cat > /etc/modules-load.d/ipvs.conf << EOF
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
ip6_udp_tunnel
udp_tunnel
EOF
# 加载模块
modprobe ip_vs
modprobe ip_vs_rr
modprobe ip_vs_wrr
modprobe ip_vs_sh
modprobe nf_conntrack
# 验证
lsmod | grep ip_vs
说明:IPVS 是 Kubernetes Service 的高性能负载均衡实现,相比 iptables 在大规模集群下性能更优。
2.8 初始化完成后重启(如必要)
bash
# 如果修改了 SELinux,建议重启所有节点
reboot
三、容器运行时安装(所有节点)
本文推荐使用 containerd 作为容器运行时,它是 Kubernetes 默认支持的 CRI 实现。
3.1 安装 containerd
bash
# 所有节点执行
# 检查当前 containerd 版本
yum list containerd
# openEuler 24.03 默认源提供 1.6.22 版本,如需更高版本可使用 Docker CE 源
yum install -y containerd
# 如需更高版本,使用 Docker CE 源(推荐)
dnf 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
dnf install -y containerd.io
3.2 安装 CNI 组件
bash
# 所有节点执行
mkdir -p /opt/cni/bin
# 下载 CNI 插件(AMD64 架构)
cd /opt/cni/bin
wget --no-check-certificate https://github.com/containernetworking/plugins/releases/download/v1.5.1/cni-plugins-linux-amd64-v1.5.1.tgz
tar -xzvf ./cni-plugins-linux-amd64-v1.5.1.tgz -C .
# 验证
ls /opt/cni/bin/
openEuler 24.03 注意事项 :ARM64 架构请下载
cni-plugins-linux-arm64-v1.5.1.tgz
3.3 配置 containerd
bash
# 所有节点执行
# 生成默认配置文件
containerd config default > /etc/containerd/config.toml
# 配置 systemd cgroup 驱动
sed -i '/SystemdCgroup/s/=.*/= true/' /etc/containerd/config.toml
# 配置 pause 镜像(使用阿里云镜像加速)
pause_img=$(kubeadm config images list 2>/dev/null | grep pause | head -1 || echo "registry.aliyuncs.com/google_containers/pause:3.9")
sed -i "s|sandbox = \".*\"|sandbox = \"${pause_img}\"|" /etc/containerd/config.toml
# 配置跳过 registry.k8s.io 证书验证(解决拉取镜像问题)
sed -i '/\[plugins."io.containerd.grpc.v1.cri".registry.configs\]/a\ [plugins."io.containerd.grpc.v1.cri".registry.configs."registry.k8s.io".tls]\n insecure_skip_verify = true' /etc/containerd/config.toml
3.4 配置 containerd 服务(代理场景,如需)
bash
# 如服务器需要通过代理访问外网,配置如下
mkdir -p /etc/systemd/system/containerd.service.d
cat > /etc/systemd/system/containerd.service.d/http-proxy.conf << EOF
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:8080"
Environment="HTTPS_PROXY=http://proxy.example.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,kubernetes.default.svc,.cluster.local"
EOF
3.5 启动 containerd
bash
# 所有节点执行
systemctl daemon-reload
systemctl enable --now containerd
systemctl status containerd
# 验证
ctr version
3.6 配置 crictl
bash
# 所有节点执行
cat > /etc/crictl.yaml << EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
# 测试连接
crictl info
四、Kubernetes 安装(所有节点)
4.1 配置 Kubernetes YUM 源
bash
# 所有节点执行
# 使用阿里云镜像源
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.29/rpm/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.29/rpm/repodata/repomd.xml.key
EOF
# 刷新缓存
yum clean all
yum makecache
4.2 安装 Kubernetes 组件
bash
# 所有节点执行
yum install -y kubelet kubeadm kubectl kubernetes-cni cri-tools
# 锁定版本(避免意外升级)
yum versionlock kubelet kubeadm kubectl
# 验证安装
kubeadm version
kubelet --version
kubectl version --client
4.3 配置 kubelet cgroup 驱动
bash
# 所有节点执行
# 配置 kubelet 使用 systemd cgroup driver
cat > /etc/sysconfig/kubelet << EOF
KUBELET_EXTRA_ARGS="--runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice"
EOF
# 启用 kubelet(暂不启动,初始化后再启动)
systemctl enable kubelet
五、集群初始化(Master 节点)
5.1 生成初始化配置文件
bash
# 仅在 Master 节点执行
cd ~
# 生成默认配置
kubeadm config print init-defaults --component-configs KubeletConfiguration > kubeletConfig.yaml
# 编辑配置文件
vim kubeletConfig.yaml
修改后的 kubeletConfig.yaml 示例:
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.33.30 # 修改为 Master IP
bindPort: 6443
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
imagePullPolicy: IfNotPresent
name: k8s-master # 修改为 Master 主机名
taints: null
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers # 使用阿里云镜像
kind: ClusterConfiguration
kubernetesVersion: 1.29.4
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
podSubnet: 10.244.0.0/16 # Flannel 网段
scheduler: {}
5.2 预拉取镜像(可选,推荐)
bash
# 仅在 Master 节点执行
# 关闭代理(如有)
unset http_proxy https_proxy
# 预拉取所有需要的镜像
kubeadm config images pull --config=kubeletConfig.yaml
# 查看已拉取的镜像
crictl images
5.3 初始化集群
bash
# 仅在 Master 节点执行
# 确保关闭代理
unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY
# 执行初始化
kubeadm init --config=kubeletConfig.yaml
# 预期输出包含:
# - kubeadm join 192.168.33.30:6443 --token xxx --discovery-token-ca-cert-hash sha256:xxx
# 请记录此命令,Worker 节点加入时需要使用
⚠️ 常见问题:如果初始化失败,检查:
- 代理是否关闭
- containerd 是否正常运行
/etc/hosts是否正确配置
5.4 配置 kubectl
bash
# 仅在 Master 节点执行
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# 验证配置
export KUBECONFIG=$HOME/.kube/config
kubectl get nodes
5.5 安装网络插件(Master 节点)
5.5.1 安装 Flannel(推荐,简单)
bash
# 仅在 Master 节点执行
# 下载 Flannel YAML
wget https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml --no-check-certificate -O kube-flannel.yml
# 如果无法直接下载,可创建以下内容
cat > kube-flannel.yml << 'EOF'
---
kind: Namespace
apiVersion: v1
metadata:
name: kube-flannel
labels:
k8s-app: flannel
pod-security.kubernetes.io/enforce: privileged
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: flannel
name: flannel
rules:
- apiGroups:
- networking.k8s.io
resources:
- networkpolicies
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
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
kind: ServiceAccount
metadata:
labels:
k8s-app: flannel
name: flannel
namespace: kube-flannel
---
kind: ConfigMap
apiVersion: v1
metadata:
name: kube-flannel-cfg
namespace: kube-flannel
labels:
tier: node
k8s-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
namespace: kube-flannel
labels:
tier: node
app: flannel
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
tier: node
app: flannel
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
hostNetwork: true
priorityClassName: system-node-critical
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni-plugin
image: docker.io/flannel/flannel-cni-plugin:v1.4.0-flannel1
command:
- cp
args:
- -f
- /flannel
- /host/opt/cni/bin/flannel
volumeMounts:
- name: cni-plugin
mountPath: /host/opt/cni/bin
containers:
- args:
- --ip-masq
- --kube-subnet-mgr
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: docker.io/flannel/flannel:v0.25.1
name: kube-flannel
command:
- /opt/bin/flanneld
resources:
requests:
cpu: 100m
memory: 50Mi
limits:
memory: 500Mi
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_RAW
privileged: false
volumeMounts:
- name: run
mountPath: /run/flannel
- name: flannel-cfg
mountPath: /etc/kube-flannel/
- name: xtables-lock
mountPath: /run/xtables.lock
volumes:
- name: run
hostPath:
path: /run/flannel
- name: cni-plugin
hostPath:
path: /opt/cni/bin
type: DirectoryOrCreate
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
- name: xtables-lock
hostPath:
path: /run/xtables.lock
type: FileOrCreate
EOF
# 应用 Flannel
kubectl apply -f kube-flannel.yml
# 查看 Flannel Pod 状态
kubectl get pods -n kube-flannel
5.5.2 验证 Master 节点状态
bash
# Master 节点执行
kubectl get nodes
# 预期输出:
# NAME STATUS ROLES AGE VERSION
# k8s-master Ready control-plane 2m v1.29.4
注意:Master 节点初始化后默认带有污点(Taint),如需在 Master 上运行 Pod,需要额外处理:
bash
# 允许 Master 节点调度 Pod(可选,仅用于测试环境)
kubectl taint nodes k8s-master node-role.kubernetes.io/control-plane:NoSchedule-
六、Worker 节点加入
6.1 在 Worker 节点执行前置配置
Worker 节点需要完成 第二章 的所有前置配置,以及 第三章、第四章 的容器运行时和 Kubernetes 安装。
6.2 获取加入命令
如果之前的 kubeadm init 输出已丢失,在 Master 节点执行:
bash
# Master 节点执行
kubeadm token create --print-join-command
# 预期输出示例:
# kubeadm join 192.168.33.30:6443 --token abcdef.0123456789abcdef \
# --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
6.3 Worker 节点加入集群
bash
# Worker 节点执行
# 确保关闭代理
unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY
# 使用上一步获取的 join 命令执行
kubeadm join 192.168.33.30:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# 如果使用 containerd,无需额外指定 --cri-socket
# 如果使用 cri-docker,需要添加:--cri-socket unix:///var/run/cri-dockerd.sock
6.4 验证集群状态
bash
# 在 Master 节点执行
kubectl get nodes
# 预期输出:
# NAME STATUS ROLES AGE VERSION
# k8s-master Ready control-plane 5m v1.29.4
# k8s-node1 Ready <none> 1m v1.29.4
# k8s-node2 Ready <none> 30s v1.29.4
6.5 为 Worker 节点添加角色标签(可选)
bash
# Master 节点执行
kubectl label node k8s-node1 node-role.kubernetes.io/worker=worker
kubectl label node k8s-node2 node-role.kubernetes.io/worker=worker
# 再次查看
kubectl get nodes
七、集群验证与基础使用
7.1 组件健康检查
bash
# Master 节点执行
# 检查所有系统 Pod 状态
kubectl get pods -A
# 预期输出(所有 Pod 应为 Running 状态):
# NAMESPACE NAME READY STATUS RESTARTS AGE
# kube-flannel kube-flannel-ds-xxxxx 1/1 Running 0 2m
# kube-system coredns-xxxxx 1/1 Running 0 5m
# kube-system etcd-k8s-master 1/1 Running 0 5m
# kube-system kube-apiserver-k8s-master 1/1 Running 0 5m
# kube-system kube-controller-manager-k8s-master 1/1 Running 0 5m
# kube-system kube-proxy-xxxxx 1/1 Running 0 5m
# kube-system kube-scheduler-k8s-master 1/1 Running 0 5m
7.2 创建测试 Pod
bash
# Master 节点执行
# 创建测试命名空间
kubectl create namespace test
# 部署 nginx 测试
cat > nginx-test.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-test
namespace: test
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: test
spec:
selector:
app: nginx
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30080
EOF
kubectl apply -f nginx-test.yaml
# 查看 Pod 状态
kubectl get pods -n test
# 查看 Service
kubectl get svc -n test
# 测试访问
curl http://k8s-node1:30080
# 或
curl http://k8s-node2:30080
7.3 集群基础命令汇总
bash
# 节点操作
kubectl get nodes # 查看所有节点
kubectl describe node <node-name> # 查看节点详情
kubectl cordon <node-name> # 标记节点为不可调度
kubectl uncordon <node-name> # 标记节点为可调度
kubectl drain <node-name> # 驱逐节点上的 Pod
# Pod 操作
kubectl get pods -A # 查看所有 Pod
kubectl logs <pod-name> -n <namespace> # 查看 Pod 日志
kubectl exec -it <pod-name> -n <namespace> -- /bin/sh # 进入 Pod
# Deployment 操作
kubectl get deployments -A # 查看所有 Deployment
kubectl scale deployment <name> --replicas=3 -n <namespace> # 扩缩容
kubectl rollout restart deployment/<name> -n <namespace> # 重启 Deployment
# 清理测试资源
kubectl delete -f nginx-test.yaml
kubectl delete namespace test
八、常见问题排查
8.1 节点状态为 NotReady
问题描述 :节点加入集群后状态一直是 NotReady。
排查步骤:
bash
# 1. 检查 kubelet 状态
systemctl status kubelet
# 2. 查看 kubelet 日志
journalctl -u kubelet -f --no-pager
# 3. 检查 containerd 状态
systemctl status containerd
# 4. 检查节点详情
kubectl describe node <node-name>
常见原因:
- 网络插件未安装或运行异常 → 参考 5.5 节重新部署 Flannel
- 容器镜像拉取失败 → 检查网络和镜像配置
- kubelet 与 API Server 通信异常 → 检查防火墙和
~/.kube/config
解决方案:
bash
# 重启 kubelet
systemctl restart kubelet
# 如节点仍有问题,可以重新加入
# 在问题节点执行
kubeadm reset --cri-socket unix:///run/containerd/containerd.sock
# 然后重新执行 join 命令
8.2 Pod 状态为 CrashLoopBackOff
问题描述:Pod 持续重启,无法正常运行。
排查步骤:
bash
# 查看 Pod 详情
kubectl describe pod <pod-name> -n <namespace>
# 查看日志
kubectl logs <pod-name> -n <namespace> --previous
常见原因:
| 原因 | 解决方案 |
|---|---|
| 镜像拉取失败 | 检查镜像配置,使用代理或配置国内镜像源 |
| 配置错误 | 检查 ConfigMap 和环境变量 |
| 资源不足 | 检查 CPU/内存限制,调整资源配置 |
| SELinux 阻止 | 确认 SELinux 已禁用 |
| 端口冲突 | 检查 Service 和 Pod 端口配置 |
8.3 CoreDNS 一直处于 Pending 状态
问题描述 :集群安装完成后 CoreDNS Pod 一直是 Pending 状态。
排查步骤:
bash
# 查看 CoreDNS Pod 详情
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl describe pod <coredns-pod-name> -n kube-system
常见原因:网络插件(Flannel/Calico)未正确安装。
解决方案:
bash
# 重新部署 Flannel
kubectl delete -f kube-flannel.yml
kubectl apply -f kube-flannel.yml
# 等待几分钟后检查
kubectl get pods -n kube-flannel
kubectl get pods -n kube-system
8.4 Worker 节点无法加入集群
问题描述 :执行 kubeadm join 命令时报错。
排查步骤:
bash
# 1. 检查 token 是否过期(默认24小时)
kubeadm token list
# 2. 如果 token 已过期,生成新的
kubeadm token create --print-join-command
# 3. 检查端口是否开放
telnet 192.168.33.30 6443
# 4. 检查时间同步
timedatectl status
解决方案:
bash
# 在 Master 节点生成新的 join 命令
kubeadm token create --print-join-command
# 关闭代理
unset http_proxy https_proxy
# 在 Worker 节点重新执行 join
8.5 镜像拉取失败
问题描述:Pod 创建时提示镜像拉取失败。
排查步骤:
bash
# 查看 Pod 事件
kubectl describe pod <pod-name>
# 手动测试镜像拉取
crictl pull nginx:alpine
常见原因:
- 网络无法访问
registry.k8s.io - 镜像不存在或版本错误
解决方案:
bash
# 配置代理(如需要)
export http_proxy=http://proxy.example.com:8080
export https_proxy=http://proxy.example.com:8080
# 或配置 containerd 代理(参考 3.4 节)
# 或使用国内镜像源
# 修改 /etc/containerd/config.toml 中的 sandbox_image
8.6 kubelet 无法启动
问题描述:kubelet 服务启动失败。
排查步骤:
bash
# 查看 kubelet 日志
journalctl -xe -u kubelet --no-pager
# 检查配置文件
cat /etc/kubernetes/kubelet.conf
cat /etc/sysconfig/kubelet
常见原因:
- 缺少
admin.conf配置文件 - cgroup 驱动配置错误
- 容器运行时未运行
解决方案:
bash
# 确保 containerd 运行正常
systemctl status containerd
# 重新生成 kubelet 配置
rm -rf /etc/kubernetes/kubelet.conf
systemctl restart kubelet
8.7 网络不通(Pod 之间无法通信)
问题描述:不同节点的 Pod 之间无法通信。
排查步骤:
bash
# 1. 检查 Flannel Pod
kubectl get pods -n kube-flannel
kubectl logs <flannel-pod-name> -n kube-flannel
# 2. 检查节点上的 flannel 接口
ip addr show flannel.1
ip route show
# 3. 检查 iptables 规则
iptables -L -n
解决方案:
bash
# 重启 Flannel
kubectl delete pods -n kube-flannel -l app=flannel
# 检查内核模块
lsmod | grep br_netfilter
# 重新加载 br_netfilter
modprobe br_netfilter
sysctl -p /etc/sysctl.d/k8s.conf
8.8 性能问题排查
bash
# 检查节点资源使用
kubectl top nodes
# 检查 Pod 资源使用
kubectl top pods -A
# 查看节点磁盘使用
df -h
# 查看内存使用
free -h
九、后续优化建议
9.1 启用 IPVS 负载均衡
bash
# Master 节点执行
# 安装 ipvsadm
yum install -y ipvsadm
# 修改 kube-proxy 配置
kubectl edit configmap kube-proxy -n kube-system
# 将 mode: "" 改为 mode: "ipvs"
# 重启 kube-proxy
kubectl rollout restart daemonset kube-proxy -n kube-system
9.2 配置 Metrics Server(可选)
bash
# 启用 top 命令需要安装 metrics-server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# 修改 deployment 添加 --kubelet-insecure-tls 参数
kubectl edit deployment metrics-server -n kube-system
9.3 配置 Kubernetes Dashboard(可选)
bash
# 部署 Dashboard
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
# 创建 admin 用户
cat > admin-user.yaml << EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
EOF
kubectl apply -f admin-user.yaml
# 获取 Token
kubectl -n kubernetes-dashboard create token admin-user
9.4 配置日志收集(可选)
推荐使用 ELK Stack 或 Loki 进行日志收集:
bash
# Loki + Grafana 部署示例
helm repo add grafana https://grafana.github.io/helm-charts
helm install loki grafana/loki-stack -n monitoring --create-namespace
十、总结
本文详细介绍了在 openEuler 24.03 LTS 系统上部署 K8S 单 Master 集群的完整流程,包括:
- ✅ 环境准备与节点规划
- ✅ 系统前置配置(防火墙、SELinux、Swap、内核参数)
- ✅ 容器运行时 containerd 安装与配置
- ✅ Kubernetes 组件安装
- ✅ 集群初始化与网络插件部署
- ✅ Worker 节点加入集群
- ✅ 集群验证与基础使用
- ✅ 常见问题排查指南
openEuler 24.03 特别说明:
- 内核 6.6 默认支持所有 Kubernetes 所需特性
- 使用 containerd 作为容器运行时,无需额外安装 Docker
- 建议使用阿里云或华为云镜像源加速镜像拉取
- 部署前确保所有节点时间同步