Skip to content

K8s

1. 一句话理解 Kubernetes(K8s)

text
K8s = 一个“集群级”的容器编排系统

Docker:管一个容器/几台机器的容器
K8s:管一群机器上的一大堆容器
K8s = 一个“集群级”的容器编排系统

Docker:管一个容器/几台机器的容器
K8s:管一群机器上的一大堆容器

简单类比:

text
单机 Docker:你自己在电脑上开 N 个程序窗口
K8s 集群:一家公司有很多电脑、很多员工,统一由“调度系统”管理谁干什么活
单机 Docker:你自己在电脑上开 N 个程序窗口
K8s 集群:一家公司有很多电脑、很多员工,统一由“调度系统”管理谁干什么活

2. 核心概念速通(用生活类比记)

2.1 集群(Cluster)= 一家公司

text
Cluster = 一整套 K8s 系统 + 很多机器
Cluster = 一整套 K8s 系统 + 很多机器
  • 只记一个点: 所有 Pod / Service 等,都是运行在某个 Cluster 里的

2.2 节点(Node)= 公司里的电脑

text
一个集群里,会有很多台机器(物理机 / 虚拟机)
这些机器在 K8s 里就叫 Node
一个集群里,会有很多台机器(物理机 / 虚拟机)
这些机器在 K8s 里就叫 Node
  • Master / Control Plane Node:管事的领导机,负责调度、决策
  • Worker Node:打工人,真正跑 Pod 的机器

2.3 Pod = 最小的“运行单元”

text
Pod = 一组紧密合作的容器
Pod = 一组紧密合作的容器
  • 特点:
    • 一个 Pod 里可以有 1~N 个容器(最常见:1 个)
    • Pod 内的容器:
      • 共用 网络 IP
      • 共用 存储卷
    • Pod 是 K8s 调度的最小单位(不会直接调度单个容器

类比:

text
容器(Container) = 单个进程
Pod = 一组捆绑在一起工作的进程(比如主程序 + 辅助 Sidecar)
容器(Container) = 单个进程
Pod = 一组捆绑在一起工作的进程(比如主程序 + 辅助 Sidecar)

2.4 控制器 & 声明式(Controller & Desired State)

K8s 的思想:声明我要的“结果”,系统帮你保持这个结果。

text
你:我要有 3 个副本的 Web 服务
K8s:好,我保证始终有 3 个在跑
   → 挂掉 1 个,我自动再拉 1 个起来
你:我要有 3 个副本的 Web 服务
K8s:好,我保证始终有 3 个在跑
   → 挂掉 1 个,我自动再拉 1 个起来

这个“保证你说的结果始终满足”的,就是各种 Controller

  • DeploymentController
  • ReplicaSetController
  • StatefulSetController

2.5 Deployment = “无状态 Web 服务模板”

text
Deployment 负责维护:N 个一模一样的 Pod
Deployment 负责维护:N 个一模一样的 Pod
  • 写一个 Deployment.yaml
    • 用哪个镜像
    • 需要几个副本(replicas)
    • 需要多少 CPU / 内存
    • 滚动更新策略
  • K8s 会自动:
    • 创建 / 删除 Pod
    • 挂掉就拉新 Pod
    • 按策略滚动更新

类比:

text
Deployment = 岗位说明书(需要 3 个人,会写前端,会 Vue)
Pod        = 招来的具体员工(小 A、小 B、小 C)
Deployment = 岗位说明书(需要 3 个人,会写前端,会 Vue)
Pod        = 招来的具体员工(小 A、小 B、小 C)

2.6 Service = 内部“固定门牌号”

Pod 的 IP 是会变的(删除重建后 IP 变),所以不能直接依赖 Pod IP。

Service 就是给一组 Pod 提供一个 固定访问入口

  • 有一个固定的名字 + 虚拟 IP
  • 通过 Label 匹配后端 Pod
  • 内置负载均衡(Round Robin)

类比:

text
Pod = 某个座位上的客服
Service = 客服总机电话(打这个号,系统随机转给一个正在上班的客服)
Pod = 某个座位上的客服
Service = 客服总机电话(打这个号,系统随机转给一个正在上班的客服)

2.7 Ingress = 暴露给外网的“网关”

Service 一般是集群内部访问用的。
要把 HTTP/HTTPS 暴露给外网,一般会用 Ingress

  • 负责域名、路径路由
  • 通常由 Ingress Controller 实现(如 Nginx Ingress)

类比:

text
Service = 公司内部分机号
Ingress = 公司对外公布的 400 电话 + 语音导航(根据按键转到不同部门)
Service = 公司内部分机号
Ingress = 公司对外公布的 400 电话 + 语音导航(根据按键转到不同部门)

2.8 ConfigMap / Secret = 配置中心

  • ConfigMap:存在明文的配置数据(如环境变量、配置文件)
  • Secret:用于敏感信息(如密码、Token),会做 base64 编码 & 可以结合外部密钥系统

类比:

text
ConfigMap = 普通配置文件
Secret    = 保险柜里的机密文件
ConfigMap = 普通配置文件
Secret    = 保险柜里的机密文件

3. 为什么要用 K8s(对前端工程师有什么用)

3.1 你可能遇到的场景

text
❌ 项目上线后,偶发 502,人工重启容器才好
❌ 高峰期时,手动多起几个容器,低峰再手动关
❌ 不同环境(dev/stage/prod)部署脚本一堆,细节极易出错
❌ 多个服务之间调用,IP/端口经常配错
❌ 项目上线后,偶发 502,人工重启容器才好
❌ 高峰期时,手动多起几个容器,低峰再手动关
❌ 不同环境(dev/stage/prod)部署脚本一堆,细节极易出错
❌ 多个服务之间调用,IP/端口经常配错

3.2 K8s 提供的能力

text
✅ 自动重启:Pod 挂了自动拉新
✅ 自动扩缩容:根据 CPU / QPS 自动加减实例
✅ 服务发现:通过 Service 名称就能互相访问
✅ 滚动更新:一批一批更新,不一次性全换
✅ 声明式配置:所有部署都写在 yaml,流程可复用
✅ 自动重启:Pod 挂了自动拉新
✅ 自动扩缩容:根据 CPU / QPS 自动加减实例
✅ 服务发现:通过 Service 名称就能互相访问
✅ 滚动更新:一批一批更新,不一次性全换
✅ 声明式配置:所有部署都写在 yaml,流程可复用

4. K8s 与 Docker / Docker Compose 的关系

4.1 三者之间的定位

text
Docker:提供“容器”这个能力
Docker Compose:在一台机器上编排多个容器
K8s:在一堆机器上编排成千上万个容器
Docker:提供“容器”这个能力
Docker Compose:在一台机器上编排多个容器
K8s:在一堆机器上编排成千上万个容器
维度Docker / ComposeKubernetes
管理范围单机集群(多机)
对象容器 / 服务Pod / Deployment / Service 等
高可用需要自己写脚本内置控制器保证副本数
服务发现需要额外方案(如 Consul 等)内置 DNS + Service
扩缩容手动调整HPA 自动扩缩容
学习复杂度相对高

4.2 心理模型

text
本地开发 / 小项目:Docker / Docker Compose 足够
公司正式环境 / 微服务:通常会跑在 K8s 上
本地开发 / 小项目:Docker / Docker Compose 足够
公司正式环境 / 微服务:通常会跑在 K8s 上

5. 最小上手:常用 kubectl 命令

假设已经有一个可用的 K8s 集群,并且你的机器上配置好了 kubectl

5.1 查看集群 & 节点

bash
# 查看当前 kubectl 连接的是哪个集群
kubectl config current-context

# 查看所有可用的 context(不同集群/环境)
kubectl config get-contexts

# 查看节点
kubectl get nodes
# 查看当前 kubectl 连接的是哪个集群
kubectl config current-context

# 查看所有可用的 context(不同集群/环境)
kubectl config get-contexts

# 查看节点
kubectl get nodes

5.2 查看常见资源

bash
# 查看所有命名空间
kubectl get ns

# 查看当前命名空间中的 Pod / Service / Deployment
kubectl get pods
kubectl get svc
kubectl get deploy

# 查看所有命名空间中的 Pod
kubectl get pods -A
# 查看所有命名空间
kubectl get ns

# 查看当前命名空间中的 Pod / Service / Deployment
kubectl get pods
kubectl get svc
kubectl get deploy

# 查看所有命名空间中的 Pod
kubectl get pods -A

5.3 查看详情 / 日志 / 进入 Pod

bash
# 查看某个 Pod 的详情
kubectl describe pod Pod名

# 查看 Pod 日志
kubectl logs Pod名

# 如果有多个容器
kubectl logs Pod名 -c 容器名

# 进入 Pod 内部(类似 docker exec)
kubectl exec -it Pod名 -- /bin/bash
# 查看某个 Pod 的详情
kubectl describe pod Pod名

# 查看 Pod 日志
kubectl logs Pod名

# 如果有多个容器
kubectl logs Pod名 -c 容器名

# 进入 Pod 内部(类似 docker exec)
kubectl exec -it Pod名 -- /bin/bash

5.4 应用 / 删除一个 yaml

bash
# 创建或更新资源(推荐)
kubectl apply -f xxx.yaml

# 删除资源
kubectl delete -f xxx.yaml
# 创建或更新资源(推荐)
kubectl apply -f xxx.yaml

# 删除资源
kubectl delete -f xxx.yaml

小经验:

text
apply = 声明“我要这个状态”,不存在就创建,存在就更新
delete = 把这份声明删掉(对应的资源也会被删)
apply = 声明“我要这个状态”,不存在就创建,存在就更新
delete = 把这份声明删掉(对应的资源也会被删)

5.5 端口转发(本地调试非常常用)

bash
# 把本地 8080 端口转发到某个 Pod 的 80 端口
kubectl port-forward pod/Pod名 8080:80

# 或者转发到 Service
kubectl port-forward svc/Service名 8080:80
# 把本地 8080 端口转发到某个 Pod 的 80 端口
kubectl port-forward pod/Pod名 8080:80

# 或者转发到 Service
kubectl port-forward svc/Service名 8080:80

这样就可以在浏览器里访问:http://localhost:8080 去调试集群内的服务。


6. 一个最小示例:部署一个 Nginx

6.1 Deployment + Service 示例

yaml
# nginx-deploy.yaml
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.25
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: ClusterIP # 仅集群内访问;也可用 NodePort / LoadBalancer
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
# nginx-deploy.yaml
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.25
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: ClusterIP # 仅集群内访问;也可用 NodePort / LoadBalancer
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80

6.2 部署 & 访问

bash
# 部署
kubectl apply -f nginx-deploy.yaml

# 查看 Pod / Service
kubectl get pods
kubectl get svc

# 本地端口转发
kubectl port-forward svc/nginx-service 8080:80
# 部署
kubectl apply -f nginx-deploy.yaml

# 查看 Pod / Service
kubectl get pods
kubectl get svc

# 本地端口转发
kubectl port-forward svc/nginx-service 8080:80

浏览器打开 http://localhost:8080,看到 Nginx 默认页面。


7. 常见资源类型速查

类型作用典型场景
Pod最小调度单元,容器的“壳”单次任务 / Job / 辅助容器
Deployment管理无状态服务的多副本 PodWeb 服务、API 服务
StatefulSet有状态服务,多副本且有固定编号、稳定标识数据库、消息队列、需要有序的服务
DaemonSet在每个节点上都跑一个 Pod日志采集、监控 Agent
Job / CronJob一次性的任务 / 定时任务数据清理、定时脚本
Service稳定访问入口 + 内部负载均衡服务间调用、对外暴露 NodePort 等
IngressHTTP / HTTPS 入口,基于域名/路径的路由对外 Web 网关
ConfigMap一般配置环境变量、配置文件
Secret敏感配置密码、Token、证书
PVC / PV持久化存储声明/实现存放数据、日志、上传文件等

8. 本地开发 & 调试时常用的姿势

8.1 只接触 kubectl,不自己搭集群

在公司里最典型的情况:

text
✔ 运维 / 平台组 已经搭好了 K8s 集群
✔ 帮你准备好了 kubeconfig,或者安装了公司内部 CLI
你只需要:
  - 写好镜像(Dockerfile)
  - 写或修改 yaml
  - 用 kubectl apply / delete 部署
  - 用 kubectl logs / exec 调试
✔ 运维 / 平台组 已经搭好了 K8s 集群
✔ 帮你准备好了 kubeconfig,或者安装了公司内部 CLI
你只需要:
  - 写好镜像(Dockerfile)
  - 写或修改 yaml
  - 用 kubectl apply / delete 部署
  - 用 kubectl logs / exec 调试

8.2 和 Docker 的心智切换

以前(Docker)现在(K8s)
docker run写 Deployment + Service,再 apply
docker logs 容器名kubectl logs Pod名
docker exec -it 容器名kubectl exec -it Pod名 -- bash
docker pskubectl get pods

9. 常见疑问

9.1 K8s 会自己拉 Docker 镜像吗?

会。

在 Deployment 里只需要写好:

yaml
image: your-registry/your-app:tag
image: your-registry/your-app:tag

K8s 会在需要的时候去对应的镜像仓库拉取镜像(前提是:

  • 节点能访问镜像仓库
  • 配好了镜像拉取凭据(私有仓库时需要 ImagePullSecret)

9.2 Pod 重建后,数据会不会丢?

取决于你 是否用了持久化存储(PVC/PV)

  • 如果只是容器内的普通目录:Pod 删了就没了
  • 如果把目录挂到了 PVC 上:Pod 重建后再挂上 PVC,数据还在

9.3 Service 有几种类型?

常用三种:

  • ClusterIP(默认):只在集群内访问
  • NodePort:在每个 Node 上打开一个端口对外暴露
  • LoadBalancer:结合云厂商的 LB 资源对外暴露

9.4 Ingress 和 Service 的关系?

text
浏览器请求 → Ingress(根据域名/路径转发)→ 对应的 Service → 对应的 Pod
浏览器请求 → Ingress(根据域名/路径转发)→ 对应的 Service → 对应的 Pod

Ingress 负责 HTTP 层面的路由;Service 负责集群内部寻址 + 负载均衡。


10. 总结

text
核心概念:
✅ Cluster / Node = 集群和机器
✅ Pod = 最小运行单元(承载容器)
✅ Deployment = 维护一组无状态 Pod 的控制器
✅ Service = 稳定访问入口 + 内部负载均衡
✅ Ingress = 对外的 HTTP 网关
✅ ConfigMap / Secret = 配置中心(普通 / 机密)

常用操作:
✅ kubectl get / describe   - 查看资源
✅ kubectl logs / exec      - 调试 Pod
✅ kubectl apply/delete -f  - 部署 / 删除 yaml
✅ kubectl port-forward     - 本地访问集群内服务
核心概念:
✅ Cluster / Node = 集群和机器
✅ Pod = 最小运行单元(承载容器)
✅ Deployment = 维护一组无状态 Pod 的控制器
✅ Service = 稳定访问入口 + 内部负载均衡
✅ Ingress = 对外的 HTTP 网关
✅ ConfigMap / Secret = 配置中心(普通 / 机密)

常用操作:
✅ kubectl get / describe   - 查看资源
✅ kubectl logs / exec      - 调试 Pod
✅ kubectl apply/delete -f  - 部署 / 删除 yaml
✅ kubectl port-forward     - 本地访问集群内服务

记住一句话:K8s 不是“高级版 Docker”,而是“在一大堆机器上,帮你让很多 Docker 容器稳定跑起来的系统”。