本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:Kubernetes(k8s)是容器编排领域的主流标准,广泛用于微服务的部署与管理。本文深入讲解通过二进制方式搭建k8s集群的完整流程,适用于希望深度掌握系统架构与组件原理的IT管理员。内容涵盖k8s架构解析、Master与Worker节点组件部署、环境准备、kubeconfig配置、CNI网络插件集成及集群状态验证。该方法虽复杂但灵活可控,有助于实现高可用与定制化集群建设,是进阶学习k8s的核心实践路径。
k8s(kubernetes)集群的两种搭建方式(二进制方式)

1. Kubernetes集群架构核心原理与组件解析

控制平面与工作节点的协同机制

Kubernetes采用经典的Master/Worker架构模型,控制平面(Control Plane)运行于Master节点,负责集群状态管理与决策。API Server作为唯一入口,接收并校验请求后写入etcd持久化存储;Controller Manager通过监听etcd变化,确保实际状态向期望状态收敛;Scheduler依据资源可用性将Pod调度至合适Worker节点。整个控制流以API Server为中心,通过watch机制实现各组件间高效事件驱动通信。

核心组件功能职责与数据流路径

etcd作为分布式键值存储,保存集群所有对象状态,其一致性协议保障高可用;kubelet在Worker节点上对接容器运行时(如Docker),执行Pod创建、启动、健康检查等生命周期操作;kube-proxy则通过iptables/ipvs规则实现Service抽象的负载均衡。控制平面组件间通过HTTPS安全通信,Worker节点经TLS认证接入,形成从声明式配置到实际运行态的完整闭环。

graph TD
    A[User/kubectl] -->|REST API| B(API Server)
    B --> C{etcd}
    B --> D(Controller Manager)
    D --> B
    B --> E(Scheduler)
    E --> B
    B --> F[kubelet]
    F --> G[Docker/CRI]
    F --> H[kube-proxy]
    H --> I(Network Policy)

该架构支持水平扩展与故障自愈,为后续二进制部署提供清晰的组件依赖关系与配置边界。

2. 二进制部署前期准备与基础环境构建

在进行 Kubernetes 集群的二进制部署前,必须完成一系列系统级和网络级的准备工作。这些前置步骤不仅决定了后续组件能否顺利安装与通信,更直接影响集群的稳定性、安全性和可维护性。本章将围绕“部署规划”、“系统配置”、“依赖安装”以及“自动化初始化”四个方面展开深入实践指导,帮助读者从零开始搭建一个符合生产要求的基础环境。

2.1 部署规划与网络拓扑设计

成功的 Kubernetes 二进制部署始于清晰的架构规划。不同于使用 kubeadm 等工具自动完成大部分配置,二进制方式要求运维人员对每台主机的角色、IP 分配策略、通信路径有精确掌控。合理的网络拓扑设计是实现高可用、低延迟通信的前提。

2.1.1 节点角色划分与IP地址分配策略

Kubernetes 典型采用 Master/Worker 架构模型,但在生产环境中通常会进一步细化节点职责,并引入高可用机制。

角色定义与推荐部署结构
节点类型 功能描述 建议数量 是否需独立网段
Control Plane(Master) 运行 API Server、etcd、Controller Manager、Scheduler ≥3(奇数)
Worker 运行 kubelet、kube-proxy、容器运行时,承载 Pod 工作负载 ≥2
Load Balancer 提供虚拟 IP(VIP),转发 API Server 请求 2(Keepalived + Nginx)
Bastion Host 运维跳板机,用于集中管理所有节点 1

说明 :为避免脑裂问题,etcd 集群建议使用奇数个节点(3或5)。Control Plane 组件可与 etcd 共存于同一物理节点,但生产环境下建议分离以提升稳定性。

示例 IP 地址分配表(私有网络:192.168.100.0/24)
主机名 角色 内网 IP 用途说明
k8s-master-01 Master + etcd member 192.168.100.11 控制平面主节点
k8s-master-02 Master + etcd member 192.168.100.12 控制平面备节点
k8s-master-03 Master + etcd member 192.168.100.13 控制平面备节点
k8s-worker-01 Worker Node 192.168.100.21 应用工作节点
k8s-worker-02 Worker Node 192.168.100.22 应用工作节点
lb-vip Virtual IP (Nginx LB) 192.168.100.100 对外提供统一 API Server 接入点
bastion-host Jump Server 192.168.100.1 所有操作从此发起

该分配方案确保了控制平面三节点高可用,同时预留足够 Worker 节点扩展空间。VIP(Virtual IP)通过 Keepalived 实现漂移,保障 API Server 的持续可用。

graph TD
    A[Bastion Host] --> B(k8s-master-01)
    A --> C(k8s-master-02)
    A --> D(k8s-master-03)
    A --> E(k8s-worker-01)
    A --> F(k8s-worker-02)

    G[Nginx Load Balancer] --> H(API Server on Masters)
    H --> I(etcd Cluster)
    J[Client Tools (kubectl)] --> G

    style A fill:#f9f,stroke:#333
    style G fill:#bbf,stroke:#333,color:#fff
    style H fill:#f96,stroke:#333

上图展示了典型的访问链路:客户端通过 LB 访问 API Server,所有操作经由跳板机执行,形成清晰的安全边界与流量路径。

子网与 VLAN 划分建议
  • 管理网段(Management Network) :192.168.100.0/24,用于 SSH、监控、日志收集。
  • Pod 网络(Pod CIDR) :建议使用独立大子网如 10.244.0.0/16(Flannel 默认),避免与 Service CIDR 冲突。
  • Service 网络(Service CIDR) :如 10.96.0.0/12,用于 ClusterIP 分配。

参数说明:
- Pod CIDR 必须在 CNI 插件中统一配置,每个节点获得唯一子网段;
- Service CIDR 需在 kube-apiserver 启动参数中指定,影响 Service IP 分配范围;
- 所有 CIDR 不应重叠,且尽量避开企业已有内网地址段。

2.1.2 主机名解析与内部通信网络配置

在无 DNS 服务的企业环境中,必须通过 /etc/hosts 实现节点间名称解析,否则证书校验将失败(因 SANs 包含主机名)。

手动配置 /etc/hosts 示例

在每一台节点上添加如下内容:

# /etc/hosts
192.168.100.11  k8s-master-01
192.168.100.12  k8s-master-02
192.168.100.13  k8s-master-03
192.168.100.21  k8s-worker-01
192.168.100.22  k8s-worker-02
192.168.100.100 lb-vip

逻辑分析
Kubernetes 组件之间通过 HTTPS 相互通信,TLS 证书中的 Subject Alternative Names(SANs)包含主机名(如 k8s-master-01),若无法解析会导致连接拒绝。因此静态 hosts 映射是必要手段,尤其在未部署内部 DNS 时。

检查连通性脚本示例
#!/bin/bash
NODES=("k8s-master-01" "k8s-master-02" "k8s-master-03" "k8s-worker-01" "k8s-worker-02")

for node in "${NODES[@]}"; do
    if ping -c 2 "$node" &> /dev/null; then
        echo "[OK] $node is reachable"
    else
        echo "[ERROR] Cannot reach $node"
    fi
done

逐行解读
1. 定义数组 NODES 存储所有节点主机名;
2. 使用 ping -c 2 发送两个 ICMP 包检测可达性;
3. &> /dev/null 屏蔽标准输出和错误输出;
4. 根据退出码判断结果并打印状态信息。

此脚本可用于批量验证网络连通性,建议集成到 Ansible Playbook 中执行。

网络 MTU 设置建议

若跨节点通信经过 VXLAN 或 GRE 封装(如 Flannel VXLAM 模式),需调整接口 MTU 至 1450 字节以下,防止分片导致性能下降。

# 修改网卡 MTU(以 ens33 为例)
ip link set dev ens33 mtu 1450

参数说明:
- dev ens33 :目标网络接口;
- mtu 1450 :设置最大传输单元为 1450 字节(原始 1500 减去 VXLAN 头部开销约 50 字节);
- 若使用 host-gw 模式(二层直连),可保持默认 1500。

2.1.3 安全边界设定与防火墙规则预置

尽管 Kubernetes 组件本身具备认证与加密机制,但操作系统层级的防火墙仍不可或缺,尤其是在暴露公网的边缘节点上。

关键端口清单与作用说明
协议 端口 来源 → 目标 用途
TCP 22 Bastion → All Nodes SSH 管理
TCP 6443 LB → Masters API Server HTTPS 端口
TCP 2379-2380 etcd members 互访 etcd peer communication
TCP 10250 API Server → Workers kubelet API(HTTPS)
TCP 10251 API Server → Scheduler kube-scheduler health
TCP 10252 API Server → Controller Manager controller-manager health
TCP 30000-32767 External Clients → NodePorts NodePort 类型 Service 暴露
UDP 8285, 8472 Flannel VXLAN 模式 VXLAN 封装通信

注:具体端口可能因版本略有差异,请参考官方文档对应版本说明。

firewalld 规则配置示例(CentOS/RHEL)
# 开启必要端口
sudo firewall-cmd --permanent --add-port=6443/tcp
sudo firewall-cmd --permanent --add-port=2379-2380/tcp
sudo firewall-cmd --permanent --add-port=10250/tcp
sudo firewall-cmd --permanent --add-port=10251/tcp
sudo firewall-cmd --permanent --add-port=10252/tcp
sudo firewall-cmd --permanent --add-port=8285/udp
sudo firewall-cmd --permanent --add-port=8472/udp

# 重新加载规则
sudo firewall-cmd --reload

逻辑分析
- --permanent 表示永久生效,重启不失效;
- --add-port 添加指定协议端口;
- --reload 重载防火墙规则而不中断现有连接;
- 若使用 iptables 替代,需编写相应规则链并持久化保存。

安全加固建议
  • 最小开放原则 :仅开放必需端口,关闭不必要的服务(如 telnet、ftp);
  • 启用日志记录 :配置 firewall-cmd --set-log-denied=all 记录被拒流量;
  • 限制源 IP :对于敏感端口(如 6443),可通过 --source 参数限定仅允许 LB 或特定运维网段访问;
  • 定期审计规则 :使用 firewall-cmd --list-all 检查当前策略是否合规。
flowchart LR
    A[External Client] --> B{Firewall Rule}
    B -->|Allowed| C[API Server:6443]
    B -->|Denied| D[Log & Drop]
    C --> E[kube-apiserver Process]
    E --> F[Authenticate & Authorize]
    F --> G[Forward to etcd/kubelet]

流程图展示了请求进入后的处理流程:先经过防火墙过滤,再由 API Server 执行身份验证与授权,最终调度到底层组件。这体现了多层防护的设计思想。


2.2 系统级前置条件配置

操作系统级别的调优是保障 Kubernetes 稳定运行的关键环节。不当的内核参数或资源限制可能导致组件崩溃、调度异常甚至数据丢失。

2.2.1 关闭Swap分区与SELinux安全模块

关闭 Swap

Kubernetes 官方明确禁止启用 Swap,因为当内存不足时,Linux 可能将关键进程换出至磁盘,导致 kubelet 或容器响应延迟,进而触发误判驱逐。

# 临时关闭
sudo swapoff -a

# 永久关闭:注释 /etc/fstab 中 swap 行
sudo sed -i '/swap/s/^/#/' /etc/fstab

# 验证是否已关闭
free -h | grep Swap

输出应为:

Swap: 0B 0B 0B

参数说明
- swapoff -a :立即禁用所有 swap 分区;
- sed 命令通过正则匹配包含 “swap” 的行并在行首加 # 注释掉;
- /etc/fstab 是开机挂载配置文件,修改后需重启才能彻底生效。

注意:某些发行版(如 Ubuntu)默认启用 swapfile,也需一并处理。

关闭 SELinux

SELinux 在严格模式下可能阻止 Docker 或 kubelet 访问关键目录(如 /var/lib/kubelet ),导致 Pod 创建失败。

# 临时设置为 permissive 模式
sudo setenforce 0

# 永久关闭
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config

# 验证状态
getenforce

预期输出: Disabled

风险提示 :完全禁用 SELinux 会降低系统安全性。替代方案是在 enforcing 模式下编写自定义策略模块,但这对新手较复杂。生产环境建议结合审计日志逐步调优而非直接关闭。

2.2.2 时间同步服务(NTP)部署与时钟一致性保障

分布式系统高度依赖时间一致性。若节点间时钟偏差超过几秒,可能引发证书验证失败、事件排序混乱等问题。

使用 chronyd 配置 NTP 同步
# 安装 chrony
sudo yum install -y chrony

# 编辑配置文件
cat <<EOF | sudo tee /etc/chrony.conf
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst
server ntp3.aliyun.com iburst

driftfile /var/lib/chrony/drift
rtcsync
makestep 1.0 3
logdir /var/log/chrony
EOF

# 启动并设为开机自启
sudo systemctl enable chronyd --now
sudo systemctl restart chronyd

配置项解释
- server ... iburst :指定阿里云 NTP 服务器, iburst 表示初始阶段快速同步;
- driftfile :记录本地时钟漂移速率;
- rtcsync :将系统时钟同步到 RTC(硬件时钟);
- makestep 1.0 3 :若偏移大于 1 秒,在前 3 次更新中直接跳跃调整(避免缓慢追赶);

验证时间同步状态
# 查看跟踪源状态
chronyc sources -v

# 查看偏移量
chronyc tracking

正常输出应显示 ^* 标记的活跃源,且偏移量在毫秒级以内。

建议在所有节点统一使用相同 NTP 源,避免因不同上游造成微小偏差累积。

2.2.3 内核参数优化与sysctl调优建议

合理设置内核参数可显著提升网络性能、文件句柄容量及稳定性。

推荐 sysctl 配置项
# 写入 /etc/sysctl.d/k8s.conf
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
fs.may_detach_mounts = 1
vm.overcommit_memory = 1
kernel.panic = 10
kernel.panic_on_oops = 1
fs.inotify.max_user_watches = 12800000
EOF

# 加载配置
sudo sysctl --system

参数详解
- bridge-nf-call-* :允许 iptables 对 bridge 流量进行过滤,CNI 插件(如 Flannel)依赖此设置;
- ip_forward = 1 :启用 IPv4 转发,跨节点 Pod 通信必需;
- fs.may_detach_mounts :支持频繁挂载/卸载容器镜像层;
- vm.overcommit_memory = 1 :允许内存过量申请,避免 OOM 导致 kubelet 挂起;
- kernel.panic* :发生内核崩溃时自动重启,提高容错能力;
- inotify.max_user_watches :增加文件监控数量,防止大量 ConfigMap/Secret 导致监听耗尽。

验证参数是否生效
sysctl net.ipv4.ip_forward
# 输出应为 1

可编写脚本批量检查所有节点的关键参数一致性,确保集群整体行为一致。

graph TB
    A[Node Initialization Script] --> B[Disable Swap]
    A --> C[Stop SELinux]
    A --> D[Configure NTP]
    A --> E[Tune Kernel Parameters]
    A --> F[Install Docker & Tools]
    B --> G[Ready for K8s Components]
    C --> G
    D --> G
    E --> G
    F --> G

初始化流程图展示了各前置任务之间的依赖关系,所有步骤完成后方可进入组件部署阶段。


2.3 核心依赖组件安装

2.3.1 Docker容器运行时安装与CRI接口适配

虽然 containerd 和 CRI-O 更轻量,但 Docker 仍是广泛使用的运行时选择。

安装 Docker CE(以 CentOS 为例)
# 添加 Docker 官方仓库
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

# 安装指定版本
sudo yum install -y docker-ce-20.10.24 docker-ce-cli-20.10.24 containerd.io

# 启动并设置开机自启
sudo systemctl enable docker --now
配置 daemon.json 支持 Kubernetes
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  },
  "storage-driver": "overlay2"
}

关键参数说明
- cgroupdriver=systemd :与 kubelet 使用相同的 cgroup 驱动,避免不一致导致 Pod 启动失败;
- log-driver :限制日志大小,防止单个容器日志撑爆磁盘;
- storage-driver=overlay2 :推荐的联合文件系统,性能优于 devicemapper。

配置后需重启 Docker:
bash sudo systemctl restart docker

验证 Docker 状态
docker info | grep -E "Cgroup Driver|Storage Driver"

输出应包含:
Cgroup Driver: systemd Storage Driver: overlay2

若显示 cgroupfs ,则需修改 kubelet 启动参数 --cgroup-driver=cgroupfs 保持一致。

2.3.2 证书生成工具cfssl安装与PKI体系搭建准备

Kubernetes 组件间通信依赖 TLS 加密,需使用 cfssl 工具构建私有 CA 体系。

安装 cfssl
curl -L https://pkg.cfssl.org/R1.1/cfssl_linux-amd64 -o /usr/local/bin/cfssl
curl -L https://pkg.cfssl.org/R1.1/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson
chmod +x /usr/local/bin/cfssl /usr/local/bin/cfssljson
初始化 CA 配置模板
{
  "ca-config": {
    "expiry": "87600h",
    "names": [
      { "C": "CN", "L": "Beijing", "O": "Kubernetes", "OU": "CA", "ST": "Beijing" }
    ]
  },
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
          "signing",
          "key encipherment",
          "server auth",
          "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}

存为 ca-config.json ,后续签发证书时引用该配置。

注意: usages server auth client auth 分别用于服务端和客户端身份验证。

2.3.3 命令行工具集(kubectl/kube-proxy/kubelet)下载与校验

从官方渠道获取静态二进制文件。

VERSION=v1.28.4
wget https://dl.k8s.io/${VERSION}/bin/linux/amd64/kubectl
wget https://dl.k8s.io/${VERSION}/bin/linux/amd64/kubelet
wget https://dl.k8s.io/${VERSION}/bin/linux/amd64/kube-proxy

chmod +x kubectl kubelet kube-proxy
sudo mv kubectl kubelet kube-proxy /usr/local/bin/
校验 SHA256 签名(可选但推荐)
echo "$(curl -sSL https://dl.k8s.io/${VERSION}/bin/linux/amd64/kubectl.sha256)  kubectl" | sha256sum -c -

输出 kubectl: OK 表示完整性验证通过。

建议将所有二进制文件集中存储并签名发布,便于版本管理和审计。


2.4 SSH免密登录与批量操作环境搭建

2.4.1 多节点间SSH互信配置流程

在跳板机生成密钥对并分发公钥:

# 生成 RSA 密钥(无需密码)
ssh-keygen -t rsa -b 2048 -N "" -f ~/.ssh/id_rsa

# 使用 ssh-copy-id 分发到各节点
for host in k8s-master-{01..03} k8s-worker-{01..02}; do
    ssh-copy-id -i ~/.ssh/id_rsa.pub "$host"
done

成功后即可实现免密登录,极大简化后续批量操作。

2.4.2 使用Ansible或Shell脚本进行初始化脚本分发

示例 Ansible Playbook(bootstrap.yml)
- hosts: all
  become: yes
  tasks:
    - name: Disable swap
      command: swapoff -a
      when: ansible_swaptotal_mb > 0

    - name: Comment out swap in fstab
      lineinfile:
        path: /etc/fstab
        regexp: '^([^#].*swap.*)$'
        line: '# \1'

    - name: Disable SELinux
      selinux:
        state: disabled

    - name: Install chrony
      yum:
        name: chrony
        state: present

    - name: Start and enable chronyd
      service:
        name: chronyd
        enabled: yes
        state: started

运行命令:

ansible-playbook -i inventory.ini bootstrap.yml

结合动态 inventory 和变量管理,可实现全集群一键初始化,大幅提升部署效率。

推荐将整个部署流程编排为 CI/CD Pipeline,实现版本化、可追溯的自动化交付。

3. 控制平面组件的二进制部署与深度配置

Kubernetes控制平面是整个集群的大脑,承担着资源调度、状态维护、API服务暴露和自动化协调等核心职责。在生产环境中,采用二进制方式手动部署控制平面组件不仅能提升对系统底层机制的理解,还能实现更精细的安全加固与性能调优。本章将深入讲解如何通过源码编译或官方预编译二进制文件,逐个部署etcd、API Server、Controller Manager 和 Scheduler 四大关键组件,并围绕高可用性、安全性与可观察性进行深度配置。

控制平面的稳定性和响应能力直接决定了集群的整体可靠性。每一个组件都运行于Master节点之上,彼此之间通过HTTP/gRPC协议通信,依赖TLS加密保障传输安全,并借助etcd作为唯一可信的数据存储中心。这种松耦合但高度协同的设计模式要求我们在部署时严格遵循启动顺序、证书匹配原则以及网络可达性规则。

接下来的内容将以三节点高可用架构为背景(即3个Master节点),详细展开每个组件的安装流程、配置参数解析、安全策略实施及故障恢复机制设计。特别强调的是,所有操作均基于Linux操作系统(以CentOS Stream 8为例),并假设已完成第二章所述的基础环境准备,包括主机名解析、时间同步、内核优化及cfssl证书工具链就绪。

3.1 etcd高可用集群搭建与数据持久化管理

etcd 是一个分布式的键值存储系统,由CoreOS开发并广泛用于Kubernetes中保存集群的全局配置和状态信息。它使用Raft一致性算法确保多个副本间的数据强一致性,是Kubernetes实现高可用架构的核心依赖之一。在实际部署中,必须将etcd配置为多节点集群模式,避免单点故障导致整个控制平面瘫痪。

3.1.1 etcd集群成员发现机制与peer通信加密配置

构建etcd集群的第一步是明确节点间的发现方式。常见的有静态配置(static)、DNS发现(DNS discovery)和代理发现(etcd proxy)。对于生产环境推荐使用 静态配置 ,因其可控性强、延迟低。

假设有三台Master节点:
- master-1: 192.168.10.11
- master-2: 192.168.10.12
- master-3: 192.168.10.13

每台节点需预先生成TLS证书用于peer间通信加密与客户端认证。以下为 etcd 服务启动时的关键参数说明:

ETCD_NAME="master-1"
ETCD_DATA_DIR="/var/lib/etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.10.11:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.10.11:2379"
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.10.11:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.10.11:2379"
ETCD_INITIAL_CLUSTER="master-1=https://192.168.10.11:2380,master-2=https://192.168.10.12:2380,master-3=https://192.168.10.13:2380"
ETCD_INITIAL_CLUSTER_TOKEN="k8s-etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

上述变量通常写入systemd service文件中的 ExecStart 命令行中。以下是完整示例:

[Unit]
Description=etcd Key-value store
After=network.target

[Service]
Type=notify
EnvironmentFile=-/etc/etcd/env.conf
ExecStart=/usr/local/bin/etcd \
  --name ${ETCD_NAME} \
  --data-dir=${ETCD_DATA_DIR} \
  --listen-peer-urls=${ETCD_LISTEN_PEER_URLS} \
  --listen-client-urls=${ETCD_LISTEN_CLIENT_URLS} \
  --advertise-client-urls=${ETCD_ADVERTISE_CLIENT_URLS} \
  --initial-advertise-peer-urls=${ETCD_INITIAL_ADVERTISE_PEER_URLS} \
  --initial-cluster=${ETCD_INITIAL_CLUSTER} \
  --initial-cluster-token=${ETCD_INITIAL_CLUSTER_TOKEN} \
  --initial-cluster-state=${ETCD_INITIAL_CLUSTER_STATE} \
  --cert-file=/etc/kubernetes/pki/etcd/server.crt \
  --key-file=/etc/kubernetes/pki/etcd/server.key \
  --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt \
  --peer-key-file=/etc/kubernetes/pki/etcd/peer.key \
  --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt \
  --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt \
  --client-cert-auth=true \
  --peer-client-cert-auth=true \
  --auto-compaction-retention=1

[Install]
WantedBy=multi-user.target
参数逻辑分析:
参数 功能说明
--name 节点唯一标识,在集群内不可重复
--data-dir 数据存储路径,建议挂载独立磁盘以提高I/O性能
--listen-peer-urls 监听其他etcd节点连接的地址(内部复制通信)
--listen-client-urls 对外提供读写服务的端口(供API Server调用)
--initial-cluster 初始成员列表,格式为“名称=URL”,必须一致
--initial-cluster-state 首次启动设为 new ;后续扩容设为 existing
--client-cert-auth 启用客户端证书验证,增强安全性

⚠️ 注意:所有节点的 initial-cluster 字段必须完全相同,否则会导致集群分裂。

为了可视化节点间通信关系,可以使用Mermaid绘制拓扑图:

graph TD
    A[master-1:2380] --> B[master-2:2380]
    A --> C[master-3:2380]
    B --> A
    B --> C
    C --> A
    C --> B
    subgraph etcd Cluster
        A; B; C
    end

该图展示了三个etcd节点通过2380端口建立全互联的gRPC通信链路,构成一个Raft共识组。任一节点宕机后,其余两节点仍可达成多数派决策,维持集群可用。

此外,peer通信启用双向TLS(mTLS)后,任何未授权节点无法加入集群,有效防止中间人攻击。证书签发应统一由私有CA完成,具体将在下一节详述。

3.1.2 使用cfssl签发TLS证书实现安全访问

安全通信的前提是建立完整的PKI体系。我们使用 cfssl 工具创建根CA,并为其签发server、peer、client三类证书。

步骤一:生成etcd CA证书
// ca-csr.json
{
  "CN": "etcd",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "Beijing",
      "O": "Kubernetes",
      "OU": "System"
    }
  ],
  "ca": {
    "expiry": "87600h"
  }
}

执行命令生成CA:

cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

输出: ca.pem , ca-key.pem

步骤二:签发各节点Server证书

创建CSR模板 server-csr.json

{
  "CN": "etcd-server",
  "hosts": [
    "127.0.0.1",
    "192.168.10.11",
    "192.168.10.12",
    "192.168.10.13"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "Beijing",
      "O": "Kubernetes",
      "OU": "System"
    }
  ]
}

分别替换IP后签名:

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=../ca-config.json -profile=server server-csr.json | cfssljson -bare server

同理生成 peer.crt/key 用于节点间通信。

最终目录结构如下:

/etc/kubernetes/pki/etcd/
├── ca.crt
├── ca.key
├── peer.crt
├── peer.key
├── server.crt
└── server.key

这些证书需复制到所有Master节点对应路径,并设置权限为 600

🔐 安全建议:私钥文件仅允许root用户读取,禁用world-readable权限。

3.1.3 数据目录设置与快照备份恢复策略

etcd默认不自动清理历史版本数据,随着时间推移会积累大量mvcc revisions,影响性能甚至耗尽磁盘空间。因此必须配置定期压缩与快照备份。

自动压缩配置

在启动参数中添加:

--auto-compaction-retention=1

表示保留最近1小时内的修订记录,超出部分自动压缩。

手动快照备份

定期执行快照命令:

ETCDCTL_API=3 etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/client.crt \
  --key=/etc/kubernetes/pki/etcd/client.key \
  snapshot save /backup/etcd-snapshot.db

输出结果包含哈希校验值,可用于验证完整性。

恢复流程(灾难场景)

当主集群损坏时,可通过快照重建新集群:

etcdutl snapshot restore /backup/etcd-snapshot.db \
  --name master-1 \
  --data-dir /var/lib/etcd \
  --initial-cluster "master-1=https://192.168.10.11:2380" \
  --initial-cluster-token k8s-etcd-cluster \
  --initial-advertise-peer-urls https://192.168.10.11:2380

📌 注意:恢复后的集群被视为全新实体,原集群编号失效,需重新配置API Server指向。

下面表格总结了常见运维操作及其用途:

操作 命令工具 场景
查看成员列表 etcdctl member list 确认集群节点健康状态
添加新节点 etcdctl member add 动态扩容
删除故障节点 etcdctl member remove <id> 清理离线实例
数据一致性检查 etcdctl check perf 性能压测与延迟检测
KV查询调试 etcdctl get "" --prefix 排查资源存储异常

综上所述,etcd不仅是数据中枢,更是集群稳定性的基石。只有在合理规划网络、正确配置证书、持续监控数据增长的前提下,才能支撑起大规模Kubernetes集群的长期运行。

3.2 API Server服务部署与安全加固

API Server 是 Kubernetes 控制平面的前端入口,所有kubectl命令、控制器、调度器乃至Web UI都必须通过它来访问或修改集群状态。它是唯一与etcd直接交互的组件,具备认证、鉴权、准入控制三大安全防线,堪称“集群守门人”。

3.2.1 启动参数详解:绑定地址、认证方式与授权模式

API Server 的功能强大源于其丰富的启动参数配置。以下是最典型的高可用部署参数集:

/usr/local/bin/kube-apiserver \
  --advertise-address=192.168.10.11 \
  --bind-address=0.0.0.0 \
  --secure-port=6443 \
  --insecure-port=0 \
  --etcd-servers=https://192.168.10.11:2379,https://192.168.10.12:2379,https://192.168.10.13:2379 \
  --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt \
  --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt \
  --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key \
  --client-ca-file=/etc/kubernetes/pki/ca.crt \
  --tls-cert-file=/etc/kubernetes/pki/apiserver.crt \
  --tls-private-key-file=/etc/kubernetes/pki/apiserver.key \
  --service-account-key-file=/etc/kubernetes/pki/sa.pub \
  --service-cluster-ip-range=10.96.0.0/12 \
  --service-node-port-range=30000-32767 \
  --allow-privileged=true \
  --authorization-mode=Node,RBAC \
  --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
  --audit-log-path=/var/log/kubernetes/audit.log \
  --audit-log-maxage=30 \
  --audit-log-maxbackup=3 \
  --v=2
关键参数逐行解读:
参数 作用
--advertise-address 向集群内部通告自身IP,用于Service endpoints注册
--bind-address=0.0.0.0 绑定所有接口,外部LB可访问
--secure-port=6443 HTTPS服务端口,标准配置
--insecure-port=0 禁用HTTP非安全端口,强制加密
--etcd-servers 连接etcd集群的地址列表,支持多节点负载
--client-ca-file 验证客户端证书的CA,启用X509认证
--authorization-mode=Node,RBAC 先由Node插件放行kubelet请求,再交由RBAC细粒度授权
--enable-admission-plugins 启用准入控制器,拦截非法操作(如超限Pod)
--audit-log-* 开启审计日志,满足合规要求

其中, authorization-mode 的执行顺序是从左到右,一旦任一模块允许即通过。 Node 模式专为kubelet设计,允许其根据Pod绑定关系发起请求; RBAC 则适用于用户和服务账户的权限划分。

3.2.2 与etcd后端存储对接及健康检查机制配置

API Server通过gRPC连接etcd,默认使用长连接保持高效通信。为确保稳定性,建议配置以下选项:

  • 启用 --etcd-quorum-read=true :强制每次读操作走leader节点,保证数据新鲜。
  • 设置超时参数: --etcd-prefix=/registry 自定义键前缀,便于隔离测试环境。

健康检查方面,API Server内置了两个探针端点:

  • /healthz :本地健康状态(HTTP 200表示正常)
  • /readyz :是否准备好接收流量(例如等待etcd连接成功)

可在负载均衡器(如Nginx)中配置如下检查规则:

location /healthz {
    proxy_pass http://127.0.0.1:6443/healthz;
    health_check interval=5 fails=3 passes=2 uri=/healthz;
}

同时配合systemd健康报告:

[Service]
HealthCheckType=http
HealthCheckPath=/readyz
HealthCheckIntervalSec=10

这样可实现自动重启异常进程。

3.2.3 RBAC权限模型初始化与超级用户创建

首次部署后需手动初始化RBAC策略,赋予管理员权限。以 cluster-admin 角色为例:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kube-apiserver-cluster-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: User
  name: admin
  apiGroup: ""

该配置授予名为 admin 的X.509证书持有者最高权限。对应的证书需在 --client-ca-file 签发范围内。

随后可通过kubeconfig文件封装证书与上下文:

users:
- name: admin
  user:
    client-certificate: /etc/kubernetes/pki/admin.crt
    client-key: /etc/kubernetes/pki/admin.key

最终效果是 kubectl --user=admin get nodes 可成功执行。

下表列出常用内置ClusterRole:

Role Name 权限范围
cluster-admin 超级管理员,全量访问
system:masters 特殊组,绕过所有鉴权
view 只读访问非敏感资源
edit 编辑资源但不能修改RBAC
admin 命名空间级管理(含RBAC)

合理分配角色可遵循最小权限原则,降低横向渗透风险。


3.3 Controller Manager多副本部署与控制器协调机制

Controller Manager 是一组控制器的集合体,负责监听API Server中的对象变更并驱动系统向期望状态收敛。它包含Node Controller、Replication Controller、Endpoint Controller等十余种控制器,共同构成了Kubernetes的“自愈引擎”。

3.3.1 –leader-elect选举机制工作原理解析

由于多数控制器只需一个实例运行,CM采用Leader Election机制防止重复处理。其核心依赖etcd实现分布式锁:

--leader-elect=true \
--leader-elect-resource-lock=configmaps \
--leader-elect-resource-name=kube-controller-manager \
--leader-elect-lease-duration=15s \
--leader-elect-renew-deadline=10s \
--leader-elect-retry-period=2s

工作机制如下:

  1. 所有CM实例尝试在 kube-system 命名空间下创建或更新名为 kube-controller-manager 的ConfigMap;
  2. 成功获取锁的节点成为Leader,其余进入Follower模式;
  3. Leader每隔几秒续租一次,若失败则释放锁;
  4. 其他节点检测到锁释放后立即竞争新Leader。

此过程可通过Mermaid流程图展示:

sequenceDiagram
    participant Node1 as CM@master-1
    participant Node2 as CM@master-2
    participant Node3 as CM@master-3
    participant ETCD as etcd(Cluster)

    Node1->>ETCD: 尝试创建 Lease 锁
    Node2->>ETCD: 尝试创建 Lease 锁
    Node3->>ETCD: 尝试创建 Lease 锁
    ETCD-->>Node1: 获取成功 → 成为 Leader
    ETCD-->>Node2: 拒绝 → Follower
    ETCD-->>Node3: 拒绝 → Follower

    loop 心跳维持
        Node1->>ETCD: 每2s续租一次
    end

    Note over Node1: 若网络中断,租约到期
    ETCD->>Node2: 检测到锁失效
    Node2->>ETCD: 抢占锁 → 新Leader

该机制确保即使某个Master宕机,业务逻辑仍可持续运行。

3.3.2 节点控制器、副本控制器等核心控制器功能验证

启动后可通过日志确认各控制器是否正常工作:

journalctl -u kube-controller-manager -f | grep "Starting controller"

预期输出:

I0401 ... Starting controller: node
I0401 ... Starting controller: replication
I0401 ... Starting controller: endpoints

还可通过模拟故障测试自愈能力:

# 手动删除某Pod
kubectl delete pod nginx-7c9d58d8d-q2xk9

# 观察Deployment是否自动重建
kubectl get pods -w

若在数秒内出现同名新Pod,则ReplicaSet Controller工作正常。

3.3.3 自定义资源回收器行为与异常处理策略

某些情况下需干预控制器行为,例如禁止删除带有特定标签的资源:

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: critical-pdb
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: database

这将阻止Horizontal Pod Autoscaler或滚动更新过程中造成服务中断。

同时,可通过调整 --concurrent-*-workers 参数控制并发协程数,平衡CPU占用与处理速度。

3.4 Scheduler调度器部署与调度策略定制

Scheduler负责将未绑定的Pod分配至合适Node。其调度过程分为 预选(Predicates) 优选(Priorities) 两个阶段。

3.4.1 调度流程分析:预选(Predicates)与优选(Priorities)阶段

预选阶段过滤不满足条件的节点(如资源不足、污点不匹配),优选阶段打分排序选出最佳候选。

经典调度策略包括:

  • SelectorSpreadPriority : 分散同一Service下的Pod
  • LeastRequestedPriority : 优先选择空闲资源多的节点
  • NodeAffinity : 基于标签亲和性调度

可通过配置文件启用自定义策略:

apiVersion: kubescheduler.config.k8s.io/v1beta3
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: default-scheduler
    plugins:
      filter:
        enabled:
          - name: TaintToleration
          - name: ResourcesFit
      score:
        enabled:
          - name: LeastAllocated
            weight: 2

3.4.2 默认调度器启动与日志监控配置

启动命令示例:

kube-scheduler \
  --authentication-kubeconfig=/etc/kubernetes/scheduler.conf \
  --authorization-kubeconfig=/etc/kubernetes/scheduler.conf \
  --bind-address=127.0.0.1 \
  --kubeconfig=/etc/kubernetes/scheduler.conf \
  --leader-elect=true \
  --port=0 \
  --secure-port=10259 \
  --tls-cert-file=/etc/kubernetes/pki/scheduler.crt \
  --tls-private-key-file=/etc/kubernetes/pki/scheduler.key \
  --v=2

日志中关注关键字:

grep "Scheduled pod" /var/log/kube-scheduler.log

3.4.3 自定义调度插件扩展接口初探

从v1.19起支持scheduler framework,允许开发者编写Go插件注入调度流程。典型应用场景包括GPU拓扑感知、跨区域容灾调度等。

未来可通过CRD+Webhook+Extender组合实现复杂调度逻辑。

4. Worker节点集成与集群网络通信实现

在Kubernetes的二进制部署流程中,控制平面组件(API Server、etcd、Controller Manager、Scheduler)的搭建仅完成了集群“大脑”的构建。真正的业务承载能力依赖于Worker节点的有效接入和跨节点之间稳定高效的网络通信机制。本章节将深入探讨如何将Worker节点安全地注册到集群中,详细解析kubelet与kube-proxy的核心配置逻辑,并重点阐述CNI(Container Network Interface)插件在实现Pod间跨主机通信中的关键作用。通过TLS引导认证、服务流量转发策略选择以及主流网络方案如Flannel与Calico的实际部署,帮助读者掌握从单机容器运行到分布式网络联通的完整链路。

4.1 kubelet服务部署与Pod运行时管理

kubelet是运行在每个Worker节点上的核心代理组件,负责监听PodSpec变更、维护容器生命周期、执行健康检查、上报节点状态等职责。它是Kubernetes控制平面与底层容器运行时之间的桥梁,直接决定了Pod能否被正确调度并稳定运行。

4.1.1 TLS引导认证(Bootstrap Token)配置流程

在首次启动kubelet时,它需要向API Server证明自己的身份以获取长期证书。由于此时节点尚无合法证书,Kubernetes引入了 TLS Bootstrap机制 ,允许节点使用一个短期有效的Bootstrap Token进行初始身份验证,随后由Controller Manager自动签发正式的客户端证书。

Bootstrap Token通常以Secret形式存储在 kube-system 命名空间中,格式为 <token-id>.<token-secret> ,例如:

07401b.f395accd246ae52d

该Token需提前通过 kubeadm 或手动方式生成并注入集群:

apiVersion: v1
kind: Secret
metadata:
  name: bootstrap-token-07401b
  namespace: kube-system
type: bootstrap.kubernetes.io/token
data:
  token-id: MDc0MDFi  # base64 encoded "07401b"
  token-secret: ZjM5NWFjY2QyNDZhZTUyZA==  # base64 encoded "f395accd246ae52d"
  usage-bootstrap-authentication: "true"
  auth-extra-groups: system:bootstrappers:kubeadm:default-node-token

在Worker节点上,需创建 bootstrap-kubeconfig 文件,用于初始化连接:

apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority-data: <BASE64_CA_CERT>
    server: https://192.168.10.100:6443
  name: bootstrap
contexts:
- context:
    cluster: bootstrap
    user: kubelet-bootstrap
  name: default
current-context: default
users:
- name: kubelet-bootstrap
  user:
    token: 07401b.f395accd246ae52d

参数说明
- certificate-authority-data :API Server CA公钥的Base64编码。
- server :高可用VIP或某Master节点IP+6443端口。
- token :Bootstrap Token值,必须与集群内Secret匹配。

随后,在启动kubelet时指定该配置:

/usr/bin/kubelet \
  --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubeconfig \
  --kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
  --cert-dir=/var/lib/kubelet/pki \
  --rotate-certificates=true \
  --node-labels=node-role.kubernetes.io/worker= \
  --register-with-taints= \
  --pod-infra-container-image=k8s.gcr.io/pause:3.6 \
  --resolv-conf=/run/systemd/resolve/resolv.conf \
  --network-plugin=cni \
  --cni-conf-dir=/etc/cni/net.d \
  --cni-bin-dir=/opt/cni/bin \
  --fail-swap-on=false \
  --feature-gates=RotateKubeletClientCertificate=true,RotateKubeletServerCertificate=true

逻辑分析
- --bootstrap-kubeconfig 提供临时凭据;
- --rotate-certificates RotateKubeletClientCertificate 特性开启后,kubelet会在首次连接成功后请求CSR(Certificate Signing Request),由 kube-controller-manager 审批并签发正式证书;
- --cert-dir 指定证书存储路径,后续正式证书将在此目录生成。

整个过程可通过以下Mermaid流程图表示:

sequenceDiagram
    participant Worker as Worker Node(kubelet)
    participant API as API Server
    participant CM as Controller Manager

    Worker->>API: 使用Bootstrap Token发起连接
    API-->>Worker: 返回401 Unauthorized但接受Token
    Worker->>API: 发送CSR请求(/apis/certificates.k8s.io/v1/certificatesigningrequests)
    API->>CM: 触发CSR事件通知
    CM->>CM: 自动审批CSR(若启用AutoApproval)
    CM->>API: 更新CSR状态为Approved
    API->>Worker: 返回已签名的client certificate
    Worker->>Worker: 保存证书至--cert-dir,替换bootstrap-kubeconfig为正式kubeconfig
    Worker->>API: 后续通信使用正式证书

此机制实现了零信任环境下的自动化节点准入,极大提升了大规模集群部署效率。

4.1.2 CRI接口对接Docker运行时与镜像拉取策略

kubelet通过CRI(Container Runtime Interface)与底层容器运行时交互。尽管Docker曾是默认运行时,但从v1.24起Kubernetes移除了内置的dockershim,推荐使用containerd或CRI-O作为中间层。

以containerd为例,需确保其配置支持CRI插件:

# /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri"]
  sandbox_image = "registry.k8s.io/pause:3.6"
  [plugins."io.containerd.grpc.v1.cri".containerd]
    default_runtime_name = "runc"
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
    runtime_type = "io.containerd.runc.v2"

重启containerd服务后,kubelet即可通过Unix Socket /run/containerd/containerd.sock 访问运行时。

此外,kubelet支持多种镜像拉取策略,通过Pod定义中的 imagePullPolicy 字段控制:

策略 行为描述 适用场景
Always 每次启动都尝试从远程仓库拉取镜像 开发测试环境、latest标签
IfNotPresent 本地存在则不拉取 生产环境、私有镜像缓存
Never 仅使用本地镜像 完全离线环境

该策略直接影响部署速度与网络开销。建议生产环境中统一采用固定版本号镜像 + IfNotPresent 策略,结合镜像预加载脚本提升启动效率。

4.1.3 Pod资源限制、健康探针与静态Pod管理

kubelet不仅负责Pod创建,还承担资源隔离与健康监控任务。通过cgroups实现CPU、内存限额:

# 示例Pod定义片段
resources:
  requests:
    memory: "64Mi"
    cpu: "250m"
  limits:
    memory: "128Mi"
    cpu: "500m"

kubelet依据这些参数设置cgroup层级,防止资源争抢。

健康检查方面,kubelet支持三种探针:

  • Liveness Probe :检测应用是否存活,失败则重启容器;
  • Readiness Probe :检测是否准备好接收流量,失败则从Service Endpoints剔除;
  • Startup Probe :判断容器是否完成启动,成功前其他探针不生效。

典型HTTP探针配置如下:

livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 30
  periodSeconds: 10
  timeoutSeconds: 5
  failureThreshold: 3

参数解释:
- initialDelaySeconds :容器启动后等待多久开始探测;
- periodSeconds :探测间隔;
- timeoutSeconds :每次请求超时时间;
- failureThreshold :连续失败几次后判定为不健康。

最后,kubelet支持“静态Pod”机制——直接监控本地Manifest目录(如 /etc/kubernetes/manifests ),无需API Server参与即可启动关键系统组件(如etcd、kube-apiserver自身)。这类Pod会自动在API Server中表现为Mirror Pod,便于监控但不可修改。

4.2 kube-proxy组件部署与服务流量转发机制

kube-proxy运行在每个节点上,负责实现Kubernetes Service抽象的底层网络规则,确保服务发现与负载均衡功能正常运作。

4.2.1 iptables/ipvs模式对比与选型建议

kube-proxy支持三种工作模式:userspace、iptables、ipvs。目前主流使用iptables和ipvs。

模式 性能表现 规则复杂度 支持会话保持 连接跟踪依赖
iptables 中等 高(O(n)规则链) 是(via CLIENTIP 是(conntrack)
ipvs 高(O(1)哈希查找) 低(内核模块管理) 是(sh/sed模式)

iptables模式原理

当创建Service时,kube-proxy监听Service与Endpoint变化,动态更新iptables规则链。例如:

# 创建Service 10.96.0.1:80 → Pod 10.244.1.10:8080, 10.244.2.11:8080
-A KUBE-SERVICES -d 10.96.0.1/32 -p tcp -m tcp --dport 80 -j KUBE-SVC-XXXXXX
-A KUBE-SVC-XXXXXX -j KUBE-SEP-YYYYYY
-A KUBE-SEP-YYYYYY -m statistic --mode random --probability 0.5 -j KUBE-CHR-AAAAAA
-A KUBE-CHR-AAAAAA -j DNAT --to-destination 10.244.1.10:8080

缺点是规则随服务数量线性增长,影响性能且难以调试。

ipvs模式优势

基于Netlink调用Linux IP Virtual Server模块,支持RR、WRR、SH等多种调度算法,具备更好的伸缩性和更低延迟。

启用ipvs前需加载内核模块:

modprobe ip_vs
modprobe ip_vs_rr
modprobe ip_vs_wrr
modprobe ip_vs_sh
modprobe nf_conntrack

并在kube-proxy配置中指定模式:

apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
  scheduler: "wrr"
  excludeCIDRs: ["10.0.0.0/8"]

scheduler : 负载均衡算法;
excludeCIDRs : 不使用ipvs处理的地址范围。

4.2.2 Service虚拟IP映射与会话保持配置

Service的ClusterIP是一个虚拟IP,不绑定任何物理接口,仅存在于iptables/ipvs规则中。kube-proxy确保所有访问该IP:Port的流量被正确转发至后端Pod。

对于需要粘性会话的应用(如状态缓存服务),可设置 sessionAffinity

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800  # 默认3小时

在ipvs模式下,对应调度器为 sh (Source Hashing),保证同一客户端IP始终路由到相同后端。

4.2.3 Headless Service与DNS解析联动机制

当不需要负载均衡或单独分配ClusterIP时,可创建Headless Service( clusterIP: None ):

apiVersion: v1
kind: Service
metadata:
  name: mysql-headless
spec:
  selector:
    app: mysql
  ports:
    - port: 3306
  clusterIP: None

此时kube-proxy不会为其生成转发规则,CoreDNS会直接返回所有匹配Pod的A记录:

mysql-headless.default.svc.cluster.local → 
  10.244.1.15
  10.244.2.16

常用于StatefulSet场景,实现稳定的网络标识(如 mysql-0.mysql-headless )。

4.3 CNI网络插件集成与跨节点通信实现

CNI是Kubernetes网络模型的核心标准,定义了容器网络配置的接口规范。只有正确部署CNI插件,才能实现Pod跨节点通信。

4.3.1 Flannel host-gw与VXLAN模式部署实践

Flannel是最轻量级的CNI之一,支持两种后端模式:

  • host-gW(Host Gateway) :适用于同层网络,通过配置路由表实现二层转发;
  • VXLAN :封装三层UDP报文,适合跨子网环境。

以VXLAN为例,部署步骤如下:

  1. 下载二进制并解压:
wget https://github.com/flannel-io/flannel/releases/latest/download/flannel-amd64.tar.gz
tar -xzf flannel-amd64.tar.gz
cp flanneld /usr/local/bin/
  1. 编写Systemd Unit:
[Unit]
Description=flanneld overlay address etcd agent
After=network.target

[Service]
ExecStart=/usr/local/bin/flanneld \
  -etcd-endpoints=https://192.168.10.101:2379,https://192.168.10.102:2379,https://192.168.10.103:2379 \
  -etcd-prefix=/atomic.io/network \
  -iface=enp0s8 \
  -etcd-cafile=/etc/ssl/etcd/ca.pem \
  -etcd-certfile=/etc/ssl/etcd/node-node1.pem \
  -etcd-keyfile=/etc/ssl/etcd/node-node1-key.pem
Restart=on-failure

[Install]
WantedBy=multi-user.target
  1. 在etcd中预设网络配置:
etcdctl --cacert=/etc/ssl/etcd/ca.pem \
        --cert=/etc/ssl/etcd/node-node1.pem \
        --key=/etc/ssl/etcd/node-node1-key.pem \
        put /atomic.io/network/config '{
          "Network": "10.244.0.0/16",
          "Backend": {
            "Type": "vxlan",
            "VNI": 1,
            "Port": 8472
          }
        }'

Flannel启动后会为每个节点分配/24子网,并通过VXLAN设备(flannel.1)封装跨节点流量。

4.3.2 Calico BGP路由协议配置与网络策略实施

Calico提供更强大的网络与安全功能,基于BGP协议在节点间传播路由信息,避免中心化转发瓶颈。

安装Calico需应用其自定义资源定义(CRD)和DaemonSet:

kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

关键配置位于 Installation 资源中:

apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
  name: default
spec:
  calicoNetwork:
    bgp: Enabled
    ipPools:
    - cidr: 10.244.0.0/16
      natOutgoing: true
      blockSize: 26

启用BGP后,各节点通过TCP 179端口建立对等体,自动交换Pod CIDR路由。可通过 calicoctl node status 查看BGP连接状态。

更重要的是,Calico原生支持 NetworkPolicy ,实现微服务间细粒度访问控制:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-db-from-unauthorized
spec:
  podSelector:
    matchLabels:
      app: postgres
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 5432

上述策略仅允许带有 role=frontend 标签的Pod访问PostgreSQL服务。

4.3.3 网络性能测试与MTU调优建议

网络性能直接影响应用延迟与吞吐。常见优化包括:

  • 设置合理MTU:VXLAN封装增加50字节开销,建议物理网络MTU≥1500,VNI接口设为1450;
  • 关闭TCP Segmentation Offload(TSO/GSO)减少CPU开销;
  • 使用SR-IOV或DPDK提升数据面性能(高级场景)。

测试工具推荐:

# 测试带宽
iperf3 -c 10.244.2.10

# 测试延迟
ping 10.244.1.5

# 查看丢包与重传
ss -i  # 显示TCP指标

4.4 kubeconfig文件生成与kubectl集群接入

完成Worker节点部署后,需为管理员生成kubeconfig以便通过kubectl操作集群。

4.4.1 用户证书签发与上下文(Context)配置

使用cfssl为用户生成证书:

{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [{
    "C": "CN",
    "ST": "Beijing",
    "L": "Haidian",
    "O": "system:masters",
    "OU": "System"
  }]
}

签发后构建kubeconfig:

kubectl config set-cluster mycluster \
  --certificate-authority=ca.pem \
  --embed-certs=true \
  --server=https://192.168.10.100:6443 \
  --kubeconfig=admin.kubeconfig

kubectl config set-credentials admin \
  --client-certificate=admin.pem \
  --client-key=admin-key.pem \
  --embed-certs=true \
  --kubeconfig=admin.kubeconfig

kubectl config set-context default \
  --cluster=mycluster \
  --user=admin \
  --kubeconfig=admin.kubeconfig

kubectl config use-context default --kubeconfig=admin.kubeconfig

4.4.2 集群内外部访问权限分离设计

生产环境中应区分内部组件访问与外部管理访问:

  • 内部kubeconfig使用短有效期证书 + RBAC最小权限;
  • 外部管理员使用独立CA签发证书,绑定 cluster-admin 角色;
  • 可通过OpenID Connect集成企业SSO系统实现统一认证。

最终形成的多上下文配置可简化切换:

kubectl config get-contexts
kubectl config use-context prod-admin

5. 高可用架构增强与生产级运维实践验证

5.1 多Master节点架构设计与负载均衡实现

在生产环境中,单Master节点的Kubernetes集群存在明显的单点故障风险。为实现真正的高可用性(HA),必须部署多Master节点,并通过负载均衡机制对外提供稳定的API Server访问入口。典型的高可用架构包含至少三个Master节点,分别运行 etcd kube-apiserver kube-controller-manager kube-scheduler 组件,其中 etcd 可独立部署或与Master共存。

5.1.1 Keepalived + Nginx实现API Server前端VIP漂移

为实现API Server的高可用接入,通常采用Keepalived结合Nginx的方式构建前端负载层。Keepalived负责虚拟IP(VIP)的漂移管理,Nginx作为反向代理将请求分发至后端多个API Server实例。

以下为Nginx配置示例( /etc/nginx/nginx.conf ):

stream {
    upstream kube_apiserver {
        server 192.168.10.11:6443;  # master-1
        server 192.168.10.12:6443;  # master-2
        server 192.168.10.13:6443;  # master-3
    }

    server {
        listen 6443;
        proxy_pass kube_apiserver;
        proxy_timeout 10s;
        proxy_responses 1;
    }
}

同时,在每台Master节点上部署Keepalived,主节点配置如下( /etc/keepalived/keepalived.conf ):

vrrp_instance VI_01 {
    state MASTER
    interface eth0
    virtual_router_id 61
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass secret123
    }
    virtual_ipaddress {
        192.168.10.100/24 dev eth0 label eth0:vip
    }
}

备节点设置 state BACKUP 并降低 priority 值(如90)。当主节点宕机时,VIP自动漂移到备份节点,确保API Server服务不中断。

5.1.2 etcd集群与Master组件跨节点分布策略

建议将 etcd 集群独立部署于三台或五台专用节点,避免与API Server竞争资源。Master节点仅作为控制平面组件运行载体,不承载业务Pod。典型部署拓扑如下表所示:

节点IP 角色 运行组件
192.168.10.11 Master + etcd member kube-apiserver, controller-manager, scheduler, etcd
192.168.10.12 Master + etcd member 同上
192.168.10.13 Master + etcd member 同上
192.168.10.21 Worker kubelet, kube-proxy, containerd
192.168.10.22 Worker 同上
192.168.10.100 VIP 虚拟IP地址(由Keepalived维护)

该结构支持任一Master节点宕机后,其余节点继续提供服务,且 etcd 保持多数派共识。

5.1.3 故障切换演练与脑裂防护机制

定期执行故障切换演练是保障HA可靠性的关键步骤。可通过手动关闭主节点网卡或停止Keepalived服务模拟故障:

# 模拟主节点宕机
systemctl stop keepalived

# 查看VIP是否已迁移至其他节点
ip addr show eth0

为防止脑裂(Split-Brain),需配置优先级抢占延迟、监控脚本联动以及网络隔离检测。例如添加健康检查脚本:

vrrp_script chk_nginx {
    script "killall -0 nginx"
    interval 2
    weight -20
}

并将此脚本绑定到VRRP实例中,确保Nginx异常时主动降权退出主角色。

graph TD
    A[Client] --> B{Load Balancer (VIP)}
    B --> C[Nginx on Master-1]
    B --> D[Nginx on Master-2]
    B --> E[Nginx on Master-3]
    C --> F[kube-apiserver]
    D --> F
    E --> F
    F --> G[etcd Cluster]
    G --> H[(Persistent Storage)]

上述架构实现了从客户端到存储层的全链路高可用设计。

5.2 集群功能完整性验证与kubectl实战操作

完成多Master部署后,需通过一系列标准操作验证集群功能完整性。

5.2.1 创建命名空间、Deployment与Service资源对象

使用 kubectl 创建测试命名空间:

kubectl create namespace demo

部署一个Nginx应用:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  namespace: demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80

应用配置:

kubectl apply -f nginx-deploy.yaml

暴露服务:

kubectl expose deployment nginx-deploy \
  --type=NodePort \
  --port=80 \
  --target-port=80 \
  -n demo

5.2.2 滚动更新、回滚与水平伸缩操作演示

更新镜像触发滚动更新:

kubectl set image deployment/nginx-deploy nginx=nginx:1.25 -n demo

查看更新状态:

kubectl rollout status deployment/nginx-deploy -n demo

若出现异常可立即回滚:

kubectl rollout undo deployment/nginx-deploy -n demo

动态扩缩容:

kubectl scale deployment/nginx-deploy --replicas=5 -n demo

5.2.3 日志采集与事件查看命令(logs/describe/get)应用

获取Pod列表:

kubectl get pods -n demo -o wide

查看Pod详细信息:

kubectl describe pod <pod-name> -n demo

查看容器日志:

kubectl logs -f <pod-name> -n demo

列出所有事件以排查问题:

kubectl get events -A --sort-by=.metadata.creationTimestamp

以下是部分常见事件输出样例:

LAST SEEN TYPE REASON OBJECT MESSAGE
10s Normal Scheduled pod/nginx-deploy-7c6b8f5d7-xz2kq Successfully assigned demo/nginx…
9s Normal Pulling pod/nginx-deploy-7c6b8f5d7-xz2kq Pulling image “nginx:1.21”
6s Normal Pulled pod/nginx-deploy-7c6b8f5d7-xz2kq Successfully pulled image “nginx:1.21”
5s Normal Created pod/nginx-deploy-7c6b8f5d7-xz2kq Created container nginx
4s Normal Started pod/nginx-deploy-7c6b8f5d7-xz2kq Started container nginx
2m Warning FailedScheduling pod/unavailable-pod No nodes available that match constraints
30s Normal ScalingReplicaSet deployment/nginx-deploy Scaled up replica set to 3
15s Normal Killing pod/nginx-deploy-7c6b8f5d7-old Container nginx failed liveness probe
8s Normal SuccessfulCreate replicaset/nginx-deploy-7c6b8f5d7 Created pod: nginx-deploy-7c6b8f5d7-new
5s Normal LeaderElection endpoints/kube-controller-manager demo-node-1 became leader
3s Warning Evicted pod/big-mem-app The node was low on resource: memory.
1s Normal NodeReady node/demo-node-2 Node demo-node-2 status is now: Ready

这些事件反映了调度、拉取镜像、健康检查、副本集变更等核心行为,是诊断集群状态的重要依据。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:Kubernetes(k8s)是容器编排领域的主流标准,广泛用于微服务的部署与管理。本文深入讲解通过二进制方式搭建k8s集群的完整流程,适用于希望深度掌握系统架构与组件原理的IT管理员。内容涵盖k8s架构解析、Master与Worker节点组件部署、环境准备、kubeconfig配置、CNI网络插件集成及集群状态验证。该方法虽复杂但灵活可控,有助于实现高可用与定制化集群建设,是进阶学习k8s的核心实践路径。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐