目錄
- 網(wǎng)絡(luò)端口映射
- Docker 容器互聯(lián)
- 解決Windows系統(tǒng)無法對(duì)docker容器進(jìn)行端口映射的問題
前面我們實(shí)現(xiàn)了通過網(wǎng)絡(luò)端口來訪問運(yùn)行在 docker 容器內(nèi)的服務(wù)。
容器中可以運(yùn)行一些網(wǎng)絡(luò)應(yīng)用,要讓外部也可以訪問這些應(yīng)用,可以通過 -P
或 -p
參數(shù)來指定端口映射。
下面我們來實(shí)現(xiàn)通過端口連接到一個(gè) docker 容器。
網(wǎng)絡(luò)端口映射
我們創(chuàng)建了一個(gè) python 應(yīng)用的容器。
csdn@csdn:~$ docker run -d -P training/webapp python app.py fce072cc88cee71b1cdceb57c2821d054a4a59f67da6b416fceb5593f059fc6d
另外,我們可以指定容器綁定的網(wǎng)絡(luò)地址,比如綁定 127.0.0.1。
我們使用 -P 綁定端口號(hào),使用 docker ps 可以看到容器端口 5000 綁定主機(jī)端口 32768。
csdn@csdn:~$ docker ps CONTAINER ID IMAGE COMMAND ... PORTS NAMES fce072cc88ce training/webapp "python app.py" ... 0.0.0.0:32768->5000/tcp grave_hopper
我們也可以使用 -p 標(biāo)識(shí)來指定容器端口綁定到主機(jī)端口。
兩種方式的區(qū)別是:
- -P :是容器內(nèi)部端口隨機(jī)映射到主機(jī)的端口。
- -p : 是容器內(nèi)部端口綁定到指定的主機(jī)端口。
csdn@csdn:~$ docker run -d -p 5000:5000 training/webapp python app.py 33e4523d30aaf0258915c368e66e03b49535de0ef20317d3f639d40222ba6bc0
csdn@csdn:~$ docker ps CONTAINER ID IMAGE COMMAND ... PORTS NAMES 33e4523d30aa training/webapp "python app.py" ... 0.0.0.0:5000->5000/tcp berserk_bartik fce072cc88ce training/webapp "python app.py" ... 0.0.0.0:32768->5000/tcp grave_hopper
另外,我們可以指定容器綁定的網(wǎng)絡(luò)地址,比如綁定 127.0.0.1。
csdn@csdn:~$ docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py 95c6ceef88ca3e71eaf303c2833fd6701d8d1b2572b5613b5a932dfdfe8a857c csdn@csdn:~$ docker ps CONTAINER ID IMAGE COMMAND ... PORTS NAMES 95c6ceef88ca training/webapp "python app.py" ... 5000/tcp, 127.0.0.1:5001->5000/tcp adoring_stonebraker 33e4523d30aa training/webapp "python app.py" ... 0.0.0.0:5000->5000/tcp berserk_bartik fce072cc88ce training/webapp "python app.py" ... 0.0.0.0:32768->5000/tcp grave_hopper
這樣我們就可以通過訪問 127.0.0.1:5001 來訪問容器的 5000 端口。
上面的例子中,默認(rèn)都是綁定 tcp 端口,如果要綁定 UDP 端口,可以在端口后面加上 /udp。
csdn@csdn:~$ docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py 6779686f06f6204579c1d655dd8b2b31e8e809b245a97b2d3a8e35abe9dcd22a csdn@csdn:~$ docker ps CONTAINER ID IMAGE COMMAND ... PORTS NAMES 6779686f06f6 training/webapp "python app.py" ... 5000/tcp, 127.0.0.1:5000->5000/udp drunk_visvesvaraya 95c6ceef88ca training/webapp "python app.py" ... 5000/tcp, 127.0.0.1:5001->5000/tcp adoring_stonebraker 33e4523d30aa training/webapp "python app.py" ... 0.0.0.0:5000->5000/tcp berserk_bartik fce072cc88ce training/webapp "python app.py" ... 0.0.0.0:32768->5000/tcp grave_hopper
docker port 命令可以讓我們快捷地查看端口的綁定情況。
csdn@csdn:~$ docker port adoring_stonebraker 5000 127.0.0.1:5001
Docker 容器互聯(lián)
端口映射并不是唯一把 docker 連接到另一個(gè)容器的方法。
docker 有一個(gè)連接系統(tǒng)允許將多個(gè)容器連接在一起,共享連接信息。
docker 連接會(huì)創(chuàng)建一個(gè)父子關(guān)系,其中父容器可以看到子容器的信息。
容器命名
當(dāng)我們創(chuàng)建一個(gè)容器的時(shí)候,docker 會(huì)自動(dòng)對(duì)它進(jìn)行命名。另外,我們也可以使用 –name 標(biāo)識(shí)來命名容器,例如:
csdn@csdn:~$ docker run -d -P --name csdn training/webapp python app.py 43780a6eabaaf14e590b6e849235c75f3012995403f97749775e38436db9a441
我們可以使用 docker ps 命令來查看容器名稱。
csdn@csdn:~$ docker ps -l CONTAINER ID IMAGE COMMAND ... PORTS NAMES 43780a6eabaa training/webapp "python app.py" ... 0.0.0.0:32769->5000/tcp csdn
新建網(wǎng)絡(luò)
下面先創(chuàng)建一個(gè)新的 Docker 網(wǎng)絡(luò)。
$ docker network create -d bridge test-net
參數(shù)說明:
-d:參數(shù)指定 Docker 網(wǎng)絡(luò)類型,有 bridge、overlay。
其中 overlay 網(wǎng)絡(luò)類型用于 Swarm mode,在本小節(jié)中你可以忽略它。
連接容器
運(yùn)行一個(gè)容器并連接到新建的 test-net 網(wǎng)絡(luò):
$ docker run -itd --name test1 --network test-net ubuntu /bin/bash
打開新的終端,再運(yùn)行一個(gè)容器并加入到 test-net 網(wǎng)絡(luò):
$ docker run -itd --name test2 --network test-net ubuntu /bin/bash
點(diǎn)擊圖片查看大圖:
下面通過 ping 來證明 test1 容器和 test2 容器建立了互聯(lián)關(guān)系。
如果 test1、test2 容器內(nèi)中無 ping 命令,則在容器內(nèi)執(zhí)行以下命令安裝 ping(即學(xué)即用:可以在一個(gè)容器里安裝好,提交容器到鏡像,在以新的鏡像重新運(yùn)行以上倆個(gè)容器)。
apt-get update apt install iputils-ping
在 test1 容器輸入以下命令:
點(diǎn)擊圖片查看大圖:
同理在 test2 容器也會(huì)成功連接到:
點(diǎn)擊圖片查看大圖:
這樣,test1 容器和 test2 容器建立了互聯(lián)關(guān)系。
如果你有多個(gè)容器之間需要互相連接,推薦使用 Docker Compose,后面會(huì)介紹。
配置 DNS
我們可以在宿主機(jī)的 /etc/docker/daemon.json 文件中增加以下內(nèi)容來設(shè)置全部容器的 DNS:
{ "dns" : [ "114.114.114.114", "8.8.8.8" ] }
設(shè)置后,啟動(dòng)容器的 DNS 會(huì)自動(dòng)配置為 114.114.114.114 和 8.8.8.8。
配置完,需要重啟 docker 才能生效。
查看容器的 DNS 是否生效可以使用以下命令,它會(huì)輸出容器的 DNS 信息:
$ docker run -it --rm ubuntu cat etc/resolv.conf
點(diǎn)擊圖片查看大圖:
手動(dòng)指定容器的配置
如果只想在指定的容器設(shè)置 DNS,則可以使用以下命令:
$ docker run -it --rm -h host_ubuntu --dns=114.114.114.114 --dns-search=test.com ubuntu
參數(shù)說明:
- –-rm:容器退出時(shí)自動(dòng)清理容器內(nèi)部的文件系統(tǒng)。
- -h HOSTNAME 或者 –hostname=HOSTNAME: 設(shè)定容器的主機(jī)名,它會(huì)被寫到容器內(nèi)的 /etc/hostname 和 /etc/hosts。
–-dns=IP_ADDRESS: 添加 DNS 服務(wù)器到容器的 /etc/resolv.conf 中,讓容器用這個(gè)服務(wù)器來解析所有不在 /etc/hosts 中的主機(jī)名。
–-dns-search=DOMAIN: 設(shè)定容器的搜索域,當(dāng)設(shè)定搜索域?yàn)?.example.com 時(shí),在搜索一個(gè)名為 host 的主機(jī)時(shí),DNS 不僅搜索 host,還會(huì)搜索 host.example.com。
點(diǎn)擊圖片查看大圖:
如果在容器啟動(dòng)時(shí)沒有指定 –-dns 和 –dns-search,Docker 會(huì)默認(rèn)用宿主主機(jī)上的 /etc/resolv.conf 來配置容器的 DNS。
解決Windows系統(tǒng)無法對(duì)docker容器進(jìn)行端口映射的問題
1、問題:
在Windows家庭版下安裝了docker,并嘗試在其中運(yùn)行jupyter notebook等服務(wù),但映射完畢之后,在主機(jī)的瀏覽器中,打開localhost:port無法訪問對(duì)應(yīng)的服務(wù)。
2、問題出現(xiàn)的原因:
The reason you’re having this, is because on Linux, the docker daemon (and your containers) run on the Linux machine itself, so “localhost” is also the host that the container is running on, and the ports are mapped to.
On Windows (and OS X), the docker daemon, and your containers cannot run natively, so only the docker client is running on your Windows machine, but the daemon (and your containers) run in a VirtualBox Virtual Machine, that runs Linux.
因?yàn)閐ocker是運(yùn)行在Linux上的,在Windows中運(yùn)行docker,實(shí)際上還是在Windows下先安裝了一個(gè)Linux環(huán)境,然后在這個(gè)系統(tǒng)中運(yùn)行的docker。也就是說,服務(wù)中使用的localhost指的是這個(gè)Linux環(huán)境的地址,而不是我們的宿主環(huán)境Windows。
3、解決方法:
通過命令:
docker-machine ip default # 其中,default 是docker-machine的name,可以通過docker-machine -ls 查看
找到這個(gè)Linux的ip地址,一般情況下這個(gè)地址是192.168.99.100,然后在Windows的瀏覽器中,輸入這個(gè)地址,加上服務(wù)的端口即可啟用了。
比如,首先運(yùn)行一個(gè)docker 容器:
docker run -it -p 8888:8888 conda:v1
其中,conda:v1是我的容器名稱。然后在容器中開啟jupyter notebook 服務(wù):
jupyter notebook --no-browser --port=8888 --ip=172.17.0.2 --allow-root
其中的ip參數(shù)為我的容器的ip地址,可以通過如下命令獲得:
docker inspect container_id
最后在Windows瀏覽器中測試結(jié)果:http://192.168.99.100:8888