Страницы

Поиск по вопросам

Показаны сообщения с ярлыком docker-compose. Показать все сообщения
Показаны сообщения с ярлыком docker-compose. Показать все сообщения

суббота, 11 января 2020 г.

Docker: можно ли контейнер, созданный из Windows разместить на Linux?

#c_sharp #администрирование #docker #aspnet_core #docker_compose


У нас стартап и мы все еще активно пополняемся единомышленниками, но наш продукт
уже в скором времени близится к пилотному запуску. ПО наше состоит из следующих модулей:


API — проект ASP.NET Core Web API 2 
MySQL
Web-клиент — приложение на Angular 5. Мы не скрестили ASP.NET Core и
Angular, а разрабатываем веб-клиент Angular отдельно с Node.js на борту.


Стоит задача, организовать стратегию менее безболезненного развертывания всех трех
узлов на инфраструктуре клиента, естественно с учетом того что будет написан туториал
по инсталяции и что установкой будет заниматься техническая служба клиента.

Операционная система, которая будет крутиться на сервере клиента неизвестна и хотелось
сделать некий универсальный процесс инсталяции который подходил бы как на Windows так
и для Linux. Понятное дело, что за универсальность надо платить.

Как писал выше, мы только развивающийся отряд, и мы не имеем пока еще в арсенале
хорошего специалиста-администратора с большим опытом решения подобных задач по развертыванию.

Docker. Докер, Docker и еще раз Докер. Естественно в первую очередь программисту
приходит в голову это ПО одной из задач (я сказал одной из) которого является избавить
программиста от проблем развертывания и дать максимально сфокусироваться на кодинге.
Ох если бы это было так.

Прокси-сервер. И как не крути, но плюс к Kestrel/HTTP.sys какой-то из серверов Apache,
IIS, nginx и т.д. все же нужен на сколько понял я. Даже если клиент планирует работать
с нашим продуктом только внутри корпоративной сети. 
Дела с HTTP.sys конечно лучше: он не такой голый как Kestrel, но у нас то речь об
универсальности, а HTTP.sys только для Windows.
Пытался к примеру установить nginx на Windows Server в качестве эксперимента: мама
родная, со стороны казалось, что я в первый раз вижу компьютер).



И если можно я задал бы два вопроса:

1) Первый вопрос он более общий, вы наверное догадались: что посоветуете?

2) А теперь, чтобы конкретизироваться: я сейчас работаю на Windows 10 и если я задумал
использовать Docker, то я ведь правильно понимаю, что мне надо создать четыре контейнера


Контейнер с прокси-сервером (Apache, nginx или IIS)
Контейнер с СУБД MySQL
Контейнер с Angular-приложением
Контейнер с проектом ASP.NET Core 2 Web API


Можно ли это сделать прямо из Windows? То есть будет ли работать контейнер созданный
на Windows-машине на Linux?
    


Ответы

Ответ 1



Docker под Windows может работать в двух режимах - Windows Containers и Linux Containers. Режимы переключаются через иконку в трее: В режиме Windows Containers он собирает и хостит контейнеры прямо в текущей операционке. Собранные в этом режиме контейнеры нельзя разместить под Linux. В режиме Linux Containers он на самом деле собирает и запускает контейнеры на линуксовой виртуалке - она видна в Hyper-V Manager. Собранные в этом режиме контейнеры можно разместить под Linux. Под каждый рантайм есть свой набор тэгов - все доступные можно посмотреть на https://hub.docker.com/r/microsoft/aspnetcore/ Т.е. да, вы можете включить режим Linux Containers, собрать набор из 4-х контейнеров (взяв nginx в качестве прокси), и потом запустить все это под Linux.

воскресенье, 29 декабря 2019 г.

Как не загружать модули с requirements при каждом старте контейнера docker?

#python #docker #docker_compose


Всем привет,

docker-compose.yml

version: '2'

services:
  web:
    build: .
    command: python3 testDj/manage.py runserver 0.0.0.0:8000
    ports:
      - "8888:8000"


Dockerfile

FROM python:3


WORKDIR /opt/web/app
COPY . /opt/web/app


RUN pip3 install -r requirements.txt


Как закэшировать загруженные модули?

При старте докера выполняется загрузка модулей пайтоне, а это долго.

Запускаю докер с pycharm docker-compose
    


Ответы

Ответ 1



Необходимо сначала скопировать requirements.txt, и поставить пакеты, а потом копировать весь проект. Т.к. докер собирает слоями, то он начнет с того места, где произошли изменения, и не будет ставить пакеты заново. Dockerfile должен будет выглядеть следующим образом: FROM python:3 COPY requirements.txt /opt/web/app RUN pip3 install -r requirements.txt WORKDIR /opt/web/app COPY . /opt/web/app

Ответ 2



docker-compose.yml version: '2' services: web: image: python:3 container_name: python_web volumes: - ./:/opt/web/app working_dir: /opt/web/app command: python3 testDj/manage.py runserver 0.0.0.0:8000 ports: - "8888:8000" В этом случаи Dockerfile вовсе не нужен. Makefile # Start docker container start-container: docker-compose up -d # Stop docker container stop-container: docker-compose stop # Dependencies dep-install: pip3 install -r requirements.txt # Dependencies install into container dep-install-into-container docker-compose exec web bash -c "make dep-install" В любой момент можно поставить зависимости не останавливая контейнер, правда я не знаю, как это будет взаимодействовать с уже запущенном приложении. С питоном никогда не работал. Я бы так сделал

понедельник, 9 декабря 2019 г.

Как оптимизировать деплой через docker-compose?

#php #docker #gitlab #docker_compose #gitlab_ci


Мы реализовали деплой через GitLab CI и docker-compose. В процессе деплоя на удалённый
сервер копируется файл docker-compose.yml и файлы Dockerfile и пр. для создания "вспомогательных"
контейнеров типа nginx и mysql

Всё работает как нужно. Беспокоят 2 момента: даунтайм и "мусорные" образы docker
(те, что с  в колонке TAG в docker images)

Вот кусок файла .gitlab-ci.yml, ответственный собственно на деплой на удалённый сервер:

.template-secure-copy: &secure-copy
    stage: deploy
    image: covex/alpine-git:1.0
    before_script:
      - eval $(ssh-agent -s)
      - ssh-add <(echo "$SSH_PRIVATE_KEY")
    script:
      - ssh -p 22 $DEPLOY_USER@$DEPLOY_HOST 'set -e ;
          rm -rf '"$DEPLOY_DIRECTORY"'_tmp ;
          mkdir -p '"$DEPLOY_DIRECTORY"'_tmp'
      - scp -P 22 -r build/* ''"$DEPLOY_USER"'@'"$DEPLOY_HOST"':'"$DEPLOY_DIRECTORY"'_tmp'
# */ <-- в оригинале строка не закоментирована =)
      - ssh -p 22 $DEPLOY_USER@$DEPLOY_HOST 'set -e ;
          cd '"$DEPLOY_DIRECTORY"'_tmp ;
          docker login -u gitlab-ci-token -p '"$CI_JOB_TOKEN"' '"$CI_REGISTRY"' ;
          docker-compose pull ;
          if [ -d '"$DEPLOY_DIRECTORY"' ]; then cd '"$DEPLOY_DIRECTORY"' && docker-compose
down --rmi local && rm -rf '"$DEPLOY_DIRECTORY"'; fi ;
          cp -r '"$DEPLOY_DIRECTORY"'_tmp '"$DEPLOY_DIRECTORY"' ;
          cd '"$DEPLOY_DIRECTORY"' ;
          docker-compose up -d --remove-orphans ;
          docker-compose exec -T php phing app-deploy -Dsymfony.env=prod ;
          rm -rf '"$DEPLOY_DIRECTORY"'_tmp'
    tags:
      - executor-docker


Даунтайм сейчас - это 1-2-3 минуты. Начинается он с docker-compose down ... и до
конца выполнения скрипта. Хочется его уменьшить.

А как сделать так, чтобы "мусорные" образы docker не появлялись - я вообще не понял.
Про docker image prune знаю, хочется не очищать, а не захламлять.

UPD1:

Файл docker-compose.yml создаётся следующей конструкцией:

.template-docker-compose: &docker-compose
    stage: build
    image: covex/docker-compose:1.0
    script:
      - for name in `env | awk -F= '{if($1 ~ /'"$ENV_SUFFIX"'$/) print $1}'`; do
          eval 'export '`echo $name|awk -F''"$ENV_SUFFIX"'$' '{print $1}'`'='$"$name"'';
        done
      - mkdir build
      - docker-compose -f docker-compose-deploy.yml config > build/docker-compose.yml
      - sed -i 's/\/builds\/'"$CI_PROJECT_NAMESPACE"'\/'"$CI_PROJECT_NAME"'/\./g'
build/docker-compose.yml
      - cp -R docker build
    artifacts:
        untracked: true
        name: "$CI_COMMIT_REF_NAME"
        paths:
          - build/
    tags:
      - executor-docker


В результате этой процедуры получается такой docker-compose.yml:

networks:
  nw_external:
    external:
      name: graynetwork
  nw_internal: {}
services:
  mysql:
    build:
      context: ./docker/mysql
    environment:
      MYSQL_DATABASE: project
      MYSQL_PASSWORD: project
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: project
    expose:
    - '3306'
    networks:
      nw_internal: null
    restart: always
    volumes:
    - database:/var/lib/mysql:rw
  nginx:
    build:
      args:
        app_php: app
        server_name: project-dev1.ru
      context: ./docker/nginx
    depends_on:
      php:
        condition: service_started
    networks:
      nw_external:
        ipv4_address: 192.168.10.13
      nw_internal: null
    ports:
    - 80/tcp
    restart: always
    volumes_from:
    - service:php:ro
  php:
    depends_on:
      mysql:
        condition: service_healthy
    environment:
      ENV_database_host: mysql
      ENV_database_name: project
      ENV_database_password: project
      ENV_database_port: '3306'
      ENV_database_user: project
      ENV_mailer_from: andrey@mindubaev.ru
      ENV_mailer_host: 127.0.0.1
      ENV_mailer_password: 'null'
      ENV_mailer_transport: smtp
      ENV_mailer_user: 'null'
      ENV_secret: ThisTokenIsNotSoSecretChangeIt
    expose:
    - '9000'
    image: gitlab.site.ru:5005/dev1-projects/symfony:master
    networks:
      nw_internal: null
    restart: always
    volumes:
    - /composer/vendor
    - /srv
version: '2.1'
volumes:
  database: {}


Dockerfile для сервиса nginx

FROM nginx:alpine
ARG server_name=docker.local
ARG app_php=app_dev

COPY ./default.conf /etc/nginx/conf.d/default.conf

RUN sed -i 's/@SERVER_NAME@/'"$server_name"'/g' /etc/nginx/conf.d/default.conf \
    && sed -i 's/@APP@/'"$app_php"'/g' /etc/nginx/conf.d/default.conf


Dockerfile для сервиса mysql

FROM mysql:5.7

HEALTHCHECK CMD mysqladmin ping --silent

    


Ответы

Ответ 1



Нужно минимум два контейнера, которые будет zero downtime. Дальше процесс (хорошо описан тут): остановить один старый, запустиить один новый и так по очереди. Но я буквально пару недель назад все это проходил и docker swarm это ОЧЕНЬ ПРОСТО, там пару команд, рецепт по ссылке в несколько раз сложнее. Для своего решения нужно настраивать балансировщик, а в docker swarm уже все есть и ставиться, ещё раз скажу, ОЧЕНЬ ПРОСТО. Переходите сразу на docker swarm. Он очень быстро настраивается и нулевой downtime из коробки. Просто docker service отличный инструмент, а docker stack вообще бомба (как раз поднимает все оружение из docker-compose подобного файла).

Ответ 2



Я существенно уменьшил downtime при деплое изменений на удалённый сервер, используя совет @alexes! Теперь downtime длится где-то около 5 секунд. Точнее, 5 секунд длится перезагрузка контейнера nginx и проверка обновлений для контейнеров nginx и mysql. А т.к. эта операция по большому счёту не обязательная, то downtime можно избежать вообще. В данный момент на удалённый сервер копируется только файл docker-compose.yml, все сервисы в этом файле используют уже готовый образ image, вместо build. Эти образы подготавливаются до внедрения приложения на сервер. Вместо одного сервиса с php-кодом, сейчас используется два абсолютно одинаковых: php и spare. Также операции по подготовке кэша приложения Symfony (cache:warmup) и статичных файлов подключаемых модулей bundles (assets:install) сейчас производятся в процессе подготовки образа приложения. В итоге, процедура деплоя получилась следующей: Загружаем новые образы всего приложения Обновляем и перезапускаем контейнер spare Обновляем статичные файлы Вносим изменения в структуру БД Обновляем и перезапускаем контейнер php Перезапускаем контейнер nginx docker-compose pull docker-compose up -d --no-recreate docker-compose up -d --force-recreate --no-deps spare docker-compose exec -T spare sh -c "cd /srv && rm -rf b/* && cp -a web/. b/ && rm -rf a/* && cp -a web/. a/" docker-compose exec -T spare phing storage-prepare database-deploy docker-compose up -d --force-recreate --no-deps php docker-compose stop nginx docker-compose up -d nginx Эту процедуру можно запускать как для инициализации, так и для обновления приложения. Конфигурация nginx. Здесь оба контейнера включены в upstream. Когда один из них становится недоступным во время обновления, он временно исключается из upstream самим nginx. Конструкция try_files /a$uri /b$uri /web$uri /app.php$is_args$args; позволяет отдавать правильные статичные файлы во время деплоя. upstream backend { server php:9000 fail_timeout=5s; server spare:9000 fail_timeout=5s; } server { listen 80 default_server; root /srv/web; server_name site.ru; charset utf-8; location / { root /srv; try_files /a$uri /b$uri /web$uri /app.php$is_args$args; } location ~ ^/app\.php(/|$) { fastcgi_split_path_info ^(.+\.php)(/.*)$; fastcgi_pass backend; include fastcgi_params; fastcgi_param SCRIPT_FILENAME /srv/web$fastcgi_script_name; fastcgi_param DOCUMENT_ROOT /srv/web; internal; } location /upload/ { root /srv/storage; } location ~ \.php$ { return 404; } sendfile off; client_max_body_size 100m; error_log /var/log/nginx/error.log error; } Новый файл docker-compose.yml networks: nw_external: external: name: graynetwork nw_internal: {} services: mysql: environment: MYSQL_DATABASE: project MYSQL_PASSWORD: project MYSQL_ROOT_PASSWORD: root MYSQL_USER: project expose: - '3306' image: covex/mysql:5.7 networks: nw_internal: null restart: always volumes: - database:/var/lib/mysql:rw nginx: depends_on: mysql: condition: service_healthy image: gitlab.site.ru:5005/dev1-projects/symfony-workflow2/nginx:master networks: nw_external: ipv4_address: 192.168.10.13 nw_internal: null ports: - 80/tcp restart: always volumes: - assets:/srv/a:ro - assets:/srv/b:ro - assets:/srv/storage:ro php: environment: ENV_database_host: mysql ENV_database_mysql_version: '5.7' ENV_database_name: project ENV_database_password: project ENV_database_port: '3306' ENV_database_user: project ENV_mailer_from: andrey@mindubaev.ru ENV_mailer_host: 127.0.0.1 ENV_mailer_password: 'null' ENV_mailer_transport: smtp ENV_mailer_user: 'null' ENV_secret: ThisTokenIsNotSoSecretChangeIt image: gitlab.site.ru:5005/dev1-projects/symfony-workflow2:master networks: nw_internal: null restart: always volumes: - assets:/srv/a:rw - assets:/srv/b:rw - assets:/srv/storage:rw spare: environment: ENV_database_host: mysql ENV_database_mysql_version: '5.7' ENV_database_name: project ENV_database_password: project ENV_database_port: '3306' ENV_database_user: project ENV_mailer_from: andrey@mindubaev.ru ENV_mailer_host: 127.0.0.1 ENV_mailer_password: 'null' ENV_mailer_transport: smtp ENV_mailer_user: 'null' ENV_secret: ThisTokenIsNotSoSecretChangeIt image: gitlab.site.ru:5005/dev1-projects/symfony-workflow2:master networks: nw_internal: null restart: always volumes: - assets:/srv/a:rw - assets:/srv/b:rw - assets:/srv/storage:rw version: '2.1' volumes: assets: {} database: {}

Ответ 3



Я использую команду без downtime: docker-compose up -d --no-deps --build Пример: docker-compose up -d --no-deps --build nginx

понедельник, 8 июля 2019 г.

Микросервисная архитектура при помощи Docker, Consul, Consul-Template и балансировщика нагрузки

Добрый день!
Я новичок в Docker. Разбираюсь со связкой Docker-machine + docker-comppose + consul + consul-template + registator. Нашел статью, в которой есть пример. Но есть некоторые отличия:
Я использую docker-machine:
docker-machine create -d azure --azure-subscription-id \ --azure-ssh-user \ --azure-open-port 80 \ --azure-subnet-prefix 10.0.2.0/24
так же использую docker-compose, а не fig:
app: image: tutum/hello-world:latest environment: SERVICE_NAME: app SERVICE_TAGS: production SERVICE_80_NAME: http SERVICE_80_CHECK_HTTP: . SERVICE_80_CHECK_INTERVAL: 15 ports: - "80"
lb: build: ./ links: - consul ports: - "80:80"
consul: command: -server -bootstrap -advertise 10.0.2.4 image: gliderlabs/consul-server ports: - "8300:8300" - "8400:8400" - "8500:8500" - "8600:53/udp" # # Service Discovery - Registrator # registrator: command: -ip=10.0.2.4 consul://consul:8500 image: gliderlabs/registrator:latest links: - consul volumes: - "/var/run/docker.sock:/tmp/docker.sock"
Проблема в следующем: После запуска контейнеров приложение не регистрируется и соответственно, при обращении на 80 порт, nginx возвращает ошибку 502. вывод консоли при этом:
docker-compose up Starting dockerloadbalancer_app_1 ... Starting dockerloadbalancer_app_1 Starting dockerloadbalancer_consul_1 ... Starting dockerloadbalancer_consul_1 ... done Starting dockerloadbalancer_lb_1 ... Starting dockerloadbalancer_registrator_1 ... Starting dockerloadbalancer_lb_1 ... done ... done Starting dockerloadbalancer_registrator_1 Attaching to dockerloadbalancer_app_1, dockerloadbalancer_consul_1, dockerloadbalancer_registrator_1, dockerloadbalancer_lb_1 consul_1 | ==> WARNING: Bootstrap mode enabled! Do not enable unless necessary consul_1 | ==> Starting Consul agent... consul_1 | ==> Starting Consul agent RPC... registrator_1 | 2017/08/30 05:09:13 Starting registrator v7 ... registrator_1 | 2017/08/30 05:09:13 Forcing host IP to 10.0.2.4 registrator_1 | 2017/08/30 05:09:13 Using consul adapter: consul://consul:8500 registrator_1 | 2017/08/30 05:09:13 Connecting to backend (0/0) lb_1 | nginx: the configuration file /etc/nginx/nginx.conf syntax is ok consul_1 | ==> Consul agent running! consul_1 | Node name: '66269e63b117' consul_1 | Datacenter: 'dc1' consul_1 | Server: true (bootstrap: true) consul_1 | Client Addr: 0.0.0.0 (HTTP: 8500, HTTPS: -1, DNS: 8600, RPC: 8400) consul_1 | Cluster Addr: 10.0.2.4 (LAN: 8301, WAN: 8302) consul_1 | Gossip encrypt: false, RPC-TLS: false, TLS-Incoming: false consul_1 | Atlas: consul_1 | consul_1 | ==> Log data will now stream in as it occurs: consul_1 | consul_1 | 2017/08/30 05:09:09 [INFO] raft: Node at 10.0.2.4:8300 [Follower] entering Follower state consul_1 | 2017/08/30 05:09:09 [INFO] serf: EventMemberJoin: 66269e63b117 10.0.2.4 consul_1 | 2017/08/30 05:09:09 [INFO] consul: adding LAN server 66269e63b117 (Addr: 10.0.2.4:8300) (DC: dc1) consul_1 | 2017/08/30 05:09:09 [INFO] serf: EventMemberJoin: 66269e63b117.dc1 10.0.2.4 consul_1 | 2017/08/30 05:09:09 [INFO] consul: adding WAN server 66269e63b117.dc1 (Addr: 10.0.2.4:8300) (DC: dc1) consul_1 | 2017/08/30 05:09:09 [ERR] agent: failed to sync remote state: No cluster leader consul_1 | 2017/08/30 05:09:10 [WARN] raft: Heartbeat timeout reached, starting election consul_1 | 2017/08/30 05:09:10 [INFO] raft: Node at 10.0.2.4:8300 [Candidate] entering Candidate state consul_1 | 2017/08/30 05:09:10 [INFO] raft: Election won. Tally: 1 consul_1 | 2017/08/30 05:09:10 [INFO] raft: Node at 10.0.2.4:8300 [Leader] entering Leader state consul_1 | 2017/08/30 05:09:10 [INFO] consul: cluster leadership acquired consul_1 | 2017/08/30 05:09:10 [INFO] consul: New leader elected: 66269e63b117 consul_1 | 2017/08/30 05:09:10 [INFO] raft: Disabling EnableSingleNode (bootstrap) consul_1 | 2017/08/30 05:09:13 [INFO] agent: Synced node info consul_1 | 2017/08/30 05:09:13 [WARN] Service name "dockerloadbalancer_lb-80" will not be discoverable via DNS due to invalid characters. Valid characters include all alpha-numerics and dashes. consul_1 | 2017/08/30 05:09:13 [INFO] agent: Synced service '54a66f0e387b:dockerloadbalancer_lb_1:80' consul_1 | 2017/08/30 05:09:13 [INFO] agent: Synced service '54a66f0e387b:dockerloadbalancer_consul_1:8400' consul_1 | 2017/08/30 05:09:13 [INFO] agent: Synced service '54a66f0e387b:dockerloadbalancer_consul_1:8500' consul_1 | 2017/08/30 05:09:13 [INFO] agent: Synced service '54a66f0e387b:dockerloadbalancer_consul_1:53:udp' registrator_1 | 2017/08/30 05:09:13 consul: current leader 10.0.2.4:8300 registrator_1 | 2017/08/30 05:09:13 Listening for Docker events ... registrator_1 | 2017/08/30 05:09:13 Syncing services on 4 containers registrator_1 | 2017/08/30 05:09:13 added: 07b7de523f24 54a66f0e387b:dockerloadbalancer_lb_1:80 registrator_1 | 2017/08/30 05:09:13 ignored: 07b7de523f24 port 443 not published on host registrator_1 | 2017/08/30 05:09:13 ignored: 54a66f0e387b no published ports registrator_1 | 2017/08/30 05:09:13 ignored: 66269e63b117 port 8302 not published on host registrator_1 | 2017/08/30 05:09:13 ignored: 66269e63b117 port 8600 not published on host registrator_1 | 2017/08/30 05:09:13 ignored: 66269e63b117 port 8600 not published on host registrator_1 | 2017/08/30 05:09:13 ignored: 66269e63b117 port 8301 not published on host registrator_1 | 2017/08/30 05:09:13 ignored: 66269e63b117 port 8302 not published on host registrator_1 | 2017/08/30 05:09:13 added: 66269e63b117 54a66f0e387b:dockerloadbalancer_consul_1:8400 registrator_1 | 2017/08/30 05:09:13 added: 66269e63b117 54a66f0e387b:dockerloadbalancer_consul_1:8500 registrator_1 | 2017/08/30 05:09:13 added: 66269e63b117 54a66f0e387b:dockerloadbalancer_consul_1:53:udp registrator_1 | 2017/08/30 05:09:13 added: 66269e63b117 54a66f0e387b:dockerloadbalancer_consul_1:8300 registrator_1 | 2017/08/30 05:09:13 ignored: 66269e63b117 port 8301 not published on host registrator_1 | 2017/08/30 05:09:13 register failed: &{54a66f0e387b:dockerloadbalancer_app_1:80 http 32780 10.0.2.4 [production] map[check_http:. check_interval:15] 0 {32780 10.0.2.4 80 172.17.0.2 tcp 819676e02aa1 819676e02aa10e14b1eca7e80d934f77932e66001bb24f237c5cde7035fcf509 0xc2080f4a80}} Unexpected response code: 400 (Request decode failed: time: missing unit in duration 15) consul_1 | 2017/08/30 05:09:13 [INFO] agent: Synced service '54a66f0e387b:dockerloadbalancer_consul_1:8300' lb_1 | nginx: configuration file /etc/nginx/nginx.conf test is successful lb_1 | 2017/08/30 05:09:44 [error] 14#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 217.118.84.156, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:65535/", host: "13.64.158.172" lb_1 | 217.118.84.156 - - [30/Aug/2017:05:09:44 +0000] "GET / HTTP/1.1" 502 575 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36" "-" lb_1 | 2017/08/30 05:09:45 [error] 14#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 217.118.84.156, server: , request: "GET /favicon.ico HTTP/1.1", upstream: "http://127.0.0.1:65535/favicon.ico", host: "13.64.158.172", referrer: "http://13.64.158.172/"
Подскажите в чем может быть проблема?


Ответ

Ошибка в статье, в файл nginx.conf, должен выглядеть так:
upstream app { least_conn; {{range service "production.http"}} server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1; {{else}} server 127.0.0.1:65333; # force a 501 {{end}} }
server { listen 80 default_server;
location / { proxy_pass http://app; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
server { listen 65333;
location / { types { application/json json; } default_type "application/json"; return 501 '{ "success": false, "deploy": false, "status": 501, "body": { "message": "No available upstream servers at current route from consul" } }'; } }
Полностью рабочий пример выложил сюда

пятница, 1 марта 2019 г.

Docker: можно ли контейнер, созданный из Windows разместить на Linux?

У нас стартап и мы все еще активно пополняемся единомышленниками, но наш продукт уже в скором времени близится к пилотному запуску. ПО наше состоит из следующих модулей:
API — проект ASP.NET Core Web API 2 MySQL Web-клиент — приложение на Angular 5. Мы не скрестили ASP.NET Core и Angular, а разрабатываем веб-клиент Angular отдельно с Node.js на борту.
Стоит задача, организовать стратегию менее безболезненного развертывания всех трех узлов на инфраструктуре клиента, естественно с учетом того что будет написан туториал по инсталяции и что установкой будет заниматься техническая служба клиента.
Операционная система, которая будет крутиться на сервере клиента неизвестна и хотелось сделать некий универсальный процесс инсталяции который подходил бы как на Windows так и для Linux. Понятное дело, что за универсальность надо платить.
Как писал выше, мы только развивающийся отряд, и мы не имеем пока еще в арсенале хорошего специалиста-администратора с большим опытом решения подобных задач по развертыванию.
Docker. Докер, Docker и еще раз Докер. Естественно в первую очередь программисту приходит в голову это ПО одной из задач (я сказал одной из) которого является избавить программиста от проблем развертывания и дать максимально сфокусироваться на кодинге. Ох если бы это было так.
Прокси-сервер. И как не крути, но плюс к Kestrel/HTTP.sys какой-то из серверов Apache, IIS, nginx и т.д. все же нужен на сколько понял я. Даже если клиент планирует работать с нашим продуктом только внутри корпоративной сети. Дела с HTTP.sys конечно лучше: он не такой голый как Kestrel, но у нас то речь об универсальности, а HTTP.sys только для Windows. Пытался к примеру установить nginx на Windows Server в качестве эксперимента: мама родная, со стороны казалось, что я в первый раз вижу компьютер).

И если можно я задал бы два вопроса:
1) Первый вопрос он более общий, вы наверное догадались: что посоветуете?
2) А теперь, чтобы конкретизироваться: я сейчас работаю на Windows 10 и если я задумал использовать Docker, то я ведь правильно понимаю, что мне надо создать четыре контейнера
Контейнер с прокси-сервером (Apache, nginx или IIS) Контейнер с СУБД MySQL Контейнер с Angular-приложением Контейнер с проектом ASP.NET Core 2 Web API
Можно ли это сделать прямо из Windows? То есть будет ли работать контейнер созданный на Windows-машине на Linux?


Ответ

Docker под Windows может работать в двух режимах - Windows Containers и Linux Containers. Режимы переключаются через иконку в трее:

В режиме Windows Containers он собирает и хостит контейнеры прямо в текущей операционке. Собранные в этом режиме контейнеры нельзя разместить под Linux.
В режиме Linux Containers он на самом деле собирает и запускает контейнеры на линуксовой виртуалке - она видна в Hyper-V Manager. Собранные в этом режиме контейнеры можно разместить под Linux.
Под каждый рантайм есть свой набор тэгов - все доступные можно посмотреть на https://hub.docker.com/r/microsoft/aspnetcore/
Т.е. да, вы можете включить режим Linux Containers, собрать набор из 4-х контейнеров (взяв nginx в качестве прокси), и потом запустить все это под Linux.

суббота, 13 октября 2018 г.

Как оптимизировать деплой через docker-compose?

Мы реализовали деплой через GitLab CI и docker-compose. В процессе деплоя на удалённый сервер копируется файл docker-compose.yml и файлы Dockerfile и пр. для создания "вспомогательных" контейнеров типа nginx и mysql
Всё работает как нужно. Беспокоят 2 момента: даунтайм и "мусорные" образы docker (те, что с в колонке TAG в docker images)
Вот кусок файла .gitlab-ci.yml, ответственный собственно на деплой на удалённый сервер:
.template-secure-copy: &secure-copy stage: deploy image: covex/alpine-git:1.0 before_script: - eval $(ssh-agent -s) - ssh-add <(echo "$SSH_PRIVATE_KEY") script: - ssh -p 22 $DEPLOY_USER@$DEPLOY_HOST 'set -e ; rm -rf '"$DEPLOY_DIRECTORY"'_tmp ; mkdir -p '"$DEPLOY_DIRECTORY"'_tmp' - scp -P 22 -r build/* ''"$DEPLOY_USER"'@'"$DEPLOY_HOST"':'"$DEPLOY_DIRECTORY"'_tmp' # */ <-- в оригинале строка не закоментирована =) - ssh -p 22 $DEPLOY_USER@$DEPLOY_HOST 'set -e ; cd '"$DEPLOY_DIRECTORY"'_tmp ; docker login -u gitlab-ci-token -p '"$CI_JOB_TOKEN"' '"$CI_REGISTRY"' ; docker-compose pull ; if [ -d '"$DEPLOY_DIRECTORY"' ]; then cd '"$DEPLOY_DIRECTORY"' && docker-compose down --rmi local && rm -rf '"$DEPLOY_DIRECTORY"'; fi ; cp -r '"$DEPLOY_DIRECTORY"'_tmp '"$DEPLOY_DIRECTORY"' ; cd '"$DEPLOY_DIRECTORY"' ; docker-compose up -d --remove-orphans ; docker-compose exec -T php phing app-deploy -Dsymfony.env=prod ; rm -rf '"$DEPLOY_DIRECTORY"'_tmp' tags: - executor-docker
Даунтайм сейчас - это 1-2-3 минуты. Начинается он с docker-compose down ... и до конца выполнения скрипта. Хочется его уменьшить.
А как сделать так, чтобы "мусорные" образы docker не появлялись - я вообще не понял. Про docker image prune знаю, хочется не очищать, а не захламлять.
UPD1:
Файл docker-compose.yml создаётся следующей конструкцией:
.template-docker-compose: &docker-compose stage: build image: covex/docker-compose:1.0 script: - for name in `env | awk -F= '{if($1 ~ /'"$ENV_SUFFIX"'$/) print $1}'`; do eval 'export '`echo $name|awk -F''"$ENV_SUFFIX"'$' '{print $1}'`'='$"$name"''; done - mkdir build - docker-compose -f docker-compose-deploy.yml config > build/docker-compose.yml - sed -i 's/\/builds\/'"$CI_PROJECT_NAMESPACE"'\/'"$CI_PROJECT_NAME"'/\./g' build/docker-compose.yml - cp -R docker build artifacts: untracked: true name: "$CI_COMMIT_REF_NAME" paths: - build/ tags: - executor-docker
В результате этой процедуры получается такой docker-compose.yml
networks: nw_external: external: name: graynetwork nw_internal: {} services: mysql: build: context: ./docker/mysql environment: MYSQL_DATABASE: project MYSQL_PASSWORD: project MYSQL_ROOT_PASSWORD: root MYSQL_USER: project expose: - '3306' networks: nw_internal: null restart: always volumes: - database:/var/lib/mysql:rw nginx: build: args: app_php: app server_name: project-dev1.ru context: ./docker/nginx depends_on: php: condition: service_started networks: nw_external: ipv4_address: 192.168.10.13 nw_internal: null ports: - 80/tcp restart: always volumes_from: - service:php:ro php: depends_on: mysql: condition: service_healthy environment: ENV_database_host: mysql ENV_database_name: project ENV_database_password: project ENV_database_port: '3306' ENV_database_user: project ENV_mailer_from: andrey@mindubaev.ru ENV_mailer_host: 127.0.0.1 ENV_mailer_password: 'null' ENV_mailer_transport: smtp ENV_mailer_user: 'null' ENV_secret: ThisTokenIsNotSoSecretChangeIt expose: - '9000' image: gitlab.site.ru:5005/dev1-projects/symfony:master networks: nw_internal: null restart: always volumes: - /composer/vendor - /srv version: '2.1' volumes: database: {}
Dockerfile для сервиса nginx
FROM nginx:alpine ARG server_name=docker.local ARG app_php=app_dev
COPY ./default.conf /etc/nginx/conf.d/default.conf
RUN sed -i 's/@SERVER_NAME@/'"$server_name"'/g' /etc/nginx/conf.d/default.conf \ && sed -i 's/@APP@/'"$app_php"'/g' /etc/nginx/conf.d/default.conf
Dockerfile для сервиса mysql
FROM mysql:5.7
HEALTHCHECK CMD mysqladmin ping --silent


Ответ

Нужно минимум два контейнера, которые будет zero downtime. Дальше процесс (хорошо описан тут): остановить один старый, запустиить один новый и так по очереди.
Но я буквально пару недель назад все это проходил и docker swarm это ОЧЕНЬ ПРОСТО, там пару команд, рецепт по ссылке в несколько раз сложнее. Для своего решения нужно настраивать балансировщик, а в docker swarm уже все есть и ставиться, ещё раз скажу, ОЧЕНЬ ПРОСТО.
Переходите сразу на docker swarm. Он очень быстро настраивается и нулевой downtime из коробки.
Просто docker service отличный инструмент, а docker stack вообще бомба (как раз поднимает все оружение из docker-compose подобного файла).