docker和k8s的最佳实践

准备工作

  1. 安装docker desktop
  2. 通过docker desktop安装k8s集群
  3. 一个基础的nest项目

docker上手

容器常用命令

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
# 查看运行的容器
docker ps

# 查看所有容器
docker ps -a

# 停止容器
docker stop <container id or name>

# 启动容器
docker start <container id or name>

# 重启容器
docker restart <container id or name>

# 后台运行一个容器
# docker run:把本地或远程的镜像“实例化”为一个正在运行的容器
# -d:--detach 让容器在后台运行,不占用当前命令行窗口
docker run -d <IMAGE NAME>

# 在容器中执行命令
# -it: 启用交互
# --rm: 退出后自动删除容器
# COMMAND一般是/bin/sh 或者 /bin/bash
docker exec -it --rm <CONTAINER_ID> <COMMAND>

# 查看容器信息
docker inspect <CONTAINER_ID>

# 后台启动一个容器,名字叫nest-test,容器内部是3000端口,映射到宿主机的3001端口,用的镜像名字是nest-app,标签是latest
# -p:--publish 把容器内部端口映射到宿主机端口,左边是宿主机(你的 Windows)可以访问的端口3001,右边是容器内部应用监听的端口(Nest 默认端口3000)
docker run -d -p 3001:3000 --name nest-test nest-app:latest

# 移除容器
docker rm <container id or name>

镜像常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 查看本地镜像
docker image ls
docker images

# 构建镜像 其中的 . 表示当前目录
# Docker 会把当前目录下的文件(Dockerfile、源代码、package.json 等)传给 Docker 引擎做构建
docker build -t <image-name> .

# 给镜像打标签,有两种方式,构建的时候打,构建之后基于镜像打
# 方式1,构建打,标签为latest
docker build -t my-app:latest .
#方式2,构建后打,镜像的标签为v2.0
docker tag <镜像ID或原镜像名> <新镜像名>:<新标签>
docker tag 123abc456def my-app:v2.0

# 构建镜像手动指定dockerfile
docker build -f <dockerfile路径> -t image-name:latest .

# 查看镜像详情
docker image inspect <IMAGE_ID>

# 删除镜像
docker rmi <IMAGE_ID>
docker rmi <REPOSITORY>:<TAG>

快速上手理解

1
docker run --name elasticsearch -d -p 9200:9200 -p 9300:9300 -v /data/elasticsearch:/usr/share/elasticsearch/data -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.16.2

我们拆分来看

  • docker run:启动命令
  • --name elasticsearch:给容器指定一个名字
  • -d:表示 detached 模式,容器会在后台运行,而不是占用当前终端
  • -p 9200:9200 -p 9300:9300:端口映射,将容器内部端口映射到宿主机端口。9200是REST API 调用和 Kibana 访问,9300是集群内部通信端口(Elasticsearch 节点间通讯)
  • -v /data/elasticsearch:/usr/share/elasticsearch/data:宿主机目录 /data/elasticsearch 映射到容器内 Elasticsearch 数据目录 /usr/share/elasticsearch/data,这样即使容器删除,数据仍然保留在宿主机上
  • -e "discovery.type=single-node":告诉 Elasticsearch 这是 单节点模式
  • docker.elastic.co/elasticsearch/elasticsearch:7.16.2:指定要运行的镜像和版本

把nest应用打包成镜像

这里我们需要一个nest new project-name,不需要任何的其他依赖,我们通过nest创建的基础模板应用可以让我们访问本机的127.0.0.1:3000端口并且成功返回Hello World!

现在我们需要把这个nest应用一步步打包成镜像,让它可以随处使用

首先,我们在项目的根目录下新建 Dockerfile 文件

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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# ============================================================
# 构建阶段(Builder Stage)
# ============================================================

# 一个轻量的 Debian 系统,预装了 Node.js 22
# 命名这个构建阶段为 `builder`,方便多阶段构建使用
FROM node:22-bullseye-slim AS builder

# 设置当前工作目录为 /app
WORKDIR /app

# 先复制依赖描述文件,利用缓存层
# 把当前项目下的 package.json 和 package-lock.json 复制到 /app 目录下
COPY package*.json ./

# 安装依赖(包含 devDependencies)
# 跑命令 npm run clean & npm run install (npm run ci)
RUN npm ci

# 复制项目源码
# 把当前项目所有代码拷贝到 /app 目录下
COPY . .

# 构建 Nest 项目
RUN npm run build

# 构建阶段结束后,app目录下就是全部的nestjs项目代码

# ============================================================
# 运行阶段(Runtime Stage)
# ============================================================

# 一个轻量的 Debian 系统,预装了 Node.js 22
# 命名这个构建阶段为 `runner`,方便多阶段构建使用
FROM node:22-bullseye-slim AS runner

# 设置当前工作目录为 /app
WORKDIR /app

# 设置生产环境变量
ENV NODE_ENV=production
ENV PORT=3000

# 拷贝构建产物与依赖说明
# 把从构建阶段的产物拷贝到当前系统的 /app 目录下
# 注意只是拷贝了 /app/dist /app/package*.json,其他多余代码无需拷贝
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./

# 只安装生产依赖
# 不会安装devdependences
RUN npm ci --omit=dev

# 创建非 root 用户以提升安全性
RUN addgroup --system app && adduser --system --ingroup app app
USER app

# 暴露端口
EXPOSE 3000

# 启动命令
CMD ["node", "dist/main.js"]

然后我们打包构建镜像,镜像名称是 nest-app,镜像的标签是 latest

1
docker build -t nest-app:latest .

最终我们通过命令基于 nest-app 镜像启动一个容器,宿主机的端口是在左边,容器内部端口是在右边,容器名称为 nest-test,镜像标签为 nest-app:latest

1
docker run -d -p 3001:3000 --name nest-test nest-app:latest

我们通过 docker images 可以查看我们的镜像信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
REPOSITORY                                TAG                                                                           IMAGE ID       CREATED         SIZE
nest-app latest 4a0880522d51 21 hours ago 376MB
node 22-bullseye-slim 81eda6ed8790 2 weeks ago 336MB
docker/desktop-kubernetes kubernetes-v1.34.1-cni-v1.7.1-critools-v1.33.0-cri-dockerd-v0.3.20-1-debian 12d6673564e0 3 weeks ago 591MB
registry.k8s.io/kube-apiserver v1.34.1 b9d7c117f8ac 4 weeks ago 118MB
registry.k8s.io/kube-controller-manager v1.34.1 2bf47c1b01f5 4 weeks ago 101MB
registry.k8s.io/kube-scheduler v1.34.1 6e9fbc4e25a5 4 weeks ago 73.5MB
registry.k8s.io/kube-proxy v1.34.1 913cc83ca0b5 4 weeks ago 102MB
registry.k8s.io/etcd 3.6.4-0 e36c08168342 2 months ago 273MB
registry.k8s.io/pause 3.10.1 278fb9dbcca9 3 months ago 1.06MB
registry.k8s.io/coredns/coredns v1.12.1 e8c262566636 6 months ago 101MB
registry.k8s.io/pause 3.10 ee6521f290b2 16 months ago 1.06MB
docker/desktop-vpnkit-controller dc331cb22850be0cdd97c84a9cfecaf44a1afb6e 7ecf567ea070 2 years ago 47MB
kubernetesui/dashboard v2.7.0 2e500d29e9d5 3 years ago 334MB
kubernetesui/metrics-scraper v1.0.8 76049887f07a 3 years ago 63.6MB
docker/desktop-storage-provisioner v2.0 115d77efe6e2 4 years ago 59.2MB

可以看到一个 repository 名字叫 nest-app,它的tag叫 latest

通过 docker ps --filter="name=nest-test"命令来查看容器信息

1
2
CONTAINER ID   IMAGE             COMMAND                   CREATED              STATUS              PORTS                                         NAMES
7ad27bc050d4 nest-app:latest "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:3001->3000/tcp, [::]:3001->3000/tcp nest-test

在浏览器上输入 http://127.0.0.1:3001/,即可以看到 Hello World!

Kubernetes上手

docker的优点

我们可以把项目直接打包成镜像,然后把镜像放到自己的镜像仓库。

docker从开发,运维,部署角度均有优点存在:

  1. 容器直接运行在操作系统内核上,不像虚拟机需要完整的 OS,因此启动快、占用资源少
  2. 同一台主机上可以运行 更多实例,节省硬件成本
  3. 容器把应用及依赖打包在一起,环境一致性保证,避免“依赖冲突”和“环境不一致”问题
  4. 镜像可移植:在不同服务器、云平台上都能运行
  5. 支持多阶段构建,能生成轻量化生产镜像,快速部署上线
  6. 与 Jenkins、GitHub Actions、GitLab CI 等 CI/CD 工具无缝集成
  7. 可以在构建阶段完成依赖安装、编译打包,再生成干净的生产镜像,实现标准化流水线
  8. 每个容器运行在独立的命名空间和文件系统中,不同容器之间互不干扰,减少了应用之间的依赖冲突
  9. 容器启动快、占用少,非常适合 微服务架构
  10. 可以从官方基础镜像出发,自定义镜像

为什么会有Kubernetes

我们发现启动一个容器,只能暴露一个宿主机端口,这就意味着,当我的nest应用需要水平扩展,这时候就需要通过nginx统一入口,然后启动容器的时候不映射宿主机端口,通过docker网络通信,用户访问nginx的固定端口,然后由nginx将请求分发到nest1和nest2应用,这显然比较麻烦。

所以docker有它的局限性:

  • Docker 本身只管理单台主机上的容器,当应用需要跨多台服务器部署时,Docker 并没有原生的集群管理能力
  • Docker 可以通过 docker-compose 做简单的多容器编排,但在生产环境中,服务数量多、依赖复杂时,Compose 不够健壮
  • 容器故障时,需要人工重启,负载均衡、弹性扩缩容、滚动更新等功能不够完善

所以k8s出现的意义,其实是与docker的互补

功能 Docker 单机 K8s(集群管理)
集群管理 ❌ 无 ✅ 管理多台服务器上的容器
弹性伸缩 ❌ 需要手动 ✅ 自动扩缩容
健康检查 ❌ 需要外部工具 ✅ 自动重启或迁移故障容器
服务发现 & 负载均衡 ❌ 内建不足 ✅ 内建服务发现与负载均衡
滚动更新 / 回滚 ❌ 手动 ✅ 原生支持
存储与网络抽象 ❌ 简单卷挂载 ✅ 支持动态卷和多网络模式

k8s的核心概念

Pod

最小的运行单元,包含一个或多个容器(通常是一个)

1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: Pod
metadata:
name: nest-pod
spec:
containers:
- name: nest-app
image: my-nest-app:latest
ports:
- containerPort: 3000

Depolyment

管理 Pod 的创建、更新、扩缩容,Deployment 是一个 控制器(Controller),用于声明“你希望有多少个 Pod、用什么镜像、如何更新”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: apps/v1
kind: Deployment
metadata:
name: nest-deployment
spec:
# 副本数量
replicas: 3
selector:
matchLabels:
app: nest
template:
metadata:
labels:
app: nest
spec:
containers:
- name: nest-app
image: my-nest-app:v1.0
ports:
- containerPort: 3000

Service

暴露 Pod 的统一访问入口,提供负载均衡与服务发现

Service 是 Pod 的抽象访问层,为一组相同功能的 Pod 提供固定的虚拟 IP、内部负载均衡和服务发现

自动把请求分发到健康的 Pod
Pod IP 动态变化时,Service IP 不变
支持多种类型

  • ClusterIP(默认,集群内部访问)
  • NodePort(通过节点端口暴露给外部)
  • LoadBalancer(云环境自动接入外部 LB)
1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Service
metadata:
name: nest-service
spec:
selector:
app: nest
ports:
- port: 80
targetPort: 3000
type: ClusterIP

Ingress

管理外部 HTTP/HTTPS 访问入口(反向代理 / API 网关)

基于域名或路径的路由(如 api.example.comnest-service
支持 SSL/TLS
可以配置重写路径、限流、鉴权等高级策略

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

ConfigMap / Secret

管理应用配置(普通配置、敏感信息)

ConfigMap:存放普通配置(非敏感)
Secret:存放敏感信息(如密码、Token、证书),会 base64 加密存储

实现配置与镜像解耦,可注入为:环境变量、配置文件、命令行参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
NODE_ENV: production
LOG_LEVEL: debug

# Secret
apiVersion: v1
kind: Secret
metadata:
name: db-secret
stringData:
DB_PASSWORD: myStrongPassword

# 在pod中使用
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: db-secret

Replica Sets

ReplicaSet 是 负责维持 Pod 数量的控制器,由 Deployment 自动管理

维持一组 Pod 的副本数
Pod 挂了自动重启新 Pod
Deployment 滚动更新时,会创建新的 ReplicaSet 并逐步替换旧的

逻辑运行图

1
2
3
4
5
6
7
8
9
10
11
[Ingress]

[Service] ←→ 发现 Pod IP 并做负载均衡

[Deployment]

[ReplicaSet] 维持 Pod 数量

[Pod] 运行 Nest 容器

[ConfigMap / Secret] 提供配置

k8s常用命令

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
# k8s 版本
kubectl version

# k8s 集群中所有节点信息
kubectl get nodes

# k8s 当前配置文件中的中的所有上下文
kubectl config get-contexts

# k8s 的集群的基本信息
kubectl cluster-info

# k8s启动一个nginx
kubectl run nginx --image=nginx

# k8s暴露端口
kubectl expose pod nginx --port=80 --type=NodePort

# k8s获取服务信息
kubectl get svc

# 安装 k8s UI
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

# 创建UI账号
kubectl create serviceaccount dashboard-admin-sa -n kubernetes-dashboard

# 赋予权限
kubectl create clusterrolebinding dashboard-admin-sa-binding --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:dashboard-admin-sa

# 创建临时token
kubectl -n kubernetes-dashboard create token dashboard-admin-sa

# 启动UI
kubectl proxy

通过k8s部署nest应用

在项目根目录下新建 k8s-deploy.yaml 文件,文件内容如下:

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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# ============================
# ConfigMap: 配置环境变量
# ============================

# 指定该资源的 API 版本为 v1
apiVersion: v1
# 声明资源类型为 ConfigMap,用于存放非敏感的配置信息(键值对)
kind: ConfigMap
# 资源的名字,集群内唯一,nest-app-config
metadata:
name: nest-app-config
# data 字段包含若干键值对(均为字符串)
data:
NODE_ENV: 'production'
PORT: '3000'

---
# ============================
# Deployment: Nest 应用
# ============================

# Deployment 属于 apps API group,版本为 v1
apiVersion: apps/v1
# 声明资源类型为 Deployment,用于声明式管理 Pod 的副本、更新策略等
kind: Deployment
# Deployment 的名字,后续 kubectl 操作会以此名字识别该 Deployment
metadata:
name: nest-app
# 指定期望的 Pod 副本数,Kubernetes 会通过 ReplicaSet 保证有 2 个 Pod 在运行(实现水平扩展/高可用)
spec:
replicas: 2 # 高可用,启动 2 个 Pod
# selector 定义 Deployment 管理哪些 Pod:通过 label selector 匹配 app: nest-app 的 Pod
selector:
matchLabels:
app: nest-app
# spec.template.metadata.labels 必须与此 selector 匹配,否则 Deployment 无法识别自己的 Pod
# Pod 模板的 metadata,给要创建的 Pod 打上 app: nest-app 的标签,确保与 selector 对应
template:
metadata:
labels:
app: nest-app
# Pod 的 spec,定义容器数组:这里只有一个容器,名字 nest-app,使用镜像 nest-app:latest
spec:
containers:
- name: nest-app
image: nest-app:latest
# 不尝试从远程仓库拉取镜像,仅使用节点本地存在的镜像
imagePullPolicy: Never # 使用本地镜像
# 声明容器内部监听的端口 3000
ports:
- containerPort: 3000
# 配置文件,将 ConfigMap 中的键按环境变量注入到容器内
envFrom:
- configMapRef:
name: nest-app-config
# 就绪探针(readinessProbe),用于判断 Pod 是否“已经准备好接收流量”
# 容器启动后等待 5 秒再开始探测,每 10 秒探测一次
readinessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
# 存活探针(livenessProbe),用于判断容器是否处于“健康运行”状态
# 容器启动后 10 秒才开始第一次检测,每 20 秒检测一次
# readiness 控制流量,liveness 控制重启
livenessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 10
periodSeconds: 20
# resources 定义容器的资源请求与上限
# requests 调度时的最小资源需求(调度器用来决定将 Pod 放到哪个 Node)
# limits 容器能使用的最大资源,超出可能被限流(CPU)或 OOM(内存)
resources:
requests:
memory: '128Mi'
cpu: '100m'
limits:
memory: '256Mi'
cpu: '500m'

---
# ============================
# Service: 对外访问
# ============================

# Service 资源,名字为 nest-service
# Service 提供稳定的访问入口,背后会负载均衡到匹配的 Pod
apiVersion: v1
kind: Service
metadata:
name: nest-service
# Service 类型为 NodePort,会在每个 Node 上分配一个固定端口
spec:
type: NodePort
# selector 指定 Service 如何选择后端 Pod:匹配带有 app: nest-app 标签的 Pod,与你的 Deployment 模板标签一致
selector:
app: nest-app
ports:
- port: 3000 # Service 内部端口
targetPort: 3000 # Pod 容器端口
nodePort: 30080 # 宿主机访问端口

然后我们执行部署命令

1
kubectl apply -f k8s-deploy.yaml
  • apply:申明式部署
  • -f:参数,表示从文件中读取定义

然后我们就成功部署了nest应用到k8s上

部署成功的表现如何

上面我们通过 kubectl proxy 启动了 k8s 的UI管理界面

我们通过 http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/workloads?namespace=default打开UI界面

我们可以看到一个deployments,两个pods,在services服务中看到了一个 nest-service,我这边暴露出来的是30080端口,直接在宿主机上访问 http://127.0.0.1:30080/,又成功看到了 Hello World!

我们用一张图来展示它们其中的关系~

flowchart TB
  subgraph Cluster["Kubernetes Cluster"]
    subgraph ConfigMapGroup["ConfigMap"]
      C1["📄 ConfigMap<br>nest-app-config"]
    end

    subgraph DeployGroup["Deployment"]
      D1["🧩 Deployment<br>nest-app"]
      RS1["🧱 ReplicaSet<br>(由 Deployment 管理)"]
    end

    subgraph PodGroup["Pods (2 replicas)"]
      P1["🟣 Pod #1<br>nest-app 容器"]
      P2["🟣 Pod #2<br>nest-app 容器"]
    end

    subgraph ServiceGroup["Service"]
      S1["🌐 Service<br>nest-service<br>NodePort:30080 → 3000"]
    end
  end

  %% 关系
  C1 -->|提供环境变量| P1
  C1 -->|提供环境变量| P2

  D1 -->|创建与管理| RS1
  RS1 -->|维持副本 replicas=2| P1
  RS1 --> P2

  S1 -->|选择 app=nest-app| P1
  S1 -->|选择 app=nest-app| P2

  %% 样式
  classDef config fill:#b3d4fc,stroke:#0366d6,stroke-width:1px,color:#000;
  classDef deploy fill:#f9d29d,stroke:#b58900,stroke-width:1px,color:#000;
  classDef service fill:#b7e4c7,stroke:#2d6a4f,stroke-width:1px,color:#000;
  classDef pod fill:#d9c2f0,stroke:#6a1b9a,stroke-width:1px,color:#000;

  class C1 config;
  class D1,RS1 deploy;
  class S1 service;
  class P1,P2 pod;

docker + ci/cd + k8s的最佳实践

CI/CD 的本质是 “构建镜像(Build) → 推送仓库(Push) → 部署更新(Deploy)”
Kubernetes 负责运行与弹性伸缩,CI/CD 负责自动化管控

我们来拆解一下Docker + CI/CD + Kubernetes 的实际执行逻辑

  • build阶段,CI/CD 工具(GitHub Actions、GitLab CI、Jenkins 等)主要拉取最新代码,然后安装依赖,构建产物,最后构建docker镜像,最后提供的是一个独立可运行的镜像(包含 Node 运行时 + 编译后的 Nest.js 应用)
  • push阶段,推送镜像到自己的仓库,CI/CD 会自动使用仓库凭证登录推送
  • Deploy 阶段,Kubernetes 根据 YAML 文件(Deployment / Service / ConfigMap 等)创建或更新资源
flowchart TD
    A[开发提交代码<br>push to Git repo] --> B[CI 构建<br>npm ci + npm run build] --> C[构建 Docker 镜像<br>docker build] --> D[推送镜像仓库<br>docker push]
    D --> E[部署阶段<br>kubectl apply 或<br>kubectl set image] --> F[Kubernetes Deployment<br>滚动更新 Pods] --> G[Service<br>统一访问入口] --> H[用户访问]

    style B fill:#f9d29d,stroke:#b58900,color:#000
    style C fill:#f4a261,stroke:#b56500,color:#fff
    style D fill:#94d2bd,stroke:#2a9d8f,color:#000
    style E fill:#bde0fe,stroke:#0077b6,color:#000
    style F fill:#bde0fe,stroke:#0077b6,color:#000
    style G fill:#caffbf,stroke:#588157,color:#000


由于我们的nest应用会不断更新迭代,所以我们遇到了一个问题,当我重复打镜像的时候,我需要先去 k8s-deployment.yaml 文件中修改镜像标签,然后再次执行 kubectl apply -f k8s-deployment.yaml,这显然很是麻烦,所以我们可以 kubectl set image deployment/nest-app nest-app=your-registry/nest-app:v2,它做了三件事:

  1. Kubernetes 直接修改 Deployment 的 Pod 模板镜像(spec.template.spec.containers[].image)
  2. Deployment 会检测到模板变化,自动触发 滚动更新
  3. 新的 Pod 会逐步替换旧 Pod,保证服务可用

如果你要增加副本数、修改资源限制、修改端口那可以再修改 k8s-deployment.yaml,后续只是更新镜像时,你 可以不用修改 YAML 文件,直接用 kubectl set image 就够了,YAML 文件仍然可以保留,用作版本控制或者重新部署集群时使用

1
2
3
4
5
6
7
8
9
10
11
# 初次布署
kubectl apply -f k8s-deployment.yaml

# 代码改动 + 镜像更新
kubectl set image deployment/nest-app nest-app=your-registry/nest-app:v2

# 查看更新状态
kubectl rollout status deployment/nest-app

# 有问题的话回滚
kubectl rollout undo deployment/nest-app

技术学习代办

  • 后续有时间再记录K8S的基础配置和敏感配置的注入
  • 记录多集群布署
  • 记录nest项目连接MySQL、MONGO、ES、REDIS等数据存储介质的方式以及部署过程
  • 使用真实服务器以及github的ci/cd部署项目

docker和k8s的最佳实践
https://shiyuq.github.io/2025/10/14/docker和k8s的最佳实践/
作者
Jack
发布于
2025年10月14日
许可协议