使用 go 语言,编写批量生成 k8s yaml 的工具

场景

游戏项目中的逻辑服务器需要部署在 k8s 中,由于逻辑服按照微服务体系划分(例如:login、gate、gm、account、chat 等),需要多个 k8s yaml 执行 kubectl apply -f *.yaml 完成批量部署。笔者在手写了 login-kube.yamlgate-kube.yaml 后发现了如下痛点:

  1. 每个种类资源的 k8s yaml 大同小异,拥有同样的结构
  2. 一个yaml 文件内,也有大量的重复变量(例如,login-kube.yaml 里,光是 “login” 这个字符串出现了十几次,包括但不限于 image、label、configmap 名等)
  3. 微服务太多,且port、label、hpa、image 改动频繁(image tag尤其频繁);假设需要批量将容器版本指定为 2022_01_12_1 ,则每个 yaml 都需要至少改动一处,人为操作太多,且不可控(人总会失误)。
  4. 懒。复制粘贴文件本身并不复杂、也不耗时。困难就困难在,每个 yaml 文件需要经过验证才能提交,复制粘贴修改的文件,不经过测试,很容易出现漏改或者设置错的情况;而每次新增、修改微服务,都需要做一次全量测试,整个维护 *.yaml 的工作量巨大

既然有这些痛点,那我们就着手做一个批量生成工具,只需要维护很少的变量,就能够批量生成所有微服务的 *.yaml 文件,从而批量部署。

工具下载地址

注:根据场景不同,第一次使用工具时需要手动更改 template 目录下的模板文件。如果场景不同,则可能需要改动 Go 相关的代码,才能正常使用

使用步骤

检查模板

检查模板是否需要更新,可以修改模板的结构和通用参数
检查模板

检查配置

检查配置是否需要更新,可以增加修改删除服务配置,支持设置多个服务间的 共用值(例如,所有服务的镜像前缀相同,镜像tag相同)。单个服务的 特殊值 设置,会覆盖共用值。
检查配置

生成 yaml

在项目根目录下执行

go run main.go # 也可以提前 go build 生成可执行文件

默认在 output/ (可配置) 目录下生成 k8s yaml 文件

生成 yaml

自定义开发

书写模板文件

我们想要自动生成配置文件,第一步首先是书写模板文件,再通过模板文件自动替换变量达到我们的目的。

以 Deployment 模板为例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: $(name)
  namespace: $(namespace)
  labels:
    app: $(name)
spec:
  replicas: $(replicas)
  revisionHistoryLimit: 5
  selector:
    matchLabels:
      app: $(name)
  template:
    metadata:
      labels:
        app: $(name)
        type: service # 项目的日志分析ELK使用到了这个,用于分类
    spec:
      containers:
        - name: $(name)
          image: $(imageprefix)$(name):$(imagetag)
          lifecycle:
            preStop:
              exec:
                command: [ "sh","-c","sleep 5" ]
          ports: $(ports)
          resources: $(resources)
          volumeMounts:
            - name: timezone
              mountPath: /etc/localtime
            - name: $(name)-cm-v
              mountPath: /app/etc
      volumes:
        - name: timezone
          hostPath:
            path: /usr/share/zoneinfo/Asia/Shanghai
        - name: $(name)-cm-v
          configMap:
            name: $(name)-cm

单一填值

我选用了 $(PARAM_NAME) 来给变量提供占位符。
其中, image: $(imageprefix)$(name):$(imagetag) 配置,意味着我们的工具需要支持多变量的拼接和自由组合,即:

# 读取模板前设置好这些值
# imageprefix: nbserver/
# name: gate
# imagetag: 2022_01_12 

# 输出
spec:
  containers:
  - image: nbserver/gate:2022_01_12 

复杂结构展开

resources: $(resources) 配置,意味着我们的工具需要支持 yaml 的动态展开和格式校验,而这一点是难点,展开后参考如下:

# 读取模板前设置好这些值
# resources:
# limits:
#   cpu: 100m
#   memory: 100Mi
# requests:
#   cpu: 50m
#   memory: 20Mi

# 输出
resources:
  limits:
    cpu: 100m
    memory: 100Mi
  requests:
    cpu: 50m
    memory: 20Mi

深度解析

以 Service 为例

apiVersion: v1
kind: Service
metadata:
  name: $(name)-svc
  namespace: $(namespace)
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: external
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
    service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
spec:
  type: LoadBalancer
  ports:
    - name: tcp-long-connection-port
      port: $(ports.network.port)
      targetPort: $(ports.network.targetport)
      protocol: TCP
  selector:
    app: $(name)

port: $(ports.network.port) 配置,意味着我们的工具需要支持深度不止为1的解析,需要把数组、字典、结构体的层级参数全部读取,并解析,参考如下:

# 读取模板前设置好这些值
# ports:
#   - port: 6000
#     type: normal
#   - port: 6001
#     type: network # 动态解析 type 类型,并提取成索引
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王元恺David

感谢你的支持~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值