Невозможно развернуть контейнеры docker с разных хостов

#jenkins #docker #continuous-integration #ansible #containers

#дженкинс #докер #непрерывная интеграция #ансибль #контейнеры

Вопрос:

Я интегрирую Docker в непрерывную интеграцию проекта, поэтому при каждой фиксации он создает образ docker, помещает его в частный реестр и запускает этот контейнер на компьютере, работающем в OpenStack. Мы используем Ansible (версия 2.1) для автоматизации, поэтому для взаимодействия с Docker я использую модуль docker_container . Помимо простого запуска контейнера docker, мне нужно ввести некоторые файлы конфигурации, которые различаются в зависимости от того, в какой среде я развертываю. Я использую опцию volumes для ввода файлов конфигурации.

Кажется, все работает нормально, я могу запустить развертывание несколько раз, контейнеры docker будут правильно заменены… но проблема начинается, когда тот же процесс запускается с другого хоста (например, с нашего хоста непрерывной интеграции, Jenkins CI или просто с другого ноутбука). Образ docker собран правильно, он помещается в частный реестр, но когда он пытается запустить новый контейнер, ему не удается удалить старый и он останавливается. Я получаю следующую ошибку ansible:

 fatal: [host-1]: FAILED! => {"changed": false, "failed": true, "msg": "Error removing container xxxx: 500 Server Error: Internal Server Error ("Driver devicemapper failed to remove root filesystem xxx: remove /var/lib/docker/overlay/yyyy/merged: device or resource busy")"}
 

Я использую следующую задачу docker_container для запуска контейнера:

  - name: Run the application container
  docker_container:
    name: "myProject-{{ environment_env }}-app"
    image: "{{ docker_app_image }}"
    state: started
    pull: yes
    restart: yes
    ports:
    - "80:80"
    - "443:443"
    volumes:
    - "{{ remote_home }}/myProject_{{ environment_env }}/log:{{ log_dir }}"
    - "{{ remote_home }}/myProject_{{ environment_env }}/local_settings.py:/server/cms/local_settings.py:ro"
    - "{{ remote_home }}/myProject_{{ environment_env }}/nginx.conf:/etc/nginx/nginx.conf:ro"
    - "{{ remote_home }}/myProject_{{ environment_env }}/myProject.pem:/etc/certificates/myProject.pem:ro"
    - "{{ remote_home }}/myProject_{{ environment_env }}/myProject_private.pem:/etc/certificates/myProject_private.pem:ro"
    - "{{ remote_home }}/myProject_{{ environment_env }}/myProject_vhost.conf:/etc/nginx/conf.d/myProject_vhost.conf:ro"
 

Я пытался изменить драйвер docker с devicemapper на overlay, но проблема остается той же. Кто-нибудь из вас сталкивался с этой проблемой раньше? Связано ли это с владельцем файла или разрешениями на другом хосте, на котором выполняется развертывание, и система docker не может справиться с этим? Любая помощь будет признательна! Спасибо.

Комментарии:

1. Работают ли команды docker (pull, stop, rm, run), если вы запускаете их из командной строки? Какую версию docker вы используете на отказавших узлах?

2. @BMitch да, когда я получаю упомянутую ошибку Ansible о неудачном удалении контейнера, команда CLI вручную docker rm также завершается с той же ошибкой. Я использую Docker 1.12.1 , я должен уничтожить компьютер и заново создать его снова, чтобы снова развернуть

3. Попробуйте lsof, чтобы узнать, можете ли вы отследить, что блокирует доступ к каталогам / файлам docker.

4. @BMitch Я проверил, что на самом деле так и было v1.12.0 , также проверил репозиторий Docker GitHub и увидел, что их последний список изменений для v1.12.2 включает » Реализовать логику повторных попыток для предотвращения ошибок «Невозможно удалить файловую систему» при использовании драйвера хранилища aufs «, ссылаясь на этот PR . Я проверю, сохраняется ли проблема в этой версии, и, если возможно, также проверю с lsof помощью команды

5. @BMitch к сожалению, проблема, похоже, сохраняется в 1.12.2 версии: (вывод lsof немного чудовищный, 4K строк и 650 строк grep docker , я загрузил оба в СУТЬ , но я не вижу там ни одной строки, которая выглядела бы как смонтированный докером том, только много строк, ссылающихся на /var/lib/docker/volumes/metadata.db

Ответ №1:

Я сам публикую ответ, надеюсь, это поможет кому-нибудь справиться с той же проблемой, с которой я столкнулся с Docker.

Я следовал этому руководству, которое в основном состоит в добавлении параметра в модульный файл docker systemd. Я добавил MountFlags=private строку в [service] раздел. Похоже, что проблема связана с пространствами имен файловой системы. С помощью этого исправления я могу развертывать контейнеры с любого количества хостов, которые я хочу, и есть 0 ошибок.

Комментарии:

1. Эта проблема сводила меня с ума в течение нескольких дней. Но я не сталкивался с ошибкой уже через день после добавления MountFlags=private . Я просто не могу в это поверить! Спасибо, что вы один из тех парней, которые сами отвечают на свой вопрос 🙂