通过helm2构建kubernetes应用(三)

通过模板创建修改多个中间件应用,并提交到本地仓库,比如elasticsearch、redis、mysql、postgresql等

wangw@DESKTOP:~/helmapp$ helm search
NAME                            CHART VERSION   APP VERSION        DESCRIPTION
localrepo/elasticsearch         0.1.2           2.4                elasticsearch single node for kubernetes
localrepo/myapp1                0.1.0           1.0                A Helm chart for Kubernetes
localrepo/mysql                 0.1.2           5.7                mysql single node for kubernetes
localrepo/postgresql            0.1.2           11.5               postgresql single node for kubernetes
localrepo/redis                 0.1.2           3.2                redis single node for Kubernetes

通过模板创建我们自己的应用

# 创建模板
wangw@DESKTOP:~/helmapp$ helm create gistack
Creating gistack
# Chart.yaml
wangw@DESKTOP:~/helmapp/gistack$ cat Chart.yaml
apiVersion: v1
appVersion: "4.3"
description: A Gis solution for Kubernetes
name: gistack
version: 0.1.0
# deployment.yaml
wangw@DESKTOP:~/helmapp/gistack/templates$ cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "gistack.fullname" . }}
  labels:
{{ include "gistack.labels" . | indent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ include "gistack.name" . }}
      app.kubernetes.io/instance: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app.kubernetes.io/name: {{ include "gistack.name" . }}
        app.kubernetes.io/instance: {{ .Release.Name }}
    spec:
    {{- with .Values.imagePullSecrets }}
      imagePullSecrets:
        {{- toYaml . | nindent 8 }}
    {{- end }}
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
      {{- with .Values.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
    {{- with .Values.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
    {{- end }}
    {{- with .Values.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
    {{- end }}
# values.yaml
wangw@DESKTOP:~/helmapp/gistack$ cat values.yaml
replicaCount: 1

image:
  repository: 192.168.199.205:80/library/jdk
  tag: 1.8
  pullPolicy: IfNotPresent

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: false
  annotations: {}
    # kubernetes.io/ingress.class: gistack
    # kubernetes.io/tls-acme: "true"
  hosts:
    - host: chart-example.local
      paths: []

  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local

resources:
  limits:
    cpu: 1
    memory: 2Gi
  requests:
    cpu: 500m
    memory: 1Gi

nodeSelector: {}

tolerations: []

affinity: {}

假设gistack应用依赖于mysql、elasticsearch、redis等应用,helm提供了依赖设置

# 添加requirements.yaml文件
wangw@DESKTOP:~/helmapp/gistack$ cat requirements.yaml
dependencies:
  - name: mysql
    version: 0.1.2
    repository: http://localhost:8879
  - name: redis
    version: 0.1.2
    repository: http://localhost:8879
  - name: elasticsearch
    version: 0.1.2
    repository: http://localhost:8879
# 每个chart依赖需要指明名称、版本、仓库地址

查看当前依赖

wangw@DESKTOP:~/helmapp/gistack$ helm dependency list
NAME            VERSION REPOSITORY              STATUS
mysql           0.1.2   http://localhost:8879   missing
redis           0.1.2   http://localhost:8879   missing
elasticsearch   0.1.2   http://localhost:8879   missing

更新下载依赖包到chart文件夹

wangw@DESKTOP:~/helmapp/gistack$ helm dependency update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "localrepo" chart repository
...Successfully got an update from the "stable" chart repository
Update Complete.
Saving 3 charts
Downloading mysql from repo http://localhost:8879
Downloading redis from repo http://localhost:8879
Downloading elasticsearch from repo http://localhost:8879
Deleting outdated charts

wangw@DESKTOP:~/helmapp/gistack$ ls charts/
elasticsearch-0.1.2.tgz  mysql-0.1.2.tgz  redis-0.1.2.tgz

检查配置文件并更新到本地仓库

wangw@DESKTOP:~/helmapp$ helm lint gistack/
==> Linting gistack/
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, no failures
wangw@DESKTOP:~/helmapp$ helm package gistack/
Successfully packaged chart and saved it to: /home/wangw/helmapp/gistack-0.1.0.tgz

更新仓库并部署应用

# 更新仓库
wangw@DESKTOP:~/helmapp$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "localrepo" chart repository
...Successfully got an update from the "stable" chart repository
Update Complete.

# 搜索gistack应用
wangw@DESKTOP:~/helmapp$ helm search gistack
NAME                    CHART VERSION   APP VERSION     DESCRIPTION
localrepo/gistack       0.1.0           4.3             A Gis solution for Kubernetes
# 部署gistack应用
wangw@DESKTOP:~/helmapp$ helm install localrepo/gistack --name gistack --namespace default
NAME:   gistack
LAST DEPLOYED: Thu Oct 24 11:01:01 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Deployment
NAME                   READY  UP-TO-DATE  AVAILABLE  AGE
gistack                0/1    1           0          1s
gistack-elasticsearch  0/1    0           0          1s
gistack-redis          0/1    1           0          1s

==> v1/PersistentVolumeClaim
NAME                   STATUS   VOLUME    CAPACITY  ACCESS MODES  STORAGECLASS  AGE
gistack-elasticsearch  Pending  longhorn  1s
gistack-mysql          Pending  longhorn  1s

==> v1/Pod(related)
NAME                                    READY  STATUS             RESTARTS  AGE
gistack-7b9fdc797f-rgf5l                0/1    ContainerCreating  0         1s
gistack-elasticsearch-5bf5fb8b78-v26l9  0/1    Pending            0         1s
gistack-mysql-7c8b85b579-c5f7w          0/1    Pending            0         1s
gistack-redis-5cc657bddb-89b7j          0/1    ContainerCreating  0         1s

==> v1/Secret
NAME           TYPE    DATA  AGE
gistack-mysql  Opaque  2     1s

==> v1/Service
NAME                   TYPE       CLUSTER-IP     EXTERNAL-IP  PORT(S)                        AGE
gistack                ClusterIP  10.43.221.42   <none>       80/TCP                         1s
gistack-elasticsearch  NodePort   10.43.143.211  <none>       9200:30305/TCP,9300:30076/TCP  1s
gistack-mysql          ClusterIP  10.43.229.209  <none>       3306/TCP                       1s
gistack-redis          NodePort   10.43.32.103   <none>       6379:31455/TCP                 1s

==> v1beta1/Deployment
NAME           READY  UP-TO-DATE  AVAILABLE  AGE
gistack-mysql  0/1    1           0          1s


NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=gistack,app.kubernetes.io/instance=gistack" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl port-forward $POD_NAME 8080:80

# 可以看出部署gistack时,其依赖会自动部署

查看gistack状态

wangw@DESKTOP:~/helmapp$ helm status gistack
LAST DEPLOYED: Thu Oct 24 11:01:01 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Deployment
NAME                   READY  UP-TO-DATE  AVAILABLE  AGE
gistack                1/1    1           1          2m40s
gistack-elasticsearch  1/1    1           1          2m40s
gistack-redis          1/1    1           1          2m40s

==> v1/PersistentVolumeClaim
NAME                   STATUS  VOLUME                                    CAPACITY  ACCESS MODES  STORAGECLASS  AGE
gistack-elasticsearch  Bound   pvc-3e9d4332-d0c4-4e2c-9ed2-57c3a534a0a2  10Gi      RWO           longhorn      2m40s
gistack-mysql          Bound   pvc-ad117f2d-fd40-47d6-8445-624271d6f895  8Gi       RWO           longhorn      2m40s

==> v1/Pod(related)
NAME                                    READY  STATUS   RESTARTS  AGE
gistack-7b9fdc797f-rgf5l                1/1    Running  0         71s
gistack-elasticsearch-5bf5fb8b78-v26l9  1/1    Running  0         2m40s
gistack-mysql-7c8b85b579-c5f7w          1/1    Running  0         2m40s
gistack-redis-5cc657bddb-89b7j          1/1    Running  0         2m40s

==> v1/Secret
NAME           TYPE    DATA  AGE
gistack-mysql  Opaque  2     2m40s

==> v1/Service
NAME                   TYPE       CLUSTER-IP     EXTERNAL-IP  PORT(S)                        AGE
gistack                ClusterIP  10.43.221.42   <none>       80/TCP                         2m40s
gistack-elasticsearch  NodePort   10.43.143.211  <none>       9200:30305/TCP,9300:30076/TCP  2m40s
gistack-mysql          ClusterIP  10.43.229.209  <none>       3306/TCP                       2m40s
gistack-redis          NodePort   10.43.32.103   <none>       6379:31455/TCP                 2m40s

==> v1beta1/Deployment
NAME           READY  UP-TO-DATE  AVAILABLE  AGE
gistack-mysql  1/1    1           1          2m40s

NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=gistack,app.kubernetes.io/instance=gistack" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl port-forward $POD_NAME 8080:80

# 目前看来,一切都按照我们想的运行了起来

虽然解决了应用依赖的问题,但是在应用层面上还需要进一步优化

  • 在需要依赖的pod下添加被依赖服务检查任务,可以通过程序本身检查,也可以通过添加initContainers处理
  • 配置文件统一管理,使用用configmap
  • 密钥管理,通过secret
  • 对应用日志的导出,可通过sidecar的方式,采用filebeat + logstash,日志卷共享emptyDir目录
  • 部分应用需要改造deployment为statfulset
  • 生产环境还需要实现应用高可用和中间件高可用
  • 更多helm用法,请多多关注helm官网

总结

  • template下的yaml文件与kubernetes原生yaml文件实际上是一致的,不同在于分离出了主要的值,以变量代替,同时支持简单的逻辑处理
  • values.yaml定义了应用的关键参数,包括任何你想要定义的参数
  • requirements.yaml定义应用需要依赖的其它应用
  • "helm之于kubernetes" 类比 "yum之于centos"
posted @ 2020-10-19 19:19  longtds  阅读(155)  评论(0编辑  收藏  举报