一个实验搞懂 Docker 和 K8s 怎么配合 ️ 我的项目目录12 个关键文件text/root/message-board/ │ ├── backend/ ← 【Docker 相关】打包后端用的 │ ├── Dockerfile ← 告诉 Docker 怎么打包后端 │ ├── package.json ← 后端依赖列表供 Docker 构建时用 │ └── server.js ← 后端代码被 Docker 打包进镜像 │ ├── frontend/ ← 【Docker 相关】打包前端用的 │ ├── Dockerfile ← 告诉 Docker 怎么打包前端 │ ├── index.html ← 前端页面被 Docker 打包进镜像 │ ├── app.js ← 前端逻辑被 Docker 打包进镜像 │ └── config.js ← 前端配置被 Docker 打包进镜像但 K8s 会覆盖它 │ └── k8s/ ← 【K8s 相关】告诉 K8s 怎么部署 ├── namespace.yaml ← 告诉 K8s创建一个叫 message-board 的文件夹 ├── api-deployment.yaml ← 告诉 K8s后端容器怎么跑 ├── api-service.yaml ← 告诉 K8s后端端口怎么对外暴露 ├── frontend-configmap.yaml ← 告诉 K8s前端配置内容是什么 ├── frontend-deployment.yaml ← 告诉 K8s前端容器怎么跑 └── frontend-service.yaml ← 告诉 K8s前端端口怎么对外暴露一、Docker 环节哪些文件参与了怎么参与的你执行的命令bashdocker build -t message-api:v1 ./backend docker build -t message-frontend:v1 ./frontend第一个命令docker build -t message-api:v1 ./backend文件在这个命令中扮演的角色backend/Dockerfile主文件。Docker 读取它按里面的步骤一步步执行backend/package.json被 Dockerfile 里的COPY package.json ./复制进镜像然后执行npm install装依赖backend/server.js被 Dockerfile 里的COPY server.js ./复制进镜像成为容器的运行代码Dockerfile 怎么说的dockerfileFROM node:20-alpine # 基础环境装好 Node.js 的 Linux COPY package.json ./ # 把依赖列表复制进去 RUN npm install # 在镜像里安装依赖 COPY server.js ./ # 把代码复制进去 CMD [npm, start] # 容器启动时执行 node server.js最终产出message-api:v1镜像。这个镜像 Node.js 环境 你的代码 依赖。第二个命令docker build -t message-frontend:v1 ./frontend文件在这个命令中扮演的角色frontend/Dockerfile主文件。Docker 读取它按里面的步骤执行frontend/index.html被复制进镜像成为 Nginx 提供的页面frontend/app.js被复制进镜像页面加载后执行frontend/config.js被复制进镜像但 K8s 部署时会用 ConfigMap 覆盖它Dockerfile 怎么说的dockerfileFROM nginx:1.25-alpine # 基础环境装好 Nginx 的 Linux COPY index.html /usr/share/nginx/html/ # 复制页面 COPY app.js /usr/share/nginx/html/ # 复制 JS COPY config.js /usr/share/nginx/html/ # 复制配置最终产出message-frontend:v1镜像。这个镜像 Nginx 你的前端文件。Docker 环节总结你的文件被谁用了用来干什么backend/DockerfileDocker 读取指导构建后端镜像backend/package.jsonDocker 构建时复制进去在镜像里装依赖backend/server.jsDocker 构建时复制进去成为容器的运行代码frontend/DockerfileDocker 读取指导构建前端镜像frontend/index.htmlDocker 构建时复制进去成为 Nginx 的页面frontend/app.jsDocker 构建时复制进去成为页面逻辑frontend/config.jsDocker 构建时复制进去作为默认配置后续被 K8s ConfigMap 覆盖二、K8s 环节哪些文件参与了怎么参与的你执行的命令bashkubectl apply -f k8s/namespace.yaml kubectl apply -f k8s/api-deployment.yaml kubectl apply -f k8s/api-service.yaml kubectl apply -f k8s/frontend-configmap.yaml kubectl apply -f k8s/frontend-deployment.yaml kubectl apply -f k8s/frontend-service.yaml逐一拆解每个 YAML 文件的作用①k8s/namespace.yamlyamlapiVersion: v1 kind: Namespace metadata: name: message-board作用告诉 K8s 创建一个叫message-board的“文件夹”后面所有资源都放里面。和 Docker/K8s 的关系纯 K8s 概念。Docker 不参与。②k8s/api-deployment.yamlyamlapiVersion: apps/v1 kind: Deployment metadata: name: message-api namespace: message-board spec: replicas: 1 template: spec: containers: - name: message-api image: message-api:v1 # ← 关键用的就是 Docker 构建的镜像 imagePullPolicy: IfNotPresent ports: - containerPort: 3000作用告诉 K8s——“我要运行 1 个容器用message-api:v1这个镜像Docker 刚打好的它监听 3000 端口”。和 Docker 的关系image: message-api:v1直接引用 Docker 构建的镜像。③k8s/api-service.yamlyamlapiVersion: v1 kind: Service metadata: name: message-api namespace: message-board spec: type: NodePort selector: app: message-api ports: - port: 3000 targetPort: 3000 nodePort: 30787作用告诉 K8s——“把后端 Pod 的 3000 端口映射到集群的 30787 端口让外部能访问”。和 Docker 的关系引用的是 Pod容器通过selector: app: message-api找到 Deployment 创建的容器。④k8s/frontend-configmap.yamlyamlapiVersion: v1 kind: ConfigMap metadata: name: frontend-config namespace: message-board data: config.js: | window.APP_CONFIG { APP_TITLE: K8s班级留言板, API_BASE_URL: http://192.168.116.168:30787 };作用告诉 K8s——“这里有一份前端配置文件内容如上”。和 Docker 的关系这个文件的内容会覆盖Docker 构建时打包进去的config.js。这就是“配置与镜像分离”。⑤k8s/frontend-deployment.yamlyamlapiVersion: apps/v1 kind: Deployment metadata: name: message-frontend namespace: message-board spec: replicas: 1 template: spec: containers: - name: message-frontend image: message-frontend:v1 # ← 关键用的就是 Docker 构建的镜像 ports: - containerPort: 80 volumeMounts: - name: frontend-config mountPath: /usr/share/nginx/html/config.js subPath: config.js # ← 用 ConfigMap 覆盖镜像里的 config.js volumes: - name: frontend-config configMap: name: frontend-config作用告诉 K8s——“运行 1 个前端容器用message-frontend:v1镜像”同时告诉 K8s——“把 ConfigMap 里的配置挂进去覆盖镜像里原来的 config.js”和 Docker 的关系image: message-frontend:v1引用 Docker 构建的镜像volumeMounts用 ConfigMap 覆盖镜像里的文件⑥k8s/frontend-service.yamlyamlapiVersion: v1 kind: Service metadata: name: message-frontend namespace: message-board spec: type: NodePort selector: app: message-frontend ports: - port: 80 targetPort: 80 nodePort: 30082作用告诉 K8s——“把前端 Pod 的 80 端口映射到集群的 30082 端口让用户浏览器能访问页面”。和 Docker 的关系引用的是 Pod容器通过selector: app: message-frontend找到 Deployment 创建的容器。三、一张图每个文件对应到 Docker/K8s 的哪个环节text┌─────────────────────────────────────────────────────────────────────┐ │ 【Docker 环节】 │ ├─────────────────────────────────────────────────────────────────────┤ │ 输入文件 → 输出 │ │ ├── backend/Dockerfile → │ │ ├── backend/package.json → message-api:v1 镜像 │ │ └── backend/server.js → │ │ │ │ ├── frontend/Dockerfile → │ │ ├── frontend/index.html → message-frontend:v1 镜像 │ │ ├── frontend/app.js → │ │ └── frontend/config.js → 默认配置会被覆盖 │ └─────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ 【K8s 环节】 │ ├─────────────────────────────────────────────────────────────────────┤ │ 输入文件 → 作用 │ │ ├── namespace.yaml → 创建“message-board”文件夹 │ │ ├── api-deployment.yaml → 用 message-api:v1 启动后端容器│ │ ├── api-service.yaml → 后端暴露 30787 端口 │ │ ├── frontend-configmap.yaml → 创建前端配置API 地址 │ │ ├── frontend-deployment.yaml → 用 message-frontend:v1 │ │ │ ConfigMap 覆盖 config.js │ │ └── frontend-service.yaml → 前端暴露 30082 端口 │ └─────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ 【最终运行】 │ ├─────────────────────────────────────────────────────────────────────┤ │ 浏览器访问 http://192.168.116.168:30082 → 看到留言板页面 ✅ │ └─────────────────────────────────────────────────────────────────────┘四、我之前疑惑的几个点现在用文件回答你的疑惑用文件回答Docker 怎么用的用backend/Dockerfile和frontend/Dockerfile分别生成message-api:v1和message-frontend:v1两个镜像K8s 怎么用的用k8s/目录下的 6 个 YAML 文件告诉 K8s 怎么运行、暴露、配置这两个镜像配置文件怎么改frontend/config.js本来在镜像里但 K8s 部署时用frontend-configmap.yaml覆盖它镜像和 YAML 什么关系api-deployment.yaml里的image: message-api:v1引用 Docker 构建的镜像frontend-deployment.yaml里的image: message-frontend:v1同理Node2 收到什么Node2 没有收到 YAML 文件收到的是 K8s 的指令“用 message-api:v1 启动容器”五、一句话总结Docker读了backend/Dockerfile和frontend/Dockerfile生成了 2 个镜像message-api:v1、message-frontend:v1。K8s读了k8s/目录下的 6 个 YAML 文件拿着这 2 个镜像在集群里启动容器、暴露端口、注入配置最终让用户通过http://192.168.116.168:30082访问到留言板。