support k8s deployment yaml generation (#247)
* simplify code, format makefile * simplify code * some optimize by kevwan and benying (#240) Co-authored-by: 杨志泉 <zhiquan.yang@yiducloud.cn> * optimization (#241) * optimize docker file generation, make docker build faster * support k8s deployment yaml generation Co-authored-by: benying <31179034+benyingY@users.noreply.github.com> Co-authored-by: 杨志泉 <zhiquan.yang@yiducloud.cn> Co-authored-by: bittoy <bittoy@qq.com>master
parent
f997aee3ba
commit
7a82cf80ce
@ -1,130 +0,0 @@
|
|||||||
package k8s
|
|
||||||
|
|
||||||
var apiRpcTmeplate = `apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: {{.name}}
|
|
||||||
namespace: {{.namespace}}
|
|
||||||
labels:
|
|
||||||
app: {{.name}}
|
|
||||||
spec:
|
|
||||||
replicas: {{.replicas}}
|
|
||||||
revisionHistoryLimit: {{.revisionHistoryLimit}}
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: {{.name}}
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: {{.name}}
|
|
||||||
spec:{{if .envIsDev}}
|
|
||||||
terminationGracePeriodSeconds: 60{{end}}
|
|
||||||
containers:
|
|
||||||
- name: {{.name}}
|
|
||||||
image: registry-vpc.cn-hangzhou.aliyuncs.com/{{.namespace}}/
|
|
||||||
lifecycle:
|
|
||||||
preStop:
|
|
||||||
exec:
|
|
||||||
command: ["sh","-c","sleep 5"]
|
|
||||||
ports:
|
|
||||||
- containerPort: {{.port}}
|
|
||||||
readinessProbe:
|
|
||||||
tcpSocket:
|
|
||||||
port: {{.port}}
|
|
||||||
initialDelaySeconds: 5
|
|
||||||
periodSeconds: 10
|
|
||||||
livenessProbe:
|
|
||||||
tcpSocket:
|
|
||||||
port: {{.port}}
|
|
||||||
initialDelaySeconds: 15
|
|
||||||
periodSeconds: 20
|
|
||||||
env:
|
|
||||||
- name: aliyun_logs_k8slog
|
|
||||||
value: "stdout"
|
|
||||||
- name: aliyun_logs_k8slog_tags
|
|
||||||
value: "stage={{.env}}"
|
|
||||||
- name: aliyun_logs_k8slog_format
|
|
||||||
value: "json"
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpu: {{.limitCpu}}m
|
|
||||||
memory: {{.limitMem}}Mi
|
|
||||||
requests:
|
|
||||||
cpu: {{.requestCpu}}m
|
|
||||||
memory: {{.requestMem}}Mi
|
|
||||||
command:
|
|
||||||
- ./{{.serviceName}}
|
|
||||||
- -f
|
|
||||||
- ./{{.name}}.json
|
|
||||||
volumeMounts:
|
|
||||||
- name: timezone
|
|
||||||
mountPath: /etc/localtime
|
|
||||||
imagePullSecrets:
|
|
||||||
- name: {{.namespace}}
|
|
||||||
volumes:
|
|
||||||
- name: timezone
|
|
||||||
hostPath:
|
|
||||||
path: /usr/share/zoneinfo/Asia/Shanghai
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: {{.name}}-svc
|
|
||||||
namespace: {{.namespace}}
|
|
||||||
spec:
|
|
||||||
ports:
|
|
||||||
- nodePort: 3{{.port}}
|
|
||||||
port: {{.port}}
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: {{.port}}
|
|
||||||
selector:
|
|
||||||
app: {{.name}}
|
|
||||||
sessionAffinity: None
|
|
||||||
type: NodePort{{if .envIsPreOrPro}}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
apiVersion: autoscaling/v2beta1
|
|
||||||
kind: HorizontalPodAutoscaler
|
|
||||||
metadata:
|
|
||||||
name: {{.name}}-hpa-c
|
|
||||||
namespace: {{.namespace}}
|
|
||||||
labels:
|
|
||||||
app: {{.name}}-hpa-c
|
|
||||||
spec:
|
|
||||||
scaleTargetRef:
|
|
||||||
apiVersion: apps/v1beta1
|
|
||||||
kind: Deployment
|
|
||||||
name: di-api
|
|
||||||
minReplicas: {{.minReplicas}}
|
|
||||||
maxReplicas: {{.maxReplicas}}
|
|
||||||
metrics:
|
|
||||||
- type: Resource
|
|
||||||
resource:
|
|
||||||
name: cpu
|
|
||||||
targetAverageUtilization: 80
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
apiVersion: autoscaling/v2beta1
|
|
||||||
kind: HorizontalPodAutoscaler
|
|
||||||
metadata:
|
|
||||||
name: {{.name}}-hpa-m
|
|
||||||
namespace: {{.namespace}}
|
|
||||||
labels:
|
|
||||||
app: {{.name}}-hpa-m
|
|
||||||
spec:
|
|
||||||
scaleTargetRef:
|
|
||||||
apiVersion: apps/v1beta1
|
|
||||||
kind: Deployment
|
|
||||||
name: {{.name}}
|
|
||||||
minReplicas: {{.minReplicas}}
|
|
||||||
maxReplicas: {{.maxReplicas}}
|
|
||||||
metrics:
|
|
||||||
- type: Resource
|
|
||||||
resource:
|
|
||||||
name: memory
|
|
||||||
targetAverageUtilization: 80{{end}}
|
|
||||||
`
|
|
@ -1,46 +0,0 @@
|
|||||||
package k8s
|
|
||||||
|
|
||||||
var jobTmeplate = `apiVersion: batch/v1beta1
|
|
||||||
kind: CronJob
|
|
||||||
metadata:
|
|
||||||
name: {{.name}}
|
|
||||||
namespace: {{.namespace}}
|
|
||||||
spec:
|
|
||||||
successfulJobsHistoryLimit: {{.successfulJobsHistoryLimit}}
|
|
||||||
schedule: "{{.schedule}}"
|
|
||||||
jobTemplate:
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: {{.name}}
|
|
||||||
image: registry-vpc.cn-hangzhou.aliyuncs.com/{{.namespace}}/
|
|
||||||
env:
|
|
||||||
- name: aliyun_logs_k8slog
|
|
||||||
value: "stdout"
|
|
||||||
- name: aliyun_logs_k8slog_tags
|
|
||||||
value: "stage={{.env}}"
|
|
||||||
- name: aliyun_logs_k8slog_format
|
|
||||||
value: "json"
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpu: {{.limitCpu}}m
|
|
||||||
memory: {{.limitMem}}Mi
|
|
||||||
requests:
|
|
||||||
cpu: {{.requestCpu}}m
|
|
||||||
memory: {{.requestMem}}Mi
|
|
||||||
command:
|
|
||||||
- ./{{.serviceName}}
|
|
||||||
- -f
|
|
||||||
- ./{{.name}}.json
|
|
||||||
volumeMounts:
|
|
||||||
- name: timezone
|
|
||||||
mountPath: /etc/localtime
|
|
||||||
imagePullSecrets:
|
|
||||||
- name: {{.namespace}}
|
|
||||||
restartPolicy: OnFailure
|
|
||||||
volumes:
|
|
||||||
- name: timezone
|
|
||||||
hostPath:
|
|
||||||
path: /usr/share/zoneinfo/Asia/Shanghai
|
|
||||||
`
|
|
@ -1,103 +0,0 @@
|
|||||||
package k8s
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"text/template"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
ServiceTypeApi ServiceType = "api"
|
|
||||||
ServiceTypeRpc ServiceType = "rpc"
|
|
||||||
ServiceTypeJob ServiceType = "job"
|
|
||||||
envDev = "dev"
|
|
||||||
)
|
|
||||||
|
|
||||||
var errUnknownServiceType = errors.New("unknown service type")
|
|
||||||
|
|
||||||
type (
|
|
||||||
ServiceType string
|
|
||||||
|
|
||||||
KubeRequest struct {
|
|
||||||
Env string
|
|
||||||
ServiceName string
|
|
||||||
ServiceType ServiceType
|
|
||||||
Namespace string
|
|
||||||
Schedule string
|
|
||||||
Replicas int
|
|
||||||
RevisionHistoryLimit int
|
|
||||||
Port int
|
|
||||||
LimitCpu int
|
|
||||||
LimitMem int
|
|
||||||
RequestCpu int
|
|
||||||
RequestMem int
|
|
||||||
SuccessfulJobsHistoryLimit int
|
|
||||||
HpaMinReplicas int
|
|
||||||
HpaMaxReplicas int
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func Gen(req KubeRequest) (string, error) {
|
|
||||||
switch req.ServiceType {
|
|
||||||
case ServiceTypeApi, ServiceTypeRpc:
|
|
||||||
return genApiRpc(req)
|
|
||||||
case ServiceTypeJob:
|
|
||||||
return genJob(req)
|
|
||||||
default:
|
|
||||||
return "", errUnknownServiceType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func genApiRpc(req KubeRequest) (string, error) {
|
|
||||||
t, err := template.New("api_rpc").Parse(apiRpcTmeplate)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
err = t.Execute(buffer, map[string]interface{}{
|
|
||||||
"name": fmt.Sprintf("%s-%s", req.ServiceName, req.ServiceType),
|
|
||||||
"namespace": req.Namespace,
|
|
||||||
"replicas": req.Replicas,
|
|
||||||
"revisionHistoryLimit": req.RevisionHistoryLimit,
|
|
||||||
"port": req.Port,
|
|
||||||
"limitCpu": req.LimitCpu,
|
|
||||||
"limitMem": req.LimitMem,
|
|
||||||
"requestCpu": req.RequestCpu,
|
|
||||||
"requestMem": req.RequestMem,
|
|
||||||
"serviceName": req.ServiceName,
|
|
||||||
"env": req.Env,
|
|
||||||
"envIsPreOrPro": req.Env != envDev,
|
|
||||||
"envIsDev": req.Env == envDev,
|
|
||||||
"minReplicas": req.HpaMinReplicas,
|
|
||||||
"maxReplicas": req.HpaMaxReplicas,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
return buffer.String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func genJob(req KubeRequest) (string, error) {
|
|
||||||
t, err := template.New("job").Parse(jobTmeplate)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
buffer := new(bytes.Buffer)
|
|
||||||
err = t.Execute(buffer, map[string]interface{}{
|
|
||||||
"name": fmt.Sprintf("%s-%s", req.ServiceName, req.ServiceType),
|
|
||||||
"namespace": req.Namespace,
|
|
||||||
"schedule": req.Schedule,
|
|
||||||
"successfulJobsHistoryLimit": req.SuccessfulJobsHistoryLimit,
|
|
||||||
"limitCpu": req.LimitCpu,
|
|
||||||
"limitMem": req.LimitMem,
|
|
||||||
"requestCpu": req.RequestCpu,
|
|
||||||
"requestMem": req.RequestMem,
|
|
||||||
"serviceName": req.ServiceName,
|
|
||||||
"env": req.Env,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
return buffer.String(), nil
|
|
||||||
}
|
|
@ -0,0 +1,117 @@
|
|||||||
|
package kube
|
||||||
|
|
||||||
|
var deploymentTemplate = `apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{.Name}}
|
||||||
|
namespace: {{.Namespace}}
|
||||||
|
labels:
|
||||||
|
app: {{.Name}}
|
||||||
|
spec:
|
||||||
|
replicas: {{.Replicas}}
|
||||||
|
revisionHistoryLimit: {{.Revisions}}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: {{.Name}}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: {{.Name}}
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: {{.Name}}
|
||||||
|
image: {{.Image}}
|
||||||
|
lifecycle:
|
||||||
|
preStop:
|
||||||
|
exec:
|
||||||
|
command: ["sh","-c","sleep 5"]
|
||||||
|
ports:
|
||||||
|
- containerPort: {{.Port}}
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: {{.Port}}
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
livenessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: {{.Port}}
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 20
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: {{.RequestCpu}}m
|
||||||
|
memory: {{.RequestMem}}Mi
|
||||||
|
limits:
|
||||||
|
cpu: {{.LimitCpu}}m
|
||||||
|
memory: {{.LimitMem}}Mi
|
||||||
|
volumeMounts:
|
||||||
|
- name: timezone
|
||||||
|
mountPath: /etc/localtime
|
||||||
|
imagePullSecrets:
|
||||||
|
- name: {{.Secret}}
|
||||||
|
volumes:
|
||||||
|
- name: timezone
|
||||||
|
hostPath:
|
||||||
|
path: /usr/share/zoneinfo/Asia/Shanghai
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{.Name}}-svc
|
||||||
|
namespace: {{.Namespace}}
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
{{if .UseNodePort}}- nodePort: {{.NodePort}}
|
||||||
|
port: {{.Port}}
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: {{.Port}}
|
||||||
|
type: NodePort{{else}}- port: {{.Port}}{{end}}
|
||||||
|
selector:
|
||||||
|
app: {{.Name}}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: autoscaling/v2beta1
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: {{.Name}}-hpa-c
|
||||||
|
namespace: {{.Namespace}}
|
||||||
|
labels:
|
||||||
|
app: {{.Name}}-hpa-c
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: {{.Name}}
|
||||||
|
minReplicas: {{.MinReplicas}}
|
||||||
|
maxReplicas: {{.MaxReplicas}}
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
targetAverageUtilization: 80
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: autoscaling/v2beta1
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: {{.Name}}-hpa-m
|
||||||
|
namespace: {{.Namespace}}
|
||||||
|
labels:
|
||||||
|
app: {{.Name}}-hpa-m
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: {{.Name}}
|
||||||
|
minReplicas: {{.MinReplicas}}
|
||||||
|
maxReplicas: {{.MaxReplicas}}
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: memory
|
||||||
|
targetAverageUtilization: 80
|
||||||
|
`
|
@ -0,0 +1,39 @@
|
|||||||
|
package kube
|
||||||
|
|
||||||
|
var jobTmeplate = `apiVersion: batch/v1
|
||||||
|
kind: CronJob
|
||||||
|
metadata:
|
||||||
|
name: {{.Name}}
|
||||||
|
namespace: {{.Namespace}}
|
||||||
|
spec:
|
||||||
|
successfulJobsHistoryLimit: {{.SuccessfulJobsHistoryLimit}}
|
||||||
|
schedule: "{{.Schedule}}"
|
||||||
|
jobTemplate:
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: {{.Name}}
|
||||||
|
image: # todo image url
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: {{.RequestCpu}}m
|
||||||
|
memory: {{.RequestMem}}Mi
|
||||||
|
limits:
|
||||||
|
cpu: {{.LimitCpu}}m
|
||||||
|
memory: {{.LimitMem}}Mi
|
||||||
|
command:
|
||||||
|
- ./{{.ServiceName}}
|
||||||
|
- -f
|
||||||
|
- ./{{.Name}}.yaml
|
||||||
|
volumeMounts:
|
||||||
|
- name: timezone
|
||||||
|
mountPath: /etc/localtime
|
||||||
|
imagePullSecrets:
|
||||||
|
- name: # registry secret, if no, remove this
|
||||||
|
restartPolicy: OnFailure
|
||||||
|
volumes:
|
||||||
|
- name: timezone
|
||||||
|
hostPath:
|
||||||
|
path: /usr/share/zoneinfo/Asia/Shanghai
|
||||||
|
`
|
@ -0,0 +1,104 @@
|
|||||||
|
package kube
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
category = "kube"
|
||||||
|
deployTemplateFile = "deployment.tpl"
|
||||||
|
jobTemplateFile = "job.tpl"
|
||||||
|
basePort = 30000
|
||||||
|
portLimit = 32767
|
||||||
|
)
|
||||||
|
|
||||||
|
var errUnknownServiceType = errors.New("unknown service type")
|
||||||
|
|
||||||
|
type (
|
||||||
|
ServiceType string
|
||||||
|
|
||||||
|
KubeRequest struct {
|
||||||
|
Env string
|
||||||
|
ServiceName string
|
||||||
|
ServiceType ServiceType
|
||||||
|
Namespace string
|
||||||
|
Schedule string
|
||||||
|
Replicas int
|
||||||
|
RevisionHistoryLimit int
|
||||||
|
Port int
|
||||||
|
LimitCpu int
|
||||||
|
LimitMem int
|
||||||
|
RequestCpu int
|
||||||
|
RequestMem int
|
||||||
|
SuccessfulJobsHistoryLimit int
|
||||||
|
HpaMinReplicas int
|
||||||
|
HpaMaxReplicas int
|
||||||
|
}
|
||||||
|
|
||||||
|
Deployment struct {
|
||||||
|
Name string
|
||||||
|
Namespace string
|
||||||
|
Image string
|
||||||
|
Secret string
|
||||||
|
Replicas int
|
||||||
|
Revisions int
|
||||||
|
Port int
|
||||||
|
NodePort int
|
||||||
|
UseNodePort bool
|
||||||
|
RequestCpu int
|
||||||
|
RequestMem int
|
||||||
|
LimitCpu int
|
||||||
|
LimitMem int
|
||||||
|
MinReplicas int
|
||||||
|
MaxReplicas int
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func DeploymentCommand(c *cli.Context) error {
|
||||||
|
nodePort := c.Int("nodePort")
|
||||||
|
// 0 to disable the nodePort type
|
||||||
|
if nodePort != 0 && (nodePort < basePort || nodePort > portLimit) {
|
||||||
|
return errors.New("nodePort should be between 30000 and 32767")
|
||||||
|
}
|
||||||
|
|
||||||
|
text, err := util.LoadTemplate(category, deployTemplateFile, deploymentTemplate)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := util.CreateIfNotExist(c.String("o"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer out.Close()
|
||||||
|
|
||||||
|
t := template.Must(template.New("deploymentTemplate").Parse(text))
|
||||||
|
return t.Execute(out, Deployment{
|
||||||
|
Name: c.String("name"),
|
||||||
|
Namespace: c.String("namespace"),
|
||||||
|
Image: c.String("image"),
|
||||||
|
Secret: c.String("secret"),
|
||||||
|
Replicas: c.Int("replicas"),
|
||||||
|
Revisions: c.Int("revisions"),
|
||||||
|
Port: c.Int("port"),
|
||||||
|
NodePort: nodePort,
|
||||||
|
UseNodePort: nodePort > 0,
|
||||||
|
RequestCpu: c.Int("requestCpu"),
|
||||||
|
RequestMem: c.Int("requestMem"),
|
||||||
|
LimitCpu: c.Int("limitCpu"),
|
||||||
|
LimitMem: c.Int("limitMem"),
|
||||||
|
MinReplicas: c.Int("minReplicas"),
|
||||||
|
MaxReplicas: c.Int("maxReplicas"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenTemplates(_ *cli.Context) error {
|
||||||
|
return util.InitTemplates(category, map[string]string{
|
||||||
|
deployTemplateFile: deploymentTemplate,
|
||||||
|
jobTemplateFile: jobTmeplate,
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue