Эластичный в стеке docker / swarm

#docker #elasticsearch #docker-swarm

#docker #elasticsearch #docker-swarm

Вопрос:

У меня есть рой из двух узлов

 [ra@speechanalytics-test ~]$ docker node ls
ID                            HOSTNAME                  STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
mlwwmkdlzbv0zlapqe1veq3uq     speechanalytics-preprod   Ready               Active                                  18.09.3
se717p88485s22s715rdir9x2 *   speechanalytics-test      Ready               Active              Leader              18.09.3
  

Я пытаюсь запустить контейнер с эластичным в стеке. Вот мой docker-compose.yml файл

 version: '3.4'
services:
  elastic:
    image: docker.elastic.co/elasticsearch/elasticsearch:6.7.0
    environment:
      - cluster.name=single-node
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - esdata:/usr/share/elasticsearch/data
    deploy:
      placement:
        constraints:
          - node.hostname==speechanalytics-preprod

volumes:
  esdata:
    driver: local
  

после запуска со стеком docker

 docker stack deploy preprod -c docker-compose.yml
  

сбой контейнера через 20 секунд

 docker service logs preprod_elastic 
...
   | OpenJDK 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release.
   | OpenJDK 64-Bit Server VM warning: UseAVX=2 is not supported on this CPU, setting it to UseAVX=0
   | [2019-04-03T16:41:30,044][WARN ][o.e.b.JNANatives         ] [unknown] Unable to lock JVM Memory: error=12, reason=Cannot allocate memory
   | [2019-04-03T16:41:30,049][WARN ][o.e.b.JNANatives         ] [unknown] This can result in part of the JVM being swapped out.
   | [2019-04-03T16:41:30,049][WARN ][o.e.b.JNANatives         ] [unknown] Increase RLIMIT_MEMLOCK, soft limit: 16777216, hard limit: 16777216
   | [2019-04-03T16:41:30,050][WARN ][o.e.b.JNANatives         ] [unknown] These can be adjusted by modifying /etc/security/limits.conf, for example:
   | OpenJDK 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release.
   |     # allow user 'elasticsearch' mlockall
   | OpenJDK 64-Bit Server VM warning: UseAVX=2 is not supported on this CPU, setting it to UseAVX=0
   |     elasticsearch soft memlock unlimited
   | [2019-04-03T16:41:02,949][WARN ][o.e.b.JNANatives         ] [unknown] Unable to lock JVM Memory: error=12, reason=Cannot allocate memory
   |     elasticsearch hard memlock unlimited
   | [2019-04-03T16:41:02,954][WARN ][o.e.b.JNANatives         ] [unknown] This can result in part of the JVM being swapped out.
   | [2019-04-03T16:41:30,050][WARN ][o.e.b.JNANatives         ] [unknown] If you are logged in interactively, you will have to re-login for the new limits to take effect.
   | [2019-04-03T16:41:02,954][WARN ][o.e.b.JNANatives         ] [unknown] Increase RLIMIT_MEMLOCK, soft limit: 16777216, hard limit: 16777216
preprod
  

на обоих узлах у меня есть

 ra@speechanalytics-preprod:~$ sysctl vm.max_map_count
vm.max_map_count = 262144
  

Есть идеи, как исправить?

Ответ №1:

Ошибки блокировки памяти, которые вы видите в Elasticsearch, являются распространенной проблемой, не связанной только с использованием Docker, но возникающей, когда Elasticsearch просят заблокировать его память, но он не может этого сделать. Вы можете обойти ошибку, удалив следующую переменную среды из docker-compose.yml файла:

 - bootstrap.memory_lock=true
  

Memlock может использоваться в режиме Docker Swarm, но с некоторыми оговорками.

Не все параметры, которые работают с docker-compose (Docker Compose), работают с docker stack deploy (режим Docker Swarm), и наоборот, несмотря на то, что оба используют синтаксис docker-compose YAML. Одним из таких вариантов является ulimits: , который при использовании с docker stack deploy будет игнорироваться с предупреждающим сообщением, например, так:

 Ignoring unsupported options: ulimits
  

Я предполагаю, что с вашим docker-compose.yml файлом Elasticsearch работает нормально docker-compose up , но не с docker stack deploy .

В режиме Docker Swarm по умолчанию у экземпляра Elasticsearch, который вы определили, будут проблемы с блокировкой памяти. В настоящее время установка ограничений для служб docker swarm еще официально не поддерживается. Однако есть способы обойти проблему.

Если хостом является Ubuntu, в службе docker может быть включена неограниченная блокировка памяти (см. Здесь и здесь). Это может быть достигнуто с помощью команд:

 echo -e "[Service]nLimitMEMLOCK=infinity" | SYSTEMD_EDITOR=tee systemctl edit docker.service
systemctl daemon-reload
systemctl restart docker
  

Однако установка memlock на бесконечность не лишена недостатков, о чем здесь говорят сами Elastic.

Основываясь на моем тестировании, решение работает в Docker 18.06, но не в 18.09. Учитывая несоответствие и возможность неудачного запуска Elasticsearch, лучшим вариантом было бы не использовать memlock с Elasticsearch при развертывании в Swarm. Вместо этого вы можете выбрать любой из других методов, упомянутых в документах Elasticsearch, для достижения аналогичных результатов.

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

1. добавлена поддержка ulimit для службы docker и развертывания стека docker: github.com/docker/cli/pull/2712