+ All Categories
Home > Software > Challenges of container configuration

Challenges of container configuration

Date post: 16-Apr-2017
Category:
Upload: lutter
View: 314 times
Download: 1 times
Share this document with a friend
87
Transcript
Page 1: Challenges of container configuration
Page 2: Challenges of container configuration

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

Page 3: Challenges of container configuration

Overview

● What is configuration ?

● Immutability

● Build vs Run

● Who configures the scheduler ?

● Conclusions

3

Page 4: Challenges of container configuration

What is configuration ?

Page 5: Challenges of container configuration

package/file/service

is only one instance of a more general problem

5

Page 6: Challenges of container configuration

Configuration is any input into infrastructure

It needs to be managed

over time and at scale

6

Page 7: Challenges of container configuration

Core configuration management features:

❏ describe system aspects in isolation

❏ combine aspects into whole

❏ common format for querying

❏ bridge across entire infrastructure

7

Page 8: Challenges of container configuration

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

Page 9: Challenges of container configuration

Immutability

Page 10: Challenges of container configuration

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

Page 11: Challenges of container configuration

$ 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: Challenges of container configuration

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

Page 13: Challenges of container configuration

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: Challenges of container configuration

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

Page 15: Challenges of container configuration

Containers are not immutable by defaultOnly as immutable as packages

15

Page 16: Challenges of container configuration

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

Page 17: Challenges of container configuration

$ 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: Challenges of container configuration

$ docker diff exampleC /runA /run/secrets

Page 19: Challenges of container configuration

Suggestion

Enable --read-only whenever possible

19

Page 20: Challenges of container configuration

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: Challenges of container configuration

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

Page 22: Challenges of container configuration

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: Challenges of container configuration

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

Page 24: Challenges of container configuration

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: Challenges of container configuration

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

Page 26: Challenges of container configuration

Suggestion

Use --tmpfs where needed

26

Page 27: Challenges of container configuration

Without technical controls you only have

social guarantees of immutability

27

Page 28: Challenges of container configuration

How do you know the correct

invocation for an image ?

28

Page 29: Challenges of container configuration

Build vs Run

Page 30: Challenges of container configuration

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: Challenges of container configuration

Given a container

❏ Who built it ?

❏ How was it built ?

❏ What software does it contain ?

❏ Is the software up-to-date ?

31

Page 32: Challenges of container configuration

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: Challenges of container configuration

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: Challenges of container configuration

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: Challenges of container configuration

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: Challenges of container configuration

Time is your enemy

36

Page 37: Challenges of container configuration

When do you rebuild images ?

37

Page 38: Challenges of container configuration

Code changes and external factors

should trigger rebuild

38

Page 39: Challenges of container configuration

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

39

Page 40: Challenges of container configuration

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: Challenges of container configuration

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

Page 42: Challenges of container configuration

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

Page 43: Challenges of container configuration

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

Page 44: Challenges of container configuration

$ 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: Challenges of container configuration

Suggestion

Decide upon and enforcemetadata standards

45

Page 46: Challenges of container configuration

LABEL com.acme.dockerfile=”/Dockerfile”

Page 47: Challenges of container configuration

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

Page 48: Challenges of container configuration

$ 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: Challenges of container configuration

Suggestion

Embed your Dockerfile in the image

49

Page 50: Challenges of container configuration

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

Page 51: Challenges of container configuration

$ 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: Challenges of container configuration

Suggestion

Make your images discoverable

52

Page 53: Challenges of container configuration

puppetlabs/puppetlabs-image_build

Page 54: Challenges of container configuration

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: Challenges of container configuration

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

Page 56: Challenges of container configuration

$ puppet docker build...

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

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

Page 57: Challenges of container configuration

Who configures the scheduler ?

Page 58: Challenges of container configuration

Schedulers/orchestrators isolate you from

❏ where individual containers run

❏ balancing due to new resources

❏ respawning due to failed resources

58

Page 59: Challenges of container configuration

Schedulers operate on constraints

59

Page 60: Challenges of container configuration

Decisions depend on accurate resource

information

60

Page 61: Challenges of container configuration

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

Page 62: Challenges of container configuration

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

Page 63: Challenges of container configuration

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: Challenges of container configuration

How do you manage properties

for all your hosts ?

64

Page 65: Challenges of container configuration

Suggestion

Compute host properties dynamically

65

Page 66: Challenges of container configuration

$ 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: Challenges of container configuration

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

Page 68: Challenges of container configuration

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

Page 69: Challenges of container configuration

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

Page 70: Challenges of container configuration

Schedulers introduce higher-level primitives

70

Page 71: Challenges of container configuration

Docker networks

Kubernetes services and replication controllers

Chronos jobs

71

Page 72: Challenges of container configuration

Many interfaces imperative not declarative

72

Page 73: Challenges of container configuration

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

Page 74: Challenges of container configuration

$ docker network create bobca7b185775966003d38ccbd9bba822fb570766e4bb

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

Page 75: Challenges of container configuration

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: Challenges of container configuration

And everything is in YAML

76

Page 77: Challenges of container configuration

“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: Challenges of container configuration

Code plus data has advantages

over data alone

78

Page 79: Challenges of container configuration

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

Page 80: Challenges of container configuration

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

Page 81: Challenges of container configuration

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

Page 82: Challenges of container configuration

Conclusions

Page 83: Challenges of container configuration

The difference between how you think a

system behaves and how it actually behaves

risks hard-to-debug production issues

83

Page 84: Challenges of container configuration

Container use at scale and over time

requires meaningful abstraction

84

Page 85: Challenges of container configuration

Configuration management as a discipline

provides tools to build those abstractions and

thereby minimize risk

85

Page 86: Challenges of container configuration

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: Challenges of container configuration

Recommended