puppetconf 2016: the challenges with container configuration – david lutterkort, puppet

87

Upload: puppet

Post on 10-Jan-2017

30 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet
Page 2: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

The challenges ofcontainer configuration David Lutterkort @lutterkort [email protected]

Page 3: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Overview

● What is configuration ?

● Immutability

● Build vs Run

● Who configures the scheduler ?

● Conclusions

3

Page 4: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

What is configuration ?

Page 5: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

package/file/service

is only one instance of a more general problem

5

Page 6: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Configuration is any input into infrastructure

It needs to be managed

over time and at scale

6

Page 7: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Core configuration management features:

❏ describe system aspects in isolation

❏ combine aspects into whole

❏ common format for querying

❏ bridge across entire infrastructure

7

Page 8: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker run -d \ -e MYSQL_HOST=mysql.example.com \ -e MYSQL_PORT=3306 \ --health-cmd /usr/bin/check \ webapp

Page 9: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Immutability

Page 10: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker run \ --name example fedora:24 \ /bin/sh -c ‘while true; do \ cat /etc/system-release; \ sleep 1; \ done’

Page 11: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker run …

Fedora release 24 (Twenty Four)Fedora release 24 (Twenty Four)Fedora release 24 (Twenty Four)Fedora release 24 (Twenty Four)Fedora release 24 (Twenty Four)Fedora release 24 (Twenty Four)Fedora release 24 (Twenty Four)Fedora release 24 (Twenty Four)

Page 12: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker exec example /bin/sh -c \ ‘sed -i -e s/24/25/ /etc/system-release’

Page 13: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Fedora release 24 (Twenty Four)Fedora release 24 (Twenty Four)

Fedora release 25 (Twenty Four)Fedora release 25 (Twenty Four)Fedora release 25 (Twenty Four)Fedora release 25 (Twenty Four)Fedora release 25 (Twenty Four)Fedora release 25 (Twenty Four)

$ docker exec …

Page 14: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker diff exampleC /runA /run/secretsC /etcC /etc/system-release

Page 15: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Containers are not immutable by defaultOnly as immutable as packages

15

Page 16: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker run --read-only \ --name example fedora:24 \ /bin/sh -c ‘while true; do \ cat /etc/system-release; \ sleep 1; \ done’

Page 17: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker exec example /bin/sh -c \ ‘sed -i -e s/24/25/ /etc/system-release’sed: couldn't open temporary file /etc/sed5OCs5t: Read-only file system

Page 18: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker diff exampleC /runA /run/secrets

Page 19: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Suggestion

Enable --read-only whenever possible

19

Page 20: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

require 'rubygems'require 'sinatra'require 'haml'

# Handle GET-request (Show the upload form)get "/upload" do haml :uploadend

# Handle POST-request (Receive and save the uploaded file)post "/upload" do File.open('uploads/' + params['myfile'][:filename], "w") do |f|

f.write(params['myfile'][:tempfile].read) end return "The file was successfully uploaded!"end

Page 21: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker run -d --read-only lutter/lolcat

Page 22: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

require 'rubygems'require 'sinatra'require 'haml'

# Handle GET-request (Show the upload form)get "/upload" do haml :uploadend

# Handle POST-request (Receive and save the uploaded file)post "/upload" do

File.open('uploads/' + params['myfile'][:filename], "w") do |f|f.write(params['myfile'][:tempfile].read)

end return "The file was successfully uploaded!"end

Page 23: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker run -d --read-only \ -v /srv/lolcat/uploads:/app/uploads \ lutter/lolcat

Page 24: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

require 'rubygems'require 'sinatra'require 'haml'

# Handle GET-request (Show the upload form)get "/upload" do haml :uploadend

# Handle POST-request (Receive and save the uploaded file)post "/upload" do File.open('uploads/' + params['myfile'][:filename], "w") do |f|

f.write(params['myfile'][:tempfile].read) end return "The file was successfully uploaded!"end

Page 25: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker run -d --read-only \ -v /srv/lolcat/uploads:/app/uploads \ --tmpfs /tmp \ lutter/lolcat

Page 26: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Suggestion

Use --tmpfs where needed

26

Page 27: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Without technical controls you only have

social guarantees of immutability

27

Page 28: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

How do you know the correct

invocation for an image ?

28

Page 29: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Build vs Run

Page 30: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Given an image

❏ What machine built this image ?

❏ How do you run this image ?

❏ Who supports this image ?

❏ Does the image contain malware ?

30

Page 31: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Given a container

❏ Who built it ?

❏ How was it built ?

❏ What software does it contain ?

❏ Is the software up-to-date ?

31

Page 32: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

FROM fedora:24

RUN dnf update -y && \ dnf install -y ruby rubygem-bundler && \ dnf clean all

COPY . /app

RUN cd /app && bundle install --path vendor/bundle

WORKDIR /appVOLUME /app/uploadsEXPOSE 9292CMD ["/usr/bin/bundle", "exec", "rackup"]

Page 33: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

FROM fedora:24

RUN dnf update -y && \ dnf install -y ruby rubygem-bundler && \ dnf clean all

COPY . /app

RUN cd /app && bundle install --path vendor/bundle

WORKDIR /appVOLUME /app/uploadsEXPOSE 9292CMD ["/usr/bin/bundle", "exec", "rackup"]

Where did the base image come from ?

Page 34: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

FROM fedora:24

RUN dnf update -y && \ dnf install -y ruby rubygem-bundler && \ dnf clean all

COPY . /app

RUN cd /app && bundle install --path vendor/bundle

WORKDIR /appVOLUME /app/uploadsEXPOSE 9292CMD ["/usr/bin/bundle", "exec", "rackup"]

What repositories and what package versions ?

Page 35: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

FROM fedora:24

RUN dnf update -y && \ dnf install -y ruby rubygem-bundler && \ dnf clean all

COPY . /app

RUN cd /app && bundle install --path vendor/bundle

WORKDIR /appVOLUME /app/uploadsEXPOSE 9292CMD ["/usr/bin/bundle", "exec", "rackup"]

What was in this directory at build time ?

Page 36: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Time is your enemy

36

Page 37: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

When do you rebuild images ?

37

Page 38: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Code changes and external factors

should trigger rebuild

38

Page 39: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Explain yourself with metadataDocker labels are a great way to do that

39

Page 40: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Name : glibcVersion : 2.23.1Release : 10.fc24Architecture: x86_64License : LGPLv2+ and LGPLv2+ with exceptions and GPLv2+Signature : RSA/SHA256, Thu 18 Aug 2016 09:27:43 AM PDT, Key ID 73bde98381b46521Source RPM : glibc-2.23.1-10.fc24.src.rpmBuild Date : Thu 18 Aug 2016 06:37:42 AM PDTBuild Host : buildvm-16.phx2.fedoraproject.orgPackager : Fedora ProjectVendor : Fedora ProjectSummary : The GNU libc libraries

Page 41: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker inspect \ -f "{{json .Config.Volumes}}" lutter/lolcat{ "/app/uploads": {}}

Page 42: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker inspect \ -f "{{json .Config.ExposedPorts}}" lutter/lolcat{ "9292/tcp": {}}

Page 43: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

LABEL vendor=”ACME Incorporated” \ com.acme.release-status=”beta” \ com.acme.version=”0.1.0-beta” \ com.acme.git.sha=”f260653a”

Page 44: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker inspect \ -f "{{json .Config.Labels}}" lutter/lolcat | jq{ "com.acme.git.sha": "f260653a", "com.acme.release-status": "beta", "com.acme.version": "0.1.0-beta", "vendor": "ACME Incorporated"}

Page 45: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Suggestion

Decide upon and enforcemetadata standards

45

Page 46: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

LABEL com.acme.dockerfile=”/Dockerfile”

Page 47: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker inspect \ -f "{{json .Config.Labels}}" lutter/alpine | jq{ "com.example.dockerfile": "/Dockerfile"}

Page 48: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker run -it lutter/alpine cat /DockerfileFROM alpineRUN apk add --update bash && rm -rf /var/cache/apk/*COPY Dockerfile /LABEL com.example.dockerfile="/Dockerfile"

Page 49: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Suggestion

Embed your Dockerfile in the image

49

Page 50: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

LABEL com.acme.cmd.packages=”apk info -vv”

Page 51: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker run -it lutter/alpine apk info -vvmusl-1.1.14-r12 - the musl c library (libc)busybox-1.24.2-r11 - Size optimized toolbox of ...alpine-baselayout-3.0.3-r0 - Alpine base dir ...alpine-keys-1.1-r0 - Public keys for Alpine Linux ...zlib-1.2.8-r2 - A compression/decompression Librarybash-4.3.42-r3 - The GNU Bourne Again shell...

Page 52: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Suggestion

Make your images discoverable

52

Page 53: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

puppetlabs/puppetlabs-image_build

Page 54: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

class { 'nginx': }

nginx::resource::vhost { 'default': www_root => '/var/www/html',}

file { '/var/www/html/index.html': ensure => present, content => 'Hello Puppet and Docker',}

exec { 'Disable Nginx daemon mode': path => '/bin', command => 'echo "daemon off;" >> /etc/nginx/nginx.conf', unless => 'grep "daemon off" /etc/nginx/nginx.conf',}

Page 55: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

# metadata.yamlcmd: nginxexpose: 80image_name: puppet/nginx

Page 56: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ puppet docker build...

$ docker run -d -p 8080:80 acme/nginx-test83d5fbe370e84d424c71c1c038ad1f5892fec579d28b...

$ curl http://127.0.0.1:8080Hello Puppet and Docker

Page 57: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Who configures the scheduler ?

Page 58: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Schedulers/orchestrators isolate you from

❏ where individual containers run

❏ balancing due to new resources

❏ respawning due to failed resources

58

Page 59: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Schedulers operate on constraints

59

Page 60: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Decisions depend on accurate resource

information

60

Page 61: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker daemon \ --label environment=production \ --label storage=ssd

Page 62: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker run -d -P \ --label com.example.environment=production \ -e constraint:storage==ssd --name db mysql

Page 63: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

template: metadata: labels: app: guestbook tier: frontend spec: containers: - name: php-redis image: gcr.io/google-samples/gb-frontend:v4 resources: requests: cpu: 100m memory: 100Mi env: - name: GET_HOSTS_FROM value: dns # If your cluster config does not include a dns service, then to # instead access environment variables to find service host # info, comment out the 'value: dns' line above, and uncomment the # line below. # value: env ports: - containerPort: 80

Page 64: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

How do you manage properties

for all your hosts ?

64

Page 65: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Suggestion

Compute host properties dynamically

65

Page 66: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ facter -y | head -n 20aio_agent_version: 1.7.0augeas: version: 1.4.0disks: sda:

model: SanDisk SDSSDA24size: 223.57 GiBsize_bytes: 240057409536vendor: ATA

...dmi: bios: ...memory:...

Page 67: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker daemon \ --label os=$(facter os.family) \ --label kernel=$(facter kernelversion) \ --label memory=$(facter memory.system.total_bytes)

Page 68: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

https://forge.puppet.com/puppetlabs/docker_platform

Page 69: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

class { 'docker': labels => [ "os=${facts[os][family]", "kernel=${facts[kernelversion]}", "memory=${facts[memory][system][total_bytes]}" ],}

Page 70: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Schedulers introduce higher-level primitives

70

Page 71: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Docker networks

Kubernetes services and replication controllers

Chronos jobs

71

Page 72: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Many interfaces imperative not declarative

72

Page 73: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ kubectl get pod mypod -o yaml \ | sed -e ‘s/\(image:myimage\):.*$/\1:v4/’ \ | kubectl replace -f -

Page 74: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

$ docker network create bobca7b185775966003d38ccbd9bba822fb570766e4bb

$ docker network create bobError response from daemon: network with name bob ...

Page 75: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

docker_network { 'bob': ensure => present, driver => 'overlay', subnet => '192.168.1.0/24', gateway => '192.168.1.1', ip_range => '192.168.1.4/32',}

Page 76: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

And everything is in YAML

76

Page 77: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

“The language to represent the data should be a simple, data-only

format such as JSON or YAML, and programmatic modification of

this data should be done in a real programming language, where

there are well-understood semantics, as well as good tooling.

Borg, Omega, and Kubernetes, ACM Queue, Volume 14 Issue 1 | http://queue.acm.org/detail.cfm?id=2898444

77

Page 78: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Code plus data has advantages

over data alone

78

Page 79: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

https://forge.puppet.com/garethr/kubernetes

Page 80: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

kubernetes_pod { 'sample-pod': ensure => present, metadata => { namespace => 'default', }, spec => { containers => [{ name => 'container-name', image => 'nginx', }] },}

Page 81: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

controller_service_pair { 'redis-master': app => 'redis', role => 'master', tier => 'backend', port => 6379,}

Page 82: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Conclusions

Page 83: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

The difference between how you think a

system behaves and how it actually behaves

risks hard-to-debug production issues

83

Page 84: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Container use at scale and over time

requires meaningful abstraction

84

Page 85: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

Configuration management as a discipline

provides tools to build those abstractions and

thereby minimize risk

85

Page 86: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet

86

Project Blueshift boothExhibition Hall

Docker, Mesos, Kubernetes and Puppet? Don't Panic !Deepak Giridharagopal, Thur, 4:45pm

Pulling the strings to containerize your lifeScott Coulton, Fri, 9:50am

Running Puppet software in Docker containersGareth Rushgrove, Fri, 1:30pm

Page 87: PuppetConf 2016: The Challenges with Container Configuration – David Lutterkort, Puppet