web-dev-qa-db-ja.com

Dockerコンテナからホストポートにアクセスする方法

私はjenkinsを実行しているdockerコンテナを持っています。ビルドプロセスの一部として、ホストマシン上でローカルに実行されているWebサーバーにアクセスする必要があります。ホストWebサーバー(ポート上で稼働するように構成できる)をjenkinsコンテナーに公開する方法はありますか?

編集:私はLinuxマシン上でネイティブにdockerを実行しています。

更新:

ホストマシンからホストIPのIPアドレスを取得するために、以下の@larsks回答に加えて、私は次のことを行います。

ip addr show docker0 | grep -Po 'inet \K[\d.]+'
165
Tri Nguyen

DockerをLinux上でネイティブに実行している場合は、docker0インターフェースのIPアドレスを使用してホストサービスにアクセスできます。コンテナの内側からは、これがデフォルトのルートになります。

たとえば、私のシステムでは、

$ ip addr show docker0
7: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::f4d2:49ff:fedd:28a0/64 scope link 
       valid_lft forever preferred_lft forever

そしてコンテナの中:

# ip route show
default via 172.17.0.1 dev eth0 
172.17.0.0/16 dev eth0  src 172.17.0.4 

簡単なシェルスクリプトを使用してこのIPアドレスを抽出するのはかなり簡単です。

#!/bin/sh

hostip=$(ip route show | awk '/default/ {print $3}')
echo $hostip

Dockerコンテナーからの接続を許可するために、ホスト上のiptables規則を変更する必要があるかもしれません。このような何かがトリックをするでしょう:

# iptables -A INPUT -i docker0 -j ACCEPT

これにより、Dockerコンテナからホスト上のすべてのポートへのアクセスが許可されます。ご了承ください:

  • iptablesの規則は順序付けされています、そしてこの規則はそれより前に来る他の規則に応じて正しいことをするかもしれないししないかもしれません。

  • (a)INADDR_ANY(別名0.0.0.0)をリッスンしているホストサービス、またはdocker0インターフェースを明示的にリッスンしているホストサービスにのみアクセスできます。

134
larsks

MacOSとWindowsの場合

Docker v 18.03以降(2018年3月21日以降)

内部IPアドレスを使用するか、ホストが使用する内部IPアドレスに解決される特別なDNS名Host.docker.internalに接続します。

Linuxのサポートは保留中です https://github.com/docker/for-linux/issues/264

MacOSと以前のバージョンのDocker

Docker for Mac v 17.12からv 18.02

上記と同じですが、代わりにdocker.for.mac.Host.internalを使用してください。

Docker for Mac v 17.06からv 17.11

上記と同じですが、代わりにdocker.for.mac.localhostを使用してください。

Docker for Mac 17.05以下

Docker containerからHost machineにアクセスするには、ネットワークインターフェースにIPエイリアスを添付する必要があります。どのIPを使用しても構いませんが、使用していないことを確認してください。

Sudo ifconfig lo0 alias 123.123.123.123/24

次に、サーバーが上記のIPまたは0.0.0.0をリ​​ッスンしていることを確認してください。 localhostの127.0.0.1をリ​​ッスンしている場合は、接続を受け入れません。

それからあなたのdockerコンテナをこのIPに向けるだけで、あなたはHostマシンにアクセスすることができます!

テストするためにはコンテナの中でcurl -X GET 123.123.123.123:3000のようなものを実行することができます。

エイリアスは再起動のたびにリセットされるので、必要に応じて起動スクリプトを作成します。

ここにソリューションとより多くのドキュメンテーション: https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds

179
Janne Annala

--net="Host"コマンドでdocker runを使用すると、dockerコンテナのlocalhostはdocker Hostを指します。

28
samthebest

Docker-composeによる解決策:ホストベースのサービスにアクセスするにはnetwork_modeパラメータ https://docs.docker.com/compose/compose-file/#network_mode を使用できます。

version: '3'
services:
  jenkins:
    network_mode: Host
10
vovan

現在MacとWindowsでこれを行う最も簡単な方法はHost Host.docker.internal を使うことです。これはホストマシンのIPアドレスに解決されます。残念ながら はまだLinuxでは動作しません (2018年4月現在)。

7
Tomáš Fejfar

私はまさにそれを行うためのdockerコンテナーを作成しました https://github.com/qoomon/docker-Host

そうすれば、単純にコンテナ名dnsを使ってホストシステムにアクセスできます。 curl http://dockerhost:9200

4
qoomon

私たちは、このネットワーキングジャンクすべてに対するより簡単な解決策は、サービスにドメインソケットを使用することであることがわかりました。とにかくホストに接続しようとしているのであれば、ソケットをボリュームとしてマウントするだけでいいのです。 postgresqlの場合、これは次のように簡単でした。

docker run -v /var/run/postgresql:/var/run/postgresql

その後、ネットワークではなくソケットを使用するようにデータベース接続を設定します。文字通りとても簡単です。

1
mlissner

ホストマシンで動作しているローカルウェブサーバーにアクセスするには2つの方法があります。

  1. パブリックIPによるアプローチ1

    Jenkins docker container内のWebサーバにアクセスするには、ホストマシンのパブリックIPアドレスを使用してください。

  2. ホストネットワークでのアプローチ2

    ホストのネットワークスタックにJenkins dockerコンテナを追加するには、 " - net Host"を使用します。ホストのスタックに配置されているコンテナは、ホストインタフェースへのアクセス権をすべて持っています。ホストマシンのプライベートIPアドレスを使ってdocker container内のロー​​カルウェブサーバーにアクセスできます。

NETWORK ID          NAME                      DRIVER              SCOPE
b3554ea51ca3        bridge                    bridge              local
2f0d6d6fdd88        Host                      Host                local
b9c2a4bc23b2        none                      null                local

ホストネットワークEg: docker run --net Host -it ubuntuでコンテナーを起動し、ifconfigを実行してdockerコンテナーから到達可能なすべての利用可能なネットワークIPアドレスをリストします。

例:私は自分のローカルホストマシンでnginxサーバを起動し、Ubuntu docker containerからnginxウェブサイトのURLにアクセスすることができます。

docker run --net Host -it ubuntu

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
a604f7af5e36        ubuntu              "/bin/bash"         22 seconds ago      Up 20 seconds                           ubuntu_server

プライベートネットワークIPアドレスを使用してUbuntu docker containerからNginx Webサーバー(ローカルホストマシンで実行中)にアクセスする。

root@linuxkit-025000000001:/# curl 192.168.x.x -I
HTTP/1.1 200 OK
Server: nginx/1.15.10
Date: Tue, 09 Apr 2019 05:12:12 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 26 Mar 2019 14:04:38 GMT
Connection: keep-alive
ETag: "5c9a3176-264"
Accept-Ranges: bytes
0
sreenivasar

2つのdockerイメージが「すでに」作成されていて、互いに通信するために2つのコンテナを配置したい場合。

そのためには、各コンテナを独自の--nameを付けて実行し、 - linkフラグを使用してそれらの間の通信を有効にすることができます。ただし、docker build中はこれを取得できません。

あなたが私のようなシナリオにいるとき、それはあなたの

docker build -t "centos7/someApp" someApp/ 

あなたがしようとするとそれは壊れます

curl http://172.17.0.1:localPort/fileIWouldLikeToDownload.tar.gz > dump.tar.gz

そして、 "curl/wget"で立ち往生し、 "ホストへの経路"が返されません。

その理由は、コンテナからホストへの通信、またはホスト上で実行されている他のコンテナへの通信をデフォルトで禁止するというdockerによって設定されているセキュリティです。これは私にとって非常に驚くべきことでした、私は言わなければなりません、あなたはローカルマシン上で走っているdockerマシンのエコーシステムがあまりにも多くのハードルなしでお互いにアクセスできることを期待するでしょう。

これについての説明は、次のドキュメントで詳しく説明されています。

http://www.dedoimedo.com/computers/docker-networking.html

ネットワークセキュリティを低下させて移動するのに役立つ2つの簡単な回避策があります。

最も簡単な方法は、ファイアウォールをオフにするか、すべて許可することです。これは、systemctl stop firewalld、iptables -F、または同等のコマンドで、必要なコマンドを実行することを意味します。

この情報がお役に立てば幸いです。

0
99Sono

私はさまざまな解決策を検討しましたが、私はこれが最もハッカーの少ない解決策だと思います。

  1. ブリッジゲートウェイIPの静的IPアドレスを定義します。
  2. Hostsファイルに、ゲートウェイIPを追加のエントリとして追加します。

唯一の欠点は、複数のネットワークやプロジェクトがある場合、それらのIPアドレス範囲が競合しないようにする必要があることです。

これがDocker Composeの例です。

version: '2.3'

services:
  redis:
    image: "redis"
    extra_hosts:
      - "dockerhost:172.20.0.1"

networks:
  default:
    ipam:
      driver: default
      config:
      - subnet: 172.20.0.0/16
        gateway: 172.20.0.1

その後、ホスト名 "dockerhost"を使用してコンテナ内からホスト上のポートにアクセスできます。

0
bcoughlan