Chuyển đến nội dung chính

LESSON 37: PRACTICE — HELM, OPERATORS AND GITOPS

Module 8 practice: Create Helm 4 chart and publish to OCI registry, install cert-manager operator, setup ArgoCD GitOps deploy application from Git, create App of Apps pattern.

🔒 DevSecOps — Lesson 37 LESSON 37: PRACTICE — HELM, OPERATORS AND GITOPS

KUBERNETES: FROM BASIC TO ADVANCED

Module 8: Helm, Operators & GitOps

xdev.asia

🎯 Practice objective__HTMLTAG_68___
  • Create Helm chart from scratch and install
  • Create Helm hooks and tests
  • Install cert-manager operator and generate TLS certificate
  • Deploy ArgoCD and create Application
  • Setup App of Apps pattern

Lab 1: Creating Helm Chart

kubectl create namespace lab8

Tạo chart mới

helm create webapp ls webapp/

Chart.yaml charts/ templates/ values.yaml

Xem chart structure

cat webapp/Chart.yaml cat webapp/values.yaml

Chỉnh sửa values.yaml

cat > webapp/values.yaml <<EOF replicaCount: 2

image: repository: nginx tag: "1.27" pullPolicy: IfNotPresent

service: type: ClusterIP port: 80

ingress: enabled: false

resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "500m" memory: "256Mi"

livenessProbe: httpGet: path: / port: http

readinessProbe: httpGet: path: / port: http EOF

Lint chart

helm lint webapp/

Dry run

helm install --dry-run --debug webapp-test webapp/ -n lab8

Install

helm install webapp webapp/ -n lab8 helm list -n lab8

Upgrade (thay đổi replicas)

helm upgrade webapp webapp/ -n lab8 --set replicaCount=3

Xem history

helm history webapp -n lab8

Rollback về revision 1

helm rollback webapp 1 -n lab8

Lab 2: Helm Hooks

# Thêm pre-upgrade hook (database migration giả lập)
cat > webapp/templates/migration-job.yaml <<EOF
apiVersion: batch/v1
kind: Job
metadata:
  name: "{{ .Release.Name }}-migration"
  annotations:
    "helm.sh/hook": pre-upgrade,pre-install
    "helm.sh/hook-weight": "-5"
    "helm.sh/hook-delete-policy": hook-succeeded
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: migration
        image: busybox:1.36
        command: ['sh', '-c', 'echo "Running DB migration..."; sleep 3; echo "Migration complete!"']
EOF

Upgrade với hook

helm upgrade webapp webapp/ -n lab8

Xem migration job

kubectl get jobs -n lab8 kubectl logs -n lab8 job/webapp-migration

Lab 3: Helm Tests

# Tạo test
mkdir -p webapp/templates/tests
cat > webapp/templates/tests/test-connection.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: "{{ .Release.Name }}-test-connection"
  annotations:
    "helm.sh/hook": test
spec:
  restartPolicy: Never
  containers:
  - name: test
    image: busybox:1.36
    command:
    - sh
    - -c
    - |
      until wget -qO- http://{{ .Release.Name }}-webapp:{{ .Values.service.port }}; do
        echo "Waiting for service..."
        sleep 2
      done
      echo "Test passed!"
EOF

helm upgrade webapp webapp/ -n lab8 helm test webapp -n lab8

Lab 4: cert-manager Operator

# Cài cert-manager
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --set crds.enabled=true

kubectl get pods -n cert-manager

cert-manager-xxx, cert-manager-cainjector-xxx, cert-manager-webhook-xxx

Tạo self-signed ClusterIssuer

cat <<EOF | kubectl apply -f - apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: selfsigned-issuer spec: selfSigned: {}

Certificate cho webapp

apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: webapp-tls namespace: lab8 spec: secretName: webapp-tls-secret issuerRef: name: selfsigned-issuer kind: ClusterIssuer dnsNames:

  • webapp.lab8.svc.cluster.local
  • webapp.example.com duration: 2160h # 90 days renewBefore: 360h # renew khi còn 15 days EOF

Xem certificate status

kubectl get certificate -n lab8 kubectl describe certificate webapp-tls -n lab8

Status: Ready

Xem generated secret

kubectl get secret webapp-tls-secret -n lab8 kubectl get secret webapp-tls-secret -n lab8 -o jsonpath='{.data.tls.crt}' | base64 -d | openssl x509 -text -noout

Lab 5: Deploy ArgoCD

# Cài ArgoCD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Chờ ArgoCD ready

kubectl wait --for=condition=available deployment/argocd-server -n argocd --timeout=120s

Lấy admin password

ARGOCD_PASSWORD=$(kubectl -n argocd get secret argocd-initial-admin-secret
-o jsonpath="{.data.password}" | base64 -d) echo "ArgoCD password: $ARGOCD_PASSWORD"

Port-forward UI

kubectl port-forward svc/argocd-server -n argocd 8080:443 & echo "ArgoCD UI: https://localhost:8080 (admin/$ARGOCD_PASSWORD)"

Hoặc dùng ArgoCD CLI

argocd login localhost:8080 --username admin --password $ARGOCD_PASSWORD --insecure

Lab 6: Creating ArgoCD Application__HTMLTAG_92___
# Tạo Application bằng CLI
argocd app create webapp-gitops \
  --repo https://github.com/argoproj/argocd-example-apps \
  --path guestbook \
  --dest-server https://kubernetes.default.svc \
  --dest-namespace lab8 \
  --sync-policy automated \
  --auto-prune \
  --self-heal

Xem status

argocd app list argocd app get webapp-gitops

Sync thủ công

argocd app sync webapp-gitops

Xem trong browser: https://localhost:8080

# Tạo Application bằng YAML
cat <<EOF | kubectl apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/argoproj/argocd-example-apps
    targetRevision: HEAD
    path: guestbook
  destination:
    server: https://kubernetes.default.svc
    namespace: lab8
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=true
EOF

Lab 7: App of Apps

# Tạo cấu trúc Git repo (simulate locally)
mkdir -p /tmp/gitops-demo/apps-of-apps
mkdir -p /tmp/gitops-demo/apps/{webapp,monitoring}

Root Application file

cat > /tmp/gitops-demo/apps-of-apps/webapp.yaml <<EOF apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: webapp-child namespace: argocd spec: project: default source: repoURL: https://github.com/argoproj/argocd-example-apps path: helm-guestbook targetRevision: HEAD destination: server: https://kubernetes.default.svc namespace: lab8 syncPolicy: automated: prune: true selfHeal: true EOF

Apply root app

kubectl apply -f /tmp/gitops-demo/apps-of-apps/ -n argocd

ArgoCD sẽ tìm và deploy tất cả Application CRDs trong thư mục

argocd app list

Lab 8: Simulate GitOps Workflow

# 1. Xem app đang chạy
kubectl get pods -n lab8

2. Simulate: ai đó thay đổi trực tiếp trong cluster (drift)

kubectl scale deployment guestbook-ui -n lab8 --replicas=0

3. ArgoCD detect và tự heal trong vài phút

kubectl get pods -n lab8 -w

4. Xem ArgoCD phục hồi về 2 replicas (self-heal)

argocd app get guestbook

5. Xem sync history

argocd app history guestbook

Cleanup

helm uninstall webapp -n lab8
kubectl delete namespace lab8
kubectl delete application guestbook webapp-gitops webapp-child -n argocd
kubectl delete namespace argocd
helm uninstall cert-manager -n cert-manager
kubectl delete namespace cert-manager

Summary

  • ✅ Helm chart from scratch: structure, templates, values
  • ✅ Helm hooks: pre-upgrade migration job
  • ✅ Helm tests: verify deployment
  • ✅ cert-manager: automatic TLS certificates
  • ✅ ArgoCD: Application + sync policy automated
  • ✅ App of Apps: manage multiple apps with 1 root app
  • ✅ GitOps self-healing: ArgoCD self-healing drift