Запуск Docker не может опубликовать диапазон портов, несмотря на то, что netstat указывает, что порты доступны

Я пытаюсь запустить образ Docker изнутри Google Cloud Shell (то есть на любезно предоставленном экземпляре Google Compute Engine) следующим образом:

docker run -d -p 20000-30000:10000-20000 -it <image-id> bash -c bash

Перед этим шагом netstat -tuapn сообщил следующее:

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:8998          0.0.0.0:*               LISTEN      249/python      
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:13080           0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:13081           0.0.0.0:*               LISTEN      -               
tcp        0      0 127.0.0.1:34490         0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:13082           0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:13083           0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:13084           0.0.0.0:*               LISTEN      -               
tcp        0      0 127.0.0.1:34490         127.0.0.1:48161         ESTABLISHED -               
tcp        0    252 172.17.0.2:22           173.194.92.34:49424     ESTABLISHED -               
tcp        0      0 127.0.0.1:48161         127.0.0.1:34490         ESTABLISHED 15784/python    
tcp6       0      0 :::22                   :::*                    LISTEN      -     

Мне кажется, что все порты между 20000 и 30000 доступны, но запуск, тем не менее, завершается следующим сообщением об ошибке:

Ответ об ошибке от демона: не удается запустить контейнер: не удалось создать конечную точку на сетевом мосте: истекло время ожидания прокси, запускающего прокси-сервер пользовательского уровня

Что тут происходит? Как получить дополнительную диагностическую информацию и в конечном итоге решить проблему (т.е. запустить образ Docker со всем доступным диапазоном портов).




Ответы (1)


Открытие портов в диапазоне в настоящее время плохо масштабируется в Docker. Вышеупомянутое приведет к созданию 10 000 процессов docker-proxy для поддержки каждого порта, включая все файловые дескрипторы, необходимые для поддержки всех этих процессов, плюс добавляется длинный список правил брандмауэра. В какой-то момент вы достигнете предела ресурсов либо для файловых дескрипторов, либо для процессов. Дополнительные сведения см. В проблеме 11185 на github.

Единственный обходной путь при работе на хосте, которым вы управляете, - не выделять порты и вручную обновлять правила брандмауэра. Не уверен, что это вообще вариант с GCE. Лучшим решением будет изменение ваших требований, чтобы диапазон портов оставался небольшим. Последний вариант - полностью обойти мостовую сеть и работать в хост-сети, где больше нет прокси и правил брандмауэра с --net=host. Последний удаляет любую сетевую изоляцию, которая у вас есть в контейнере, поэтому, как правило, не рекомендуется.

person BMitch    schedule 17.07.2016
comment
+1 Thx за объяснение. Я должен иметь возможность изменить свои требования, чтобы диапазон портов оставался небольшим (э-э). Но это кажется независимым от рассматриваемой проблемы, когда Docker, кажется, жалуется на порт в диапазоне 10000-20000, в то время как netstat так не думает. Как я могу быть уверен, что этого не произойдет и с меньшим диапазоном портов? - person Drux; 17.07.2016
comment
Я изменил свои требования (и Dockerfile), чтобы использовать диапазон из 10 портов вместо 10000 (что должно работать на данный момент), и проблема волшебным образом исчезла: docker run больше не вызывает ошибок. - person Drux; 18.07.2016
comment
Прокси-сервер с истекшим временем ожидания, запускающий прокси-сервер пользовательского уровня, не выглядит как жалоба на захват порта, а скорее говорит о том, что для запуска docker-proxy процесса потребовалось слишком много времени. Это могло быть слишком долго, так как 9 999 других процессов пытались запустить одновременно, или это могло быть побочным эффектом исчерпания файловых дескрипторов или какого-либо другого ресурса. - person BMitch; 18.07.2016