Wprowadzenie do Helm Chart

Wprowadzenie do Helm Chart

Helm Chart to mechanizm który pozwala uprościć zarządzanie aplikacją w klastrze Kubernetesa. Zanim przejdziemy do zdefiniowania Helm Chart należy zestawić klaster kubernetesa. W tym celu polecam zapoznać się z następującymi artykułami:

  • https://javaleader.pl/2021/03/29/jak-zestawic-klaster-kubernetesa-na-ubuntu-18-04/
  • https://javaleader.pl/2021/04/13/klaster-kubernetesa-z-uzyciem-kubespray-i-ansible/

Jeśli klaster jest prawidłowo zestawiony:

NAME     STATUS   ROLES                  AGE     VERSION
worker   Ready    <none>                 28s     v1.21.0
master   Ready    control-plane,master   4m27s   v1.21.0

możemy przystąpić do instalacji narzędzia Helm (maszyna master node):

snap install helm --classic

weryfikacja:

helm version

wynik:

version.BuildInfo{Version:"v3.5.4", GitCommit:"1b5edb69df3d3a08df77c9902dc17af864ff05d1", GitTreeState:"clean", GoVersion:"go1.15.11"}

tworzymy Heml Chart:

helm create myFirstHelmChart

weryfikacja:

 ls -lart | grep myFirstHelmChart
tree myFirstHelmChart

wynik:

myFirstHelmChart
├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

Edycja Values.yaml:

Jako, że chcemy mieć dostęp do serwisu Kubernetesa na zewnątrz klastra należy zmodyfikować zmienną:

service.type

w następujący sposób:

service:
  type: NodePort
  port: 80

Instalacja Helm Chart:

helm install myfirstchart myFirstHelmChart

wynik:

NAME: myfirstchart
LAST DEPLOYED: Sat May  1 16:03:26 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
  export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services myfirstchart)
  export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
  echo http://$NODE_IP:$NODE_PORT

[UWAGA] w przypadku błędu należy sprawdzić jaka nazwa jest w Chart.yml dla zmiennej:

name: myfirstchart

nazwa musi być małymi literami!

Weryfikacja serwisu Kubernetesa:

kubectl get service
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes     ClusterIP   10.96.0.1       <none>        443/TCP        37m
myfirstchart   NodePort    10.101.73.131   <none>        80:30967/TCP   106s

sprawdzamy jeszcze czy kontener jest gotowy (trochę trwa zanim będzie gotowy…):

NAME                            READY   STATUS              RESTARTS   AGE
myfirstchart-5f6f9b7cd6-ttpdm   0/1     ContainerCreating   0          5m11s

kontener prawidłowo utworzony:

NAME                            READY   STATUS    RESTARTS   AGE
myfirstchart-5f6f9b7cd6-ttpdm   1/1     Running   0          12m

zatem pod adresem:

http://ipworkerNode:30967/

zobaczymy widok Nginxa:

Welcome to nginx!
 
If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
 
For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.
 
Thank you for using nginx.

usunięcie:

helm delete myfirstchart

Wdrożenie przykładowej aplikacji Spring Boota z użyciem HelmChart:

Tworzymy plik konfiguracyjny:

service-account-tiller.yaml

z zawartością:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: tiller
    namespace: kube-system
kubectl create -f service-account-tiller.yaml
kubectl get pods -A

tworzymy helm chart:

helm create springboot

edytujemy plik values.yml:

replicaCount: 3
image:
  repository: mwarycha/docker-app
  pullPolicy: IfNotPresent
  tag: latest

instalujemy helm chart:

helm install springboot springboot

odczyt tablicy parametrów:

kubectl create clusterrolebinding default-admin --clusterrole cluster-admin --serviceaccount=default:springboot

poprawka portu:

usuwamy:

- --port=0

w pliku:

sudo vim /etc/kubernetes/manifests/kube-scheduler.yaml

wynik:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    component: kube-scheduler
    tier: control-plane
  name: kube-scheduler
  namespace: kube-system
spec:
  containers:
  - command:
    - kube-scheduler
    - --authentication-kubeconfig=/etc/kubernetes/scheduler.conf
    - --authorization-kubeconfig=/etc/kubernetes/scheduler.conf
    - --bind-address=0.0.0.0
    - --kubeconfig=/etc/kubernetes/scheduler.conf
    - --leader-elect=true
    image: k8s.gcr.io/kube-scheduler:v1.21.0
    imagePullPolicy: IfNotPresent
    livenessProbe:
      failureThreshold: 8
      httpGet:
        host: 0.0.0.0
        path: /healthz
        port: 80
        scheme: HTTPS
      initialDelaySeconds: 10
      periodSeconds: 10
      timeoutSeconds: 15
    name: kube-scheduler
    resources:
      requests:
        cpu: 100m
    startupProbe:
      failureThreshold: 24
      httpGet:
        host: 0.0.0.0
        path: /healthz
        port: 80
        scheme: HTTPS
      initialDelaySeconds: 10
      periodSeconds: 10
      timeoutSeconds: 15
    volumeMounts:
    - mountPath: /etc/kubernetes/scheduler.conf
      name: kubeconfig
      readOnly: true
  hostNetwork: true
  priorityClassName: system-node-critical
  volumes:
  - hostPath:
      path: /etc/kubernetes/scheduler.conf
      type: FileOrCreate
    name: kubeconfig
status: {}

oraz w pliku:

sudo vim /etc/kubernetes/manifests/kube-controller-manager.yaml

wynik:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    component: kube-controller-manager
    tier: control-plane
  name: kube-controller-manager
  namespace: kube-system
spec:
  containers:
  - command:
    - kube-controller-manager
    - --allocate-node-cidrs=true
    - --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf
    - --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf
    - --bind-address=0.0.0.0
    - --client-ca-file=/etc/kubernetes/pki/ca.crt
    - --cluster-cidr=10.244.0.0/16
    - --cluster-name=kubernetes
    - --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
    - --cluster-signing-key-file=/etc/kubernetes/pki/ca.key
    - --controllers=*,bootstrapsigner,tokencleaner
    - --kubeconfig=/etc/kubernetes/controller-manager.conf
    - --leader-elect=true
    - --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
    - --root-ca-file=/etc/kubernetes/pki/ca.crt
    - --service-account-private-key-file=/etc/kubernetes/pki/sa.key
    - --service-cluster-ip-range=10.96.0.0/12
    - --use-service-account-credentials=true
    image: k8s.gcr.io/kube-controller-manager:v1.21.0
    imagePullPolicy: IfNotPresent
    livenessProbe:
      failureThreshold: 8
      httpGet:
        host: 0.0.0.0
        path: /healthz
        port: 10257
        scheme: HTTPS
      initialDelaySeconds: 10
      periodSeconds: 10
      timeoutSeconds: 15
    name: kube-controller-manager
    resources:
      requests:
        cpu: 200m
    startupProbe:
      failureThreshold: 24
      httpGet:
        host: 0.0.0.0
        path: /healthz
        port: 10257
        scheme: HTTPS
      initialDelaySeconds: 10
      periodSeconds: 10
      timeoutSeconds: 15
    volumeMounts:
    - mountPath: /etc/ssl/certs
      name: ca-certs
      readOnly: true
    - mountPath: /etc/ca-certificates
      name: etc-ca-certificates

odświeżamy konfigurację:

sudo systemctl restart kubelet.service

sprawdzamy czy wszystko ok:

kubectl get cs

wynik:

Warning: v1 ComponentStatus is deprecated in v1.19+
NAME                 STATUS    MESSAGE             ERROR
controller-manager   Healthy   ok
scheduler            Healthy   ok
etcd-0               Healthy   {"health":"true"}

edycja pliku ./templates/deployment.yml:

containers:
        - name: {{ .Chart.Name }}
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /hello
              port: http
            initialDelaySeconds: 60
            periodSeconds: 5
            timeoutSeconds: 35
            successThreshold: 1
            failureThreshold: 1
          readinessProbe:
            httpGet:
              path: /hello
              port: http
            initialDelaySeconds: 60
          resources:
                 ...
  • jeśli kontener nie przejdzie prób livenessProbe oraz readinessProbe to nie wystartuje (nie będzie w statusie ready)!
  • port kontenera mus być ustawiony na 8080
  • TCP liveness: kubectl apply -f https://k8s.io/examples/pods/probe/tcp-liveness-readiness.yaml

 

 

Leave a comment

Your email address will not be published.


*