2017-03-11 02 Денис Нелюбин. docker & ansible - лучшие друзья devops
TRANSCRIPT
![Page 1: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/1.jpg)
Docker & AnsibleDevOps best friends
Denis Nelubin7bits
![Page 2: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/2.jpg)
Docker● Blue whale● Good UI over (not only) Linux containers
○ And infrastructure
● Vanguard of containerization● Container != Virtual Machine
![Page 3: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/3.jpg)
Containers & Images● Pull image● Run image as container● Save changes as image● Run image as container● …● Push image
![Page 4: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/4.jpg)
Image Layers● Copy-on-Write● Diffs on filesystem
![Page 5: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/5.jpg)
Dockerfile● Image build automation
FROM java:7-jreMAINTAINER Denis Nelubin <[email protected] >RUN apt-get update \&& DEBIAN_FRONTEND=noninteractive apt-get install -y \ curl \ postfix \ rsyslog \&& rm -rf /var/lib/apt/lists/*EXPOSE 25RUN curl -L https://github.com/kelseyhightower/confd/releases/download/v0.11.0/confd-0.11.0-linux-amd64 -o /usr/local/bin/confd \&& chmod 755 /usr/local/bin/confdCOPY etc/ /etc/WORKDIR /opt/coolappCOPY ./docker/docker-entrypoint.sh /CMD ["/bin/bash", "-e", "/docker-entrypoint.sh"]
![Page 6: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/6.jpg)
Ports & Networks● Network between containers● Exposed ports
![Page 7: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/7.jpg)
Volumes● Access to host filesystem● Put something changeable
to container● Extract something persistent
from container
![Page 8: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/8.jpg)
Docker Compose● Bring multiple containers together
version: '2'services: app: image: openjdk:8-jre-alpine volumes: - ./coolapp/build/libs/coolapp-0.0.1-SNAPSHOT.jar:/app.jar command: java -jar /app.jar --spring.profiles.active=docker --server.port=8080 ports: - "8088:8080" environment: DATABASE_URL: jdbc:postgresql://db:5432/postgres DATABASE_USERNAME: postgres DATABASE_PASSWORD: links: - db depends_on: - db
![Page 9: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/9.jpg)
Example
![Page 10: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/10.jpg)
Databasedb: image: postgres:9.5 # https://hub.docker.com/_/postgres/ environment: TZ: "US/Central" volumes: - ./postgres:/docker-entrypoint-initdb.d:ro ports: - "54320:5432"
![Page 11: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/11.jpg)
Applicationapp: image: openjdk:8-jre-alpine # https://hub.docker.com/_/openjdk/
volumes: - ./app/build/libs/app-0.0.1-SNAPSHOT.jar:/app.jar command: java -jar /app.jar --server.port=9001 ports: - "9001:9001"
environment: DATABASE_URL: jdbc:postgresql://db:5432/postgres DATABASE_USERNAME: postgres DATABASE_PASSWORD: TZ: "US/Central"
links: - db depends_on: - db
![Page 12: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/12.jpg)
Proxyproxy: image: nginx:stable-alpine # https://hub.docker.com/_/nginx/
environment: TZ: "US/Central" volumes: - ./frontend/static:/usr/share/nginx/html:ro - ./proxy/etc/nginx.conf:/etc/nginx/nginx.conf:ro links: - app
![Page 13: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/13.jpg)
Alpine Linuxhttps://alpinelinux.org/
● Lightweight Linux distribution
Docker Images:
● Alpine-based● Debian-based● Ubuntu-based
![Page 14: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/14.jpg)
Development vs Production● Standard images● Code as volumes● Data in containers (temporary)● Configuration with environment● Docker network — OK
● All (debug) ports are exposed● Non-privileged ports are exposed
● Custom images (Dockerfiles)● Code "baked" to image● Data in volumes (persistent)● Configuration with environment● Docker network? Swarm?
Kubernetes? Expose ports?
● Public ports are exposed● Privileged ports are exposed
![Page 15: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/15.jpg)
EnvironmentSystem.getenv("DATABASE_URL");
spring: datasource: main_db: type: com.zaxxer.hikari.HikariDataSource jdbc-url: ${DATABASE_URL} username: ${DATABASE_USERNAME} password: ${DATABASE_PASSWORD}
Confd
relayhost = {{ getenv "RELAY" }}
/usr/local/bin/confd -onetime -backend env
![Page 16: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/16.jpg)
ConfdTemplate
relayhost = {{ getenv "RELAY" }}
Generate configs
/usr/local/bin/confd -onetime -backend env
![Page 17: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/17.jpg)
ORLY?
![Page 18: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/18.jpg)
Docker in Production: A History of Failurehttps://thehftguy.com/2016/11/01/docker-in-production-an-history-of-failure/
● Breaking changes and regressions● Kernel support (or lack thereof)
○ The AUFS driver is unstable○ The AUFS filesystem was finally dropped in kernel version 4○ OverlayFS development was abandoned within 1 year of its initial release○ Then comes Overlay2
● Docker Registry can’t clean images● Docker MUST NOT run any databases in production, EVER
![Page 19: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/19.jpg)
Ansible● Strange A● Good remote execution tool
○ Requires only SSH and Python 2
● Has tons of modules○ Try to avoid to write a custom module (v<2)
● Pretty configurable○ YAML
● Remote Execution != Configuration Management
![Page 20: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/20.jpg)
Inventory● Hosts● Groups● Host Variables
[coolapp_servers]192.168.238.42 dns_name=cool.example.com
![Page 21: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/21.jpg)
Playbook● What to do with the specified hosts● Apply roles!
- name: Init My Cool App hosts: coolapp_servers remote_user: root roles: - common - postgres - coolapp-postgres - java - nginx - coolapp-nginx
![Page 22: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/22.jpg)
Roles● Tasks● Role Variables● Files● Templates● Handlers
● Can be taken from Ansible Galaxy○ https://galaxy.ansible.com/
![Page 23: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/23.jpg)
Tasks● One action● Parameters● Verification before apply
○ Idempotence
● Standard/Built-in/Out-of-the-box
![Page 24: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/24.jpg)
Handlers● Conditional actions● Applied after all tasks executed● Use them to restart a service when the config was changed
![Page 25: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/25.jpg)
Ansible
![Page 26: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/26.jpg)
Variables● Host Variables● Group Variables● Playbook Variables● Role Variables● Role Defaults● ...
![Page 27: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/27.jpg)
Database# https://www.postgresql.org/download/linux/debian/- name: install apt key apt_key: url=https://www.postgresql.org/media/keys/ACCC4CF8.asc state=present- name: add apt repository apt_repository: repo='deb http://apt.postgresql.org/pub/repos/apt/
jessie-pgdg main' state=present filename='pgdg'
- name: install postgres apt: name='postgresql-{{ postgres_version }}'- name: install postgres contrib apt: name='postgresql-contrib-{{ postgres_version }}'- name: start postgres service: name=postgresql state=started
![Page 28: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/28.jpg)
Database for app- name: create postgres user postgresql_user: name='{{ coolapp_db_user }}' password='{{ coolapp_db_password }}' become: true become_user: postgres- name: create postgres database postgresql_db: name='{{ coolapp_db_name }}' owner='{{ coolapp_db_user }}' become: true become_user: postgres- name: add postgres ltree extension postgresql_ext: name=ltree db='{{ coolapp_db_name }}' become: true become_user: postgres
![Page 29: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/29.jpg)
Java- name: add backports repository apt_repository: repo: 'deb {{ java_debian_mirror }} jessie-backports main' state: present filename: 'jessie-backports'- name: install java apt: name: - '{{ java_package }}' - 'ca-certificates-java' default_release: 'jessie-backports'
![Page 30: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/30.jpg)
Application- name: add user user: name='{{ coolapp_user }}' system=yes- name: create base dir file: path='{{ coolapp_basedir }}' owner='{{ coolapp_user }}' state=directory- name: copy jar file copy: src='{{ item }}' dest='{{ coolapp_basedir }}/app.jar' owner='{{ collapp_user }}' with_fileglob: - ../../../coolapp/build/libs/coolapp-*.jar notify: restart service
- name: create service config template: src=service dest='/etc/systemd/system/{{ coolapp_service_name }}.service' notify: reload systemd- name: enable service service: name='{{ coolapp_service_name }}' enabled=yes- name: start service service: name='{{ coolapp_service_name }}' state=started
![Page 31: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/31.jpg)
Systemd Unit[Unit]Description={{ coolapp_service_description }}[Service]Type=simpleWorkingDirectory={{ coolapp_basedir }}ExecStart={{ collapp_java }} -jar app.jar --server.port={{ coolapp_port }}User={{ coolapp_user }}Environment=DATABASE_URL=jdbc:postgresql://{{ coolapp_db_host }}:5432/{{ coolapp_db_name }}
Environment=DATABASE_USERNAME={{ coolapp_db_user }}Environment=DATABASE_PASSWORD={{ coolapp_db_password }}[Install]WantedBy=multi-user.target
![Page 32: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/32.jpg)
Nginx- name: add backports repository apt_repository: repo='deb {{ nginx_debian_mirror }} jessie-backports main' state=present filename='jessie-backports'
when: ansible_os_family == 'Debian'- name: install nginx apt: name=nginx default_release=jessie-backports state=latest when: ansible_os_family == 'Debian'- name: install nginx yum: name=nginx state=latest when: ansible_os_family == 'RedHat'- name: enable nginx service: name=nginx enabled=yes- name: start nginx service: name=nginx state=started
![Page 33: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/33.jpg)
Nginx for app- name: generate DH params command: openssl dhparam -out /etc/nginx/dhparams.pem 2048 args: creates: /etc/nginx/dhparams.pem- name: copy nginx configuration template: src=config dest=/etc/nginx/sites-available/{{ coolapp_site_config }} notify: restart nginx- name: enable nginx configuration file: src=/etc/nginx/sites-available/{{ coolapp_site_config }} dest=/etc/nginx/sites-enabled/{{ coolapp_site_config }} state=link
notify: restart nginx
- name: validate nginx configuration command: /usr/sbin/nginx -t changed_when: false
![Page 34: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/34.jpg)
Let's Encrypt# https://github.com/thefinn93/ansible-letsencrypt- role: letsencrypt letsencrypt_webroot_path: /var/www/html letsencrypt_email: [email protected] letsencrypt_cert_domains: - '{{ dns_name }}' letsencrypt_renewal_command_args: '--renew-hook "systemctl restart nginx"'
![Page 35: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/35.jpg)
Docker → Ansible● Docker Service → Ansible Roles
○ Role for base image■ Take care on versions
○ Role for this project modifications
● Configuration by Environment○ Systemd Units
● Template config files● Take care on network
○ Open ports in firewall○ Define addresses of depending services
![Page 36: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/36.jpg)
Ansible Notes● Variables hell● Don't use nested variables coolapp.basedir
○ Hard to override
● Roles are fragile○ Be ready to fix them on next deploy○ Ansible Galaxy is mostly useless
● Can you trust 3rd party roles?○ Read them carefully○ Do it yourself
● Never change anything on servers manually○ Modify roles and apply them
● Ansible Roles and Playbooks — the best deployment documentation
![Page 37: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/37.jpg)
Docker vs Ansible● Run everything
on developer's machine● Official images from Hub● Environment variables
(via Docker Compose)● Config file templates
(via Confd)● docker-compose.yml, Dockerfile
● Run everything on production
● Official packages from repos● Environment variables
(via Systemd Units)● Config file templates
(via built-in Ansible templates)● Roles and everything
Anyway you may need Ansible to install Docker/Swarm/Kubernetes ;)
![Page 38: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/38.jpg)
Girls vs DevOps
![Page 39: 2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps](https://reader030.vdocuments.net/reader030/viewer/2022020718/58ce67d01a28ab2f268b6f43/html5/thumbnails/39.jpg)
https://www.slideshare.net/lilobase/devops-a-brief-introduction-to-vagrant-ansible