0%

helm charts 开发实践

Helm 是 Kubernetes 的包管理器,我们可以使用helm打包应用,管理应用的依赖关系,管理应用版本并发布应用到软件仓库。对于使用者,不需要使用k8s的yaml文件去部署应用,直接helm install就可以安装应用。

今天我们就来构建一下jenkins的chart,并通过helm把jenkins部署到k8s集群中去

1.首先创建模板

helm create jenkins
helm tree jenkins
jenkins
├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt  chart的"帮助文本"。这会在你的用户执行helm install时展示给他们
│   ├── _helpers.tpl   放置可以通过chart复用的模板辅助对象
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

3 directories, 10 files

其实主要关注两个目录

  • templates:这个目录里面存放要部署的模板,里面主要是k8s对应的要部署服务相关的yaml。开发者可以将动态部分抽出为可变参数,通过values.yaml来动态传入。比如我们不同环境的jenkins规模不一样,所需要的cpu和内存就不同,就可以抽出来
  • values.yaml 则是配置模板需要的参数,许多参数我们可以提前内置进去

额外在说一下_helpers.tpl ,这个是对chart里面变量的一个扩展。我们可以define来定义全局可访问变量,比如定义jenkins的fullname:

{{- define "jenkins.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

我们就可以在chart和所有的子chart使用该变量。

    metadata:
  name: {{ include "jenkins.fullname" . }}
  

具体模板规范见helm官网

2.配置模板参数

Chart.yaml文件中为介绍chart的一些基本信息,我们这边就用默认生成的不做更改。
因为我们jenkins只是做简单的测试,所以serviceAccount、hpa、ingress不做配置就直接删掉了。
接下来就是values.yaml、service.yaml、deployment.yaml的配置,
其实就是按照k8s的deployment、service的yaml的配置把需要动态的参数用模板语言抽出来,放在values.yaml里面做配置。

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: {{ include "jenkins.fullname" . }}
  annotations:
        #用rang函数来输出key  value
        {{- range $key, $val := .Values.service.annotations }}
        {{ $key }}: {{ $val | quote }}
        {{- end }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: {{ .Values.service.targetPort }}
      protocol: TCP
      name: http
  selector:
    {{- include "jenkins.selectorLabels" . | nindent 4 }}
    

service对应的values.yaml配置

  service:
  type: LoadBalancer
  port: 80
  targetPort: 8080
  annotations: {
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small 
    service.beta.kubernetes.io/alicloud-loadbalancer-address-type: intranet  #阿里云内网负载均衡          
  }  
  

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "jenkins.fullname" . }}
  labels:
    {{- include "jenkins.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "jenkins.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "jenkins.selectorLabels" . | nindent 8 }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          securityContext: {}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          resources:
            {{- toYaml .Values.resources | nindent 12 }}

   

deployment.yaml对应的values.yaml配置

replicaCount: 1
image:
  repository: 你的jenkins镜像地址
  pullPolicy: Always
  # Overrides the image tag whose default is the chart appVersion.
  tag: "ansible-utf-8"

resources: {
   limits:
     cpu: 4
     memory: 8G
   requests:
     cpu: 4
     memory: 8G
}

删除Notes.txt的模板语言,因为values里面我们删除了一下值,会让该模板语言报错。

3.检查和部署

在jenkins的文件下执行helm install –dry-run –debug jenkins . 生成如下的模板:
# Source: jenkins/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: jenkins
annotations:
service.beta.kubernetes.io/alicloud-loadbalancer-address-type: “intranet”
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app.kubernetes.io/name: jenkins
app.kubernetes.io/instance: jenkins

kind: Deployment
metadata:
  name: jenkins
  labels:
    helm.sh/chart: jenkins-0.1.0
    app.kubernetes.io/name: jenkins
    app.kubernetes.io/instance: jenkins
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: jenkins
      app.kubernetes.io/instance: jenkins
  template:
    metadata:
      labels:
        app.kubernetes.io/name: jenkins
        app.kubernetes.io/instance: jenkins
    spec:
      containers:
        - name: jenkins
          securityContext: {}
          image: "harbor.dui88.com/library/jenkins:ansible-utf-8"
          imagePullPolicy: Always
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          resources:
            limits:
              cpu: 4
              memory: 8G
            requests:
              cpu: 4

查看没有啥问题后执行 helm install jenkins .去部署

helm install  jenkins . 
NAME: jenkins
LAST DEPLOYED: Wed Mar 10 16:44:44 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1

然后登陆k8s后台,可以看见default ns下有jenkins服务,

svc也创建好了

访问也可以看见jenkins初始页面

回滚操作

helm uninstall jenkins
release "jenkins" uninstalled

然后集群中jenkins部署和svc就会被删除了