SlideShare a Scribd company logo
From GitOps to an adaptable
CI/CD pattern for Kubernetes
Andrew Phillips
Continuous Delivery : NYC; Nov 1, 2018
From GitOps to an adaptable
CI/CD pattern...for everything?
Andrew Phillips
Continuous Delivery : NYC; Nov 1, 2018
The bio slide
● Been on most sides of this space: developer, infra builder, product owner,
evangelist and more
● Long-standing open-source contributor
● Author and regular conference and meetup presenter
● Co-organizer of ContainerDays Boston & NYC
Agenda
1. What’s the challenge?
2. CI/CD practices & patterns today
3. What does Kubernetes add into the mix?
4. A CI/CD pipeline for Kubernetes
5. Next steps for your scenario
6. Q&A
1. The context
● Lots of organizations looking at Kubernetes right now
● Trying to use this also as an opportunity to “clean up” sub-optimal software
delivery pipelines
● How to do this right?
1. The challenge
● Lots of new runtime-specific concepts to deal with
● “Kubernetes-native” best practices still very much in flux
● Wrapping your head around “new” practices (e.g. GitOps) is hard
● Extrapolating from new practices in theory to actual, working implementations
is even harder
● Figuring out how all this new stuff relates to accepted industry practices and
tools is harder still
Failure mode: CCAOA
Cargo Cult All Over Again
1. The approach
● Recall good practices that we’d like to retain
● Incorporate refinements related to Kubernetes to create a straw man setup
● Develop a mental model to understand advantages and shortfalls of the setup
● Refine the setup based on tradeoffs to be made related to each user’s
particular situation
● Implement using appropriate tools
2. Existing good practice
● Reproducible builds
● Store source and derived artifacts appropriately
● Minimize duplication, especially around environment config
● Keep the business process flexible and the env automation robust
● Support 4 related processes:
○ Application update
○ Environment (config) update
○ Environment spin-up/restore
○ Environment drift detection and remediation
● Specifically, support env-specific (e.g. log settings change) and cross-env
(e.g. new app version rollout) processes concisely
Deployment execution: business process vs. technical process
Release pipeline A business process, represented as a sequence, possibly very specific to a service
Test environment Staging environment
Technical components with
interdependencies, defined
“as-code”. To be
automatically sequenced if
possible
Production environment
Deploy to Test Review Approve Deploy to Prod...
App
Endpoint
Config
App
Endpoint
Config’
Old app version
Namespace
2. The four related processes
● Application update
○ “I want to validate a new release candidate and promote it through envs to prod”
● Environment (config) update
○ “I want to change the attributes of a particular env only”
● Environment spin-up/restore
○ “I want to (re-)create an environment from scratch, with config from a specific checkpoint/point
in time”
● Environment diff, drift detection and remediation
○ “I want to understand how the actual config of an env relates to the intended config, also
potentially across different environments”
3. What’s new with Kubernetes
● “as-code” description of what an environment should look like
(“environments-as-code”)
● Actuation based on reconciliation engine built into runtime with continuous
enforcement
○ Interest in “pull-based”, async invocation via repo-watching
● Out-of-the-box support for some types of rollout via Deployment object, as
well as CRDs to define your own
○ But can also manipulate underlying objects directly
● GitOps ~ environments-as-code + async invocation + repo workflow for
business process
Deployment execution: adding in Kubernetes
Release pipeline A business process, represented as a sequence, possibly very specific to a service
Test environment Staging environment
Technical components with
interdependencies, defined
“as-code”. To be
automatically sequenced if
possible
Production environment
“environments-as-code” repositories
Deploy to Test Review Approve Deploy to Prod...
App
Endpoint
Config
App
Endpoint
Config’
Old app version
Namespace
TL;DR
Release pipeline A business process, represented as a sequence, possibly very specific to a service
Test environment Staging environment
Technical components with
interdependencies, defined
“as-code”. To be
automatically sequenced if
possible
Production environment
“environments-as-code” repositories
Deploy to Test Review Approve Deploy to Prod...
App
Endpoint
Config
App
Endpoint
Config’
Old app version
Namespace
Imperative pipeline across environments
Declarative spec for each environment
(with support for some imperative “cheating” where necessary)
3. The straw man
team1-repo
env-repo
applied-staging-branch applied-prod-branch
master-
branch
service
config
staging-
branch
deployme
nt
prod-
branch
deployme
nt
team2-repo
master-
branch
custom-s
ettings
staging-
branch
config
prod-
branch
config
App1 update
team1-repo
env-repo
applied-staging-branch applied-prod-branch
master-
branch
service
config
staging-
branch
deployme
nt
prod-
branch
deployme
nt
team2-repo
master-
branch
custom-s
ettings
staging-
branch
config
prod-bra
nch
config
apiVersion: v1
kind: Service
metadata:
name: app1-service
...
spec:
type: ClusterIP
ports:
- port: 808080
targetPort: http
protocol: TCP
name: http
selector:
app: app1
env: {{ environment }}
team1-repo
env-repo
applied-staging-branch
app1.yaml
applied-prod-branch
master-
branch
service
config
staging-
branch
deployme
nt
prod-
branch
deployme
nt
team2-repo
master-
branch
custom-s
ettings
staging-
branch
config
prod-bra
nch
config
apiVersion: v1
kind: Service
metadata:
name: app1-service
...
spec:
type: ClusterIP
ports:
- port: 808080
targetPort: http
protocol: TCP
name: http
selector:
app: app1
env: {{ environment }}
Step 1
apiVersion: v1
kind: Service
metadata:
name: app1-service
...
spec:
type: ClusterIP
ports:
- port: 8080
targetPort: http
protocol: TCP
name: http
selector:
app: app1
env: staging
---
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: app1
namespace: staging
...
---
apiVersion: v1
kind: ConfigMap
...
team1-repo
env-repo
applied-staging-branch
app1.yaml
applied-prod-branch
app1.yaml
master-
branch
service
config
staging-
branch
deployme
nt
prod-
branch
deployme
nt
team2-repo
master-
branch
custom-s
ettings
staging-
branch
config
prod-bra
nch
config
apiVersion: v1
kind: Service
metadata:
name: app1-service
...
spec:
type: ClusterIP
ports:
- port: 808080
targetPort: http
protocol: TCP
name: http
selector:
app: app1
env: {{ environment }}
Step 2
apiVersion: v1
kind: Service
metadata:
name: app1-service
...
spec:
type: ClusterIP
ports:
- port: 8080
targetPort: http
protocol: TCP
name: http
selector:
app: app1
env: production
---
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: app1
namespace: production
...
---
apiVersion: v1
kind: ConfigMap
...
App2 update
team1-repo
env-repo
applied-staging-branch
app1.yaml
applied-prod-branch
app1.yaml
master-
branch
service
config
staging-
branch
deployme
nt
prod-
branch
deployme
nt
team2-repo
master-
branch
custom-s
ettings
staging-
branch
config
prod-
branch
config
app.version: 0.0.34
port: 8090
image: gcr.io/image@sha256:{{
container.image.digest }}
team1-repo
env-repo
applied-staging-branch
app1.yaml
app2.yaml
app2-env.yaml
applied-prod-branch
app1.yaml
master-
branch
service
config
staging-
branch
deployme
nt
prod-
branch
deployme
nt
team2-repo
master-
branch
custom-s
ettings
staging-
branch
config
prod-
branch
config
Step 1app.version: 0.0.34
port: 8090
image: gcr.io/image@sha256:{{
container.image.digest }}
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: app2
namespace: staging
...
spec:
replicas: 1
...
image:
gcr.io/image@sha256:abcdef
ports:
- name: http
containerPort: 90
---
...
---
apiVersion: v1
kind: ConfigMap
...
data:
config.yaml: |
'app.version': 0.0.4
team1-repo
env-repo
applied-staging-branch
app1.yaml
app2.yaml
app2-env.yaml
applied-prod-branch
app1.yaml
app2.yaml
app2-env.yaml
master-
branch
service
config
staging-
branch
deployme
nt
prod-
branch
deployme
nt
team2-repo
master-
branch
custom-s
ettings
staging-
branch
config
prod-
branch
config
Step 2
app.version: 0.0.34
port: 8090
image: gcr.io/image@sha256:{{
container.image.digest }}
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: app2
namespace: production
...
spec:
replicas: 1
...
image:
gcr.io/image@sha256:abcdef
ports:
- name: http
containerPort: 90
---
...
---
apiVersion: v1
kind: ConfigMap
...
data:
config.yaml: |
'app.version': 0.0.4
App2 prod config change
team1-repo
env-repo
applied-staging-branch
app1.yaml
app2.yaml
app2-env.yaml
applied-prod-branch
app1.yaml
app2.yaml
app2-env.yaml
master-
branch
service
config
staging-
branch
deployme
nt
prod-
branch
deployme
nt
team2-repo
master-
branch
custom-s
ettings
staging-
branch
config
prod-
branch
config
apiVersion: v1
kind: ConfigMap
metadata:
name: app2-env-config
namespace: production
labels:
app: app2
env: production
data:
config.yaml: |
'log.level': INFOTRACE
team1-repo
env-repo
applied-staging-branch
app1.yaml
app2.yaml
app2-env.yaml
applied-prod-branch
app1.yaml
app2.yaml
app2-env.yaml
master-
branch
service
config
staging-
branch
deployme
nt
prod-
branch
deployme
nt
team2-repo
master-
branch
custom-s
ettings
staging-
branch
config
prod-
branch
config
Step 1
apiVersion: v1
kind: ConfigMap
metadata:
name: app2-env-config
namespace: production
labels:
app: app2
env: production
data:
config.yaml: |
'log.level': INFOTRACE
apiVersion: v1
kind: ConfigMap
metadata:
name: app2-env-config
namespace: production
labels:
app: app2
env: production
data:
config.yaml: |
'log.level': TRACE
3. The straw man
● Source config in app repo, “compiled” (a.k.a. hydrated) config in env repo(s)
○ Cf. source code in app repo, compiled code in artifact repository
● One app repo per app/team, shared env repos for environments
● Use branches where possible to represent different environments
○ If greater separation via access control is needed, use different repos or consider other
storage
● Keep config in app repo unless it needs to be independent of the app lifecycle
or you really, really need to be able to change it for one env
○ Allows you to use templating/overriding to cut down on duplication
○ The fewer places to keep track of config, the better
● Source config doesn’t have to be “raw” YAML, can be more suitable
abstraction!
○ Cf. higher-level language source code vs. low-level assembly code
3. The straw man
● Prefer explicit invocation over “repo-watching”
○ Avoids “root-level” process running inside cluster, and provides more flexibility for
multi-step rollouts
○ “Repo-watching” makes visualizing current status harder, and requires some sort of
feedback mechanism to distinguish successful from failed deployments in the repo
○ Hard to support phased/multi-step application
○ Easier to reproduce/simulate
3. The straw man
● Prefer explicit invocation over “repo-watching”
○ Avoids “root-level” process running inside cluster, and provides more flexibility for
multi-step rollouts
○ “Repo-watching” makes visualizing current status harder, and requires some sort of
feedback mechanism to distinguish successful from failed deployments in the repo
○ Hard to support phased/multi-step application
○ Easier to reproduce/simulate
● Commit after successful application, not before
○ Avoids having to distinguish attempted from successful deployments in the repo
○ Allows for richer pre-application validation than code diff in a PR (e.g. three-way diff
against actual environment)
○ Avoids commit rights to repo being equivalent to deploy rights to env (and your
automation will need commit rights to make pull requests, unless you used forked repos)
○ Harder if pull requests are used for the business process (as in vanilla GitOps) - requires
multiple branches or “on approve” deployment
4. The mental model
● Understand how your app is updated across two dimensions:
● code change promoted through to
prod
● common externalized config setting,
e.g. localized title
dependent on app version
independent
of
environment
4. The mental model
● Understand how your app is updated across two dimensions:
● code change promoted through to
prod
● common externalized config setting,
e.g. localized title
● adding debug logging to staging
● configuring a scaling policy in prod
based on a new metric
dependent on app version
independent
of
environment
dependent
on
environment
4. The mental model
● Understand how your app is updated across two dimensions:
● code change promoted through to
prod
● common externalized config setting,
e.g. localized title ● rotating database credentials for
prod
● updating discovery service
endpoint
● adding debug logging to staging
● configuring a scaling policy in prod
based on a new metric
dependent on app version
independent
of
environment
dependent
on
environment
independent of app version
4. The mental model
● Understand how your app is updated across two dimensions:
Application update
Static environment config
update
(App-linked) environment config
update
dependent on app version
independent
of
environment
dependent
on
environment
independent of app version
4. The mental model
● Understand how your app is updated across two dimensions:
Application update
Static environment config update
(App-linked) environment config
update
dev responsibility ~ app repo platform responsibility ~ env repo
4. The mental model
1. Application update
a. “I want to validate a new release candidate and promote it through envs to prod”
2. Environment (config) update
a. “I want to change the attributes of a particular env only”
3. Environment spin-up/restore
a. “I want to (re-)create an environment from scratch, with config from a specific checkpoint/point
in time”
4. Environment diff, drift detection and remediation
a. “I want to understand how the actual config of an env relates to the intended config, also
potentially across different environments”
● App repo is driving deployment, env repo is snapshotting cluster state
○ Think source code in github is to docker image in registry as template in app repo is to
manifest in env repo
● Env repo is just a checkpoint in time, cluster can evolve
○ Kubernetes applies changes to manifests
○ Strategies like exponential rollouts or traffic shifting apply changes over time
● Env repo is not a guaranteed healthy state
○ We can defer snapshotting until some health/success metric… but rollback has no silver bullet
● Deletion from either repo ≠ deletion from cluster
○ Challenge is: not trivial to know if cluster depends, or will depend on manifest not submitted to
repo
○ kubectl apply --prune attempts to solve this with a lot of (scary) caveats
4. The mental model
5. Tuning for your scenario
● Appropriate level of abstraction? How much “raw” Kubernetes YAML
should our developers have access to?
● Where should the abstraction live? In templates? In CRDs? In the
automation tool?
● What to use for templating? Token replacement or overrides?
● When do you snapshot/publish to the env repo? On every change to the
cluster? Or when a desired end-state is reached? (think multi-step rollout)
● Access control: how many repos do you need? Are code repositories right
for your use case, or e.g. a blobstore better?
● Am I distributing or deploying? Helm is much better suited for distribution
than deployment
○ Its templating capability is often used as part of deployment flows, though
5. Implement
● Choose storage implementations and partitioning strategies for your
environments-as-code
● Define the appropriate level of abstraction for your developers and choose
tools to support it
● Choose a flexible automation tool for your deployment business process
● Define an appropriate definition of deployment health/success to determine
when a deployment is “good”
● Decide which of the four processes - app update, env config update, env
restore and env drift detection - you want to support
● Build pipelines
● Done!

More Related Content

What's hot (20)

PDF
Continuous Security for GitOps
Weaveworks
 
PDF
GitOps: Git come unica fonte di verità per applicazioni e infrastruttura
sparkfabrik
 
PDF
Gitops Hands On
Brice Fernandes
 
PDF
The journey to GitOps
Nicola Baldi
 
PPTX
GitOps - Modern best practices for high velocity app dev using cloud native t...
Weaveworks
 
PDF
Flagger: Istio Progressive Delivery Operator
Weaveworks
 
PDF
Kubernetes GitOps featuring GitHub, Kustomize and ArgoCD
Sunnyvale
 
PDF
Openshift argo cd_v1_2
RastinKenarsari
 
PDF
Gitops: the kubernetes way
sparkfabrik
 
PDF
GitOps Toolkit (Cloud Native Nordics Tech Talk)
Weaveworks
 
PDF
The Power of GitOps with Flux & GitOps Toolkit
Weaveworks
 
PDF
Cloud Technical Challenges
Guy Coates
 
PDF
Gitops: a new paradigm for software defined operations
Mariano Cunietti
 
PDF
A GitOps Kubernetes Native CICD Solution with Argo Events, Workflows, and CD
Julian Mazzitelli
 
PDF
Gitlab ci, cncf.sk
Juraj Hantak
 
PDF
GitOps with ArgoCD
CloudOps2005
 
PDF
Intro to Kubernetes & GitOps Workshop
Weaveworks
 
PDF
Introducing GitLab
Taisuke Inoue
 
PPTX
Git & GitLab
Gaurav Wable
 
PDF
DevOps: The Future of Software Development
Opsta
 
Continuous Security for GitOps
Weaveworks
 
GitOps: Git come unica fonte di verità per applicazioni e infrastruttura
sparkfabrik
 
Gitops Hands On
Brice Fernandes
 
The journey to GitOps
Nicola Baldi
 
GitOps - Modern best practices for high velocity app dev using cloud native t...
Weaveworks
 
Flagger: Istio Progressive Delivery Operator
Weaveworks
 
Kubernetes GitOps featuring GitHub, Kustomize and ArgoCD
Sunnyvale
 
Openshift argo cd_v1_2
RastinKenarsari
 
Gitops: the kubernetes way
sparkfabrik
 
GitOps Toolkit (Cloud Native Nordics Tech Talk)
Weaveworks
 
The Power of GitOps with Flux & GitOps Toolkit
Weaveworks
 
Cloud Technical Challenges
Guy Coates
 
Gitops: a new paradigm for software defined operations
Mariano Cunietti
 
A GitOps Kubernetes Native CICD Solution with Argo Events, Workflows, and CD
Julian Mazzitelli
 
Gitlab ci, cncf.sk
Juraj Hantak
 
GitOps with ArgoCD
CloudOps2005
 
Intro to Kubernetes & GitOps Workshop
Weaveworks
 
Introducing GitLab
Taisuke Inoue
 
Git & GitLab
Gaurav Wable
 
DevOps: The Future of Software Development
Opsta
 

Similar to Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubernetes (20)

PDF
Spinnaker Summit 2018: CI/CD Patterns for Kubernetes with Spinnaker
Andrew Phillips
 
PPTX
Cloud Native Transformation (Alexis Richardson) - Continuous Lifecycle 2018 ...
Weaveworks
 
PDF
Promise of DevOps
Juraj Hantak
 
PDF
GitOps 101 Presentation.pdf
ssuser31375f
 
PPTX
OpenNfv Talk On Kubernetes and Network Function Virtualization
Glenn West
 
PPTX
Everything as Code with Azure DevOps
Venura Athukorala
 
PPTX
Devops CI-CD pipeline with Containers
NuSpace
 
PDF
GitOps and Kubernetes 1st Edition Billy Yuen Alexander Matyushentsev Jesse Su...
alanebrodixm
 
PDF
GitOps and Kubernetes 1st Edition Billy Yuen Alexander Matyushentsev Jesse Su...
ptrkbxhxe670
 
PDF
GitOps is the best modern practice for CD with Kubernetes
Volodymyr Shynkar
 
PDF
The Self-Service Developer - GOTOCon CPH
Laszlo Fogas
 
PDF
PDF GitOps Cookbook (Third Early Release) Natale Vinto download
xamysakuchuk
 
PDF
Kubernetes + Jenkins X: a Cloud Native Approach
Thessaloniki Software Testing and QA meetup
 
PDF
Gitops Cookbook Second Early Release Natale Vinto Alex Soto Bueno
rockesakkay
 
PPTX
"Modern DevOps & Real Life Applications. 3.0.0-devops+20230318", Igor Fesenko
Fwdays
 
PDF
Rise of the machines: Continuous Delivery at SEEK - YOW! Night Summary Slides
DiUS
 
PDF
Free GitOps Workshop
Weaveworks
 
PDF
Continuous Delivery: 5 years later (Incontro DevOps 2018)
Giovanni Toraldo
 
PPTX
Devops
Aravindan A
 
PDF
Dipping Your Toes Into Cloud Native Application Development
Matthew Farina
 
Spinnaker Summit 2018: CI/CD Patterns for Kubernetes with Spinnaker
Andrew Phillips
 
Cloud Native Transformation (Alexis Richardson) - Continuous Lifecycle 2018 ...
Weaveworks
 
Promise of DevOps
Juraj Hantak
 
GitOps 101 Presentation.pdf
ssuser31375f
 
OpenNfv Talk On Kubernetes and Network Function Virtualization
Glenn West
 
Everything as Code with Azure DevOps
Venura Athukorala
 
Devops CI-CD pipeline with Containers
NuSpace
 
GitOps and Kubernetes 1st Edition Billy Yuen Alexander Matyushentsev Jesse Su...
alanebrodixm
 
GitOps and Kubernetes 1st Edition Billy Yuen Alexander Matyushentsev Jesse Su...
ptrkbxhxe670
 
GitOps is the best modern practice for CD with Kubernetes
Volodymyr Shynkar
 
The Self-Service Developer - GOTOCon CPH
Laszlo Fogas
 
PDF GitOps Cookbook (Third Early Release) Natale Vinto download
xamysakuchuk
 
Kubernetes + Jenkins X: a Cloud Native Approach
Thessaloniki Software Testing and QA meetup
 
Gitops Cookbook Second Early Release Natale Vinto Alex Soto Bueno
rockesakkay
 
"Modern DevOps & Real Life Applications. 3.0.0-devops+20230318", Igor Fesenko
Fwdays
 
Rise of the machines: Continuous Delivery at SEEK - YOW! Night Summary Slides
DiUS
 
Free GitOps Workshop
Weaveworks
 
Continuous Delivery: 5 years later (Incontro DevOps 2018)
Giovanni Toraldo
 
Devops
Aravindan A
 
Dipping Your Toes Into Cloud Native Application Development
Matthew Farina
 
Ad

More from Andrew Phillips (12)

PDF
Spinnaker Summit 2019: Where are we heading? The Future of Continuous Delivery
Andrew Phillips
 
PDF
OpenDev 2018: "Open CD for Open Infrastructure - Hybrid and Multi-Cloud Deplo...
Andrew Phillips
 
PDF
New York Kubernetes: CI/CD Patterns for Kubernetes
Andrew Phillips
 
PDF
nycdevops: "Breaking Down the Prod/Dev Wall"
Andrew Phillips
 
PDF
Metrics-driven Continuous Delivery
Andrew Phillips
 
PPTX
BASE Meetup: "Analysing Scala Puzzlers: Essential and Accidental Complexity i...
Andrew Phillips
 
PPTX
Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexit...
Andrew Phillips
 
PPTX
The Multiple Dimensions of Cross-Cloud Computing
Andrew Phillips
 
PDF
Implementing Continuous Deployment
Andrew Phillips
 
PDF
Know your cirrus from your cumulus (with notes)
Andrew Phillips
 
PDF
Know your cirrus from your cumulus
Andrew Phillips
 
PDF
Deployment is the new build
Andrew Phillips
 
Spinnaker Summit 2019: Where are we heading? The Future of Continuous Delivery
Andrew Phillips
 
OpenDev 2018: "Open CD for Open Infrastructure - Hybrid and Multi-Cloud Deplo...
Andrew Phillips
 
New York Kubernetes: CI/CD Patterns for Kubernetes
Andrew Phillips
 
nycdevops: "Breaking Down the Prod/Dev Wall"
Andrew Phillips
 
Metrics-driven Continuous Delivery
Andrew Phillips
 
BASE Meetup: "Analysing Scala Puzzlers: Essential and Accidental Complexity i...
Andrew Phillips
 
Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexit...
Andrew Phillips
 
The Multiple Dimensions of Cross-Cloud Computing
Andrew Phillips
 
Implementing Continuous Deployment
Andrew Phillips
 
Know your cirrus from your cumulus (with notes)
Andrew Phillips
 
Know your cirrus from your cumulus
Andrew Phillips
 
Deployment is the new build
Andrew Phillips
 
Ad

Recently uploaded (20)

PDF
NLJUG Speaker academy 2025 - first session
Bert Jan Schrijver
 
PDF
SIZING YOUR AIR CONDITIONER---A PRACTICAL GUIDE.pdf
Muhammad Rizwan Akram
 
PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PDF
Staying Human in a Machine- Accelerated World
Catalin Jora
 
PDF
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
 
PPTX
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
PDF
CIFDAQ Market Wrap for the week of 4th July 2025
CIFDAQ
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PDF
Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
PDF
UPDF - AI PDF Editor & Converter Key Features
DealFuel
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
PDF
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
PDF
“Voice Interfaces on a Budget: Building Real-time Speech Recognition on Low-c...
Edge AI and Vision Alliance
 
PPTX
Agentforce World Tour Toronto '25 - MCP with MuleSoft
Alexandra N. Martinez
 
PDF
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PDF
How do you fast track Agentic automation use cases discovery?
DianaGray10
 
PDF
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
PDF
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
PDF
Transforming Utility Networks: Large-scale Data Migrations with FME
Safe Software
 
NLJUG Speaker academy 2025 - first session
Bert Jan Schrijver
 
SIZING YOUR AIR CONDITIONER---A PRACTICAL GUIDE.pdf
Muhammad Rizwan Akram
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
Staying Human in a Machine- Accelerated World
Catalin Jora
 
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
 
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
CIFDAQ Market Wrap for the week of 4th July 2025
CIFDAQ
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
UPDF - AI PDF Editor & Converter Key Features
DealFuel
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
“Voice Interfaces on a Budget: Building Real-time Speech Recognition on Low-c...
Edge AI and Vision Alliance
 
Agentforce World Tour Toronto '25 - MCP with MuleSoft
Alexandra N. Martinez
 
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
How do you fast track Agentic automation use cases discovery?
DianaGray10
 
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
Transforming Utility Networks: Large-scale Data Migrations with FME
Safe Software
 

Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubernetes

  • 1. From GitOps to an adaptable CI/CD pattern for Kubernetes Andrew Phillips Continuous Delivery : NYC; Nov 1, 2018
  • 2. From GitOps to an adaptable CI/CD pattern...for everything? Andrew Phillips Continuous Delivery : NYC; Nov 1, 2018
  • 3. The bio slide ● Been on most sides of this space: developer, infra builder, product owner, evangelist and more ● Long-standing open-source contributor ● Author and regular conference and meetup presenter ● Co-organizer of ContainerDays Boston & NYC
  • 4. Agenda 1. What’s the challenge? 2. CI/CD practices & patterns today 3. What does Kubernetes add into the mix? 4. A CI/CD pipeline for Kubernetes 5. Next steps for your scenario 6. Q&A
  • 5. 1. The context ● Lots of organizations looking at Kubernetes right now ● Trying to use this also as an opportunity to “clean up” sub-optimal software delivery pipelines ● How to do this right?
  • 6. 1. The challenge ● Lots of new runtime-specific concepts to deal with ● “Kubernetes-native” best practices still very much in flux ● Wrapping your head around “new” practices (e.g. GitOps) is hard ● Extrapolating from new practices in theory to actual, working implementations is even harder ● Figuring out how all this new stuff relates to accepted industry practices and tools is harder still
  • 7. Failure mode: CCAOA Cargo Cult All Over Again
  • 8. 1. The approach ● Recall good practices that we’d like to retain ● Incorporate refinements related to Kubernetes to create a straw man setup ● Develop a mental model to understand advantages and shortfalls of the setup ● Refine the setup based on tradeoffs to be made related to each user’s particular situation ● Implement using appropriate tools
  • 9. 2. Existing good practice ● Reproducible builds ● Store source and derived artifacts appropriately ● Minimize duplication, especially around environment config ● Keep the business process flexible and the env automation robust ● Support 4 related processes: ○ Application update ○ Environment (config) update ○ Environment spin-up/restore ○ Environment drift detection and remediation ● Specifically, support env-specific (e.g. log settings change) and cross-env (e.g. new app version rollout) processes concisely
  • 10. Deployment execution: business process vs. technical process Release pipeline A business process, represented as a sequence, possibly very specific to a service Test environment Staging environment Technical components with interdependencies, defined “as-code”. To be automatically sequenced if possible Production environment Deploy to Test Review Approve Deploy to Prod... App Endpoint Config App Endpoint Config’ Old app version Namespace
  • 11. 2. The four related processes ● Application update ○ “I want to validate a new release candidate and promote it through envs to prod” ● Environment (config) update ○ “I want to change the attributes of a particular env only” ● Environment spin-up/restore ○ “I want to (re-)create an environment from scratch, with config from a specific checkpoint/point in time” ● Environment diff, drift detection and remediation ○ “I want to understand how the actual config of an env relates to the intended config, also potentially across different environments”
  • 12. 3. What’s new with Kubernetes ● “as-code” description of what an environment should look like (“environments-as-code”) ● Actuation based on reconciliation engine built into runtime with continuous enforcement ○ Interest in “pull-based”, async invocation via repo-watching ● Out-of-the-box support for some types of rollout via Deployment object, as well as CRDs to define your own ○ But can also manipulate underlying objects directly ● GitOps ~ environments-as-code + async invocation + repo workflow for business process
  • 13. Deployment execution: adding in Kubernetes Release pipeline A business process, represented as a sequence, possibly very specific to a service Test environment Staging environment Technical components with interdependencies, defined “as-code”. To be automatically sequenced if possible Production environment “environments-as-code” repositories Deploy to Test Review Approve Deploy to Prod... App Endpoint Config App Endpoint Config’ Old app version Namespace
  • 14. TL;DR Release pipeline A business process, represented as a sequence, possibly very specific to a service Test environment Staging environment Technical components with interdependencies, defined “as-code”. To be automatically sequenced if possible Production environment “environments-as-code” repositories Deploy to Test Review Approve Deploy to Prod... App Endpoint Config App Endpoint Config’ Old app version Namespace Imperative pipeline across environments Declarative spec for each environment (with support for some imperative “cheating” where necessary)
  • 18. team1-repo env-repo applied-staging-branch applied-prod-branch master- branch service config staging- branch deployme nt prod- branch deployme nt team2-repo master- branch custom-s ettings staging- branch config prod-bra nch config apiVersion: v1 kind: Service metadata: name: app1-service ... spec: type: ClusterIP ports: - port: 808080 targetPort: http protocol: TCP name: http selector: app: app1 env: {{ environment }}
  • 19. team1-repo env-repo applied-staging-branch app1.yaml applied-prod-branch master- branch service config staging- branch deployme nt prod- branch deployme nt team2-repo master- branch custom-s ettings staging- branch config prod-bra nch config apiVersion: v1 kind: Service metadata: name: app1-service ... spec: type: ClusterIP ports: - port: 808080 targetPort: http protocol: TCP name: http selector: app: app1 env: {{ environment }} Step 1 apiVersion: v1 kind: Service metadata: name: app1-service ... spec: type: ClusterIP ports: - port: 8080 targetPort: http protocol: TCP name: http selector: app: app1 env: staging --- apiVersion: apps/v1beta2 kind: Deployment metadata: name: app1 namespace: staging ... --- apiVersion: v1 kind: ConfigMap ...
  • 20. team1-repo env-repo applied-staging-branch app1.yaml applied-prod-branch app1.yaml master- branch service config staging- branch deployme nt prod- branch deployme nt team2-repo master- branch custom-s ettings staging- branch config prod-bra nch config apiVersion: v1 kind: Service metadata: name: app1-service ... spec: type: ClusterIP ports: - port: 808080 targetPort: http protocol: TCP name: http selector: app: app1 env: {{ environment }} Step 2 apiVersion: v1 kind: Service metadata: name: app1-service ... spec: type: ClusterIP ports: - port: 8080 targetPort: http protocol: TCP name: http selector: app: app1 env: production --- apiVersion: apps/v1beta2 kind: Deployment metadata: name: app1 namespace: production ... --- apiVersion: v1 kind: ConfigMap ...
  • 23. team1-repo env-repo applied-staging-branch app1.yaml app2.yaml app2-env.yaml applied-prod-branch app1.yaml master- branch service config staging- branch deployme nt prod- branch deployme nt team2-repo master- branch custom-s ettings staging- branch config prod- branch config Step 1app.version: 0.0.34 port: 8090 image: gcr.io/image@sha256:{{ container.image.digest }} apiVersion: apps/v1beta2 kind: Deployment metadata: name: app2 namespace: staging ... spec: replicas: 1 ... image: gcr.io/image@sha256:abcdef ports: - name: http containerPort: 90 --- ... --- apiVersion: v1 kind: ConfigMap ... data: config.yaml: | 'app.version': 0.0.4
  • 24. team1-repo env-repo applied-staging-branch app1.yaml app2.yaml app2-env.yaml applied-prod-branch app1.yaml app2.yaml app2-env.yaml master- branch service config staging- branch deployme nt prod- branch deployme nt team2-repo master- branch custom-s ettings staging- branch config prod- branch config Step 2 app.version: 0.0.34 port: 8090 image: gcr.io/image@sha256:{{ container.image.digest }} apiVersion: apps/v1beta2 kind: Deployment metadata: name: app2 namespace: production ... spec: replicas: 1 ... image: gcr.io/image@sha256:abcdef ports: - name: http containerPort: 90 --- ... --- apiVersion: v1 kind: ConfigMap ... data: config.yaml: | 'app.version': 0.0.4
  • 27. team1-repo env-repo applied-staging-branch app1.yaml app2.yaml app2-env.yaml applied-prod-branch app1.yaml app2.yaml app2-env.yaml master- branch service config staging- branch deployme nt prod- branch deployme nt team2-repo master- branch custom-s ettings staging- branch config prod- branch config Step 1 apiVersion: v1 kind: ConfigMap metadata: name: app2-env-config namespace: production labels: app: app2 env: production data: config.yaml: | 'log.level': INFOTRACE apiVersion: v1 kind: ConfigMap metadata: name: app2-env-config namespace: production labels: app: app2 env: production data: config.yaml: | 'log.level': TRACE
  • 28. 3. The straw man ● Source config in app repo, “compiled” (a.k.a. hydrated) config in env repo(s) ○ Cf. source code in app repo, compiled code in artifact repository ● One app repo per app/team, shared env repos for environments ● Use branches where possible to represent different environments ○ If greater separation via access control is needed, use different repos or consider other storage ● Keep config in app repo unless it needs to be independent of the app lifecycle or you really, really need to be able to change it for one env ○ Allows you to use templating/overriding to cut down on duplication ○ The fewer places to keep track of config, the better ● Source config doesn’t have to be “raw” YAML, can be more suitable abstraction! ○ Cf. higher-level language source code vs. low-level assembly code
  • 29. 3. The straw man ● Prefer explicit invocation over “repo-watching” ○ Avoids “root-level” process running inside cluster, and provides more flexibility for multi-step rollouts ○ “Repo-watching” makes visualizing current status harder, and requires some sort of feedback mechanism to distinguish successful from failed deployments in the repo ○ Hard to support phased/multi-step application ○ Easier to reproduce/simulate
  • 30. 3. The straw man ● Prefer explicit invocation over “repo-watching” ○ Avoids “root-level” process running inside cluster, and provides more flexibility for multi-step rollouts ○ “Repo-watching” makes visualizing current status harder, and requires some sort of feedback mechanism to distinguish successful from failed deployments in the repo ○ Hard to support phased/multi-step application ○ Easier to reproduce/simulate ● Commit after successful application, not before ○ Avoids having to distinguish attempted from successful deployments in the repo ○ Allows for richer pre-application validation than code diff in a PR (e.g. three-way diff against actual environment) ○ Avoids commit rights to repo being equivalent to deploy rights to env (and your automation will need commit rights to make pull requests, unless you used forked repos) ○ Harder if pull requests are used for the business process (as in vanilla GitOps) - requires multiple branches or “on approve” deployment
  • 31. 4. The mental model ● Understand how your app is updated across two dimensions: ● code change promoted through to prod ● common externalized config setting, e.g. localized title dependent on app version independent of environment
  • 32. 4. The mental model ● Understand how your app is updated across two dimensions: ● code change promoted through to prod ● common externalized config setting, e.g. localized title ● adding debug logging to staging ● configuring a scaling policy in prod based on a new metric dependent on app version independent of environment dependent on environment
  • 33. 4. The mental model ● Understand how your app is updated across two dimensions: ● code change promoted through to prod ● common externalized config setting, e.g. localized title ● rotating database credentials for prod ● updating discovery service endpoint ● adding debug logging to staging ● configuring a scaling policy in prod based on a new metric dependent on app version independent of environment dependent on environment independent of app version
  • 34. 4. The mental model ● Understand how your app is updated across two dimensions: Application update Static environment config update (App-linked) environment config update dependent on app version independent of environment dependent on environment independent of app version
  • 35. 4. The mental model ● Understand how your app is updated across two dimensions: Application update Static environment config update (App-linked) environment config update dev responsibility ~ app repo platform responsibility ~ env repo
  • 36. 4. The mental model 1. Application update a. “I want to validate a new release candidate and promote it through envs to prod” 2. Environment (config) update a. “I want to change the attributes of a particular env only” 3. Environment spin-up/restore a. “I want to (re-)create an environment from scratch, with config from a specific checkpoint/point in time” 4. Environment diff, drift detection and remediation a. “I want to understand how the actual config of an env relates to the intended config, also potentially across different environments”
  • 37. ● App repo is driving deployment, env repo is snapshotting cluster state ○ Think source code in github is to docker image in registry as template in app repo is to manifest in env repo ● Env repo is just a checkpoint in time, cluster can evolve ○ Kubernetes applies changes to manifests ○ Strategies like exponential rollouts or traffic shifting apply changes over time ● Env repo is not a guaranteed healthy state ○ We can defer snapshotting until some health/success metric… but rollback has no silver bullet ● Deletion from either repo ≠ deletion from cluster ○ Challenge is: not trivial to know if cluster depends, or will depend on manifest not submitted to repo ○ kubectl apply --prune attempts to solve this with a lot of (scary) caveats 4. The mental model
  • 38. 5. Tuning for your scenario ● Appropriate level of abstraction? How much “raw” Kubernetes YAML should our developers have access to? ● Where should the abstraction live? In templates? In CRDs? In the automation tool? ● What to use for templating? Token replacement or overrides? ● When do you snapshot/publish to the env repo? On every change to the cluster? Or when a desired end-state is reached? (think multi-step rollout) ● Access control: how many repos do you need? Are code repositories right for your use case, or e.g. a blobstore better? ● Am I distributing or deploying? Helm is much better suited for distribution than deployment ○ Its templating capability is often used as part of deployment flows, though
  • 39. 5. Implement ● Choose storage implementations and partitioning strategies for your environments-as-code ● Define the appropriate level of abstraction for your developers and choose tools to support it ● Choose a flexible automation tool for your deployment business process ● Define an appropriate definition of deployment health/success to determine when a deployment is “good” ● Decide which of the four processes - app update, env config update, env restore and env drift detection - you want to support ● Build pipelines ● Done!