diff --git a/k8s/ROLLOUTS.md b/k8s/ROLLOUTS.md new file mode 100644 index 0000000000..deb3e10da3 --- /dev/null +++ b/k8s/ROLLOUTS.md @@ -0,0 +1,135 @@ +# Lab 14 + +## Argo Rollouts Setup + +### Installation verification + +```bash +$ kubectl argo rollouts version +kubectl-argo-rollouts: v1.9.0+838d4e7 + BuildDate: 2026-03-20T21:08:11Z + GitCommit: 838d4e792be666ec11bd0c80331e0c5511b5010e + GitTreeState: clean + GoVersion: go1.24.13 + Compiler: gc + Platform: linux/amd64 +``` + +### Dashboard access + +![alt text](lab14_screenshots/image.png) + +## Canary Deployment + +```bash +helm install myapp ./mychart -n default +NAME: myapp +LAST DEPLOYED: Thu Apr 30 17:47:57 2026 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +DESCRIPTION: Install complete +TEST SUITE: None +NOTES: +export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services myapp-mychart) + export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT + +kubectl get rollouts +NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE +myapp-mychart 3 3 3 3 52s +``` + +Strategy configuration explained + +- setWeight: X - Routes X% of traffic to new version, (100-X)% to stable +- pause: {} - requires kubectl argo rollouts promote to continue +- pause: {duration: 30s} - waits 30 seconds, then automatically proceeds + +The first pause requires manual approval (safety checkpoint), then the rest auto-progress. + +Step-by-step rollout progression (screenshots from dashboard) +![alt text](lab14_screenshots/image-1.png) +![alt text](lab14_screenshots/image-2.png) + +Promotion and abort demonstration + +After promotion: +![alt text](lab14_screenshots/image-3.png) + +After abort: +![alt text](lab14_screenshots/image-4.png) + +## Blue-Green Deployment + +### Strategy configuration explained + +- Active Servic - Routes production traffic to current version (blue) +- Preview Service - Routes test traffic to new version (green) +- autoPromotionEnabled: false - Requires manual kubectl argo rollouts promote to switch traffic + +### Preview vs active service + +Preview version (has new endpoints): +![alt text](lab14_screenshots/image-5.png) + +Active service: +![alt text](lab14_screenshots/image-6.png) + +### Promotion process + +![alt text](lab14_screenshots/image-7.png) +![alt text](lab14_screenshots/image-8.png) + +## Strategy Comparison + +| Aspect | Canary | Blue-Green | +|--------|--------|-----------| +| **Traffic Shift** | Gradual (20% → 40% → 60%...) | Instant (0% → 100%) | +| **Rollback Speed** | Instant | Instant | +| **Resource Usage** | 1.5x replicas | 2x replicas | +| **Testing Approach** | Monitor live traffic | Full preview before production | +| **Risk Level** | Lower (gradual exposure) | Higher (full switch at once) | +| **Downtime** | Zero | Zero | + +### When to use canary vs blue-green + +#### Use Canary When: + +- **You need confidence** in code changes before full rollout +- **You want to catch issues early** with real traffic (10-20%) +- **You have metrics/analytics** to monitor during progression +- **You prefer graduated risk** over instant switches +- **Example:** API changes, database migrations, performance optimizations + +#### Use Blue-Green When: + +- **You need instant rollback capability** (database schema changes) +- **You want complete isolation** between versions before testing +- **You have sufficient resources** for 2x deployment +- **You prefer human approval** over automated progression +- **Example:** Major UI redesigns, critical infrastructure updates + +### Your recommendation for different scenarios + +| Scenario | Strategy | Reason | +|----------|----------|--------| +| New feature rollout | **Canary** | Monitor real user behavior safely | +| Hotfix for production bug | **Blue-Green** | Need instant rollback if issues arise | +| Database schema change | **Blue-Green** | Can't run both versions simultaneously | +| Performance optimization | **Canary** | Gradual traffic allows metric comparison | +| Security patch | **Canary** | Early detection of compatibility issues | +| UI redesign | **Blue-Green** | Full preview testing before customer exposure | + +## CLI Commands Reference + +Useful commands you used + +```bash +helm install myapp ./mychart +helm upgrade myapp ./mychart + +kubectl get rollouts + +kubectl argo rollouts get rollout mychart --watch +``` diff --git a/k8s/lab14_screenshots/image-1.png b/k8s/lab14_screenshots/image-1.png new file mode 100644 index 0000000000..934b66494b Binary files /dev/null and b/k8s/lab14_screenshots/image-1.png differ diff --git a/k8s/lab14_screenshots/image-2.png b/k8s/lab14_screenshots/image-2.png new file mode 100644 index 0000000000..953d996bad Binary files /dev/null and b/k8s/lab14_screenshots/image-2.png differ diff --git a/k8s/lab14_screenshots/image-3.png b/k8s/lab14_screenshots/image-3.png new file mode 100644 index 0000000000..2c83a2d8f8 Binary files /dev/null and b/k8s/lab14_screenshots/image-3.png differ diff --git a/k8s/lab14_screenshots/image-4.png b/k8s/lab14_screenshots/image-4.png new file mode 100644 index 0000000000..c77fbebe81 Binary files /dev/null and b/k8s/lab14_screenshots/image-4.png differ diff --git a/k8s/lab14_screenshots/image-5.png b/k8s/lab14_screenshots/image-5.png new file mode 100644 index 0000000000..4416a86c36 Binary files /dev/null and b/k8s/lab14_screenshots/image-5.png differ diff --git a/k8s/lab14_screenshots/image-6.png b/k8s/lab14_screenshots/image-6.png new file mode 100644 index 0000000000..55705a0505 Binary files /dev/null and b/k8s/lab14_screenshots/image-6.png differ diff --git a/k8s/lab14_screenshots/image-7.png b/k8s/lab14_screenshots/image-7.png new file mode 100644 index 0000000000..6875ff85c6 Binary files /dev/null and b/k8s/lab14_screenshots/image-7.png differ diff --git a/k8s/lab14_screenshots/image-8.png b/k8s/lab14_screenshots/image-8.png new file mode 100644 index 0000000000..b9059966c2 Binary files /dev/null and b/k8s/lab14_screenshots/image-8.png differ diff --git a/k8s/lab14_screenshots/image.png b/k8s/lab14_screenshots/image.png new file mode 100644 index 0000000000..01286e0e38 Binary files /dev/null and b/k8s/lab14_screenshots/image.png differ diff --git a/k8s/mychart/templates/rollout.yaml b/k8s/mychart/templates/rollout.yaml new file mode 100644 index 0000000000..574554ff6d --- /dev/null +++ b/k8s/mychart/templates/rollout.yaml @@ -0,0 +1,95 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Rollout +metadata: + name: {{ include "mychart.fullname" . }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "mychart.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "mychart.labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + envFrom: + - secretRef: + name: {{ include "mychart.fullname" . }}-credentials + - configMapRef: + name: {{ include "mychart.fullname" . }}-env-config + ports: + - name: http + containerPort: {{ .Values.service.targetPort }} + protocol: TCP + {{- with .Values.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: config-volume + mountPath: /config + - name: data-volume + mountPath: /data + {{- with .Values.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + volumes: + - name: config-volume + configMap: + name: {{ include "mychart.fullname" . }}-config + {{- if .Values.persistence.enabled }} + - name: data-volume + persistentVolumeClaim: + claimName: {{ include "mychart.fullname" . }}-data + {{- end }} + {{- with .Values.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + strategy: + blueGreen: + activeService: {{ include "mychart.fullname" . }} + previewService: {{ include "mychart.fullname" . }}-preview + autoPromotionEnabled: false \ No newline at end of file diff --git a/k8s/mychart/templates/service-preview.yaml b/k8s/mychart/templates/service-preview.yaml new file mode 100644 index 0000000000..87a4f6c9f5 --- /dev/null +++ b/k8s/mychart/templates/service-preview.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "mychart.fullname" . }}-preview + labels: + {{- include "mychart.labels" . | nindent 4 }} +spec: + type: ClusterIP + selector: + {{- include "mychart.selectorLabels" . | nindent 4 }} + ports: + - port: {{ .Values.service.port }} + targetPort: {{ .Values.service.targetPort }} + protocol: TCP + name: http diff --git a/k8s/mychart/values.yaml b/k8s/mychart/values.yaml index 7f4742b4be..950bc431b1 100644 --- a/k8s/mychart/values.yaml +++ b/k8s/mychart/values.yaml @@ -11,7 +11,7 @@ image: # This sets the pull policy for images. pullPolicy: IfNotPresent # Overrides the image tag whose default is the chart appVersion. - tag: "1.2.0" + tag: "1.3.0" # This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ imagePullSecrets: []