SlideShare a Scribd company logo
Kubernetes Configuration
Management
Lee Briggs
Principle Infrastructure Engineer
07/11/2018
© 2016 Apptio, All rights reserved (v2.5)2
$(whoami)
 Based in Seattle (formerly London)
 Work for Apptio
 We are hiring! (remote US, remote EMEA, remote APAC)
 Using Kubernetes since 2015
 We tried out v1.0. It was a bad idea.
 Multiple cluster over many environments/regions
 Github:
https://github.com/jaxxstorm
https://github.com/apptio
 Twitter:
https://twitter.com/briggsl
 Blog:
https://www.leebriggs.co.uk
What is Config Management?
© 2016 Apptio, All rights reserved (v2.5)4
Quick Overview
 Remove “snowflakes”
 Hand crafted servers in your environment
 Provision New Servers
 Version control of Server configuration
 Replication of server environments
© 2016 Apptio, All rights reserved (v2.5)5
Cfg Mgmt Players
Enter Kubernetes
Or insert your fav orchestrator here
© 2016 Apptio, All rights reserved (v2.5)7
Configuration Layer
 With the classic tools, the configuration layer is the server
 Apps, config and resources are managed at the individual server level
 K8s provides an abstraction layer above many servers
 API Driven
 Idempotent
 Convergent
 Lots of orgs run only a few clusters
 Configuring the clusters relatively straightforward.
 K8s solves a lot of the server config mgmt. problem
 DaemonSets are a good example here
© 2016 Apptio, All rights reserved (v2.5)8
“Components”
 Components is a term we use to describe a thing that runs on
Kubernetes that is needed for a cluster to be useful
 Examples of components:
 Ingress Controller: https://github.com/kubernetes/ingress-nginx
 Cluster Autoscaler: https://github.com/kubernetes/autoscaler
 Sealed Secrets: https://github.com/bitnami-labs/sealed-secrets
 RBAC Config: https://kubernetes.io/docs/reference/access-authn-authz/rbac/
 Prometheus: https://prometheus.io/
 These components are vital for an operating cluster
 We need to install them on all clusters!
© 2016 Apptio, All rights reserved (v2.5)9
Components: What’s the problem?
 A lot of the config for these components is the same
 But, a lot is slightly different:
 Path to the SSL certificate for the Ingress Controller
 List of endpoints to scrape for Prometheus
 RBAC config between dev and prod
 ASG names for cluster autoscaler
 Different namespaces on different clusters
 How can you manage this using the traditional config management tools?
 Spoiler Alert: You can’t!
The Contenders
© 2016 Apptio, All rights reserved (v2.5)11
Helm
 Helm seems to be the #1 tool for this
 Lots of helm charts written by the community
 Allows you to set “values” for config in manifests
 You can specify these values via the cmdline or via a yaml based “values” file
 Templated Golang
 Relatively shallow learning curve
© 2016 Apptio, All rights reserved (v2.5)12
Helm: The downsides
 Helm is a security nightmare
 Cluster admin access for tiller!
 Helm 3 addressing this
 Managing values files doesn’t help
 You end up with lots of <dc>-values.yml for each DC
 Templated Golang is a not fun
 Having to range through values with templates became a chore
 Once you have all the config, how do you apply it to multiple clusters?
 You need to specify the right values file for each cluster
 We tried to use ansible and puppet for this, but it didn’t work
© 2016 Apptio, All rights reserved (v2.5)13
Helm: The downsides
© 2016 Apptio, All rights reserved (v2.5)14
Ansible
 Ansible supports using clusters as endpoints
 You simply define the API endpoint when using kubernetes manifests
 Has a k8s_raw module which can be used
 This allows you to hit specific endpoints when running ansible
 Also has a helm module
 Unfortunately it’s very broken
© 2016 Apptio, All rights reserved (v2.5)15
Ansible: The downsides
 Ansible uses yaml
 K8s already has us in yaml hell 
 You’re changing one yaml templating tool (Golang) with another (jinja2)
 Templating yaml is not fun
 Using the k8s_raw module meant fully writing all deployments
 You can’t easily make use of existing helm charts
 You would need to write and then retemplate all the config you’d need 
 Anecdotally, setting up python for the required libraries wasn’t very fun
© 2016 Apptio, All rights reserved (v2.5)16
Terraform
 Terraform has a nice HCL language construct
 Makes writing JSON much easier
 Has a Kubernetes & Helm Provider
 The Kubernetes provider is ”official”
 The Helm provider is community based
 Is easily extensible
© 2016 Apptio, All rights reserved (v2.5)17
Terraform: The downsides
 Both the helm and kubernetes provider weren’t very active
 No merges for a long time
 Seemed extremely buggy
 Often would error hitting APIs
 Because the k8s API changes slightly with each release, issues occurred
 For example, as APIs moved from beta to stable, the provider needs updating
 It needs to be continuously updated for each k8s release
© 2016 Apptio, All rights reserved (v2.5)18
Some other options:
 Ksonnet
 Seemed promising
 Dramatically overcomplicated
 You have to use the ksonnet ecosystem and way of deploying
 Kapitan
 Jinja2 templates 
 Was very promising conceptually
 Has to be pure jsonnet, no support for existing helm templates etc ]
 Pulumi
 Relatively new player in this space
 Terraform based
 Requires subscription to use now 
© 2016 Apptio, All rights reserved (v2.5)19
Jsonnet
 It became clear very quickly that using jsonnet was desirable
 Language written by Google specifically for interacting with JSON
 Used in both ksonnet and kapitan
 Has Golang wrappers, easy to embed into Go apps
 External variables mean ability to template JSON
 Pass in a variable at compile time, it changes the JSON
kr8
© 2016 Apptio, All rights reserved (v2.5)21
Design Goals
 Simple
 As few moving parts as possible
 Only write parts we can’t find
 We are a very small team, we don’t want to manage a large codebase
 Opinionated
 We wanted to enforce a structure that works for us
 Helps when fixing bugs
 Flexible
 Ability to render components based on Helm or any other yaml source input
© 2016 Apptio, All rights reserved (v2.5)22
What is kr8?
 Attempt to leverage the power of jsonnet
 Render jsonnet and other things into usable manifests for each cluster
 Written in Go
 Open Source!
 Features:
 Automatic population of jsonnet external variables
 Automatic concatenation of jsonnet files
 Ability to patch helm charts
 Uses jsonnet to render yaml, then patches the json on top of that
 Ability to leverage other config tools like Kasane and Kustomize
© 2016 Apptio, All rights reserved (v2.5)23
Other Automation Components
 Task: https://github.com/go-task/task
 Like Make. Written in Go. Takes yaml/json config
 Instead of writing makefiles, we make templated jsonnet taskfiles
 Helm: https://helm.sh/
 We use helm charts, render them locally and then patch them with jsonnet
 Kubecfg: https://github.com/ksonnet/kubecfg
 Applies manifests in a sane way
 Can use ”garbage collection” to remove unused manifests
Kr8 Walkthrough
Enhancements
© 2016 Apptio, All rights reserved (v2.5)26
Future Tasks
 Split components into separate repos
 Allow them to be downloaded like Terraform modules
 Unit Tests
 Documentation
 Pull requests welcome!
© 2016 Apptio, All rights reserved (v2.5)27
Links
 Introductory Blogpost: https://leebriggs.co.uk/blog/2018/11/07/kr8-
kubernetes-config-mgmt.html
 kr8: https://github.com/apptio/kr8
 Example Configs: https://github.com/apptio/kr8-configs
 My Configs! https://github.com/jaxxstorm/cluster_config
Thankyou!
Colin Spargo
Sanyu Melwani
Shawn Xue
THANK YOU

More Related Content

PPTX
From training to explainability via git ops
PDF
Terraform GitOps on Codefresh
PDF
Introduction of cloud native CI/CD on kubernetes
PDF
Kubeflow control plane
PDF
Lessons learned from the charts repo
PPTX
Kubeflow on google kubernetes engine
PDF
Cloud Native CI/CD with GitOps
PDF
Aws Deployment Tools - Overview, Details, Implementation
From training to explainability via git ops
Terraform GitOps on Codefresh
Introduction of cloud native CI/CD on kubernetes
Kubeflow control plane
Lessons learned from the charts repo
Kubeflow on google kubernetes engine
Cloud Native CI/CD with GitOps
Aws Deployment Tools - Overview, Details, Implementation

What's hot (20)

PDF
GitOps Toolkit (Cloud Native Nordics Tech Talk)
PDF
Kubernetes GitOps featuring GitHub, Kustomize and ArgoCD
PDF
Introducing Kubeflow (w. Special Guests Tensorflow and Apache Spark)
PDF
Android Jetpack + Coroutines: To infinity and beyond
PDF
What's Coming in Apache Airflow 2.0 - PyDataWarsaw 2019
PDF
Brief introduction to Angular 2.0 & 4.0
PDF
Jenkins X - automated CI/CD solution for cloud native applications on Kubernetes
PPTX
From java monolith to kubernetes microservices - an open source journey with ...
PPTX
Spring Boot & Spring Cloud on k8s and PCF
PDF
Visual Studio로 Kubernetes 사용하기
PDF
IL2CPP: Debugging and Profiling
PDF
Handling Kubernetes Resources
PDF
JS Fest 2019/Autumn. Алексей Орленко. Node.js N-API for Rust
PDF
GitOps - Operation By Pull Request
PDF
JFall 2018 k8s patterns
PDF
Openstack benelux 2015
PDF
老派浪漫:用 Kotlin 寫 Command Line 工具
PDF
Rene Groeschke
PDF
The Power of GitOps with Flux & GitOps Toolkit
PDF
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
GitOps Toolkit (Cloud Native Nordics Tech Talk)
Kubernetes GitOps featuring GitHub, Kustomize and ArgoCD
Introducing Kubeflow (w. Special Guests Tensorflow and Apache Spark)
Android Jetpack + Coroutines: To infinity and beyond
What's Coming in Apache Airflow 2.0 - PyDataWarsaw 2019
Brief introduction to Angular 2.0 & 4.0
Jenkins X - automated CI/CD solution for cloud native applications on Kubernetes
From java monolith to kubernetes microservices - an open source journey with ...
Spring Boot & Spring Cloud on k8s and PCF
Visual Studio로 Kubernetes 사용하기
IL2CPP: Debugging and Profiling
Handling Kubernetes Resources
JS Fest 2019/Autumn. Алексей Орленко. Node.js N-API for Rust
GitOps - Operation By Pull Request
JFall 2018 k8s patterns
Openstack benelux 2015
老派浪漫:用 Kotlin 寫 Command Line 工具
Rene Groeschke
The Power of GitOps with Flux & GitOps Toolkit
[Kotlin Serverless 工作坊] 單元 2 - 簡介 Kotlin Serverless
Ad

Similar to Kube cfg-mgmt (20)

PPTX
Sensu 1.x & kubernetes
PDF
Sensu and Kubernetes 1.x
PDF
How to Structure Your K8s GitOps Repository at Scale by Erik Berdonces - DevO...
PPT
Syncevolution: Open Source and Funambol
PPTX
Ultimate Guide to Microservice Architecture on Kubernetes
PDF
AKS: k8s e azure
PPTX
New and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
PDF
Introduction to kubernetes
PDF
Microsoft .NET 6 -What's All About The New Update
PPTX
Kubernetes 101
PDF
Heroku to Kubernetes & Gihub to Gitlab success story
PPTX
AOT(Ahead Of Time)
PPTX
PaaS on Openstack
PPTX
Sst hackathon express
PPTX
Apigee deploy grunt plugin.1.0
PDF
Web componenet using angular element
PPTX
Node.js primer for ITE students
DOCX
PDF
AWS 고객사를 위한 ‘AWS 컨테이너 교육’ - 유재석, AWS 솔루션즈 아키텍트
PDF
Scalable Cloud-Native Masterless Puppet, with PuppetDB and Bolt, Craig Watson...
Sensu 1.x & kubernetes
Sensu and Kubernetes 1.x
How to Structure Your K8s GitOps Repository at Scale by Erik Berdonces - DevO...
Syncevolution: Open Source and Funambol
Ultimate Guide to Microservice Architecture on Kubernetes
AKS: k8s e azure
New and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
Introduction to kubernetes
Microsoft .NET 6 -What's All About The New Update
Kubernetes 101
Heroku to Kubernetes & Gihub to Gitlab success story
AOT(Ahead Of Time)
PaaS on Openstack
Sst hackathon express
Apigee deploy grunt plugin.1.0
Web componenet using angular element
Node.js primer for ITE students
AWS 고객사를 위한 ‘AWS 컨테이너 교육’ - 유재석, AWS 솔루션즈 아키텍트
Scalable Cloud-Native Masterless Puppet, with PuppetDB and Bolt, Craig Watson...
Ad

Recently uploaded (20)

PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PPTX
A Presentation on Artificial Intelligence
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
Empathic Computing: Creating Shared Understanding
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Approach and Philosophy of On baking technology
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Encapsulation theory and applications.pdf
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
NewMind AI Weekly Chronicles - August'25 Week I
NewMind AI Monthly Chronicles - July 2025
The Rise and Fall of 3GPP – Time for a Sabbatical?
A Presentation on Artificial Intelligence
20250228 LYD VKU AI Blended-Learning.pptx
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Empathic Computing: Creating Shared Understanding
Chapter 3 Spatial Domain Image Processing.pdf
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Approach and Philosophy of On baking technology
Unlocking AI with Model Context Protocol (MCP)
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
CIFDAQ's Market Insight: SEC Turns Pro Crypto
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
The AUB Centre for AI in Media Proposal.docx
Encapsulation theory and applications.pdf
Diabetes mellitus diagnosis method based random forest with bat algorithm

Kube cfg-mgmt

  • 1. Kubernetes Configuration Management Lee Briggs Principle Infrastructure Engineer 07/11/2018
  • 2. © 2016 Apptio, All rights reserved (v2.5)2 $(whoami)  Based in Seattle (formerly London)  Work for Apptio  We are hiring! (remote US, remote EMEA, remote APAC)  Using Kubernetes since 2015  We tried out v1.0. It was a bad idea.  Multiple cluster over many environments/regions  Github: https://github.com/jaxxstorm https://github.com/apptio  Twitter: https://twitter.com/briggsl  Blog: https://www.leebriggs.co.uk
  • 3. What is Config Management?
  • 4. © 2016 Apptio, All rights reserved (v2.5)4 Quick Overview  Remove “snowflakes”  Hand crafted servers in your environment  Provision New Servers  Version control of Server configuration  Replication of server environments
  • 5. © 2016 Apptio, All rights reserved (v2.5)5 Cfg Mgmt Players
  • 6. Enter Kubernetes Or insert your fav orchestrator here
  • 7. © 2016 Apptio, All rights reserved (v2.5)7 Configuration Layer  With the classic tools, the configuration layer is the server  Apps, config and resources are managed at the individual server level  K8s provides an abstraction layer above many servers  API Driven  Idempotent  Convergent  Lots of orgs run only a few clusters  Configuring the clusters relatively straightforward.  K8s solves a lot of the server config mgmt. problem  DaemonSets are a good example here
  • 8. © 2016 Apptio, All rights reserved (v2.5)8 “Components”  Components is a term we use to describe a thing that runs on Kubernetes that is needed for a cluster to be useful  Examples of components:  Ingress Controller: https://github.com/kubernetes/ingress-nginx  Cluster Autoscaler: https://github.com/kubernetes/autoscaler  Sealed Secrets: https://github.com/bitnami-labs/sealed-secrets  RBAC Config: https://kubernetes.io/docs/reference/access-authn-authz/rbac/  Prometheus: https://prometheus.io/  These components are vital for an operating cluster  We need to install them on all clusters!
  • 9. © 2016 Apptio, All rights reserved (v2.5)9 Components: What’s the problem?  A lot of the config for these components is the same  But, a lot is slightly different:  Path to the SSL certificate for the Ingress Controller  List of endpoints to scrape for Prometheus  RBAC config between dev and prod  ASG names for cluster autoscaler  Different namespaces on different clusters  How can you manage this using the traditional config management tools?  Spoiler Alert: You can’t!
  • 11. © 2016 Apptio, All rights reserved (v2.5)11 Helm  Helm seems to be the #1 tool for this  Lots of helm charts written by the community  Allows you to set “values” for config in manifests  You can specify these values via the cmdline or via a yaml based “values” file  Templated Golang  Relatively shallow learning curve
  • 12. © 2016 Apptio, All rights reserved (v2.5)12 Helm: The downsides  Helm is a security nightmare  Cluster admin access for tiller!  Helm 3 addressing this  Managing values files doesn’t help  You end up with lots of <dc>-values.yml for each DC  Templated Golang is a not fun  Having to range through values with templates became a chore  Once you have all the config, how do you apply it to multiple clusters?  You need to specify the right values file for each cluster  We tried to use ansible and puppet for this, but it didn’t work
  • 13. © 2016 Apptio, All rights reserved (v2.5)13 Helm: The downsides
  • 14. © 2016 Apptio, All rights reserved (v2.5)14 Ansible  Ansible supports using clusters as endpoints  You simply define the API endpoint when using kubernetes manifests  Has a k8s_raw module which can be used  This allows you to hit specific endpoints when running ansible  Also has a helm module  Unfortunately it’s very broken
  • 15. © 2016 Apptio, All rights reserved (v2.5)15 Ansible: The downsides  Ansible uses yaml  K8s already has us in yaml hell   You’re changing one yaml templating tool (Golang) with another (jinja2)  Templating yaml is not fun  Using the k8s_raw module meant fully writing all deployments  You can’t easily make use of existing helm charts  You would need to write and then retemplate all the config you’d need   Anecdotally, setting up python for the required libraries wasn’t very fun
  • 16. © 2016 Apptio, All rights reserved (v2.5)16 Terraform  Terraform has a nice HCL language construct  Makes writing JSON much easier  Has a Kubernetes & Helm Provider  The Kubernetes provider is ”official”  The Helm provider is community based  Is easily extensible
  • 17. © 2016 Apptio, All rights reserved (v2.5)17 Terraform: The downsides  Both the helm and kubernetes provider weren’t very active  No merges for a long time  Seemed extremely buggy  Often would error hitting APIs  Because the k8s API changes slightly with each release, issues occurred  For example, as APIs moved from beta to stable, the provider needs updating  It needs to be continuously updated for each k8s release
  • 18. © 2016 Apptio, All rights reserved (v2.5)18 Some other options:  Ksonnet  Seemed promising  Dramatically overcomplicated  You have to use the ksonnet ecosystem and way of deploying  Kapitan  Jinja2 templates   Was very promising conceptually  Has to be pure jsonnet, no support for existing helm templates etc ]  Pulumi  Relatively new player in this space  Terraform based  Requires subscription to use now 
  • 19. © 2016 Apptio, All rights reserved (v2.5)19 Jsonnet  It became clear very quickly that using jsonnet was desirable  Language written by Google specifically for interacting with JSON  Used in both ksonnet and kapitan  Has Golang wrappers, easy to embed into Go apps  External variables mean ability to template JSON  Pass in a variable at compile time, it changes the JSON
  • 20. kr8
  • 21. © 2016 Apptio, All rights reserved (v2.5)21 Design Goals  Simple  As few moving parts as possible  Only write parts we can’t find  We are a very small team, we don’t want to manage a large codebase  Opinionated  We wanted to enforce a structure that works for us  Helps when fixing bugs  Flexible  Ability to render components based on Helm or any other yaml source input
  • 22. © 2016 Apptio, All rights reserved (v2.5)22 What is kr8?  Attempt to leverage the power of jsonnet  Render jsonnet and other things into usable manifests for each cluster  Written in Go  Open Source!  Features:  Automatic population of jsonnet external variables  Automatic concatenation of jsonnet files  Ability to patch helm charts  Uses jsonnet to render yaml, then patches the json on top of that  Ability to leverage other config tools like Kasane and Kustomize
  • 23. © 2016 Apptio, All rights reserved (v2.5)23 Other Automation Components  Task: https://github.com/go-task/task  Like Make. Written in Go. Takes yaml/json config  Instead of writing makefiles, we make templated jsonnet taskfiles  Helm: https://helm.sh/  We use helm charts, render them locally and then patch them with jsonnet  Kubecfg: https://github.com/ksonnet/kubecfg  Applies manifests in a sane way  Can use ”garbage collection” to remove unused manifests
  • 26. © 2016 Apptio, All rights reserved (v2.5)26 Future Tasks  Split components into separate repos  Allow them to be downloaded like Terraform modules  Unit Tests  Documentation  Pull requests welcome!
  • 27. © 2016 Apptio, All rights reserved (v2.5)27 Links  Introductory Blogpost: https://leebriggs.co.uk/blog/2018/11/07/kr8- kubernetes-config-mgmt.html  kr8: https://github.com/apptio/kr8  Example Configs: https://github.com/apptio/kr8-configs  My Configs! https://github.com/jaxxstorm/cluster_config

Editor's Notes

  • #5: “Server config mgmt” mainly Talk about days of servers being managed by hand/shell scripts
  • #8: You still need cfg mgmt. to deploy kubernetes components! Kubeadm etc Once deployed, there are k8s resources like DaemonSets for deploying container services to many nodes Why might you have lots of clusters?
  • #10: Why would we have multiple clusters?
  • #12: If you thought about the last problem, you probably thought about helm
  • #13: It didn’t work because puppet isn’t cluster aware, only machine aware Ansible’s helm module doesn’t work at all  Golang templates/helm3/lua Helm only solves the packaging of the app, it doesn’t solve the problem of which components to which clusters
  • #16: It’s ansible :trollface:
  • #18: If you haven’t accidentally destroyed all your infra with terraform, are you really using it at all?
  • #19: Heptio Quote: I have no idea what they’re doing with ksonnet
  • #22: Kasane is another deployment tool by Google Helm chart merge time is high
  • #23: Kasane is another deployment tool by Google Helm chart merge time is high
  • #29: Colin: Inventor* Sanyu: Contributor Shawn: Contributor