Başlığın dediği gibi. Docker ana IP adresi ve ana bilgisayardan kapsayıcıya portmaps almak ve kabın içinde bunu yapmak gerekir.
Başlığın dediği gibi. Docker ana IP adresi ve ana bilgisayardan kapsayıcıya portmaps almak ve kabın içinde bunu yapmak gerekir.
Yanıtlar:
/sbin/ip route|awk '/default/ { print $3 }'
@MichaelNeale'ın fark ettiği gibi, bu yöntemi kullanmanın bir anlamı yoktur Dockerfile
(bu derleme sırasında yalnızca bu IP'ye ihtiyacımız olduğu durumlar hariç), çünkü bu IP derleme süresi boyunca sabit olarak kodlanacaktır.
18.03 sürümünden host.docker.internal
itibaren, ana bilgisayarın IP'si olarak kullanabilirsiniz .
İçinde İşleri Mac için Docker , Windows için Docker ve belki diğer platformlarda da.
Bu, Mac'e özgü docker.for.mac.localhost
, 17.06 sürümünden beri kullanılabilen ve docker.for.mac.host.internal
17.12 sürümünden beri kullanılabilen ve yine de bu platformda da çalışabilen bir güncellemedir.
Not olduğu gibi , Mac ve , Windows belgelerine, bu gelişme amaçlıdır.
Örneğin, ana bilgisayarımda ayarlanmış ortam değişkenleri var:
MONGO_SERVER=host.docker.internal
Benim docker-compose.yml
dosyamda, bu var:
version: '3'
services:
api:
build: ./api
volumes:
- ./api:/usr/src/app:ro
ports:
- "8000"
environment:
- MONGO_SERVER
command: /usr/local/bin/gunicorn -c /usr/src/app/gunicorn_config.py -w 1 -b :8000 wsgi
docker.for.mac..
çoğu durumda şirketinizde bir Linux- veya Mac okunur bir ortam olmadığı için işe yaramaz. Karışık, Linux ve Mac ve Windows kullanan geliştiricileriniz var. % 99 oranında karma bir Host OS ortamı olduğu için bu etki alanı bir anlam ifade etmiyor. MacOS altında bir kap geliştirmiyorum ve bir macOS sunucusuna dağıtmıyorum. Linux'a konuşluyorum. Herkes böyle yapar. Peki bütün mesele ne docker.for.mac..
?
docker.for.mac.host.internal
, Docker'ı kullanıp kullanmadığınızın önemi yoktur docker-compose
. Yapılandırma dosyalarında sabit bir ana bilgisayar kullanmak istiyorum. Örneğin, her zaman ana bilgisayar IP adresini docker.host.internal
gösteren IDK . Hangi ana bilgisayar sistemini kullandığımdan bağımsız olarak. Docker'ı kullanmanın bütün mesele bu: Özerk olmak istiyorum. Ana bilgisayar sistemi ve kap arasında başka bir katmanınız olduğu için macOS'ta daha da karmaşık olduğunu anlıyorum. Ama yine de, sadece macOS için kullanabiliyorsanız , bence işe yaramaz. docker.for.mac.host.internal
Güncelleme: Mac için Docker'da , 18.03 sürümünden itibaren, ana bilgisayarın IP'si olarak host.docker.internal öğesini kullanabilirsiniz . Allanberry'nin cevabına bakınız . Mac için Docker'ın önceki sürümleri için aşağıdaki yanıt yine de faydalı olabilir:
Mac için Docker'da docker0
köprü mevcut değildir, bu nedenle buradaki diğer yanıtlar çalışmayabilir. Bununla birlikte, giden tüm trafik ana ana makineniz üzerinden yönlendirilir, böylece bir IP'ye bağlanmaya çalıştığınız sürece, kendisi olarak tanıdığı (ve docker kapsayıcısının kendisi olduğunu düşünmediği) bağlanabilmeniz gerekir. Örneğin, bunu ana makine çalıştırmasından çalıştırırsanız:
ipconfig getifaddr en0
Bu, Mac'inizin mevcut ağındaki IP'sini göstermeli ve docker konteynerinizin de bu adrese bağlanabilmesi gerekir. Bu IP adresi hiç değişmezse bu bir acıdır, ancak Mac'inize ana makinede böyle bir şey yaparak kabın kendisinin olduğunu düşünmediği özel bir geri döngü IP'si ekleyebilirsiniz:
sudo ifconfig lo0 alias 192.168.46.49
Daha sonra bağlantıyı telnet ile docker konteynerinden test edebilirsiniz. Benim durumumda uzak bir xdebug sunucusuna bağlanmak istedim:
telnet 192.168.46.49 9000
Artık 192.168.46.49 adresli Mac'inize trafik geldiğinde (ve konteynırınızdan çıkan tüm trafik Mac'inizden geçiyorsa) Mac'iniz IP'nin kendisinin olduğunu varsayacaktır. Bu IP'yi kullanmayı bitirdiğinizde, geri döngü diğer adını aşağıdaki gibi kaldırabilirsiniz:
sudo ifconfig lo0 -alias 192.168.46.49
Dikkat edilmesi gereken bir şey, docker konteynerinin, trafiğin hedefinin kendisi olduğunu düşünüyorsa ana ana bilgisayara trafik göndermeyeceğidir. Bu nedenle, sorun yaşıyorsanız kabın içindeki geri döngü arayüzünü kontrol edin:
sudo ip addr show lo
Benim durumumda, bu inet 127.0.0.1/8
, 127.*
aralıkta herhangi bir IP kullanamayacağım anlamına geldi . Bu yüzden 192.168.*
yukarıdaki örnekte kullandım . Kullandığınız IP'nin kendi ağınızdaki bir şeyle çakışmadığından emin olun.
Docker'ı AWS'de çalıştıranlar için, ana bilgisayarın örnek meta verileri kapsayıcının içinden hala kullanılabilir.
curl http://169.254.169.254/latest/meta-data/local-ipv4
Örneğin:
$ docker run alpine /bin/sh -c "apk update ; apk add curl ; curl -s http://169.254.169.254/latest/meta-data/local-ipv4 ; echo"
fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/community/x86_64/APKINDEX.tar.gz
v3.3.1-119-gb247c0a [http://dl-cdn.alpinelinux.org/alpine/v3.3/main]
v3.3.1-59-g48b0368 [http://dl-cdn.alpinelinux.org/alpine/v3.3/community]
OK: 5855 distinct packages available
(1/4) Installing openssl (1.0.2g-r0)
(2/4) Installing ca-certificates (20160104-r2)
(3/4) Installing libssh2 (1.6.0-r1)
(4/4) Installing curl (7.47.0-r0)
Executing busybox-1.24.1-r7.trigger
Executing ca-certificates-20160104-r2.trigger
OK: 7 MiB in 15 packages
172.31.27.238
$ ifconfig eth0 | grep -oP 'inet addr:\K\S+'
172.31.27.238
ifconfig eth0 | grep -oP 'inet \K\S+'
Tek yol, bir kapsayıcı oluşturduğunuzda ana bilgisayar bilgilerini ortam olarak iletmektir
run --env <key>=<value>
-e "DOCKER_HOST=$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')"
( unix.stackexchange.com/questions/87468/… ' dan kabul edilen cevap kullanılarak )
--add-host
Daha temiz bir çözüm olabilir (ancak liman parçası olmadan, sadece ev sahibi bu çözüm ile ele alınabilir). Yani, docker run
emrinizde, şöyle bir şey yapın:
docker run --add-host dockerhost:`/sbin/ip route|awk '/default/ { print $3}'` [my container]
Otomatik olarak yapmak isteyen çoğu uygulamalar için uygulama standardı: Bunu yapmazsanız . Bunun yerine, kapsayıcıyı çalıştıran kişinin yapılandırma olarak harici bir ana bilgisayar adı / ip adresi, örneğin bir ortam değişkeni veya yapılandırma dosyası enjekte etmesini sağlayın. Kullanıcının bunu enjekte etmesine izin vermek size en taşınabilir tasarımı sağlar.
Bu neden bu kadar zor? Çünkü kaplar, tasarım gereği uygulamayı ana bilgisayar ortamından yalıtacaktır. Ağ, varsayılan olarak yalnızca bu kapsayıcıya adlandırılır ve ana bilgisayarın ayrıntıları, kap içinde çalışan ve tam olarak güvenilir olmayabilecek işlemden korunur.
Özel durumunuza bağlı olarak farklı seçenekler vardır:
Kapsayıcınız ana bilgisayar ağıyla çalışıyorsa, varsayılan yolu görmek için doğrudan ana bilgisayardaki yönlendirme tablosuna bakabilirsiniz. Gönderen bu soruya beni örn için aşağıdaki çalışır:
ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'
Bunu bir kapsayıcıdaki ana bilgisayar ağıyla gösteren bir örnek şuna benzer:
docker run --rm --net host busybox /bin/sh -c \
"ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'"
Docker Desktop'ın bazı sürümleri için, yerleşik VM'ye bir DNS girişi enjekte ettiler:
getent hosts host.docker.internal | awk '{print $1}'
Bir bulut ortamında çalışıyorsanız, meta veri hizmetini bulut sağlayıcısından, örneğin AWS'den kontrol edebilirsiniz:
curl http://169.254.169.254/latest/meta-data/local-ipv4
Harici / internet adresinizi istiyorsanız, aşağıdaki gibi bir uzak hizmeti sorgulayabilirsiniz:
curl ifconfig.co
Bunların her birinin sınırlamaları vardır ve yalnızca belirli senaryolarda çalışır. En taşınabilir seçenek, konteynerinizi IP adresi bir yapılandırma olarak enjekte edilerek çalıştırılmaya devam etmektir, örneğin, burada ip
ana makinede önceki komutu çalıştıran ve ortam değişkeni olarak enjekte eden bir seçenek :
export HOST_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')
docker run --rm -e HOST_IP busybox printenv HOST_IP
Gerçek IP
adres (köprü değil IP
) Windows
istiyorsanız ve liman işleyiciniz 18.03
(veya daha yenisi ) varsa şunları yapın :
Resim adının bulunduğu ana bilgisayardan konteyner üzerinde bash komutunu çalıştırın nginx
(üzerinde çalışır Alpine Linux distribution
):
docker run -it nginx /bin/ash
Sonra kabın içinde çalıştırın
/ # nslookup host.docker.internal
Name: host.docker.internal
Address 1: 192.168.65.2
192.168.65.2
ana bilgisayarın IP'sidir - spinus
kabul edilen yanıttaki gibi köprü IP'si değildir .
Burada host.docker.internal kullanıyorum :
Ana bilgisayarın değişen bir IP adresi vardır (veya ağ erişiminiz yoksa hiçbiri). 18.03'ten itibaren önerimiz, ana bilgisayar tarafından kullanılan dahili IP adresine çözümleyen özel DNS adı host.docker.internal'a bağlanmaktır. Bu geliştirme amaçlıdır ve Docker for Windows dışındaki bir üretim ortamında çalışmaz.
Alpine Linux
mı? Değilse, özel için eşdeğer kontrol edin linux distribution
.
linux containers
ve ben kullanmıyorum. windows containers
Bunu sağ tıklayarak docker icon
ve seçerek yapabilirsiniz Switch to Linux containers
. Resim indirirken bunun önemli olabileceğini düşünüyorum. Eğer olsaydı windows container
çek eski silme eğer nginx
görüntü ve size bir başka konteyner alacak yeniden indirmeyi. Hala sizin için çalışmaz ise - yükleyip deneyebilirsiniz daha nslookup
içinde ash
.
host.docker.internal
konteynerin içinden bu ana bilgisayar adını ( ) kullanıyorum
docker run -it --rm alpine nslookup host.docker.internal
... ana bilgisayarın IP adresini yazdırır ...
nslookup: can't resolve '(null)': Name does not resolve
Name: host.docker.internal
Address 1: 192.168.65.2
On Mac ve Windows'ta , özel DNS adını kullanabilirsiniz host.docker.internal
.
Ana bilgisayarın değişen bir IP adresi vardır (veya ağ erişiminiz yoksa hiçbiri). 18.03'ten itibaren önerimiz, ana bilgisayar tarafından kullanılan dahili IP adresine çözümleyen özel DNS adı host.docker.internal'a bağlanmaktır. Bu geliştirme amaçlıdır ve Mac için Docker Desktop dışındaki bir üretim ortamında çalışmaz.
Mac için Docker Bir kapsayıcıdan ana bilgisayardaki bir hizmete bağlanmak istiyorum
Ana bilgisayarın değişen bir IP adresi vardır (veya ağ erişiminiz yoksa hiçbiri). 18.03'ten itibaren önerimiz, ana bilgisayar tarafından kullanılan dahili IP adresine çözümleyen özel DNS adı host.docker.internal'a bağlanmaktır.
Ağ geçidine gateway.docker.internal olarak da erişilebilir. https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds
Docker uzak API'sını ( örneğin üzerinden ) etkinleştirdiyseniz ve ana makinenin ana bilgisayar adını veya IP adresini biliyorsanız, bu çok fazla bash ile yapılabilir.-H
tcp://0.0.0.0:4243
Kabamın kullanıcısının içinde bashrc
:
export hostIP=$(ip r | awk '/default/{print $3}')
export containerID=$(awk -F/ '/docker/{print $NF;exit;}' /proc/self/cgroup)
export proxyPort=$(
curl -s http://$hostIP:4243/containers/$containerID/json |
node -pe 'JSON.parse(require("fs").readFileSync("/dev/stdin").toString()).NetworkSettings.Ports["DESIRED_PORT/tcp"][0].HostPort'
)
İkinci satır, kapsayıcı kimliğini yerel /proc/self/cgroup
dosyanızdan alır.
Üçüncü satır, ana makineye doğru kıvrılır (4243'ü liman işçisinin bağlantı noktası olarak kullandığınızı varsayar), sonra döndürülen JSON'u için ayrıştırmak için düğümü kullanır DESIRED_PORT
.
HostPort
de burada yararlı bilgiler HostIp
olabilir , maalesef olabilir0.0.0.0
Ubuntu 16.03 sürümüne sahibim. Benim için
docker run --add-host dockerhost:`/sbin/ip route|awk '/default/ { print $3}'` [image]
does dEĞİL çalışmak (yanlış ip üreten edilmiştir)
Benim çalışma çözümüm şuydu:
docker run --add-host dockerhost:`docker network inspect --format='{{range .IPAM.Config}}{{.Gateway}}{{end}}' bridge` [image]
İşte AWS'de Docker'ı çalıştıranlar için başka bir seçenek. Bu seçenek, kıvırma paketini eklemek için apk kullanmaktan kaçınır ve değerli 7mb alandan tasarruf sağlar. Yerleşik aracı kullanın (yekpare BusyBox ikili dosyasının bir parçası):
wget -q -O - http://169.254.169.254/latest/meta-data/local-ipv4
AFAIK, Linux için Docker (standart dağıtım) durumunda, ana bilgisayarın ip adresi her zaman olacaktır 172.17.0.1
.
Bunu almanın en kolay yolu ifconfig
ana bilgisayardan (docker0 arayüzü) geçmektir:
ifconfig
Bir liman işçisinin içinden, bağlantı istasyonundan aşağıdaki komut: ip -4 route show default | cut -d" " -f3
Aşağıdaki komut satırıyla bir docker'da hızlı bir şekilde çalıştırabilirsiniz:
# 1. Run an ubuntu docker
# 2. Updates dependencies (quietly)
# 3. Install ip package (quietly)
# 4. Shows (nicely) the ip of the host
# 5. Removes the docker (thanks to `--rm` arg)
docker run -it --rm ubuntu:19.10 bash -c "apt-get update && apt-get install iproute2 -y && ip -4 route show default | cut -d' ' -f3"
Umut ediyorum bu yardım eder.
Linux'ta koşabilirsiniz
HOST_IP=`hostname -I | awk '{print $1}'`
MacOS'ta ana makineniz Docker ana makinesi değildir. Docker, ana bilgisayar işletim sistemini VirtualBox'a kuracaktır.
HOST_IP=`docker run busybox ping -c 1 docker.for.mac.localhost | awk 'FNR==2 {print $4}' | sed s'/.$//'`
hostname -I
"çıktının sırası hakkında herhangi bir varsayımda bulunmama" konusunda uyarıyor.
Bu, Node.js'de , yukarıda belirtilen EC2 Meta Veri örneğini kullanarak ana bilgisayarı AWS EC2 bulut sunucularında çalıştıran minimalist bir uygulamadır.
const cp = require('child_process');
const ec2 = function (callback) {
const URL = 'http://169.254.169.254/latest/meta-data/local-ipv4';
// we make it silent and timeout to 1 sec
const args = [URL, '-s', '--max-time', '1'];
const opts = {};
cp.execFile('curl', args, opts, (error, stdout) => {
if (error) return callback(new Error('ec2 ip error'));
else return callback(null, stdout);
})
.on('error', (error) => callback(new Error('ec2 ip error')));
}//ec2
ve olarak kullanılır
ec2(function(err, ip) {
if(err) console.log(err)
else console.log(ip);
})
Service Fabric kümesinde bir Windows kapsayıcısı çalıştırıyorsanız, ana bilgisayarın IP adresine ortam değişkeni üzerinden erişilebilir Fabric_NodeIPOrFQDN
. Service Fabric ortam değişkenleri
İşte böyle yapıyorum. Bu durumda, yerel makine IP adresime Toros-Host'u işaret eden docker görüntüsü içindeki / etc / hosts içine bir hosts girişi ekler:
TAURUS_HOST=`ipconfig getifaddr en0`
docker run -it --rm -e MY_ENVIRONMENT='local' --add-host "taurus-host:${TAURUS_HOST}" ...
Ardından, Docker kapsayıcısının içinden komut dosyası, docker kapsayıcısını barındıran yerel makineme çıkmak için toros-host ana bilgisayar adını kullanabilir.
Belki de oluşturduğum kapsayıcı da yararlıdır https://github.com/qoomon/docker-host
Ana bilgisayar sistemine erişmek için konteyner adı dns'i kullanabilirsiniz , örneğin curl http: // dockerhost: 9200 , bu nedenle herhangi bir IP adresi ile uğraşmanıza gerek yoktur.
Kullandığım çözüm, Docker ana bilgisayarının bir http isteği aldığında harici adresini döndüren bir "sunucu" ya dayanmaktadır.
"Sunucu" da:
1) jwilder / nginx-proxy'yi başlatın
# docker run -d -p <external server port>:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy
2) ipify konteyner başlatmak
# docker run -e VIRTUAL_HOST=<external server name/address> --detach --name ipify osixia/ipify-api:0.1.0
Şimdi bir kap sunucuya bir http isteği gönderdiğinde, ör.
# curl http://<external server name/address>:<external server port>
Docker ana bilgisayarının IP adresi ipify tarafından "X-Forwarded-For" http başlığı aracılığıyla döndürülür
Örnek (ipify sunucusunun adı "ipify.example.com" ve 80 numaralı bağlantı noktasında çalışır, docker ana bilgisayarında IP 10.20.30.40 bulunur):
# docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy
# docker run -e VIRTUAL_HOST=ipify.example.com --detach --name ipify osixia/ipify-api:0.1.0
Artık kabın içinde şunları arayabilirsiniz:
# curl http://ipify.example.com
10.20.30.40
Bunu dene
docker run --rm -i --net = ana bilgisayar alp ifconfig
Ubuntu'da, hostname
komut aşağıdaki seçeneklerle kullanılabilir:
-i
, --ip-address
ana bilgisayar adının adresleri-I
, --all-ip-addresses
ev sahibinin tüm adresleriÖrneğin:
$ hostname -i
172.17.0.2
Değişkeni atamak için aşağıdaki tek astar kullanılabilir:
IP=$(hostname -i)
ile https://docs.docker.com/machine/install-machine/
a) $ docker-makine ip
b) Bir veya daha fazla makinenin IP adresini alın.
$ docker-machine ip host_name
$ docker-machine ip host_name1 host_name2