Developing Kubernetes Services

Similar documents
OpenShift Roadmap Enterprise Kubernetes for Developers. Clayton Coleman, Architect, OpenShift

Code: Slides:

Continuous delivery while migrating to Kubernetes

The Long Road from Capistrano to Kubernetes

Important DevOps Technologies (3+2+3days) for Deployment

Containers, Serverless and Functions in a nutshell. Eugene Fedorenko

Kuber-what?! Learn about Kubernetes

Building a Kubernetes on Bare-Metal Cluster to Serve Wikipedia. Alexandros Kosiaris Giuseppe Lavagetto

Introduction to Kubernetes

An Introduction to Kubernetes

WHITE PAPER. RedHat OpenShift Container Platform. Benefits: Abstract. 1.1 Introduction

/ Cloud Computing. Recitation 5 February 14th, 2017

OpenShift 3 Technical Architecture. Clayton Coleman, Dan McPherson Lead Engineers

DevOps Technologies. for Deployment

DevOps Workflow. From 0 to kube in 60 min. Christian Kniep, v Technical Account Manager, Docker Inc.

What s New in K8s 1.3

What s New in K8s 1.3

DevOps Course Content

KUBERNETES IN A GROWN ENVIRONMENT AND INTEGRATION INTO CONTINUOUS DELIVERY

Red Hat OpenShift Roadmap Q4 CY16 and H1 CY17 Releases. Lutz Lange Solution

Distributed CI: Scaling Jenkins on Mesos and Marathon. Roger Ignazio Puppet Labs, Inc. MesosCon 2015 Seattle, WA


Disclaimer This presentation may contain product features that are currently under development. This overview of new technology represents no commitme

IBM Cloud Developer Tools (IDT) and App Service Console Overview

Kubernetes. Introduction

Sunil Shah SECURE, FLEXIBLE CONTINUOUS DELIVERY PIPELINES WITH GITLAB AND DC/OS Mesosphere, Inc. All Rights Reserved.

Container Orchestration on Amazon Web Services. Arun

Kuberiter White Paper. Kubernetes. Cloud Provider Comparison Chart. Lawrence Manickam Kuberiter Inc

Running MarkLogic in Containers (Both Docker and Kubernetes)

Kubernetes Integration Guide

Kubernetes 1.9 Features and Future

Top Nine Kubernetes Settings You Should Check Right Now to Maximize Security

Advanced Continuous Delivery Strategies for Containerized Applications Using DC/OS

Hacking and Hardening Kubernetes

Kubernetes 101. Doug Davis, STSM September, 2017

Two years of on Kubernetes

/ Cloud Computing. Recitation 5 September 26 th, 2017

Building an on premise Kubernetes cluster DANNY TURNER

Accelerate at DevOps Speed With Openshift v3. Alessandro Vozza & Samuel Terburg Red Hat

Disclaimer This presentation may contain product features that are currently under development. This overview of new technology represents no commitme

Kubernetes made easy with Docker EE. Patrick van der Bleek Sr. Solutions Engineer NEMEA

Handel-CodePipeline Documentation

Building Kubernetes cloud: real world deployment examples, challenges and approaches. Alena Prokharchyk, Rancher Labs

Taming Distributed Pets with Kubernetes

Question: 2 Kubernetes changed the name of cluster members to "Nodes." What were they called before that? Choose the correct answer:

Orchestrating the Continuous Delivery Process

This document (including, without limitation, any product roadmap or statement of direction data) illustrates the planned testing, release and

Getting Started With Containers

TM DevOps Use Case. 2017TechMinfy All Rights Reserved

AZURE CONTAINER INSTANCES

Infoblox IPAM Driver for Kubernetes User's Guide

CONTAINERS AND MICROSERVICES WITH CONTRAIL

Continuous Delivery the hard way with Kubernetes. Luke Marsden, Developer

São Paulo. August,

Federated Prometheus Monitoring at Scale

Infoblox IPAM Driver for Kubernetes. Page 1

ASP.NET Core & Docker

EASILY DEPLOY AND SCALE KUBERNETES WITH RANCHER

Continuous Integration and Delivery with Spinnaker

Docker and Oracle Everything You Wanted To Know

Linux System Management with Puppet, Gitlab, and R10k. Scott Nolin, SSEC Technical Computing 22 June 2017

Change-sets. Basavaraj Karadakal

DevOps + Infrastructure TRACK SUPPORTED BY

A DEVOPS STATE OF MIND. Chris Van Tuin Chief Technologist, West

Containerizing GPU Applications with Docker for Scaling to the Cloud

A DEVOPS STATE OF MIND. Chris Van Tuin Chief Technologist, West

Microservices. Chaos Kontrolle mit Kubernetes. Robert Kubis - Developer Advocate,

Multi-Arch Layered Image Build System

Deep Dive on AWS CodeStar

AGILE DEVELOPMENT AND PAAS USING THE MESOSPHERE DCOS

Convergence of VM and containers orchestration using KubeVirt. Chunfu Wen

Lessons learnt building Kubernetes controllers. David Cheney - Heptio

Docker at Lyft Speeding up development Matthew #dockercon

Seven Habits of Highly Effective Jenkins Users

Managing Compute and Storage at Scale with Kubernetes. Dan Paik / Google

Introduction to Kubernetes Storage Primitives for Stateful Workloads

Secure Kubernetes Container Workloads

Securing Containers on the High Seas. Jack OWASP Belgium September 2018

Continuous Integration and Deployment (CI/CD)

Bright Cluster Manager: Using the NVIDIA NGC Deep Learning Containers

Kubernetes: Integration vs Native Solution

EVERYTHING AS CODE A Journey into IT Automation and Standardization. Raphaël Pinson

From development to production

Ingress Kubernetes Tutorial

Docker Live Hacking: From Raspberry Pi to Kubernetes

SQUASH. Debugger for microservices. Idit Levine solo.io

Kubernetes: Twelve KeyFeatures

BUILDING A GPU-FOCUSED CI SOLUTION

gcp / gke / k8s microservices

The missing CI/CD Kubernetes component: Helm package manager

ACCELERATE APPLICATION DELIVERY WITH OPENSHIFT. Siamak Sadeghianfar Sr Technical Marketing Manager, April 2016

DevOps Tooling from AWS

Containers Infrastructure for Advanced Management. Federico Simoncelli Associate Manager, Red Hat October 2016

Jenkins: A complete solution. From Continuous Integration to Continuous Delivery For HSBC

Leveraging the Serverless Architecture for Securing Linux Containers

FROM VSTS TO AZURE DEVOPS

Red Hat Roadmap for Containers and DevOps

Docker All The Things

Overview of Container Management

Singularity CRI User Documentation

Transcription:

/ MARCH 2019 / CON LONDON Developing Kubernetes Services at Airbnb Scale

What is kubernetes?

@MELAN IECEBULA Who am I?

A BRIEF HISTORY

Why Microservices? 4000000 3000000 MONOLITH LOC 2000000 1000000 0 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018

Why Microservices? 1000 750 ENGINEERING TEAM 500 250 0 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018

Why Microservices? SCALING CONTINUOUS DELIVERY

Why Microservices? Deploys per week (all apps, all environments)

Why Microservices? Monolith production deploys per week

Why Microservices? 125,000 production deploys per year

Why kubernetes? EVOLUTION OF CONFIGURATION MANAGEMENT Manually configuring boxes Automate configuration of applications with Chef Automate configuration and orchestration of containerized applications with Kubernetes

Why kubernetes? declarative portable human-friendly data efficient scheduling immutable standard format extensible API reproducible

TODAY

migration progress 50% of services in kubernetes

migration progress 250+ critical services in kubernetes

Challenges with kubernetes? complex configuration complex tooling integrating with your current infrastructure open issues scaling and more!

Challenges with kubernetes? complex configuration complex tooling integrating with your current infrastructure open issues solvable problems! scaling and more!

you are not alone.

Solutions? 1. abstract away k8s configuration 2. generate service boilerplate 3. version + refactor configuration 4. opinionated kubectl 5. custom ci/cd + validation

ABSTRACT AWAY CONFIGURATION

kubernetes config files Production Deployment Canary Deployment Dev Deployment kubernetes kubectl apply Production ConfigMap Canary ConfigMap Dev ConfigMap kubernetes cluster Production Service Canary Service Dev Service P

lots of boilerplate kubernetes config files repetitive by environment Production Deployment Canary Deployment Dev Deployment kubectl apply kubernetes resources Production ConfigMap Canary ConfigMap Dev ConfigMap kubernetes cluster Production Service Canary Service Dev Service P environments

Prefer templating over file inheritance Reducing k8s boilerplate OUR REQUIREMENTS Input should be templated YAML files Make it easier to migrate 100s of legacy services Make it easier to retrain 1000 engineers

generating k8s configs kubernetes config files Project Apps Production Deployment Canary Deployment Dev Deployment Containers kube-gen generate kubectl apply Files Production ConfigMap Canary ConfigMap Dev ConfigMap kubernetes cluster Volumes Production Service Canary Service Dev Service Dockerfile

generating k8s configs kube-gen! kubernetes config files Project Apps Production Deployment Canary Deployment Dev Deployment Containers kube-gen generate kubectl apply Files Production ConfigMap Canary ConfigMap Dev ConfigMap kubernetes cluster Volumes Production Service Canary Service Dev Service Dockerfile

sets params per environment Project Apps Reducing k8s boilerplate WHAT WE WENT WITH Containers Files other files access params Volumes Dockerfile

generating k8s configs Project Apps Containers kube-gen generate Files Volumes Dockerfile

generating k8s configs Project Apps Containers kube-gen generate standardized namespaces based on environments! Files Volumes Dockerfile

Project Apps Which shared components to use? kube-gen COMPONENTS Containers Files example components Volumes nginx logging statsd Dockerfile

nginx component Main Container Containers common pattern abstracted into component kube-gen COMPONENTS Main App Volumes component yams is merged into project on generate components can require or set default params Files Dockerfile

Reducing k8s boilerplate OPEN SOURCE OPTIONS 1. Combine with package management (ex: helm) 2. Override configuration via file inheritance (ex: kustomize) 3. Override configuration via templating (ex: kapitan)

Takeaways Reduce kubernetes boilerplate Standardize on environments and namespaces

GENERATE SERVICE BOILERPLATE

Everything about a service is in one place in git, and managed with one process.

Everything about a service is in one place in git Configuration LIVES IN ONE PLACE All configuration lives in _infra alongside project code Edit code and configuration with one pull request Easy to add new configuration Statically validated in CI/CD

What we support: kube-gen files framework boilerplate API boilerplate Configuration LIVES IN ONE PLACE CI/CD docs AWS IAM roles project ownership storage.. and more!

this hello world service was created in one command Configuration LIVES IN ONE PLACE

collection of config generators (ex: docs, ci) Configuration LIVES IN ONE PLACE

Configuration LIVES IN ONE PLACE collection of framework-specific generators (ex: Rails, Dropwizard)

make best practices the default (ex: deploy pipeline, autoscaling, docs) Configuration CAN BE GENERATED run generators individually or as a group support for review, update, commit

Takeaways Everything about a service should be in one place in git Make best practices the default by generating configuration

VERSION CONFIGURATION

Why do we version our kube configuration? add support for something new (ex: k8s version) kube.yml v1 kubev1 deploy kubev2 deploy want to change something (ex: deployment strategy) want to drop support for kubernetes cluster something (breaking kube.yml v2 change) know which versions are bad when we make a regression support release cycle and cadence

How do we version our kube configuration? 1. version field 2. publish binaries for each version 3. channels point to binaries (ex: stable) 4. generate and apply using the appropriate binary bonk kube-gen.yml

Why do we version our generated configuration? kube.yml generated by sha1 kubev1 deploy what our project generators generate changes over kubernetes cluster time kube.yml generated by sha2 best practices change and bugs in the generators are found! generator at sha2 has a bug

How do we version our generated configuration? generator tags generated files with version, sha, and timestamp

REFACTOR CONFIGURATION

Why do we refactor configuration? FOR HUNDREDS OF SERVICES services should be up-to-date with latest best practices update configuration to the latest supported versions apply security patches to images configuration migrations should be automated

(we don t want to manually refactor) 250+ critical services in kubernetes

How do we refactor configuration? get-repos.py close.py collection of general purpose scripts list-pr-urls.py refactor.py scripts are modular scripts cover the lifecycle of a refactor updateprs.py status.py refactorator

The lifecycle of a refactor Run Refactor Update Merge Checks out repo, finds project, runs refactor job, tags owners, creates PR Comments on the PR, reminding owners to verify, edit, and merge the PR Merges the PR with different levels of force

How do we refactor configuration? refactorator upgradekube.py refactor job refactorator will run a refactor for all services given a refactor job refactor job updates _infra file(s) ex: upgrade kube version to stable

Bumping stable version bump stable version runs daily on weekdays refactorator upgradekube.py cron job uses refactorator and with the upgradekube.py refactor job to create PRs k8s cron job refactor job another cron job handling updating and merging PRs

Takeaways Configuration should be versioned and refactored automatically.

OPINIONATED KUBECTL

lots of boilerplate kubernetes config files repetitive by environment Production Deployment Canary Deployment Dev Deployment kubectl apply kubernetes resources Production ConfigMap Canary ConfigMap Dev ConfigMap kubernetes cluster Production Service Canary Service Dev Service P environments

kubernetes config files Production Deployment Canary Deployment Dev Deployment kubectl apply kubernetes Production ConfigMap Canary ConfigMap Dev ConfigMap kubernetes cluster verbose Production Service Canary Service Dev Service repetitive by namespace P

@MELAN IECEBULA k tool KUBECTL WRAPPER Production Deployment Canary Deployment Dev Deployment kubectl apply Production ConfigMap Production Service Canary ConfigMap Canary Service Dev ConfigMap Dev Service kubernetes cluster calls kubectl commands (incl. plugins)

@MELAN IECEBULA k tool OPINIO NATED KUBECTL

Runs in the project home directory: $ cd /path/to/bonk $ k status k tool USES ENV VARS Environment variables for arguments: $ k status ENV=staging Prints the command that it will execute: $ k status ENV=staging standardized namespaces! kubectl get pods --namespace=bonk-staging

k generate generates kubernetes files k build performs project build, docker build and k tool SIMPLIFIES BUILDS AND DEPLOYS docker push with tags k deploy creates namespace, applies/replaces kubernetes files, sleeps and checks deployment status can chain commands; ex: k all

defaults to random pod, main container: k tool A DEBUGGING TOOL $ k ssh ENV=staging specify particular pod, specific container: $ k logs ENV=staging POD= CONTAINER=bonk automates debugging with k diagnose ENV=staging

defaults to random pod, main container: k tool A DEBUGGING TOOL $ k ssh ENV=staging specify particular pod, specific container: call kubectl diagnose $ k logs ENV=staging POD= CONTAINER=bonk automates debugging with k diagnose ENV=staging

What are kubectl plugins?

What are kubectl plugins?

k diagnose SETUP deploy bonk service with failing command new pod in CrashLoopBackoff

k diagnose MANUALLY 1. use get pods - o=yaml and look for problems 2. grab logs for unready container

k diagnose MANUALLY 3. get k8s events related to this pod

kubectl podevents KUBECTL PLUGIN kubectl podevents plugin

kubectl diagnose USES COBRA GO CLI // defines CLI command and flags var Namespace string var rootcmd = &cobra.command{ Use: kubectl diagnose namespace<namespace>" Short: diagnoses a namespace with pods in CrashLoopBackOff Run: func(cmd *cobra.command, arg[]string) { // Fill in with program logic } } func Execute() { rootcmd.flags().stringvarp(&namespace, "namespace", "n", ) rootcmd.markflagrequired("namespace") if err := rootcmd.execute(); err!= nil { fmt.println(err) os.exit(1) }

kubectl diagnose USES K8S CLIENT-GO // get pods (assume Namespace is defined) kubeconfig := filepath.join(os.getenv("home"), ".kube","config") config, err := clientcmd.buildconfigfromflags("", kubeconfig) if err!= nil { } clientset, err := kubernetes.newforconfig(config) if err!= nil { } pods, err := clientset.corev1().pods(namespace).list(metav1.listoptions{}) fmt.printf("there are %d pods in the namespace %s\n", len(pods.items), Namespace) for _, pod := range pod.items { podname := pod.name for _, c := range pod.status.containerstatuses { if c.ready!= true { // print c.lastterminatedstate and c.state } } uses k8s client-go and Namespace param to get pods

kubectl diagnose USES K8S CLIENT-GO // get pods (assume Namespace is defined) kubeconfig := filepath.join(os.getenv("home"), ".kube","config") config, err := clientcmd.buildconfigfromflags("", kubeconfig) if err!= nil { } clientset, err := kubernetes.newforconfig(config) if err!= nil { } pods, err := clientset.corev1().pods(namespace).list(metav1.listoptions{}) fmt.printf("there are %d pods in the namespace %s\n", len(pods.items), Namespace) for _, pod := range pod.items { podname := pod.name for _, c := range pod.status.containerstatuses { if c.ready!= true { // print c.lastterminatedstate and c.state prints info for all unready containers } }

// get pod events for namespace and pod kubectl diagnose USES OS/EXEC (WHEN LAZY) cmd := exec.command("kubectl", "podevents", Namespace, podname) var out bytes.buffer var stderr bytes.buffer cmd.stdout = &out podevents kubectl plugin cmd.stderr = &stderr err := cmd.run() if err!= nil { } fmt.println(fmt.sprint(err) + ": " + stderr.string()) log.fatal(err) } else { } fmt.println("events: \n" + out.string()) // also grab logs cmd = exec.command("kubectl", "logs", podname, fmt.sprintf("-- namespace=%s", Namespace), "-c", "bonk")

kubectl diagnose GO KUBECTL PLUGIN

kubectl diagnose GO KUBECTL PLUGIN 1. unready container info

kubectl diagnose GO KUBECTL PLUGIN 1. unready container info 2. kubectl podevents

kubectl diagnose GO KUBECTL PLUGIN 1. unready container info 2. kubectl podevents 3. pod logs for unready containers

Takeaways Create an opinionated kubectl wrapper Automate common k8s workflows with kubectl plugins

CI/CD

Each step in our CI /CD jobs are RUN steps in a build Dockerfile

runs k commands

DEPLOY PROCESS

A single deploy process for every change Develop Merge Deploy Write code and config under your project Open a PR and merge your code to master Deploy all code and config changes

A single deploy process for every change Deployment AWS Project ownership Storage kubectl apply ConfigMap Alerts Docs Service Discovery kubernetes cluster Service Dashboards Secrets API Gateway Routes

How do we apply k8s configuration? Deployment kubectl apply all files kubectl apply in some cases where apply fails, replace files without ConfigMap kubernetes cluster force always restart pods on deploy to pick up changes Service return atomic success or failure state by sleeping and checking status

How do you always restart pods on deploy? We add a date label to the pod spec, Deployment which convinces k8s to relaunch all pods kubectl apply ConfigMap kubernetes cluster Service

How do we apply custom configuration?

How do we apply custom configuration? kubectl apply aws.yml kubernetes cluster AWS AWS AWS CRD Controller webhook

How do we apply custom configuration? kubectl apply 1. Create a custom resource definition aws.yml kubernetes cluster for aws.yml AWS AWS AWS CRD Controller webhook

How do we apply custom configuration? aws.yml kubectl apply kubernetes cluster 2. Create a controller that calls a web hook when aws.yml is applied AWS AWS AWS CRD Controller webhook

How do we apply custom configuration? kubectl apply 3. Create a web hook that updates a aws.yml kubernetes cluster custom resource AWS AWS AWS CRD Controller webhook

How do we apply custom configuration? 4. AWS lambda exposes web hook to be called AWS CRD AWS Controller AWS webhook AWS lambda

Takeaways Code and configuration should be deployed with the same process Use custom resources and custom controllers to integrate k8s with your infra

VALIDATION

enforce best practices at build time with validation scripts Configuration at deploy time with admission controller SHOULD BE VALIDATED

How do we validate configuration at build time?

How do we validate configuration at build time? project.yml validation script kube validation script job dispatcher project build global validation docs build jobs aws.yml validation script bonk CI jobs global jobs repo

How do we validate configuration at build time? project.yml validation script kube validation script job dispatcher project build global validation docs build jobs aws.yml validation script 1. Define global job in global jobs repo bonk CI jobs global jobs repo

How do we validate configuration at build time? project.yml validation script kube validation script job dispatcher project build global validation docs build jobs 2. job dispatcher aws.yml validation script always dispatches global jobs to projects bonk CI jobs global jobs repo

How do we validate configuration at build time? project.yml validation script kube validation script job dispatcher project build global validation docs build jobs aws.yml validation script 3. global job runs alongside project bonk CI jobs global jobs repo jobs

What do we validate at build time? project.yml validation script invalid yaml invalid k8s configuration kube validation script job dispatcher bad configuration versions max namespace length (63 chars) valid project name aws.yml validation script valid team owner in project.yml global jobs repo

How do we validate configuration at deploy time? kubectl apply admission controller project.yml kubernetes cluster admission controller intercepts requests to the k8s api server prior to persistence of the object

How do we validate configuration at deploy time? metadata is encoded as admission controller annotations at generate time project.yml admission controller checks for required annotations reject any update to resources that are missing required annotations

What do we validate with admission controller? admission controller project ownership annotations project.yml configuration stored in git configuration uses minimally supported version

What do we validate with admission controller? production images must be admission controller uploaded to production ECR project.yml prevent deployment of unsafe workloads prevent deployment of development namespaces to production clusters

What do we validate with admission controller? production images must be admission controller uploaded to production ECR project.yml prevent deployment of unsafe workloads prevent deployment of development namespaces to production clusters standardized namespaces!

Takeaways CI/CD should run the same commands that engineers run locally CI/CD should run in a container Validate configuration as part of CI/ CD

10 Takeaways 1. Abstract away complex kubernetes configuration 2. Standardize on environments and namespaces 3. Everything about a service should be in one place in git 4. Make best practices the default by generating configuration 5. Configuration should be versioned and refactored automatically. 6. Create an opinionated kubectl wrapper that automates common workflows 7. CI/CD should run the same commands that engineers run locally, in a container 8. Code and configuration should be deployed with the same process 9. Use custom resources and custom controllers to integrate with your infrastructure 10. Validate configuration as part of CI/CD

2019 Challenges thousands of services running in k8s moving all configuration to gitops workflow w/ custom controllers scaling the cluster / scaling etcd / multi cluster support stateful services / high memory requirements tighter integration with kubectl plugins and more! keno