本文由 Claude-3.7-Sonnet 生成。

从裸机到容器:应对复杂性的演进

1. 物理服务器时代的困境

最初,应用程序直接部署在物理服务器上,导致:

  • 资源利用率低下(一台服务器只运行一个应用)
  • 环境一致性问题(”在我的机器上能运行”)
  • 应用隔离性差

2. 虚拟机的改进

虚拟化技术出现,每台物理服务器可运行多个虚拟机:

  • 提高了资源利用率
  • 但启动慢、资源占用大

3. 容器(Container)的革命

容器技术解决了关键痛点:

  • 轻量级(共享宿主机OS内核)
  • 快速启动(秒级)
  • 可移植性强(构建一次,到处运行)
  • 资源占用小

但问题出现了: 当容器数量增长,单机管理变得困难,集群管理更是挑战。

Kubernetes组件的逐步演进

1. Pod:为什么不直接使用容器?

容器本身有局限性:

  • 单个容器难以满足应用的协作需求
  • 需要将紧密关联的功能组合在一起

因此诞生了Pod:

  • Pod是最小部署单元,包含一个或多个容器
  • 共享网络命名空间和存储卷
  • 同一Pod中的容器总是在同一节点上运行
  • 适合边车(sidecar)模式,如日志收集、代理容器

多容器Pod的深度实践

当我们需要在一个Pod中运行多个容器时,理解它们之间的协作机制至关重要:

资源共享与隔离

graph LR
    subgraph Pod沙箱
        A[主应用容器] -->|共享localhost| B[Sidecar容器]
        A -->|共享存储卷| B
        C[Init容器] -->|前置准备| A
    end

关键特性:

  • 网络共享:所有容器共享同一个网络命名空间,可通过localhost直接通信
  • 存储共享:通过Volume挂载实现文件共享,如日志收集场景
  • 生命周期同步:所有容器同时收到SIGTERM信号,但独立执行优雅终止

Sidecar模式实战

以日志收集为例,典型的sidecar配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
spec:
containers:
- name: main-app
image: my-app:latest
volumeMounts:
- name: logs
mountPath: /var/log/app
- name: log-collector
image: fluent-bit:latest
volumeMounts:
- name: logs
mountPath: /var/log/app
readOnly: true

启动与停止的同步机制

  • 启动阶段:所有容器并行启动,无严格顺序(init容器除外)
  • 停止阶段:同步发送SIGTERM,但各容器独立执行preStop钩子
  • 优雅终止:共享terminationGracePeriodSeconds时间窗口

何时使用独立Pod?

虽然多容器Pod有诸多优势,但在以下场景应考虑独立Pod:

  • 需要独立扩缩容的组件
  • 安全隔离要求不同的服务
  • 需要部署到不同节点的组件
  • 生命周期差异较大的服务

实际案例:Web应用增强

在我们的生产环境中,一个典型的Web应用Pod可能包含:

  • 主容器:运行Spring Boot应用
  • Sidecar容器:日志收集器(如Filebeat)
  • Init容器:数据库权限初始化
  • 共享资源:配置文件、日志目录、临时存储

这种架构既保持了组件间的紧密协作,又实现了关注点分离,是云原生应用的最佳实践之一。

2. ReplicaSet:确保可用性

Pod解决了部署问题,但如何确保高可用?

  • 如果Pod崩溃怎么办?
  • 如何保持指定数量的实例?

ReplicaSet应运而生:

  • 自动维护指定数量的Pod副本
  • 监控Pod状态,替换失败的Pod
  • 实现应用的可扩展性

3. Deployment:应对变更

应用需要更新,但如何安全更新?

  • 如何避免更新过程中的服务中断?
  • 如何在出问题时回滚?

Deployment提供了解决方案:

  • 管理ReplicaSet的版本更迭
  • 实现无缝的滚动更新
  • 提供版本历史和回滚能力

4. Service:解决网络稳定性

Pod是临时的,IP地址会变,如何稳定访问?

  • Pod重启后IP会改变
  • 扩缩容会导致Pod增减
  • 客户端如何发现可用服务?

Service提供了答案:

  • 提供稳定的网络端点(IP和DNS名)
  • 自动负载均衡到后端Pod
  • 服务发现机制

注意: 并非所有Pod都需要Service,但如果需要被网络访问,通常都需要Service。如:

  • 前端应用需要Service暴露给用户
  • 后端API需要Service供其他服务调用
  • 仅做数据处理的批处理Pod可能不需要Service
  • 是一个网络抽象层
  • 为 Pod 提供稳定的访问端点(IP/DNS)
  • 不包含任何容器或运行时代码
  • 只是定义了一组网络规则,告诉流量如何路由到 Pod

Service不仅仅是”一组规则”,而是一个完整的Kubernetes资源对象,它包含:

  • 虚拟IP(ClusterIP) - 在集群内部稳定不变的IP地址
  • 服务发现机制 - 通过DNS或环境变量提供
  • 负载均衡功能 - 将流量分发到多个后端Pod
  • 端口映射规则 - 定义服务端口与目标Pod端口的映射
  • 在实现层面,kube-proxy确实会在每个节点上创建规则(如iptables规则),但Service本身是一个在控制平面定义和管理的抽象对象。

完整的Kubernetes架构图

1
2
3
4
5
6
7
8
9
10
11
12
13
Feature: Kubernetes集群架构
Scenario: 核心组件协作
Given 控制平面包含API Server, etcd, Scheduler, Controller Manager
When 用户创建Deployment
Then Deployment管理ReplicaSet
And ReplicaSet确保Pod副本数
And Service提供稳定网络端点

Scenario: 工作节点组件
Given 每个工作节点运行kubelet, kube-proxy, Container Runtime
When Pod被调度到节点
Then kubelet管理Pod生命周期
And kube-proxy处理网络规则
graph TD
    subgraph 控制平面
        API[API Server]
        ETCD[etcd]
        SCH[Scheduler]
        CM[Controller Manager]
    end
    
    subgraph 工作节点
        KUBELET[kubelet]
        PROXY[kube-proxy]
        RUNTIME[Container Runtime]
        
        subgraph Pod1
            C1[容器1]
            C2[容器2]
        end
        
        subgraph Pod2
            C3[容器3]
        end
    end
    
    API --> KUBELET
    SCH --> KUBELET
    CM --> KUBELET
    KUBELET --> Pod1
    KUBELET --> Pod2

扩展的Kubernetes资源生态

除了核心工作负载资源外,Kubernetes还提供了丰富的命名资源来构建完整的云原生平台:

1. 命名空间与多租户隔离

graph TD
    subgraph 集群
        NS1[default命名空间]
        NS2[kube-system命名空间]
        NS3[app-prj命名空间]
        
        NS1 -->|包含| Pod1[Pod/Service/ConfigMap]
        NS2 -->|包含| Sys[系统组件]
        NS3 -->|包含| App[业务应用]
    end

Namespace - 逻辑隔离单元:

  • 资源分组和隔离
  • 权限控制边界
  • 资源配额管理

2. 网络与流量管理

Ingress - 集群入口流量管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- host: leads.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80

NetworkPolicy - 网络安全策略

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: app-netpol
spec:
podSelector:
matchLabels:
app: app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: allowed-client

3. 身份认证与授权 (RBAC)

graph LR
    User[用户/服务] -->|绑定| SA[ServiceAccount]
    SA -->|关联| Binding[RoleBinding]
    Role[Role] -->|授权| Binding
    Binding -->|权限生效| Pod[Pod]

核心RBAC资源:

  • ServiceAccount: Pod的身份标识
  • Role/ClusterRole: 权限定义
  • RoleBinding/ClusterRoleBinding: 权限绑定

4. 扩展与自动伸缩

HorizontalPodAutoscaler (HPA)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70

PodDisruptionBudget (PDB)

1
2
3
4
5
6
7
8
9
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: app-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: app

5. 资源管理与治理

ResourceQuota - 资源配额

1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: ResourceQuota
metadata:
name: app-quota
spec:
hard:
requests.cpu: "10"
requests.memory: 20Gi
persistentvolumeclaims: "5"

LimitRange - 资源限制范围

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: LimitRange
metadata:
name: app-limits
spec:
limits:
- default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 100m
memory: 128Mi
type: Container

6. 存储资源

PersistentVolume (PV) 和 PersistentVolumeClaim (PVC)

graph LR
    SC[StorageClass] -->|动态供给| PV[PersistentVolume]
    PVC[PersistentVolumeClaim] -->|绑定| PV
    Pod -->|使用| PVC

7. 自定义资源扩展 (CRD)

graph LR
    CRD[CustomResourceDefinition] -->|定义| TApp[TApp]
    CRD -->|扩展| Custom[YourCustomResource]

实际案例:TApp CRD
在您的环境中使用的TApp就是腾讯云TKE的自定义资源:

  • 扩展了标准Deployment的功能
  • 支持多模板版本管理
  • 提供实例级精细控制

8. 完整的扩展架构图

graph TD
    subgraph 网络层
        Ingress[Ingress<br/>集群入口]
        Service[Service<br/>服务发现]
    end
    
    subgraph 应用层
        Pod[Pod<br/>多容器]
        Pod --> Main[主容器]
        Pod --> Sidecar[Sidecar容器]
        Pod --> Init[Init容器]
    end
    
    subgraph 配置层
        ConfigMap[ConfigMap<br/>配置管理]
        Secret[Secret<br/>敏感信息]
    end
    
    subgraph 存储层
        Volume[Volume<br/>存储卷]
    end
    
    subgraph 治理层
        HPA[HPA<br/>自动伸缩]
        PDB[PDB<br/>中断预算]
        Quota[ResourceQuota<br/>资源配额]
    end
    
    subgraph 安全层
        SA[ServiceAccount<br/>服务身份]
        Role[Role<br/>权限定义]
        Binding[RoleBinding<br/>权限绑定]
    end
    
    subgraph 隔离层
        NS[Namespace<br/>命名空间]
    end
    
    subgraph 扩展层
        CRD[CRD<br/>扩展API]
    end
    
    Ingress --> Service
    Service --> Pod
    ConfigMap --> Pod
    Secret --> Pod
    Volume --> Pod
    HPA --> Pod
    PDB --> Pod
    Quota --> NS
    SA --> Pod
    Role --> Binding
    Binding --> SA
    NS --> Pod
    CRD --> TApp

9. 资源关系总结

这些资源如何协同工作:

  1. Namespace 提供顶层隔离
  2. ServiceAccount + RBAC 提供身份和权限
  3. ResourceQuota + LimitRange 提供资源治理
  4. Ingress + Service 提供流量入口
  5. HPA + PDB 提供弹性伸缩
  6. CRD 提供无限扩展能力

10. 实际部署建议

对于您的app-prod应用,建议补充:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 1. 创建专用命名空间
apiVersion: v1
kind: Namespace
metadata:
name: app-production

# 2. 配置资源配额
apiVersion: v1
kind: ResourceQuota
metadata:
name: app-quota
namespace: app-production
spec:
hard:
requests.cpu: "32"
requests.memory: 64Gi
limits.cpu: "64"
limits.memory: 128Gi

# 3. 配置HPA自动伸缩
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa
spec:
scaleTargetRef:
apiVersion: apps.tkestack.io/v1
kind: TApp
name: app-springboot-prod
minReplicas: 4
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80

这套完整的资源体系构成了现代云原生应用平台的基础,支持从简单应用到复杂企业级系统的各种需求。