Showing posts with label docker. Show all posts
Showing posts with label docker. Show all posts

Thursday, November 14, 2019

Docker: контейнеры это не виртуальные машины

Всем привет!
Docker выпустил небольшую книжечку "Docker for the Virtualization Admin", поэтому я решил ее быстренько пролистать и поделиться своим мнением, что там интересного.
И вот что я для себя выделил.

Когда начинаешь работать с докером, контейнеры описываются как "легкие виртуальные машины” и это понятно, потому как 2 технологии(docker and VMs) используют похожие характеристики.
2 главных критерия сходства:
  • Каждый из них предназначен для обеспечения изолированной
    среды, в которой выполняется некоторое приложение. 
  • Каждая среда представлена в виде двоичного артефакта (binary artifact), и может быть легко перемещена между хостами.

Ключевое различие заключается в архитектуре! Контейнеры и виртуальные машины имеют похожие преимущества изоляции и распределения ресурсов, но функционируют по-разному: контейнеры виртуализируют операционную систему вместо аппаратных ресурсов. Эта облегченная форма показывает эффект создания контейнеров как более портативных, так и более эффективных, чем виртуальные машины. Другая форма сравнения, виртуалка - огромный приусадебный дом, а контейнер - небольшая квартира. Примерно, все тоже самое, но в совсем в других размерах и абстракциях.
Администратор создает образ Docker, который включает в себя только необходимое для запуска своего приложения. Виртуальная машина собирается в обратном направлении: начиная с полной операционной системы и, в зависимости от приложения, добавляются нужные компоненты.
Виртуальная машина по-прежнему рассматривается как сервер, включая традиционное резервное копирование, аварийное восстановления, и другие серверные задачи.
С контейнерами Docker - это движение в сторону микросервисов, единственная служба, которая и является приложением. В архитектуре микросервисов существует множество небольших служб, каждый представлен как одиночный контейнер Docker, содержит
только свое приложение. Большие и тяжелые приложения теперь могут быть деконструированы на небольшие компоненты(контейнеры).

Как забэкапить контейнер?
А никак! Данные приложения не живут в контейнере, они живут в томе(docker volume), который совместно используется между одним или несколькими контейнерами, как определено архитектурой приложения. Тома поддерживают различные виды бэкапирования, включая облачное, поэтому администратор создает резервную копию тома данных, и забывает о контейнере.

Как управлять обновлениями?
Администратор обновляет существующий образ(image) Docker, останавливает выполнение
контейнера, и запускает заново. Контейнер можно запустить за доли секунды, поэтому эти обновления выполняются намного быстрее, чем на виртуальной машине. Нет необходимости перезагружать всю ОС-просто остановите старую версию вашего контейнера и запустите  снова из нового образа.

И самый главный вопрос - где лучше запускать контейнеры на виртуальных серверах или на физических? 
Эксперты докера отвечают "все зависит от ...". А далее от того чем вы располагаете, то к чему стремитесь, что хотите получить в итоге. Любое ИТ-решение основано на множестве переменных: производительности, масштабируемости, надежности, безопасности и др.
Docker предоставляет вам возможность развернуть приложения без проблем, независимо от базовой инфраструктуры, будь то железный сервер или виртуальная машина, центр обработки данных или публичное облако. Основное тут ,что вы можете в дальнейшем перенести ваше приложение на другую платформу.

Задержка (Latency). Приложения с низким порогом задержки лучше разворачивать на  физических серверах. Как пример, торговые приложения(площадки). 

Доступное пространство(Capacity). Если ваши контейнерные приложения не потребляют всю емкость на физическом сервере, виртуализация предлагает преимущество преимущество. Например, можно назначить данное пространство для песочницы для разработчиков.

Смешанные Операционные Системы(Mixed Operating Systems). Если вам потребуются контейнеры разных ОС, Windows и Linux на одном хосте, вам нужно будет
использовать виртуализацию.

Мультиарендность(Multitenancy). Некоторые приложения испытывают рабочие нагрузки, которые не могут совместно использовать ядра или ресурсы. В этом случае виртуальные машины предоставляют дополнительный слой изоляции по сравнению с контейнерами на физическом сервере.

Пулы Ресурсов / Квоты(Resource Pools /Quotas). Многие решения для виртуализации имеют широкий спектр функций управления и приоритизации использования общих ресурсов виртуальными машинами. Docker предоставляет концепцию ограничений ресурсов для
контейнера, но если вы обеспокоены что эти разрешения будут проигнорированы, виртуальные машины могут добавить еще один пограничный слой



Tuesday, October 15, 2019

Docker: nginx + wordpress + php-fpm

Всем привет!
Продолжаем контейнеризировать все по-тихонечку. На этот раз переведем сайт на использование вордпресс. Сам официальный туториал не вызывает особого интереса - как мне показалось, там довольно все просто. И когда друг ко мне обратился за помощью, я подумал, что там будет все быстро сделано. Но, есть всегда свои но! Вперед:)
Первое, взглянем на оф. документ по инсталяции. Все просто! Нам понадобится docker-compose, если у вас еще не установлен, устанавливаем.
Второе, создаем директорию, где будем размещать все нужные нам файлы. Для начала хочу заметить, что по оф. доку у меня не получилось так быстро все сделать, т.к. WP не захотел работать без php-fpm, поэтому я сразу решал эту проблему. Далее показываю уже работающий конфиг, а ошибку укажу внизу поста.
Создаем docker-compose.yml
version: '3.1'
services:


Далее создаем контейнеры для WP, вашей базы данных - на выбор или Myslq или MariaDb, для Nginx и для PHP.

Контейнер WP, зависит от контейнера с базой данных:
   wordpress:
        image: wordpress
        restart: always
        ports:
            - 8080:80
        depends_on:
            - db
        environment:
            WORDPRESS_DB_HOST: db
            WORDPRESS_DB_USER: exampleuser
            WORDPRESS_DB_PASSWORD: examplepass
            WORDPRESS_DB_NAME: maindb
        volumes:
         - ./html:/var/www/html 


Контейнер с базой данных:
    db:
        image: mysql:5.7
        restart: always
        environment:
            MYSQL_DATABASE: maindb
            MYSQL_USER: exampleuser
            MYSQL_PASSWORD: examplepass
            MYSQL_RANDOM_ROOT_PASSWORD: '1'
        volumes:
         - ./database:/var/lib/mysql
         - ./my.cnf:/etc/my.cnf

Я добавил файл с некоторыми настройками для MySql. Т.к. у меня на сервере мало оперативной памяти, то я сократил размер буфера. если этого не сделать, то демон mysqld будет ругаться и не стартанет. Содержимое my.cnf:
[mysqld]
innodb_buffer_pool_size = 16M


Контейнер с веб-сервером:
   nginx:
        image: nginx3
        ports:
            - 443:443
        volumes:
            - ./nginx:/etc/nginx/
            - ./logs/nginx:/var/log/nginx
            - ./html:/var/www/html
        links:
            - wordpress
            - php
        restart: always

 
Я настроил nginx, чтобы он работал только по 443 порту и выложил все конфиги в директории ./nginx, аналогично для логов. Конфиг для Nginx'a:
server {
        listen       443 ssl http2 default_server;
        listen       [::]:443 ssl http2 default_server;
        server_name  _;
        root   /var/www/html;
       
        ssl_certificate "/etc/ssl/certs/nginx-selfsigned.crt";
        ssl_certificate_key "/etc/ssl/certs/nginx-selfsigned.key";
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;

        location / {
            try_files $uri /index.php?$args;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass php:9000;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
        }
        location /test{
            proxy_pass https://ya.ru;
        }        

}

Тут интерес вызывают только самоподписанные сертификаты и настройки php. Для тестов директория /test перекидывает на сайт яндекса.
Последний контейнер для PHP.
   php:
        build: ./php/
        volumes:
        - ./html:/var/www/html 

 
Для подключения к WP требуется библиотека mysqli, которая не установлена по умолчанию, поэтому собираем из докерфайла образ.  Я образ собираю по докер-файлу, вот содержимое:
FROM php:7-fpm
RUN docker-php-ext-install mysqli


Далее добавляем:
volumes:
    wordpress:
    db:

networks:
    local:


Запустил все с помощью:
docker-compose up -d
Проверяю логи контейнеров:
docker logs IDContainer

На этом настройка Docker'a закончена и далее уже можно переходить к настройкам самого WP. Теперь расскажу на какие грабли я наступил. Ошибки в студию:)
База показывает ошибку:
1) docker wordpress MySQL Connection Error: (2002) Connection refused
2) PHP Warning:  mysqli::__construct(): php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution in Standard input code on line 22
Браузер показывает ошибку:
3) Error establishing a database connection
Неверный формат файла конфига для базы 
4) [ERROR] Found option without preceding group in config file /etc/my.cnf at line 1!

Успехов! 

Wednesday, September 18, 2019

Docker: запускаем Nginx

Логинемся в докер хаб. 
#docker login

 Создадим и запустим простой контейнер на основе Nginx
# docker run --name mynginx1 -P -d nginx
-P (Publish all exposed ports to random ports) сопоставляем порты Nginx(80,443) с произвольным портом из диапазона между 49153 и 65535. 
-d (Run container in background and print container ID) запускаем контейнер в бэкграунде.

Стандартного образа в системе нет, поэтому он был скачан с хаба.
проверяем, что нгинкс работает(номер порта - 52267)
#curl http://localhost:52267

Если вы хотите настроить образ под себя, то нужно модифицировать докерфайл.
Например, сопируем файлы и папки nginx'a.
Файлы, в том числе и  сертификаты, кладем в текущую директорию. Из стандартного образа nginx строим шаблон, открываем порт 443.  
FROM nginx
COPY ./html /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
COPY nginx-selfsigned.crt /etc/ssl/certs/nginx-selfsigned.crt
COPY nginx-selfsigned.key /etc/ssl/certs/nginx-selfsigned.key
EXPOSE 443

Генерируем шаблон
#docker build -t nginx1 .
Запускаем на 443 порту этот шаблон
#docker run -p 443:443 -d nginx1

По умолчанию докер присвоит некоторое имя для вашего контейнера, но вы можете сделать это самостоятельно. Удобнее работать с именованным контейнером. 
#docker run -d -P --name nginxserver nginx1:latest

Если вы хотите добавить некоторые директории в ваш конфиг(не копировать, а смонтировать), то нужно запускать докер таким образом:
docker run --name nginx_server -v /yourfiles/html:/var/www/html:ro \
-v /yourfiles/nginx:/etc/nginx:ro -p 443:443 -d nginx3
\ - используется как перевод каретки(читай объединение строк)
ro - монтируются в контейнер в режиме только чтение

Остановка контейнера с приложением:

#docker stop nginxserver 

Успехов!

Tuesday, September 17, 2019

Docker: архитектура

Docker предоставляет возможность упаковывать и запускать приложение в изолированной среде, называемой контейнером. Изоляция и безопасность позволяют запускать много контейнеров одновременно на одной машине(хосте). Контейнеры являются легкими, потому что не используют гипервизор, но только ресурсы хоста. Docker может быть запущен и на виртуальных машинах, главное чтобы хватило ресурсов!
Docker Engine-это клиент-серверное приложение, состоящее их 3-х основных компонентов:
  •   Сервер, который является типом длительной программы, или проще говоря демон (dockerd). Демон прослушивает запросы API Docker и управляет объектами Docker, такими как изображения, контейнеры, сети и тома.
  •     REST API, определяет интерфейсы, которые программы могут использовать для общения с демоном и инструктировать его, что делать.
  •     Клиент интерфейса командной строки (CLI) (команда docker). Клиент отправляет команды в dockerd, который их выполняет(например, docker run).
Посмотрим на архитектуру докера:

Dockerfile используется как шаблон(набор инструкций), по которому можно сделать образ(docker image). Обратите внимание, что файл создается без разрешения! Каждая инструкция в этом файле создает отдельный слой в образе. При изменении Dockerfile и перестроении изображения перестраиваются только те слои, которые были изменены. Поэтому образы такие легкие и небольшого размера, плюс довольно быстрые, по сравнению с другими технологиями виртуализации.
Например, самый простой dockerfile будет выглядеть так, слой за слоеем:
FROM centos:7
RUN yum update -y
CMD ["bash] 
Создаем образ из этого файла:
#docker build -t image_from .
-f если файл находится вне текущей директории.

На хабре есть отличная статья про файлы докера и команды.
  1. FROM — задаёт базовый (родительский) образ.
  2. LABEL — описывает метаданные. Например — сведения о том, кто создал и поддерживает образ.
  3. ENV — устанавливает постоянные переменные среды.
  4. RUN — выполняет команду и создаёт слой образа. Используется для установки в контейнер пакетов.
  5. COPY — копирует в контейнер файлы и папки.
  6. ADD — копирует файлы и папки в контейнер, может распаковывать локальные .tar-файлы.
  7. CMD — описывает команду с аргументами, которую нужно выполнить когда контейнер будет запущен. Аргументы могут быть переопределены при запуске контейнера. В файле может присутствовать лишь одна инструкция CMD.
  8. WORKDIR — задаёт рабочую директорию для следующей инструкции.
  9. ARG — задаёт переменные для передачи Docker во время сборки образа.
  10. ENTRYPOINT — предоставляет команду с аргументами для вызова во время выполнения контейнера. Аргументы не переопределяются.
  11. EXPOSE — указывает на необходимость открыть порт.
  12. VOLUME — создаёт точку монтирования для работы с постоянным хранилищем.

Docker Image
С помощью docker файла мы сделали новый образ(read only!), который является шаблоном с инструкциями для создания контейнера. Как видно из примера, получившийся шаблон(docker-image) основан на другом шаблоне centos,  но с дополнениями(yum update). Как вариант, вы можете создать свой шаблон, который устанавливает ваше приложение с вашими настройками и конфигами. Также есть возможность опубликовать собственные разработки на docker-hub'e, откуда они будут доступны другим участникам.

Containers(контейнер) - это выполняемый экземпляр образа(самодостаточная ОС, в которой только самое необходимое и код приложения). Вы можете создать, запустить, остановить, переместить или удалить контейнер с помощью Docker API или CLI. Вы можете подключить контейнер к одной или нескольким сетям, присоединить к нему хранилище или даже создать новый образ на основе его текущего состояния.
По умолчанию контейнер изолирован от других контейнеров и от хоста, на котором он запущен. При удалении контейнера все изменения, которые вы сделали за время его работы, если они не хранятся в в постоянном хранилище, потеряются.

Services (сервисы) - позволяют масштабировать контейнеры между несколькими демонами Docker, которые работают вместе в кластере(swarm)с несколькими менеджерами и работниками(manager and workers). Каждый член кластера является демоном Docker, и все демоны взаимодействуют с помощью API Docker.
Служба позволяет определить желаемое состояние, например количество реплик службы, которые должны быть доступны в любой момент времени. По умолчанию служба балансирует нагрузку на всех рабочих узлах кластера.

Успехов!

Friday, September 13, 2019

Docker installation(Установка Докера)

Докер(Docker) - открытая (open) платформа для разработчиков и админов, помогающая проектировать и запускать "контейнеризированные" приложения, главный плюс которого - упаковать приложение со всеми зависимостями в отдельный контейнер(можно даже опубликовать в хабе). Контейнеры не создают такой нагрузки как виртуальные машины, поэтому более эффективно используют ресурсы системы.
"Из википедии: программное обеспечение для автоматизации развёртывания и управления приложениями в среде виртуализации на уровне операционной системы; позволяет «упаковать» приложение со всем его окружением и зависимостями в контейнер, а также предоставляет среду по управлению контейнерами".

Установка Docker'a на CentOS.
1. Для начала нужно удалить старые версии, если они существуют:
#sudo yum remove docker

2. Далее устанавливаем необходимые утилиты и добавляем репозиторий с докером
#yum install -y yum-utils \ device-mapper-persistent-data \ lvm2

 #yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo


3.Далее устанавливаем Docker Engine
#yum install docker-ce docker-ce-cli containerd.io
Установщик предлагает принять PGP-key, проверяем, что ключ совпадает с указанным на сайте:
 060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35
Принимаем.

4. Запускаем Докер
#systemctl start docker
5. Установка завершена, можно запустить первое приложение. 
#docker run hello-world 
 
6. Не забудьте добавить пользователю docker права рута, а то будет неудобно запускать команды используя sudo. И да, я делал все под рутом, что не очень правильно:)
 
Успехов!