Real world Docker – Intro or nah? – Configuration management



Real world Docker – Intro or nah? – Configuration management

0 0


real-world-docker

Docker tips

On Github jlabusch / real-world-docker

Real world Docker

@jlabusch

Intro or nah?

docker image much faster than building an AMI

Docker architecture

Microservices & The 12 Factor App

Development workflow

Production essentials

  • Configuration management
  • Deployment
  • Logging
  • Monitoring
  • Debugging
  • Security

Configuration management

The purpose of Configuration Management is to establish and maintain the integrity of work products using configuration identification, configuration control, configuration status accounting, and configuration audits. — CMMI-SE/SW, V1.02

bare minimum stuff for capability maturity model integration level 2 puppet + git processes too, not just tools

...applied to Docker

  • Host level
  • Container level
  • Organisation level

Host level

Bread and butter stuff

  • Configure host OS
  • Install docker engine
  • Start containers

Supported by Puppet, Chef, Ansible, Salt, …

Container level

  • Configuration applied during new image builds
  • Replace containers, don't upgrade them
  • Treat running containers as read-only
Probably masterless via puppet apply.

Organisation level

  • Share playbooks between containers and hosts, and between teams and projects
  • Slot into existing management and audit processes

Deployment

Starting simply…

 

Let's start from first principles.

Dev

  • Dev commits change
  • CI builds image and tags it
  • CI pushes image to registry

Ops

  • Pull image
  • Stop/rm/rmi
  • Tag?
  • Run

Now with zero downtime

docker pull, docker stop, docker rm/rmi, docker tag, docker run multiple containers on different ports, HAproxy load balancing (https://github.com/DevTable/gantryd)

Key infrastructure

  • Image registry
  • Orchestration layer

Image registry

  • Your own private registry → totally doable
  • Registry Docker image available (of course)
  • Supports different storage backends (files, S3, …)
setup: # curl -sSL https://get.docker.com/ | sh # Set DOCKER_OPTS="--insecure-registry example.com:5001" in /etc/default/docker # sudo service docker restart # registry only: gen SSL certs as per https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-docker-registry-on-ubuntu-14-04 REGISTRY $ docker run -d -p 5001:5000 --restart=always --name registry -v $PWD/certs:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/dev-docker-registry.com.crt -e REGISTRY_HTTP_TLS_KEY=/certs/dev-docker-registry.com.key registry:2 REGISTRY $ docker ps REGISTRY CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES REGISTRY c76096a64cab registry:2 "/bin/registry /etc/d" 3 seconds ago Up 2 seconds 0.0.0.0:5001->5000/tcp registry REGISTRY $ docker images REGISTRY REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE REGISTRY registry 2 2f1ef7702586 2 days ago 220.6 MB REGISTRY $ docker images example.com:5001 REGISTRY REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE REGISTRY $ curl -k -i https://localhost:5001/v2/ REGISTRY HTTP/1.1 200 OK REGISTRY Content-Length: 2 REGISTRY Content-Type: application/json; charset=utf-8 REGISTRY Docker-Distribution-Api-Version: registry/2.0 REGISTRY Date: Sat, 15 Aug 2015 23:54:13 GMT REGISTRY REGISTRY {} REGISTRY BUILDER $ docker pull busybox BUILDER $ docker tag busybox example.com:5001/busybox:x.y.z BUILDER $ docker push example.com:5001/busybox:x.y.z RUNNER $ docker pull example.com:5001/busybox:x.y.z RUNNER $ docker run -it example.com:5001/busybox:x.y.z

Orchestration

  • Deployment
  • Scaling and packing
  • Availability
Deployment: staging/prod, A/B testing, rolling updates Scaling/packing: auto-scaling + effective use of hardware Availability: auto-restart, load balancing

Orchestration

  • For small systems, DIY can work
Orchestration: zero downtime deploys and rollbacks with puppet. Swarm beta: constraints, resource affinity. placement strategies - bin packing, random, spread constraints - based on labels you specify on daemon startup affinities - automatic for -link, -volumes-from, -net=container TODO: fault tolerance, HA scheduler Kubernetes (koo-ber-net-ees or k8s): - pods containing 1 or more cooperating containers - Pods serve as units of deployment and horizontal scaling/replication. - replication controllers create multiple pod replicas and create replacements when one (or its host) fails - no affinity-based co-scheduling - Kubernetes encourages a flat address space and does not dynamically allocate ports, instead allowing users to select whichever ports are convenient for them. To achieve this, it allocates an IP address for each pod. - Service abstraction which provides a stable IP address and DNS name for dynamic set of pods e.g. micro-service. Defined using label selector - can refer to any set of pods. Connections forwarded by a local agent (kube proxy) running on the source machine, to one of the back-end containers. Exact back-end is chosen by round-robin. Kube proxy takes care of tracking pods as they're replaced, so the service IP address (and DNS name) never changes. - http://kubernetes.io/v1.0/docs/design/architecture.png?raw=true - Turn Docker iptables networking off with --iptables=false --ip-masq=false on the Docker dameon, but it should not trigger anyway. - Public IP - real-deal IP of a host running a kube proxy. Portal IP is just for inter-container access within kubernetes - portal IPs never leave a single host. - By default, the container hits its default gateway (the host) when looking for the portal IP. The portal IP is referenced in the iptables rule which sends that traffic to the host IP on a particular port. The kube-proxy (running locally) is listening on that port, picks up that traffic, and then load balances it round robin to a pod IP address. That pod can be running on any other host across the kubernetes cluster. - replication controllers can also be used to maintain availability of master-elected, sharded, and worker-pool applications. Such applications should use dynamic work assignment mechanisms, such as the etcd lock module or RabbitMQ work queues, as opposed to static/one-time customization of the configuration of each pod, which is considered an anti-pattern - can change scaling programmatically, e.g. in response to monitoring feedback - kubectl resize/rolling-update (creates a new replication controller) Single process - oversimplification. Think single role instead.

Logging

Can output in logstash format (or text or json)

Monitoring

Tools like NewRelic APM and check_docker

Debugging

Security

Questions?

Real world Docker @jlabusch