K8S 单 Master 集群在 openEuler 24.03 上的部署指南

一、环境准备

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 节点加入时需要使用

⚠️ 常见问题:如果初始化失败,检查:

  1. 代理是否关闭
  2. containerd 是否正常运行
  3. /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 StackLoki 进行日志收集:

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 集群的完整流程,包括:

  1. ✅ 环境准备与节点规划
  2. ✅ 系统前置配置(防火墙、SELinux、Swap、内核参数)
  3. ✅ 容器运行时 containerd 安装与配置
  4. ✅ Kubernetes 组件安装
  5. ✅ 集群初始化与网络插件部署
  6. ✅ Worker 节点加入集群
  7. ✅ 集群验证与基础使用
  8. ✅ 常见问题排查指南

openEuler 24.03 特别说明

  • 内核 6.6 默认支持所有 Kubernetes 所需特性
  • 使用 containerd 作为容器运行时,无需额外安装 Docker
  • 建议使用阿里云或华为云镜像源加速镜像拉取
  • 部署前确保所有节点时间同步
相关推荐
运维开发故事3 天前
基于 Arthas 的多集群在线诊断系统设计与实现
kubernetes
Patrick_Wilson4 天前
从「改个端口」到 502:Next.js on k8s 的容器端口、Service 映射与 env 覆盖
docker·kubernetes·next.js
探索云原生5 天前
K8s 1.36 这个 GA 特性,把 initContainer 拉模型的 hack 干掉了
ai·云原生·kubernetes
云恒要逆袭5 天前
运行你的第一个Docker容器
后端·docker·容器
Java之美6 天前
一次k8s升级引发的DevicePlugin注册失败
云原生·kubernetes
程序员老赵7 天前
10 分钟部署 OpenCode:Docker 一键安装,浏览器打开就能用 AI 写代码(附完整命令与排错)
docker·容器·ai编程
两个人的幸福9 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
武子康10 天前
调查研究-183 Apple container:Mac 上用轻量 VM 跑 Linux 容器,Swift 会改写本地容器体验吗?
docker·容器·apple
BingoGo11 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php