Mevcut bir Docker kapsayıcısına nasıl bağlantı noktası eşlemesi atayabilirim?


436

Burada bir şeyleri yanlış anladığımdan emin değilim, ancak sadece bir görüntüden yeni bir kap oluşturarak bağlantı noktası eşlemeleri ayarlamak mümkün görünüyor. Mevcut bir Docker kapsayıcısına bağlantı noktası eşlemesi atamanın bir yolu var mı?



2
Bunun tasarımdan şüpheleniyorum. Docker sizi "tekrarlanabilir" olmaya zorlamaya çalışıyor ve kapsayıcı bir tür "kayıt sistemi". Kabı etkilemeyen adım olarak yaptığınız her şey, kolayca kaybedilen bir manuel adım olacaktır. Başka bir deyişle: Kabınızın çalışması için gereken tüm yapılandırmayı temsil etmesini istiyorsunuz. Bu nedenle, yeni bir bağlantı noktası açmak istiyorsanız, yeni bir kap oluşturmanız gerekir.
Lance Kind

2
Eski soru ve ben cevap vermiyorum, ama belki siz ve bu soruyu ve cevapları destekleyen insanlar, liman işçisi kavramını tamamen yanlış anlamış olabilir. Docker, defalarca ölçeklendirilebilen veya küçültülebilen vatansız uygulama içindir. Yeniden oluşturulamayan bir üretim ortamı için konteynerin içinde hiçbir zaman ısrar etmemelisiniz, devam etmeniz gerekiyorsa dizinleri eşleyin. Docker bir "hafif vm" gibi bir şey değildir, belki de aradığınız şey linuxcontainers.org'dur, lxd docker konseptine dayanır, ancak "hafif vm" göz önünde bulundurulur.
Edgar Carvalho

bunun yardımcı olabileceği durumda, zaten çalışan kaplara bağlantı noktası eşlemesi eklemek için "Kitematic" aracını kullanmak mümkündür. Bu, aynı şeyi yapmak için küçük bir googling ile docker komutu olması gerektiği anlamına gelmelidir :) İyi şanslar
Yaffah

Yanıtlar:


298

Bağlantı noktası eşlemesini doğrudan hostconfig.jsonadresindeki dosyayı düzenleyerek değiştirebilirsiniz . /var/lib/docker/containers/[hash_of_the_container]/hostconfig.json

[Hash_of_the_container] docker inspect <container_name>komutunu belirleyebilirsiniz ve "Id" alanının değeri hash olur.

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

Dolayısıyla bu yaklaşımla bir görüntü oluşturmanıza gerek yok. Yeniden başlatma bayrağını buradan da değiştirebilirsiniz.

Not : Docker motorunuzu ana makinenize göre doğru şekilde nasıl yeniden başlatacağınızı öğrenmek için https://docs.docker.com/engine/admin/ adresini ziyaret edebilirsiniz . Ben kullanılan sudo systemctl restart dockerUbuntu 16.04 çalışıyorsa benim liman işçisi motoru yeniden başlatmak için


17
Docker durduğunda, değişikliklerinizin üzerine
yazılıyor

5
Yukarıdakileri denedim ve işe yarıyor. Daha fazla ayrıntı için bkz. Mybrainimage.wordpress.com/2017/02/05/…
rohitmohta

11
Konteyneri durdurmak, liman işçisi motorunu durdurmak ve her ikisini de değiştirmek hostconfig.jsonve config.v2.jsonbu işi yapmak önemlidir . Ayrıntıları görmek için @rohitmohta tarafından sağlanan bağlantıyı kullanın.
Kalpak Gadre

5
: mac liman işçisi uygulamasını kullanarak, / lib / liman işçisi / konteynerler klasör için / var almak için buradaki talimatları izlerseniz, benim için tek bir şey çalıştı stackoverflow.com/a/41226917/2048266 temelde çalıştırmak screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/ttysizi çalıştıran tty olabilir olsun sana kez / var / lib / docker'a gidin
nommer

14
Windows için, herhangi biri bana conatiners klasörünün yerini paylaşabilirsiniz.?
Vijay

463

Ben de bu problemle ilgileniyorum.

As @Thasmo bahsedildiği, liman yönlendirmeler, SADECE ile belirtilebilir docker run(ve docker create) komutu.
Diğer komutlar, seçeneğe docker startsahip değildir -pve docker portyalnızca geçerli yönlendirmeleri görüntüler.

Bağlantı noktası yönlendirmeleri eklemek için her zaman şu adımları izlerim,

  1. konteyner çalıştırmayı durdur

    docker stop test01
    
  2. taahhüt kabın

    docker commit test01 test02
    

    Not: Yukarıdaki, kapsayıcıdan test02inşa ettiğim yeni bir görüntüdür test01.

  3. yeniden çalıştırmak kaydedilmeyen görüntüden

    docker run -p 8080:8080 -td test02
    

İlk 8080 yerel bağlantı noktası ve ikinci 8080 konteyner bağlantı noktasıdır.


15
Test01 adını tutmak istersem ne olur?
user69715

12
Bağlantı noktası belirtimine (--publish) izin vermek için Docker'da açık bir sorun olup olmadığını bilen var docker startmı?
Elijah Lynn

8
Ve bu senaryodaki hacimlerde ne oluyor?
Andrew Savinykh

78
Bu korkunç bir çözüm, 250 upvotes kazanmayı nasıl başardığına dair hiçbir fikrim yok. Belki de bu şekilde değerlendirilenler bu çözümün ne tür bir karışıklığa neden olduğunu bilmiyorlardı. Evet, bu korkunç ve farklı bir bağlantı noktasında çalışan yeni bir kapsayıcı başlatmaya eşit.
Arrrr

25
@Arrrr Belki daha iyi bir cevap bırakmak istersiniz? Eminim bize bunu yapmanın çok daha iyi bir yolunu söylerseniz hepimiz takdir edeceğiz.
crockeea

40

"Mevcut" ile "çalışıyor" demek istiyorsanız, bir bağlantı noktası eşlemesi eklemek (şu anda) mümkün değildir.

Ancak, çalışan bir kapsayıcıda bir hizmeti durdurmadan / yeniden başlatmadan açığa çıkarmanız gerekirse, örneğin Pipework ile dinamik olarak yeni bir ağ arabirimi ekleyebilirsiniz .


4
Bu en iyi cevap olmalı. Özlü ve OP'nin diğerlerinin yapmadığı sorusunu ele alıyor! Bazen olumsuz bir sonuç bir sonuçtur!
Parçalı Bulutlu

19

Çalışan bir kapsayıcıya bağlantı noktası eşleme uygulayıp uygulayamayacağınızdan emin değilsiniz. Yeni bir kapsayıcı oluşturmaktan farklı bir kapsayıcı çalıştırırken bağlantı noktası iletme uygulayabilirsiniz.

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

kapsayıcıyı çalıştırmaya başlayacak. Bu eğiticide bağlantı noktası yeniden yönlendirmesi açıklanmaktadır.


2
Öyleyse, sadece konteyner oluşturmada port eşleme gibi seçenekler ayarlamak mümkün görünüyor.
thasmo

20
Bu cevap tamamen doğru değil. docker runyeni bir kap oluşturur ve başlatır. Bunu yaparken eşdeğerdir docker createizledi docker start.
Trevor Sullivan

19

Hostconfig.json dosyasını düzenlemek artık çalışmıyor. Yalnızca bu bağlantı noktasının açığa çıkması ancak sunucuda yayınlanmamasıyla sona erer. Kapsayıcılık yapmak ve yeniden yaratmak benim için en iyi yaklaşım değil. Kimse bahsetmedi docker networkmi?

En iyi çözüm, ters çevrilmiş proxy'yi aynı ağ içinde kullanmak olabilir

  1. Önceki kapsayıcı adınız yoksa yeni bir ağ oluşturun.

    docker network create my_network

  2. Mevcut kapsayıcınızı oluşturulan ağa katılın

    docker network connect my_network my_existing_container

  3. Aynı ağa katılarak, ihtiyacınız olan bağlantı noktalarını yayınlayan ters bir proxy hizmeti (örn. Nginx) başlatın

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

    İsteğe bağlı olarak nginx'teki default.conf dosyasını kaldırın

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

  4. Yeni bir nginx yapılandırması oluşturma

    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;
        }
    }
    

    Yapılandırmayı nginx konteynerine kopyalayın.

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

  5. Nginx'i yeniden başlat

    docker restart nginx

Avantajları : Yeni bağlantı noktaları yayınlamak için, iş konteynerine dokunmadan nginx konteynerini güvenli bir şekilde durdurabilir / güncelleyebilirsiniz / yeniden oluşturabilirsiniz. Nginx için sıfır kesinti zamanına ihtiyacınız varsa, aynı ağa katılan daha fazla ters çevrilmiş proxy hizmetleri eklemek mümkündür. Ayrıca, bir kap birden fazla ağa katılabilir.

Düzenle:

Http olmayan proxy hizmetlerini tersine çevirmek için yapılandırma dosyası biraz farklıdır. İşte basit bir örnek:

upstream my_service {
    server my_existing_container:9000;
}

server {
    listen 9000;
    proxy_pass my_service;
}

1
Şaşırtıcı ve pratik, ancak kurumsal sistemler için bu yaklaşım şaşkın görünüyor. Tek bir sistemin iş akışını kontrol etmesine izin vermek çok daha iyidir.
Afşin

1
@Afshin Kurumsal sistemler veya projeler için, bu çözümün yeniden oluşturma (zamana neden olur) veya hostconfig.json dosyasını (en azından resmi olarak tanıtılmamış) hacklemekten daha iyi olduğunu düşünüyorum. Ekstra kapsayıcıda değişiklik yapmak yerine, işletme kapsayıcınızın dahili bağlantı noktasını gösterir.
Sean

1
Müthiş bir yaklaşım. Kapsama bir proxy arkasında çalışması için nginx farklı yapılandırmak gerekiyordu, ama bir şeyler yapmak için doğru bir yol gibi görünüyor. Mavi-yeşil dağıtım için de çalışır.
Brooks DuBois

18

Fujimoto Youichi örneğinde test01bir konteyner, oysa test02bir görüntüdür.

Yapmadan önce docker runorijinal kabı çıkarabilir ve daha sonra kabı aynı adı tekrar atayabilirsiniz:

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

( -PPortları manuel olarak atamak yerine rastgele portlara maruz bırakmak için kullanılır).


12
Lütfen unutmayın. içindeki uygulamaya bağlı olarak tüm verilerinizi KAYBEDECEKSİNİZ.
Barry

14

Eğer çalıştırırsanız docker run <NAME>, muhtemelen istediğiniz gibi olmayan yeni bir görüntü ortaya çıkar.

Geçerli bir görüntüyü değiştirmek istiyorsanız aşağıdakileri yapın:

docker ps -a

Hedef kapsayıcınızın kimliğini alın ve şu adrese gidin:

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

Kabı durdurun:

docker stop <NAME>

Dosyaları değiştirme

vi config.v2.json

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

Ve dosyayı değiştir

vi hostconfig.json

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

Docker'ınızı yeniden başlatın ve çalışması gerekir.


2
Bu benim için Docker 17.09.0-ce sürümünde işe yaramadı. Kapsayıcı yapılandırma dosyalarını başlattıktan sonra eski değerlere geri yazıldım.
thegeko

3
ana sistemde docker hizmetini yeniden başlatın @thegeko
yurenchen

1
bu çalışıyor! tks! 1. durdurma kabı, 2. değiştirme dosyaları, 3. yeniden başlatma docker, 4. yeniden başlatma kabı
datdinhquoc

12

Doble derinlik yapılandırması konusunda rahat değilseniz IPtables arkadaşınız olacaktır.

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}

Bu sadece benim bir senaryo ile çalışır tavsiye edilen bir yol değil bir hile çünkü ben konteyner durduramadı umarım size de yardımcı olacaktır.


bu harika bir cevap! Teşekkür ederim! Ben eşleştirmek istiyorsanız DOCKER_PORTiçin MACHINE_PORT, hangi parçaların değiştirilmesi gerektiğini?
Ciprian Tomoiagă

Docker'ın bu manuel ekleme hakkında bilgi sahibi olmayacağını unutmayın. Daha sonra docker bağlantı noktalarını düzgün şekilde açığa çıkararak hizmeti yeniden başlattığınızda SO girdileri kaldırılmaz. Bir şey değiştiğinde, iptables'ları çok dikkatli bir şekilde kontrol ettiğinizden emin olun. Özellikle çift girişleri arayın!
Anthony

8

bunu kolayca gerçekleştirmek için ssh gibi kullanışlı araçlar kullanıyoruz.

Ubuntu host ve ubuntu tabanlı docker imajını kullanıyordum.

  1. Docker içinde openssh-client kurulu.
  2. Dış bağlantı istasyonunda (ana bilgisayar) openssh-sunucu sunucusu yüklü.

yeni bir portun haritalandırılması gerektiğinde,

docker'ın içinde aşağıdaki komutu çalıştırın

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

172.17.0.1, docker arayüzünün ipiydi (bunu ifconfig docker0 | grep "inet addr" | cut -f2 -d":" | cut -f1 -d" "ana bilgisayarda çalıştırarak alabilirsiniz ).

Burada geri 8888 ana eşlenen yerel 8888 bağlantı noktası vardı. gerektiği gibi bağlantı noktasını değiştirebilirsiniz.

bir bağlantı noktasına daha ihtiyacınız varsa, ssh'ı öldürebilir ve yeni bağlantı noktasıyla bir -R satırı daha ekleyebilirsiniz.

Bunu netcat ile test ettim.


2
  1. Liman işçisi motorunu ve kabı durdurun.
  2. /var/lib/docker/containers/${container_id}Dizine git ve düzenlehostconfig.json
  3. Düzen PortBindings.HostPortdeğişikliği istediğimi.
  4. Liman işçisi motorunu ve kabını çalıştırın.

-1

Windows ve Mac Kullanıcıları için, eşleme bağlantı noktasını değiştirmenin başka bir kolay ve kolay yolu daha vardır:

  1. kitematic indir

  2. kapsayıcının ayarlar sayfasına gidin, bağlantı noktaları sekmesinde, orada yayınlanan bağlantı noktasını doğrudan değiştirebilirsiniz.

  3. kabı tekrar başlat


2
Bu yaklaşımı denedim. Kinematic gerçekten de liman eşlemelerini uyguladı. Ancak bunları uygulamak için, konteyneri orijinal görüntüden yeniden oluşturdu. Dolayısıyla, kabın kendisinde yapılan değişiklikleri kaybetmekten korkuyorsanız, bu yöntemi kullanmayın.
VeganHunter

1
Bunu tercih ettim, soruyu cevaplamıyor ve yeni bir kap oluşturuyor. Ama en azından işe yarıyor ve bu SO sonucu araştırmam sırasında ortaya çıktı. +1
2b77bee6-5445-4c77-b1eb-4df3e5

-7

Kısa Yanıt: Mevcut bir Docker kapsayıcısına bağlantı noktası eşlemesi atayamazsınız

Yeni bir konteynere ihtiyacın var ... onunla uğraş.


4
Tutuma gerek yok. Ayrıca bu cevap tamamen eksiktir.
lovefaithswing

1
Detaylara gerek yok. Bu zaman kazandıran cevabı ve konteynerlerin geçici doğasını iletmek için ton çok önemlidir.
stephen

-11

Çalışan kabın bağlantı noktasını değiştirmek istiyorsanız, şunları yapabilirsiniz:

  1. mevcut kapsayıcıyı durdur

    sudo docker durağı NAME

  2. şimdi yeni port eşlemesi ile yeniden başlat

    sudo docker run -d -p 81:80 İSİM

buna karşılık:

liman işçisine arka plan / deamon için "-d"

"-p" bağlantı noktası eşleştirmeyi etkinleştir

Tarayıcınızla erişmek için kullandığınız "81" harici (açık) bağlantı noktası

"80" dahili docker konteyneri dinleme bağlantı noktası


4
Bu sadece yanlış. Olarak docker runkomut, NAMEoysa bir kabı çalıştırmak için görüntü adıdır durdurmak için kabın adını gösterir. docker stopNAME
jonatan

1
"docker run" yeni bir kap oluşturur. Durdurulmuş olanla aynı kapsayıcı adını kullanamaz, çünkü bu ada sahip yalnızca bir kapsayıcıya sahip olabilirsiniz. Bu yüzden yapmanız gerekenler: "docker stop NAME", docker container rm NAME, ardından "docker run -d -p 81:80 NAME" yazdıkça.
Lance Kind
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.