Kubernetes YAML 生成器
6 种资源类型 · Deployment / StatefulSet / Ingress / ConfigMap / CronJob / HPA
Deployment/Service/Ingress 模板
6 种资源类型 · Deployment / StatefulSet / Ingress / ConfigMap / CronJob / HPA
了解工具定位 · 使用场景 · 对比优势
后端开发者在本地写完一个 Go/Java 微服务后,需要手动编写 Deployment(副本数/镜像/端口)、Service(ClusterIP 暴露)和 Ingress(域名路由)。本工具将三个模板集中在一个页面,只需填写服务名、镜像地址、容器端口和域名,就能一键生成完整 YAML 文件,省去反复查阅 K8s 文档和拼写字段的时间。
刚接触 K8s 的学员在尝试搭建一个 Nginx 示例时,经常把 Deployment 的 selector 和 Service 的 selector 写错,导致 Pod 无法被访问。本工具通过三个模板的联动关系(Deployment 标签自动匹配 Service 选择器),让学员直接看到正确的 YAML 结构,降低试错成本,快速理解 Pod、Service、Ingress 三层模型。
DevOps 工程师在 Jenkins/GitLab CI 中配置自动部署时,每次新服务上线都需要手动拼接 Deployment 和 Service 的 YAML 片段。本工具提供结构化的输入表单,输出可直接粘贴到流水线脚本中,配合 kubectl apply 命令完成自动部署,避免手写 YAML 时的缩进错误和字段遗漏。
运维人员需要为同一个应用生成开发、测试、生产三套 YAML,差异仅在于副本数、镜像标签和域名。本工具允许在同一个页面内快速修改这几个参数并重新生成,无需从零编写或复制粘贴后逐行修改,减少因环境配置不一致导致的部署事故。
| 维度 | 本工具 | 竞品 A (K8s YAML Generator) | 传统方法 (手写 YAML) |
|---|---|---|---|
| 数据隐私 | 纯浏览器,零上传,YAML 在本地生成 | 需上传到服务器处理 | 完全本地,无网络传输 |
| 处理速度 | 1 秒内 | 2-5 秒 | 数分钟到数小时(取决于复杂度) |
| 离线可用 | 支持(页面加载后) | 不支持,需联网 | 完全离线 |
| 学习成本 | 零学习成本,填写表单即可 | 低学习成本,需理解部分 K8s 概念 | 高学习成本,需掌握 YAML 语法和 K8s 资源定义 |
| 模板规范性 | 内置最佳实践模板,减少人为错误 | 内置模板,但更新频率未知 | 依赖个人经验,易出现格式或配置错误 |
| 自定义灵活性 | 高,支持 Deployment/Service/Ingress 字段自定义 | 中,部分字段固定 | 完全灵活,可任意编写 |
| 结果可编辑性 | 生成后可在编辑器内直接修改 YAML | 生成后下载文件,修改需重新上传 | 直接在编辑器中修改 |
上手步骤 · 输入输出 · 避坑提示
| 输入 | 输出 | 说明 |
|---|---|---|
| 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 | /db | apiVersion: 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/v1 | apiVersion: 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 | /status | apiVersion: 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 示例结构相同但镜像不同 |
Deployment 的 spec.template.metadata.labels 写 app: my-app,Service 的 spec.selector 写 app: my-app-v2Deployment 的 spec.template.metadata.labels 写 app: my-app,Service 的 spec.selector 写 app: my-appService 通过 selector 的键值对精确匹配 Pod 的 label;不匹配时 Service 不会将流量路由到任何 Pod,ClusterIP 形同虚设
spec.rules[0].host: "my-app.example" 或 "my-app.example.cm"spec.rules[0].host: "my-app.example.com"Ingress controller 根据 Host 头路由流量;拼写错误的域名会导致 404 或路由到默认后端;DNS 解析失败则完全无法访问
spec.replicas: 0spec.replicas: 3 或 spec.replicas: 1replicas: 0 是合法的,但会立即缩容到零个 Pod,服务不可用;常见于误将 0 当作「默认值」或「未设置」
spec.ports[0].port: 80, spec.ports[0].targetPort: 8080(但容器实际监听 3000)spec.ports[0].port: 80, spec.ports[0].targetPort: 3000port 是 Service 暴露的端口,targetPort 是 Pod 容器监听的端口;两者不一致时流量到达 Pod 后会被转发到错误的端口,导致连接拒绝
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 做路径重写
spec.template.spec.containers[0].image: "my-app:latest"spec.template.spec.containers[0].image: "my-app:v1.2.3"latest 标签在每次部署时可能拉取不同版本,导致回滚困难、环境不一致;生产环境应使用语义化版本或 commit SHA
spec.type: NodePort,不写 spec.ports[0].nodePort,依赖集群随机分配(可能被占用)spec.type: NodePort, spec.ports[0].nodePort: 30080(在 30000-32767 范围内)NodePort 端口范围默认 30000-32767;不指定时随机分配,可能与其他 Service 冲突或超出范围;显式指定可避免冲突
spec.rules[0].http.paths[0].pathType: "Exact"(期望匹配 /api 但实际路径是 /api/v1)spec.rules[0].http.paths[0].pathType: "Prefix"Exact 只匹配完全相同的路径,Prefix 匹配前缀;误用 Exact 会导致子路径请求被拒绝,返回 404
Service 的 targetPort: 8080,但 Deployment 的 spec.template.spec.containers[0].ports 中未声明任何端口Deployment 中声明 spec.template.spec.containers[0].ports[0].containerPort: 8080containerPort 声明不是强制但强烈推荐;缺少时 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 规范。
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 个高频疑问
「容器 / K8s」下的其他工具