web-dev-qa-db-ja.com

既存のDockerコンテナーにポートマッピングを割り当てる方法

誤解したかどうかはわかりませんが、イメージから新しいコンテナを作成してポートマッピングを設定することしかできないようです。既存のDockerコンテナーにポートマッピングを割り当てる方法はありますか?

317
Thasmo

私もこの問題に興味があります。

@Thasmo で述べたように、ポート転送はdocker runコマンドでのみ指定できます。
他のコマンド、docker start-pオプションを持たず、docker portは現在の転送のみを表示します。

ポート転送を追加するために、私はいつもこれらのステップに従います、

  1. 停止 コンテナの実行

    docker stop test01
    
  2. コミット コンテナ

    docker commit test01 test02
    

    注: 上記のtest02は、私がtest01コンテナから作成した新しいイメージです。

  3. コミットされた画像から - 実行

    docker run -p 8080:8080 -td test02
    

最初の8080がローカルポートで、2番目の8080がコンテナポートです。

375

hostconfig.jsonにある/var/lib/docker/containers/[hash_of_the_container]/hostconfig.jsonファイルを直接編集してポートマッピングを変更できます。

docker inspect <container_name>コマンドで[hash_of_the_container]を決定でき、 "Id"フィールドの値はハッシュです。

1) stop the container 
2) stop docker service (per Tacsiazuma's comment)
3) change the file
4) restart your docker engine (to flush/clear config caches)
5) start the container

だからあなたはこのアプローチで画像を作成する必要はありません。ここで再起動フラグを変更することもできます。

P.S https://docs.docker.com/engine/admin/ にアクセスして、ホストマシンに従ってdockerエンジンを正しく再起動する方法を学ぶことができます。 Ubuntu 16.04で動いているdockerエンジンを再起動するのにSudo systemctl restart dockerを使いました

198
holdfenytolvaj

「既存」とは「実行中」を意味するのであれば、(現在)ポートマッピングを追加することはできません。

ただし、新しいネットワークインターフェイスを動的に追加することはできます。 Pipework 実行中のコンテナ内でサービスを停止または再起動せずにサービスを公開する必要がある場合。

26
jpetazzo

実行中のコンテナにポートマッピングを適用できるかどうかわからない。新しいコンテナーの作成とは異なるコンテナーの実行中にポート転送を適用できます。

$ docker run -p <public_port>:<private_port> -d <image>  

コンテナの実行を開始します。 このチュートリアル はポートのリダイレクトについて説明しています。

16
rajalokan

藤本陽一の例では、test01はコンテナですが、test02はイメージです。

docker runを実行する前に、元のコンテナを削除してからコンテナに同じ名前を再度割り当てることができます。

$ docker stop container01
$ docker commit container01 image01
$ docker rm container01
$ docker run -d -P --name container01 image01

(手動で割り当てるのではなく-Pを使ってポートをランダムなポートに公開する).

13
Luca

hostconfig.json を編集しても動作しないようです。それは公開されているがホストに公開されていないそのポートで終わるだけです。コンテナをコミットして再作成することは私にとって最良の方法ではありません。誰もdocker networkを言及しませんでしたか?

最善の解決策は、同じネットワーク内でリバースプロキシを使用することです

  1. 以前のコンテナーが名前付きのコンテナーにない場合は、新しいネットワークを作成します。

    docker network create my_network

  2. 既存のコンテナを作成したネットワークに参加させる

    docker network connect my_network my_existing_container

  3. 同じネットワークに参加しながら、必要なポートを公開するリバースプロキシサービス(nginxなど)を起動します。

    docker run -d --name nginx --network my_network -p 9000:9000 nginx

    必要に応じて、nginxの default.conf を削除します。

    docker exec nginx rm /etc/nginx/conf.d/default.conf

  4. 新しいnginx設定を作成する

    server
    {
        listen 9000;
    
        location / {
            proxy_pass http://my_existing_container:9000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $Host;
            proxy_cache_bypass $http_upgrade;
        }
    }
    

    設定をnginxコンテナにコピーします。

    docker cp ./my_conf.conf nginx:/etc/nginx/conf.d/my_conf.conf

  5. Nginxを再起動

    docker restart nginx

長所 :新しいポートを公開するために、ビジネスコンテナに触れずにnginxコンテナを安全に停止/更新/再作成できます。 nginxにゼロダウンタイムが必要な場合は、同じネットワークに参加するリバースプロキシサービスを追加することが可能です。さらに、コンテナは複数のネットワークに参加できます。

編集する

Http以外のサービスをリバースプロキシするために、設定ファイルは少し異なります。これは簡単な例です:

upstream my_service {
    server my_existing_container:9000;
}

server {
    listen 9000;
    proxy_pass my_service;
}
8
Sean C.

docker run <NAME>を実行すると、新しい画像が生成されますが、これはおそらくあなたが望むものではありません。

現在の画像を変更したい場合は、次の手順に従ってください。

docker ps -a

ターゲットコンテナのIDを取得して、に移動します。

cd /var/lib/docker/containers/<conainerID><and then some:)>

コンテナを停止します。

docker stop <NAME>

ファイルを変更する

vi config.v2.json

"Config": {
    ....
    "ExposedPorts": {
        "80/tcp": {},
        "8888/tcp": {}
    },
    ....
},
"NetworkSettings": {
....
"Ports": {
     "80/tcp": [
         {
             "HostIp": "",
             "HostPort": "80"
         }
     ],

そしてファイルを変更する

vi hostconfig.json

"PortBindings": {
     "80/tcp": [
         {
             "HostIp": "",
             "HostPort": "80"
         }
     ],
     "8888/tcp": [
         {
             "HostIp": "",
             "HostPort": "8888"
         } 
     ]
 }

Dockerを再起動すればうまくいくはずです。

6
docker-noob

私達はこれを簡単に達成するためにsshのような便利なツールを使っています。

私はubuntuホストとubuntuベースのdockerイメージを使っていました。

  1. 内側dockerにはopenssh-clientがインストールされています。
  2. 外部docker(Host)にopenssh-server serverがインストールされています。

新しいポートをマップアウトする必要があるとき

docker内で次のコマンドを実行します。

ssh -R8888:localhost:8888 <username>@172.17.0.1

172.17.0.1はdockerインターフェースのIPアドレスでした(これはホスト上でifconfig docker0 | grep "inet addr" | cut -f2 -d":" | cut -f1 -d" "を実行することで得られます)。

ここでは、ローカル8888ポートをホスト8888にマッピングし直しました。必要に応じてポートを変更できます。

もう1つポートが必要な場合は、sshを終了して新しいポートで-Rをもう1行追加します。

私はこれをnetcatでテストしました。

4
melchi
  1. Dockerエンジンとそのコンテナを停止します。
  2. /var/lib/docker/containers/${container_id}ディレクトリに移動して、hostconfig.jsonを編集します
  3. 変更するPortBindings.HostPortを編集します。
  4. Dockerエンジンとコンテナーを起動します。
1
ezileli

あなたがDockerの深さ設定IPtablesに慣れていないならば、あなたの周りの他の方法はあなたの友人でしょう。

iptables -t nat -A DOCKER -p tcp --dport ${YOURPORT} -j DNAT --to-destination ${CONTAINERIP}:${YOURPORT}

iptables -t nat -A POSTROUTING -j MASQUERADE -p tcp --source ${CONTAINERIP} --destination ${CONTAINERIP} --dport ${YOURPORT}

iptables -A DOCKER -j ACCEPT -p tcp --destination ${CONTAINERIP} --dport ${YOURPORT}

これは私のシナリオでうまくいくお勧めの方法ではなく、単なるトリックです。

1
Mansur Ali

WindowsおよびMacユーザーの場合、マッピングポートを変更する別の非常に簡単でフレンドリーな方法があります。

  1. カイトマティックをダウンロードする

  2. コンテナの設定ページの[ポート]タブで、公開されているポートを直接変更できます。

  3. コンテナを再起動します

0
john

レスポンス / の補完として@ @ Fujimoto-Youichi

コンテナの作成中に$ docker run -P CONTAINERを使ってポートをランダムにマッピングすることもできますが、セキュリティ面では注意が必要です。

-Peqから--publish-all: "公開されているすべてのポートをランダムなポートに公開する"、

次に、下の図に示すように、docker inspect CONTAINERを実行してportsマッピングをfinにします。

docker inspect for a rabbitmq container show all ports mapping

docker rundocker run -Pについてもっと読む

0
aitbahaa