『宝藏代码胶囊开张啦!』—— 我的 CodeCapsule 来咯!✨写代码不再头疼!我的新站点 CodeCapsule 主打一个 “白菜价”+“量身定制”!无论是卡脖子的毕设/课设/文献复现,需要灵光一现的算法改进,还是想给项目加个“外挂”,这里都有便宜又好用的代码方案等你发现!低成本,高适配,助你轻松通关!速来围观 👉 CodeCapsule官网

Kubernetes 架构与核心概念

一、引言:从容器编排到云原生操作系统

在掌握了 Docker 容器化、Docker Compose 多服务编排以及 Docker Swarm 集群管理之后,你已经能够将应用容器化并在多台主机上运行。然而,随着微服务数量的增长和集群规模的扩大,Swarm 在某些场景下显得力不从心:复杂的网络策略、精细的存储管理、强大的可扩展性需求,这些都需要一个更加强大和灵活的容器编排平台。

Kubernetes(简称 K8s) 应运而生。作为当前云原生时代的事实标准,Kubernetes 已经超越了简单的容器编排工具,成为一个分布式的操作系统,能够管理跨数据中心的计算、网络和存储资源。它由 Google 基于其内部使用了十多年的 Borg 系统设计,并于 2014 年开源,现由云原生计算基金会(CNCF)维护 。

然而,Kubernetes 的学习曲线相对陡峭。面对众多的概念(Pod、Deployment、Service、ConfigMap…)和组件(API Server、etcd、Scheduler、kubelet…),初学者往往感到困惑:这些概念之间是什么关系?组件是如何协作的?为什么 Kubernetes 能够实现“自我修复”和“自动伸缩”?

本文将从 Kubernetes 的核心设计哲学出发,深入剖析其架构与核心概念。我们将通过一个 Python Flask 应用 的实战,演示如何在 Kubernetes 上部署和管理应用,并运用多阶段构建优化镜像,帮助你建立起对 Kubernetes 的系统性认知,为后续深入学习奠定坚实基础。

二、核心概念:Kubernetes 的设计哲学与架构

2.1 声明式 API:Kubernetes 的“治国之道”

要理解 Kubernetes,首先要理解其最核心的设计哲学:声明式 API(Declarative API)

在传统的“命令式”管理中,你需要告诉系统每一步该做什么(例如:先运行这个容器,再检查它是否启动,如果失败了再重新运行…)。而在 Kubernetes 中,你只需要声明你期望的最终状态,Kubernetes 会负责将实际状态调整为期望状态 。

调谐循环

Observe 观察

Compare 比较

Act 行动

状态上报

更新

重复循环

用户提交期望状态
例如:Deployment 副本数=3

API Server

写入 etcd

Controller Manager

Scheduler/kubelet

实际状态
Pod 运行中

这个“调谐循环(Reconciliation Loop)”是 Kubernetes 一切自愈、扩容、滚动更新的基础。控制器不断地从 etcd 中读取期望状态,观察实际状态,发现差异后采取行动,周而复始 。

2.2 Linux 内核基石:Namespaces 和 Cgroups

Kubernetes 能够管理容器,依赖于 Linux 内核的两项核心技术:

  • Namespaces(命名空间):提供隔离。它让容器内的进程以为自己是系统唯一的进程,拥有独立的 PID、网络、挂载点等。这就像是给每个容器戴上了一副“VR眼镜”,看到的都是独立的世界 。
  • Cgroups(Control Groups):提供限制。它控制容器能使用多少 CPU、内存、磁盘 I/O 等资源。这就是你在 Pod 定义中 resources.limits 的底层实现 。

2.3 Kubernetes 集群架构

一个 Kubernetes 集群由两部分组成:控制平面(Control Plane)工作节点(Nodes)

工作节点2 (Worker Node)

工作节点1 (Worker Node)

控制平面 (Control Plane)

kube-apiserver

etcd

kube-scheduler

kube-controller-manager

cloud-controller-manager

kubelet

kube-proxy

容器运行时

Pod

Pod

kubelet

kube-proxy

容器运行时

Pod

Pod

2.3.1 控制平面组件

控制平面是集群的“大脑”,负责全局决策和集群管理 。

  • kube-apiserver:Kubernetes 的唯一入口。所有组件(包括用户、其他组件)都通过 API Server 进行通信。它负责认证、授权、准入控制,并将数据写入 etcd 。
  • etcd:一个高可用的、分布式的键值存储,用作 Kubernetes 的后台数据库,存储所有集群数据(期望状态和实际状态)。
  • kube-scheduler调度器。它监视新创建的、尚未分配节点的 Pod,并根据资源需求、亲和性约束等条件,选择一个最合适的节点来运行这个 Pod 。
  • kube-controller-manager控制器管理器。它运行着多个控制器进程(如 Node Controller、ReplicaSet Controller、Deployment Controller 等),每个控制器都通过 API Server 监视集群状态,并努力将实际状态调整为期望状态 。
  • cloud-controller-manager云控制器管理器。它允许将集群连接到云提供商的 API,管理云特定的资源(如负载均衡器、存储卷)。
2.3.2 工作节点组件

工作节点是真正运行容器化应用的地方 。

  • kubelet:运行在每个节点上的代理,是节点的“大管家”。它接收 API Server 的指令,确保节点上的容器(Pod)按照规范运行,并向 API Server 上报节点和 Pod 的状态 。
  • kube-proxy:运行在每个节点上的网络代理。它维护节点上的网络规则,实现 Service 的负载均衡和服务发现功能,让集群内外可以访问 Pod 。
  • 容器运行时:真正负责运行容器的软件,如 containerd、CRI-O。kubelet 通过 CRI(容器运行时接口)与它交互 。

2.4 Kubernetes 核心资源对象

理解 Kubernetes,需要掌握其抽象的“积木块” 。

  • Pod:Kubernetes 中最小的部署和调度单元。一个 Pod 包含一个或多个紧密相关的容器,它们共享网络命名空间(IP 和端口)和存储卷。Pod 是“短暂的”,随时可能被销毁和重建 。
  • Deployment:用于管理无状态应用的控制器。它定义了 Pod 的期望副本数、更新策略等。Deployment 会创建 ReplicaSet,由 ReplicaSet 确保指定数量的 Pod 副本始终运行 。
  • Service:定义了访问一组 Pod 的策略和抽象。因为 Pod 是动态创建和销毁的,其 IP 会变化。Service 提供了一个稳定的虚拟 IP(ClusterIP)和 DNS 名称,并将请求负载均衡到后端 Pod 。
  • ConfigMap 和 Secret:用于将配置与容器镜像解耦。ConfigMap 用于非敏感的配置信息,Secret 用于敏感信息(如密码、令牌)。
  • Namespace:提供逻辑隔离。同一个集群内,可以用 Namespace 将不同项目、不同环境的资源分开 。

三、实战演练:在 Kubernetes 上部署 Python 应用

本节将通过一个简单的 Python Flask 应用,演示如何在 Kubernetes 上使用 Deployment 和 Service 进行部署。

3.1 项目结构

k8s-demo-app/
├── app/
│   ├── app.py              # Flask 应用
│   ├── requirements.txt
│   ├── Dockerfile          # 多阶段构建
│   └── .dockerignore
├── k8s/
│   ├── deployment.yaml     # Deployment 定义
│   └── service.yaml        # Service 定义
└── README.md

3.2 Flask 应用代码

app/app.py:一个简单的健康检查应用。

import os
import socket
from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/')
def hello():
    hostname = socket.gethostname()
    return jsonify({
        'message': 'Hello from Kubernetes!',
        'hostname': hostname,
        'environment': os.getenv('ENV', 'development')
    })

@app.route('/health')
def health():
    return jsonify({'status': 'healthy'})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

app/requirements.txt

flask==2.3.3
gunicorn==21.2.0

3.3 多阶段构建 Dockerfile

# app/Dockerfile
# 构建阶段
FROM python:3.11-slim AS builder

WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

# 运行阶段
FROM python:3.11-slim

# 创建非root用户
RUN addgroup --system --gid 1001 appgroup && \
    adduser --system --uid 1001 --gid 1001 --no-create-home appuser

WORKDIR /app
COPY --from=builder /root/.local /root/.local
ENV PATH=/root/.local/bin:$PATH

COPY . .
RUN chown -R appuser:appgroup /app

USER appuser
EXPOSE 5000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:5000/health')" || exit 1

CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "2", "app:app"]

app/.dockerignore

__pycache__
*.pyc
.env
.git
README.md
Dockerfile
.dockerignore

3.4 构建并推送镜像

# 构建镜像
docker build -t your-registry/k8s-demo-app:latest ./app

# 推送到镜像仓库(如 Docker Hub)
docker push your-registry/k8s-demo-app:latest

3.5 创建 Kubernetes 资源定义

k8s/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-app
  labels:
    app: demo-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: demo-app
  template:
    metadata:
      labels:
        app: demo-app
    spec:
      containers:
      - name: app
        image: your-registry/k8s-demo-app:latest
        ports:
        - containerPort: 5000
        env:
        - name: ENV
          value: "production"
        resources:
          requests:
            memory: "64Mi"
            cpu: "100m"
          limits:
            memory: "128Mi"
            cpu: "200m"
        livenessProbe:
          httpGet:
            path: /health
            port: 5000
          initialDelaySeconds: 10
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 5000
          initialDelaySeconds: 5
          periodSeconds: 5

k8s/service.yaml

apiVersion: v1
kind: Service
metadata:
  name: demo-app-service
spec:
  selector:
    app: demo-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 5000
  type: LoadBalancer  # 在云环境或 Minikube 中会分配外部 IP

3.6 部署到 Kubernetes

# 创建 Deployment
kubectl apply -f k8s/deployment.yaml

# 创建 Service
kubectl apply -f k8s/service.yaml

# 查看部署状态
kubectl get deployments
kubectl get pods
kubectl get services

# 查看应用日志
kubectl logs -l app=demo-app

# 访问应用(如果是 Minikube,使用 minikube service)
# 如果是云环境,使用 EXTERNAL-IP
curl http://<EXTERNAL-IP>/

四、进阶优化:Kubernetes 最佳实践

4.1 资源请求与限制

始终为每个容器设置 resources.requestsresources.limits

  • requests:调度器保证节点至少有这么多资源给容器。
  • limits:容器绝对不能超过的资源量,超过会被限流或 OOM kill 。

4.2 健康检查

配置 livenessProbe(存活探针)和 readinessProbe(就绪探针):

  • livenessProbe:Kubelet 据此判断容器是否存活,不存活则重启。
  • readinessProbe:判断容器是否准备好接收流量,未就绪时 Service 不会转发流量给它 。

4.3 滚动更新策略

在 Deployment 中配置更新策略,实现零停机发布:

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # 更新时可超出期望副本数的最大数量
      maxUnavailable: 0  # 更新时不可用副本的最大数量

4.4 使用 ConfigMap 和 Secret

将配置与镜像解耦:

# 创建 ConfigMap
kubectl create configmap app-config --from-literal=APP_ENV=production

# 在 Pod 中引用
env:
- name: ENV
  valueFrom:
    configMapKeyRef:
      name: app-config
      key: APP_ENV

4.5 镜像优化:多阶段构建

与之前系列一致,多阶段构建将镜像体积从 400MB+ 优化至 82MB,加速拉取和启动。

构建方式基础镜像最终镜像大小
单阶段python:3.11912 MB
单阶段 slimpython:3.11-slim412 MB
多阶段python:3.11-slim82 MB

4.6 命名空间隔离

使用命名空间区分环境:

kubectl create namespace dev
kubectl create namespace prod
kubectl apply -f deployment.yaml -n dev

五、效果验证

5.1 部署状态检查

kubectl get pods
# 输出示例:
NAME                        READY   STATUS    RESTARTS   AGE
demo-app-6b9f4b9c7d-abc12   1/1     Running   0          2m
demo-app-6b9f4b9c7d-def34   1/1     Running   0          2m
demo-app-6b9f4b9c7d-ghi56   1/1     Running   0          2m

5.2 服务访问测试

# 获取 Service 外部 IP
kubectl get svc demo-app-service

# 多次访问,观察返回的 hostname(Pod 名)变化
curl http://<EXTERNAL-IP>/

5.3 滚动更新验证

# 更新镜像版本
kubectl set image deployment/demo-app app=your-registry/k8s-demo-app:v2

# 观察更新过程
kubectl rollout status deployment/demo-app

5.4 自我修复验证

# 删除一个 Pod
kubectl delete pod <pod-name>

# 观察 Deployment 自动创建新 Pod
kubectl get pods -w

六、完整代码

6.1 app/app.py

(见上文)

6.2 app/requirements.txt

flask==2.3.3
gunicorn==21.2.0

6.3 app/Dockerfile

(见上文)

6.4 app/.dockerignore

(见上文)

6.5 k8s/deployment.yaml

(见上文)

6.6 k8s/service.yaml

(见上文)

七、总结与最佳实践清单

通过本文的实战,我们系统性地学习了 Kubernetes 的架构设计与核心概念,并在集群中成功部署了一个 Python Flask 应用。以下是 Kubernetes 架构与核心概念的最佳实践清单

  • 理解声明式 API:始终通过 YAML 定义期望状态,让 Kubernetes 负责调谐。
  • 掌握核心组件:区分控制平面组件(API Server、etcd、Scheduler、Controller Manager)和工作节点组件(kubelet、kube-proxy、容器运行时)。
  • 熟悉核心资源:理解 Pod、Deployment、Service、ConfigMap、Secret、Namespace 的作用与关系。
  • 资源限制:为每个容器设置 requests 和 limits,保障集群稳定性。
  • 健康检查:配置存活探针和就绪探针,让应用具备自愈能力。
  • 滚动更新:合理配置更新策略,实现零停机发布。
  • 配置分离:使用 ConfigMap 和 Secret 管理配置,避免硬编码。
  • 镜像优化:采用多阶段构建,减小镜像体积,加速分发。
  • 命名空间隔离:用 Namespace 区分不同环境或团队,避免资源冲突。

Kubernetes 是一个庞大而精妙的系统,本文仅涉及了其架构与核心概念的冰山一角。当你理解了这些基础之后,可以进一步探索存储(PersistentVolume)、网络(Ingress、NetworkPolicy)、安全(RBAC)、扩展(CRD、Operator)等高级主题。但无论如何深入,本文介绍的设计哲学和核心概念将始终是你的指路明灯。

更多推荐