Slide 1

Slide 1 text

Continuous Deployment for Kubernetes

Slide 2

Slide 2 text

Waldemar Biller Software Architect, Manager 10+ years in IT Java, Spring, DDD, Kubernetes, Vue, Flutter, ... Email: [email protected] Twitter: @wbiller

Slide 3

Slide 3 text

CI / CD Developer Code Repository Continuous Integration Container Registry kubectl / helm Push Build & Test Publish D eploy R un Icons: CC BY 3.0

Slide 4

Slide 4 text

3:03

Slide 5

Slide 5 text

CI / CD Developer Code Repository Continuous Integration Container Registry kubectl / helm Push Build & Test Publish D eploy R un Icons: CC BY 3.0 Where is your state? What’s your MTTR in case of a complete outage? Why does your CI system has access to the cluster?

Slide 6

Slide 6 text

The single source of truth

Slide 7

Slide 7 text

The entire system is described declaratively Icons: CC BY 3.0

Slide 8

Slide 8 text

The canonical desired system state is versioned in Git Icons: CC BY 3.0

Slide 9

Slide 9 text

Approved changes to the desired state are automatically applied to the system Icons: CC BY 3.0

Slide 10

Slide 10 text

Software agents ensure correctness and alert on divergence Icons: CC BY 3.0

Slide 11

Slide 11 text

GitOps Compatibility State Repository Declaratively Automatic Rollouts Notifications Keel https://keel.sh Can be activated only via annotations No Exposes Webhooks to trigger deployment Slack, HipChat, etc. ArgoCD https://argoproj.github.io/ Relies on Helm, Ksonnet, Kubernetes, etc. State is held in the application Updates have to triggered manually through UI No Flux CD https://www.fluxcd.io/ Relies on Kubernetes, CRD for Helm Charts, Integrations available Yes Compares current state and desired state and triggers deployment Yes, via Fluxcloud Icons: CC BY 3.0

Slide 12

Slide 12 text

Flux CD GitOps in Practice

Slide 13

Slide 13 text

Developer Code Repository Continuous Integration Container Registry Ops State Repository State Sync Deployment Sync Icons: CC BY 3.0 CI / CD with GitOps Push Build & Test Publish Update Pull Watch / Download Notify

Slide 14

Slide 14 text

Developer Code Repository Continuous Integration Container Registry Ops State Repository State Sync Deployment Sync Icons: CC BY 3.0 CI / CD with GitOps Push Build & Test Publish Update Pull Watch / Download Notify

Slide 15

Slide 15 text

Developer Code Repository Continuous Integration Container Registry Ops State Repository State Sync Deployment Sync Icons: CC BY 3.0 CI / CD with GitOps Push Build & Test Publish Update Pull Watch / Download Notify

Slide 16

Slide 16 text

Workflow Push Code to Code Repository Push the code the Code Repository and follow usual workflow with PRs and Reviews. Build & Test Build the Code and execute the Unit and Integration Tests. Publish Publish the Docker Image to the Container Registry. Optionally the Helm Chart can be published to a Chart Museum. Notify or create PR directly Optionally notify Ops about the new version, so they can roll-out the application Push State changes Push the state changes to the State Repository and follow the usual workflow with PRs and Reviews. Sync State Watch the State Repository and sync on changes. Download Images and Deploy Download the new Docker Image and run the deployment Developer Operations

Slide 17

Slide 17 text

Developer Code Repository Continuous Integration Container Registry Ops State Repository State Sync Deployment Sync Icons: CC BY 3.0 CI / CD with GitOps Push Build & Test Publish Update Pull Watch / Download Notify

Slide 18

Slide 18 text

Workflow Watch the Container Registry Watch the Container Registry for newer versions and optionally download the new images. Update State Update the state definition to match the image version. Automatic

Slide 19

Slide 19 text

Automation Deployments are always executed when state repository is updated Automation is activated by annotations: flux.weave.works/automated: "true" Supports SemVer, RegEx and Glob Patterns: flux.weave.works/tag.fluxcloud: semver:^0.34.0 flux.weave.works/tag.fluxcloud: glob:0.34.* flux.weave.works/tag.fluxcloud: regex:dev-.*

Slide 20

Slide 20 text

Installation helm repo add fluxcd https://charts.fluxcd.io helm upgrade -i flux \ --set helmOperator.create=true \ --set helmOperator.createCRD=true \ --set [email protected]:wbiller/state-repository \ --set git.path=development \ --set git.branch=master \ --namespace flux \ fluxcd/flux fluxctl identity --k8s-fwd-ns flux

Slide 21

Slide 21 text

Custom Resources HelmRelease (Chart) spec: chart: repository: # Chart Museum URL name: # Chart name version: # Chart version releaseName: # Name to use for release values: # Overwrites for chart variables valuesFrom: # Sources for overwrites configMapKeyRef: name: key: optional: secretKeyRef: name: key: optional: externalSourceRef: url: optional: HelmRelease (Git) spec: chart: git: # Repository URL path: # Path to chart branch: # Branch to use releaseName: # Name to use for release values: # Overwrites for chart variables valuesFrom: # Sources for overwrites configMapKeyRef: name: key: optional: secretKeyRef: name: key: optional: externalSourceRef: url: optional:

Slide 22

Slide 22 text

Helm Charts apiVersion: flux.weave.works/v1beta1 kind: HelmRelease metadata: name: nginx-ingress spec: chart: repository: https://kubernetes-charts.storage.googleapis.com/ name: nginx-ingress version: 1.24.3 releaseName: nginx-ingress values: controller: config: server-tokens: "false" use-forwarded-headers: "true"

Slide 23

Slide 23 text

Separate Repositories preview production

Slide 24

Slide 24 text

Separate Branches master preview production

Slide 25

Slide 25 text

preview production Separate Directories development

Slide 26

Slide 26 text

Directory Structure . ├── README.md ├── common │ ├── cert-manager-issuers-crd.yaml │ ├── letsencrypt-prod-ClusterIssuer.yaml │ ├── monitoring │ │ ├── prometheus-HelmRelease.yaml │ │ └── prometheus-operator-HelmRelease.yaml │ ├── monitoring-ns.yaml │ ├── ext-system │ │ ├── cert-manager-HelmRelease.yaml │ │ ├── flux-HelmRelease.yaml │ │ ├── nginx-ingress-HelmRelease.yaml │ └── ext-system-ns.yaml ├── dev │ ├── application │ │ └── application-HelmRelease.yaml └── test └── application └── application-HelmRelease.yaml

Slide 27

Slide 27 text

Manifest factorization Integration with Kustomize to patch base definitions for specific targets/envs Requires additional parameters for fluxd apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: webapp namespace: webapp spec: rules: - host: dev.example.com http: paths: - backend: serviceName: webapp servicePort: 80 path: / namespace: webapp bases: - ../base patchesStrategicMerge: - ingress.yaml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: webapp namespace: webapp spec: rules: - host: www.example.com http: paths: - backend: serviceName: webapp servicePort: 80 path: /app base/ingress.yaml prod/kustomization.yaml prod/ingress.yaml

Slide 28

Slide 28 text

Multiple Environments path: common, preview path: common, production State Repository Preview Production

Slide 29

Slide 29 text

Blue/Green Migrations State Repository branch: production branch: production-new

Slide 30

Slide 30 text

Co-Located Cluster Europe Americas State Repository path: common, production path: common, production

Slide 31

Slide 31 text

Manage Clusters with GitOps Cluster API allows creation of new clusters from within Kubernetes Custom Resource Definitions for Clusters, Machines and Kubeadm Config Current list of implementations: AWS, Azure, GCP, Bare Metal, OpenStack, etc. See https://cluster-api.sigs.k8s.io/user/quick-start.html

Slide 32

Slide 32 text

State Repository Management Cluster New Cluster Read cluster definition Read desired state Deploy cluster Cluster Management

Slide 33

Slide 33 text

Sealed Secrets Prevent leaking clear text secrets into version control Provides certificate that’s created inside the cluster Secrets are encrypted using the certificate and decrypted in the cluster Provides a kubeseal CLI Create a intermediate secret in JSON kubectl -n ext-system create secret generic token --from-literal=token=token --dry-run -o json > token.json Encrypt the secret kubeseal --controller-namespace=ext-system --controller-name=sealed-secrets \ --format=yaml < token.json > token-sealedsecret.yaml

Slide 34

Slide 34 text

Thank you! Waldemar Biller Email: [email protected] Twitter: @wbiller