4、Kubernetes入门:K8s架构与核心组件、Pod与Deployment、Service与Ingress

好,咱们进入Kubernetes的世界。说实话,K8s是云原生流水线的核心底座。没有它,你那些容器化的应用就像散落一地的乐高积木,拼不成城堡。

我个人习惯把K8s看作一个「数据中心操作系统」。它管理的不再是单个进程,而是整个集群的资源。你告诉它「我要跑3个Nginx实例」,它自己会去找三台机器部署好,挂了还会自动重启。是不是很省心?

4.1 K8s架构:Master与Node的分工

K8s集群分两拨人:Master节点(控制面)和Worker节点(数据面)。

Master节点负责决策和调度。它里面有几个关键组件:

  • API Server:整个集群的入口。你所有操作(kubectl命令)都走它。它就像公司的前台,谁来了都得先登记。
  • etcd:集群的数据库。存着所有状态信息。这玩意儿挂了,集群就失忆了。我在生产环境遇到过etcd磁盘写满导致集群瘫痪的事故,嗯,从那以后我给它配了独立的SSD和定期快照。
  • Scheduler:调度器。决定一个新Pod该放到哪个Worker节点上。它会看节点资源够不够、有没有污点等。
  • Controller Manager:控制器大脑。确保集群的实际状态符合你的期望状态。比如你声明要3个Pod,它发现只有2个,就会立刻创建第3个。

Worker节点是真正跑应用的地方。每个节点上都有:

  • Kubelet:节点上的「监工」。负责跟Master通信,管理Pod的生命周期。它要是罢工了,这个节点就失联了。
  • Kube-proxy:网络代理。负责实现Service的网络规则,让Pod之间能互相通信。
  • 容器运行时:比如Docker、containerd。真正拉镜像、跑容器的底层工具。

一句话总结:Master负责想(调度决策),Worker负责干(跑容器)。

4.2 Pod:最小的调度单元

Pod是K8s里你能创建和部署的最小单元。它里面可以有一个或多个容器。这些容器共享网络栈和存储卷。

你可能会问:为什么不用容器直接作为最小单元?

我举个例子。假设你有个日志采集器(Filebeat),它需要跟你的业务容器跑在一起,共享日志目录。如果它们是两个独立的容器,调度时可能被分到不同机器上。但放在同一个Pod里,K8s保证它们永远在一起。

Pod的生命周期是短暂的。它可能因为节点故障、资源不足、更新版本等原因被销毁重建。所以,永远不要直接创建Pod,而是通过控制器来管理。

# 一个简单的Pod定义
apiVersion: v1
kind: Pod
metadata:
  name: my-nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.21
    ports:
    - containerPort: 80

避坑指南:我曾经在生产环境直接删了一个Pod,以为它会自动重建。结果发现它没有控制器管理,直接消失了。那是一个没有配置Deployment的测试Pod,导致服务中断了5分钟。从那以后,我要求团队所有Pod必须通过Deployment或StatefulSet创建。

4.3 Deployment:声明式更新与扩缩容

Deployment是K8s里最常用的工作负载控制器。它负责管理一组Pod的副本,并保证它们按你期望的方式运行。

说白了,你告诉Deployment「我要5个Nginx Pod」,它会创建5个。如果某个Pod挂了,它会自动再创建一个。如果你想升级版本,它支持滚动更新,逐个替换Pod,保证服务不中断。

# Deployment示例
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80

Deployment有几个核心能力:

  • 滚动更新:逐步替换旧版本Pod,可以控制更新速度和暂停。
  • 回滚:如果新版本有问题,一键回滚到上一个版本。
  • 扩缩容:修改replicas字段,K8s会自动增加或减少Pod数量。

注意:滚动更新时,如果新Pod启动失败,Deployment会停止更新。我曾经遇到过新镜像拉取失败,导致更新卡住,旧Pod也被删了一半。所以,一定要配置存活探针(livenessProbe)和就绪探针(readinessProbe),让K8s知道你的应用是否真的准备好了。

4.4 Service:稳定的网络入口

Pod是动态的,IP地址会变。那客户端怎么访问你的应用?Service就是来解决这个问题的。

Service为一组Pod提供一个稳定的虚拟IP和DNS名称。客户端只需要访问这个Service,K8s会自动把流量转发到后端的Pod上。

# Service示例
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: ClusterIP

Service有几种类型:

类型 说明 使用场景
ClusterIP 集群内部IP,外部无法访问 内部服务间调用
NodePort 在每个节点上开放一个端口 开发测试环境
LoadBalancer 云厂商提供负载均衡器 生产环境对外暴露

我的经验:NodePort只适合临时调试。生产环境一定要用LoadBalancer或Ingress。我曾经见过有人用NodePort暴露生产服务,结果端口被扫描攻击,差点出事。

4.5 Ingress:七层路由与域名管理

Service的LoadBalancer类型每个服务都要一个公网IP,成本高且管理麻烦。Ingress就是来解决这个问题的。

Ingress工作在七层(HTTP/HTTPS),可以根据域名、路径把请求路由到不同的Service。它就像Nginx的反向代理,但配置是声明式的。

# Ingress示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80

要实现Ingress,集群里需要安装Ingress Controller,比如Nginx Ingress Controller、Traefik。它负责读取Ingress规则并配置实际的负载均衡器。

核心要点:

  • Pod是临时工,Deployment是项目经理
  • Service是内部电话总机,Ingress是前台接待
  • 永远不要依赖Pod的IP,用Service或Ingress访问

好了,这一章的内容就到这里。K8s的入门其实不难,关键是理解它的设计思想:声明式、控制器模式、分层抽象。下一章我们会深入实战,用K8s部署一个完整的微服务应用。