Контейнер Docker, работающий под Apache, всегда выставляет порт 80 - PullRequest
2 голосов
/ 30 апреля 2019

У меня есть образ Docker, на котором работает Apache, и я настроил Apache (через httpd.conf ) для прослушивания через порт 8080.

Listen 8080

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

docker build -t my/apache:8080 .
docker run --name "MyWebsite" -p 8080:8080 -v ~/dir:/mnt/dir -d -t my/apache:8080

Однако, когда я перечисляю свои работающие контейнеры, используя docker ps, я вижу, что порт 80 также по какой-то причине был открыт.

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES
23c4e1f0ea66        my/apache:8080      "/docker-entrypoint.…"   12 minutes ago      Up 12 minutes       80/tcp, 0.0.0.0:8080->8080/tcp   MyWebsite

Когда я подключаюсь к работающему контейнеру и выполняю поиск экземпляров «Listen 80», ничего не появляется, кроме экземпляра «Listen 8080», который я добавил в httpd.conf .

docker exec -it 23c4e1f0ea66 /bin/bash
grep -ri "Listen 80"

Мой Dockerfile содержит только одно объявление EXPOSE - EXPOSE 8080. Тем не менее, я не верю, что это на самом деле представляет порт в любом случае и предназначено скорее как способ документирования того, какой порт должен быть открыт при запуске контейнера, использующего изображение.

Как я могу узнать, когда открывается порт 80, и, что особенно важно, как я могу остановить его от разоблачения?

Dockerfile

FROM httpd:2.4

COPY httpd.conf /usr/local/apache2/conf/
COPY docker-entrypoint.sh /

ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["apache"]

### Apache (proxies to MapProxy).
EXPOSE 8080

Сценарий входа

#!/bin/bash
set -e

if [ "$1" = 'apache' ]; then
        echo "Starting Apache"
        httpd-foreground
fi

exec "$@"

HTTP config

ServerRoot "/usr/local/apache2"

Listen 8080

LoadModule mpm_event_module modules/mod_mpm_event.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule reqtimeout_module modules/mod_reqtimeout.so
LoadModule filter_module modules/mod_filter.so
LoadModule mime_module modules/mod_mime.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule env_module modules/mod_env.so
LoadModule headers_module modules/mod_headers.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
<IfModule !mpm_prefork_module>
</IfModule>
<IfModule mpm_prefork_module>
</IfModule>
LoadModule dir_module modules/mod_dir.so
LoadModule alias_module modules/mod_alias.so

<IfModule unixd_module>
        User daemon
        Group daemon
</IfModule>

ServerAdmin applicationdelivery@landmark.co.uk
ServerName mapproxy.gcs.lmkcloud.net:8080
DocumentRoot "/usr/local/apache2/htdocs"
ErrorLog /proc/self/fd/2

LogLevel warn

<IfModule log_config_module>
        LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
        LogFormat "%h %l %u %t \"%r\" %>s %b" common

        <IfModule logio_module>
                LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
        </IfModule>

        CustomLog /proc/self/fd/1 common

</IfModule>

<IfModule mime_module>
        TypesConfig conf/mime.types
        AddType application/x-compress .Z
        AddType application/x-gzip .gz .tgz
</IfModule>

<IfModule ssl_module>
        SSLRandomSeed startup builtin
        SSLRandomSeed connect builtin
</IfModule>

ProxyPreserveHost On
ProxyPass / http://example.com:8001/ retry=1 acquire=3000 timeout=20 Keepalive=On
ProxyPassReverse / http://example.com:8001/

1 Ответ

3 голосов
/ 30 апреля 2019

Порт 80 предоставляется родительским Dockerfile для httpd:2.4 image -
https://github.com/docker-library/httpd/blob/75e85910d1d9954ea0709960c61517376fc9b254/2.4/Dockerfile

Оператор EXPOSE внутри Dockerfile в конечном итоге даст вам вывод в docker ps.Однако он доступен только для сети контейнеров и не позволит осуществлять связь через определенные порты с контейнерами вне той же сети или с хост-машиной.Чтобы это произошло, вам нужно опубликовать порты.


Пример -

docker run -dit --expose 8008 httpd:2.4

Вывод -

CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS                  PORTS                              NAMES
d628b537aded        httpd:2.4                 "httpd-foreground"       3 seconds ago       Up 2 seconds            80/tcp, 8008/tcp                   objective_dewdney

Thisвыставляет контейнерный порт.Аргумент --expose равен оператору, использующему EXPOSE в Dockerfile.


Попробуем опубликовать порт сейчас -

docker run -dit -p 8009 httpd:2.4

Вывод -

CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS                  PORTS                              NAMES
2c8c93a78e97        httpd:2.4                 "httpd-foreground"       2 seconds ago       Up 2 seconds            80/tcp, 0.0.0.0:32768->8009/tcp    keen_swirles

См. 0.0.0.0:32768, теперь он опубликован на хост-машине со случайным эфемерным портом, т. Е. 32768. Вы также можете опубликовать его на определенном хост-порте.


Пример -

docker run -dit -p 8009:8009 httpd:2.4

Вывод -

CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS                  PORTS                              NAMES
1023df9822e5        httpd:2.4                 "httpd-foreground"       2 seconds ago       Up 2 seconds            80/tcp, 0.0.0.0:8009->8009/tcp     fervent_almeida

В двух словах, в настоящее время нет способа освободить порт 80 от родительского Dockerfile,Вы, конечно, можете выставить больше портов.

Это открытый вопрос -
https://github.com/moby/moby/issues/2210
https://github.com/moby/moby/issues/3465

Добавление комментария @BMitch к ответу, который, я считаю, актуален с тех порконтейнеры могут связываться друг с другом в одной и той же сети независимо от того, какой порт открыт -

Согласно @BMitch -

EXPOSE - это только документация / метаданные.Это не меняет способ взаимодействия контейнеров друг с другом.Docker ps просто сообщает вам порт, который документировал создатель изображения, но он не был опубликован (поскольку на карте нет хост-стороны).Здесь нечего менять, если у вас нет кода или пользователей, которые настаивают на том, что эта документация соответствует вашей среде.Для этого вам нужно перестроить исходный образ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...