K8s YAML 生成

Deployment/Service/Ingress 模板

411 次访问

Kubernetes YAML 生成器

6 种资源类型 · Deployment / StatefulSet / Ingress / ConfigMap / CronJob / HPA

关于本工具

了解工具定位 · 使用场景 · 对比优势

使用场景

🏗️

微服务快速部署

后端开发者在本地写完一个 Go/Java 微服务后,需要手动编写 Deployment(副本数/镜像/端口)、Service(ClusterIP 暴露)和 Ingress(域名路由)。本工具将三个模板集中在一个页面,只需填写服务名、镜像地址、容器端口和域名,就能一键生成完整 YAML 文件,省去反复查阅 K8s 文档和拼写字段的时间。

🎓

K8s 学习实验

刚接触 K8s 的学员在尝试搭建一个 Nginx 示例时,经常把 Deployment 的 selector 和 Service 的 selector 写错,导致 Pod 无法被访问。本工具通过三个模板的联动关系(Deployment 标签自动匹配 Service 选择器),让学员直接看到正确的 YAML 结构,降低试错成本,快速理解 Pod、Service、Ingress 三层模型。

🔄

CI/CD 流水线集成

DevOps 工程师在 Jenkins/GitLab CI 中配置自动部署时,每次新服务上线都需要手动拼接 Deployment 和 Service 的 YAML 片段。本工具提供结构化的输入表单,输出可直接粘贴到流水线脚本中,配合 kubectl apply 命令完成自动部署,避免手写 YAML 时的缩进错误和字段遗漏。

📦

多环境配置复用

运维人员需要为同一个应用生成开发、测试、生产三套 YAML,差异仅在于副本数、镜像标签和域名。本工具允许在同一个页面内快速修改这几个参数并重新生成,无需从零编写或复制粘贴后逐行修改,减少因环境配置不一致导致的部署事故。

对比矩阵本工具 vs 竞品 vs 传统方法

维度本工具竞品 A (K8s YAML Generator)传统方法 (手写 YAML)
数据隐私纯浏览器,零上传,YAML 在本地生成需上传到服务器处理完全本地,无网络传输
处理速度1 秒内2-5 秒数分钟到数小时(取决于复杂度)
离线可用支持(页面加载后)不支持,需联网完全离线
学习成本零学习成本,填写表单即可低学习成本,需理解部分 K8s 概念高学习成本,需掌握 YAML 语法和 K8s 资源定义
模板规范性内置最佳实践模板,减少人为错误内置模板,但更新频率未知依赖个人经验,易出现格式或配置错误
自定义灵活性高,支持 Deployment/Service/Ingress 字段自定义中,部分字段固定完全灵活,可任意编写
结果可编辑性生成后可在编辑器内直接修改 YAML生成后下载文件,修改需重新上传直接在编辑器中修改

使用指南

上手步骤 · 输入输出 · 避坑提示

输入输出示例6 个典型场景,覆盖常规、边界与易错

输入输出说明
nginx:1.25 | 3 | 80 | ClusterIP | my-app | /apiVersion: apps/v1 kind: Deployment metadata: name: my-app-deployment spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: nginx image: nginx:1.25 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-app-service spec: type: ClusterIP selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 80 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-app-ingress spec: rules: - host: my-app.example.com http: paths: - path: / pathType: Prefix backend: service: name: my-app-service port: number: 80典型场景:Nginx 无状态服务,三副本 + ClusterIP + 根路径 Ingress
postgres:15 | 1 | 5432 | NodePort | postgres-db | /dbapiVersion: apps/v1 kind: Deployment metadata: name: postgres-db-deployment spec: replicas: 1 selector: matchLabels: app: postgres-db template: metadata: labels: app: postgres-db spec: containers: - name: postgres image: postgres:15 ports: - containerPort: 5432 --- apiVersion: v1 kind: Service metadata: name: postgres-db-service spec: type: NodePort selector: app: postgres-db ports: - protocol: TCP port: 5432 targetPort: 5432 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: postgres-db-ingress spec: rules: - host: postgres-db.example.com http: paths: - path: /db pathType: Prefix backend: service: name: postgres-db-service port: number: 5432边界 case:有状态数据库单副本 + NodePort 暴露 + 子路径 Ingress
myapp:latest | 5 | 8080 | LoadBalancer | web-app | /api/v1apiVersion: apps/v1 kind: Deployment metadata: name: web-app-deployment spec: replicas: 5 selector: matchLabels: app: web-app template: metadata: labels: app: web-app spec: containers: - name: myapp image: myapp:latest ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: web-app-service spec: type: LoadBalancer selector: app: web-app ports: - protocol: TCP port: 8080 targetPort: 8080 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web-app-ingress spec: rules: - host: web-app.example.com http: paths: - path: /api/v1 pathType: Prefix backend: service: name: web-app-service port: number: 8080典型场景:API 服务五副本 + LoadBalancer + 带版本前缀路径
redis:7 | 0 | 6379 | ClusterIP | cache | /apiVersion: apps/v1 kind: Deployment metadata: name: cache-deployment spec: replicas: 0 selector: matchLabels: app: cache template: metadata: labels: app: cache spec: containers: - name: redis image: redis:7 ports: - containerPort: 6379 --- apiVersion: v1 kind: Service metadata: name: cache-service spec: type: ClusterIP selector: app: cache ports: - protocol: TCP port: 6379 targetPort: 6379 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: cache-ingress spec: rules: - host: cache.example.com http: paths: - path: / pathType: Prefix backend: service: name: cache-service port: number: 6379边界 case:副本数为 0(暂停部署),工具仍生成完整 YAML
alpine:3.19 | 2 | 0 | ClusterIP | health-check | /statusapiVersion: apps/v1 kind: Deployment metadata: name: health-check-deployment spec: replicas: 2 selector: matchLabels: app: health-check template: metadata: labels: app: health-check spec: containers: - name: alpine image: alpine:3.19 ports: - containerPort: 0 --- apiVersion: v1 kind: Service metadata: name: health-check-service spec: type: ClusterIP selector: app: health-check ports: - protocol: TCP port: 0 targetPort: 0 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: health-check-ingress spec: rules: - host: health-check.example.com http: paths: - path: /status pathType: Prefix backend: service: name: health-check-service port: number: 0易错 case:端口填 0(无效),工具未校验,生成无效 YAML
golang:1.22 | 3 | 8080 | ClusterIP | my-app | /apiVersion: apps/v1 kind: Deployment metadata: name: my-app-deployment spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: golang image: golang:1.22 ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: my-app-service spec: type: ClusterIP selector: app: my-app ports: - protocol: TCP port: 8080 targetPort: 8080 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-app-ingress spec: rules: - host: my-app.example.com http: paths: - path: / pathType: Prefix backend: service: name: my-app-service port: number: 8080典型场景:Go 应用镜像,与 Nginx 示例结构相同但镜像不同

常见错误对照9 个常踩的坑 · 错误 → 修复

1. Service 的 selector 与 Deployment 的 label 不匹配

错误
Deployment 的 spec.template.metadata.labels 写 app: my-app,Service 的 spec.selector 写 app: my-app-v2
修复
Deployment 的 spec.template.metadata.labels 写 app: my-app,Service 的 spec.selector 写 app: my-app

Service 通过 selector 的键值对精确匹配 Pod 的 label;不匹配时 Service 不会将流量路由到任何 Pod,ClusterIP 形同虚设

2. Ingress 的 host 字段拼错域名

错误
spec.rules[0].host: "my-app.example" 或 "my-app.example.cm"
修复
spec.rules[0].host: "my-app.example.com"

Ingress controller 根据 Host 头路由流量;拼写错误的域名会导致 404 或路由到默认后端;DNS 解析失败则完全无法访问

3. Deployment 的 replicas 写 0 导致 Pod 被删除

错误
spec.replicas: 0
修复
spec.replicas: 3 或 spec.replicas: 1

replicas: 0 是合法的,但会立即缩容到零个 Pod,服务不可用;常见于误将 0 当作「默认值」或「未设置」

4. Service 的 port 和 targetPort 混用

错误
spec.ports[0].port: 80, spec.ports[0].targetPort: 8080(但容器实际监听 3000)
修复
spec.ports[0].port: 80, spec.ports[0].targetPort: 3000

port 是 Service 暴露的端口,targetPort 是 Pod 容器监听的端口;两者不一致时流量到达 Pod 后会被转发到错误的端口,导致连接拒绝

5. Ingress 的 path 写死路径前缀但后端路由不匹配

错误
spec.rules[0].http.paths[0].path: "/api/v1",后端 Deployment 的容器路由期望 "/api/v1/users" 但未做前缀剥离
修复
spec.rules[0].http.paths[0].path: "/api/v1",且后端应用配置 pathPrefix 剥离(如 nginx rewrite /api/v1 -> /)

Ingress 默认将整个 path 透传给后端;如果后端路由不匹配前缀,会返回 404;需要后端或 Ingress annotation 做路径重写

6. Deployment 的 image 写 latest 标签导致版本不可控

错误
spec.template.spec.containers[0].image: "my-app:latest"
修复
spec.template.spec.containers[0].image: "my-app:v1.2.3"

latest 标签在每次部署时可能拉取不同版本,导致回滚困难、环境不一致;生产环境应使用语义化版本或 commit SHA

7. Service 类型选 NodePort 但未指定 nodePort 端口范围冲突

错误
spec.type: NodePort,不写 spec.ports[0].nodePort,依赖集群随机分配(可能被占用)
修复
spec.type: NodePort, spec.ports[0].nodePort: 30080(在 30000-32767 范围内)

NodePort 端口范围默认 30000-32767;不指定时随机分配,可能与其他 Service 冲突或超出范围;显式指定可避免冲突

8. Ingress 的 pathType 写错导致路由匹配异常

错误
spec.rules[0].http.paths[0].pathType: "Exact"(期望匹配 /api 但实际路径是 /api/v1)
修复
spec.rules[0].http.paths[0].pathType: "Prefix"

Exact 只匹配完全相同的路径,Prefix 匹配前缀;误用 Exact 会导致子路径请求被拒绝,返回 404

9. Deployment 的 containerPort 未声明但 Service 引用

错误
Service 的 targetPort: 8080,但 Deployment 的 spec.template.spec.containers[0].ports 中未声明任何端口
修复
Deployment 中声明 spec.template.spec.containers[0].ports[0].containerPort: 8080

containerPort 声明不是强制但强烈推荐;缺少时 Service 仍可工作(通过 targetPort 直接映射),但可读性差且 kubectl describe 不显示端口信息

工作原理

公式推导 · 流程图解 · 依据出处

核心公式

apiVersion: apps/v1 kind: Deployment metadata: name: {name} spec: replicas: {replicas} selector: matchLabels: app: {name} template: metadata: labels: app: {name} spec: containers: - name: {name} image: {image} ports: - containerPort: {port}

变量说明

  • {name} — Deployment 名称,如 my-app
  • {replicas} — Pod 副本数,正整数
  • {image} — 容器镜像,如 nginx:1.25
  • {port} — 容器监听端口,如 80

示例

生成一个 Nginx Deployment:name=web-app, replicas=3, image=nginx:1.25, port=80。输出 YAML 中 replicas 为 3,containers 下 image 为 nginx:1.25,ports 下 containerPort 为 80。

适用范围

适用于 Kubernetes 1.19+ 集群,生成标准 Deployment 模板。不适用于 StatefulSet/DaemonSet 等有状态工作负载。模板基于 Kubernetes 官方 API 规范。

原理图

填写表单名称 / 镜像 / 端口浏览器内模板YAML 组装输出 YAMLDeployment / Service / Ingress浏览器内渲染实时预览 / 语法高亮复制 / 下载直接使用用户输入无需后端
用户输入 本地处理 输出结果

开发者集成

3 种主流语言 · 复制即用

import yaml

# 定义 Deployment 模板
deployment = {
    "apiVersion": "apps/v1",
    "kind": "Deployment",
    "metadata": {"name": "my-app", "labels": {"app": "my-app"}},
    "spec": {
        "replicas": 3,
        "selector": {"matchLabels": {"app": "my-app"}},
        "template": {
            "metadata": {"labels": {"app": "my-app"}},
            "spec": {
                "containers": [{
                    "name": "app",
                    "image": "nginx:1.25",
                    "ports": [{"containerPort": 80}]
                }]
            }
        }
    }
}

# 序列化为 YAML 字符串
print(yaml.dump(deployment, default_flow_style=False))
package main

import (
	"fmt"
	"os"

	appsv1 "k8s.io/api/apps/v1"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sigs.k8s.io/yaml"
)

func main() {
	// 构建 Deployment 对象
	deploy := &appsv1.Deployment{
		TypeMeta: metav1.TypeMeta{APIVersion: "apps/v1", Kind: "Deployment"},
		ObjectMeta: metav1.ObjectMeta{Name: "my-app"},
		Spec: appsv1.DeploymentSpec{
			Replicas: int32Ptr(3),
			Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"app": "my-app"}},
			Template: corev1.PodTemplateSpec{
				ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"app": "my-app"}},
				Spec: corev1.PodSpec{
					Containers: []corev1.Container{{
						Name:  "app",
						Image: "nginx:1.25",
						Ports: []corev1.ContainerPort{{ContainerPort: 80}},
					}},
				},
			},
		},
	}

	// 序列化为 YAML
	out, err := yaml.Marshal(deploy)
	if err != nil {
		fmt.Fprintf(os.Stderr, "marshal error: %v\n", err)
		os.Exit(1)
	}
	fmt.Print(string(out))
}

func int32Ptr(i int32) *int32 { return &i }
const yaml = require('js-yaml');

// 定义 Service 模板
const service = {
  apiVersion: 'v1',
  kind: 'Service',
  metadata: { name: 'my-app-svc' },
  spec: {
    selector: { app: 'my-app' },
    ports: [
      { protocol: 'TCP', port: 80, targetPort: 80 }
    ],
    type: 'ClusterIP'
  }
};

// 序列化为 YAML 字符串
try {
  const yamlStr = yaml.dump(service);
  console.log(yamlStr);
} catch (e) {
  console.error('YAML serialization failed:', e.message);
}

常见问题

8 个高频疑问

生成的 YAML 直接复制到集群里就能用吗?
不一定。工具生成的 Deployment/Service/Ingress 是通用模板,镜像名称(image)、端口(containerPort)和 Ingress 域名(host)需要根据实际项目替换。Deployment 的 replicas 默认为 1,Service 的 type 默认为 ClusterIP(仅集群内访问)。如果要用 NodePort 或 LoadBalancer,需手动修改 type 字段。Ingress 默认不带 TLS,生产环境需补充 tls 段和证书注解。
生成的 Service 为什么端口是 80,但我容器跑在 8080?
模板里 Service 的 port 和 targetPort 都设成 80 作为占位符。如果容器监听 8080,需要把 spec.ports[0].targetPort 改成 8080,port 保持 80(集群内访问的端口)或改成 8080(与容器一致)。注意:Deployment 的 containerPort 也要同步改成 8080,否则 kube-proxy 转发会失败。
Ingress 里没有写 pathType,部署时会报错吗?
会。Kubernetes 1.18+ 要求 Ingress 规则必须指定 pathType,否则 API 拒绝创建。工具生成的 Ingress 模板默认留空 pathType,需要手动补充。最常用的是 Prefix(前缀匹配,如 /api 匹配 /api/v1)和 Exact(精确匹配,如 /login 只匹配 /login)。生产环境建议用 Prefix,配合 rewrite-target 注解避免路径丢失。
生成的 YAML 能在 K8s 1.16 以下的旧版本用吗?
部分能用。Deployment 的 apiVersion 是 apps/v1,K8s 1.9+ 都支持。Service 的 apiVersion 是 v1,所有版本都支持。但 Ingress 的 apiVersion 在 1.19 之前是 networking.k8s.io/v1beta1,1.19 之后才是 networking.k8s.io/v1。如果集群版本低于 1.19,需要手动把 apiVersion 改成 v1beta1,并把 spec 里的 pathType 删除。
工具生成的 Deployment 没有 resource limits,会被 OOM 杀死吗?
有可能。模板默认不设 resources.requests 和 limits,Pod 会使用节点空闲资源。但当节点内存不足时,没有 limits 的 Pod 优先级最低,会被 OOMKill。生产环境建议至少设置 limits.memory(如 512Mi)和 requests.cpu(如 0.5),防止资源争抢。工具提供的是基础模板,资源配额需根据实际负载补充。
为什么生成的 Service 没有 selector?这样 Pod 能关联上吗?
模板里 Service 的 selector 默认留空,需要手动填写。selector 必须匹配 Deployment 的 metadata.labels 中定义的键值对,比如 Deployment 有 app: my-app,Service 的 selector 就要写 app: my-app。如果 selector 不匹配,Service 的 Endpoints 列表会为空,流量无法路由到 Pod。可以在 Service 的 spec.selector 下补全标签。
生成的 Ingress 默认不带 TLS,怎么加上 HTTPS?
需要两步:先在集群中创建 Secret(包含证书和私钥),再在 Ingress 的 spec.tls 字段引用 Secret。例如:tls: - hosts: ["example.com"] secretName: example-tls。如果使用 cert-manager 自动签发,可加注解 kubernetes.io/ingress.class: "nginx" 和 cert-manager.io/cluster-issuer: "letsencrypt-prod"。工具不提供证书管理功能,需自行准备。
工具在浏览器里生成 YAML,数据会上传到服务器吗?
不会。工具是纯前端实现(FE),所有 YAML 生成逻辑在浏览器内 JavaScript 完成,不向后端发送任何请求。可以打开浏览器 DevTools 的 Network 面板确认——填写表单并点击生成时,没有 HTTP 请求外发。断网后刷新页面仍然能正常使用。生成的 YAML 仅存在于当前页面内存中,关闭页面即清除。
选择 打开 +新窗口 esc关闭