Docker基礎-端口映射與容器互聯

一、端口映射實現訪問容器

1.從外部訪問容器應用

  在啓動容器的時候,若是不指定對應的參數,在容器外部是沒法經過網絡來訪問容器內部的網絡應用和服務的。
  當容器中運行一些網絡應用,要讓外部訪問這些應用時,能夠經過-p或-P參數來指定端口映射。當使用-P(大寫P)標記時,Docker會隨機映射一個端口到內部容器開放的網絡端口(端口範圍在Linux系統使用的端口以外,通常都過萬):html

[root@docker ~]# docker run -d --name nginx_1 -P nginx:latest 
f769af3e98478b27b87e008f3ad785e2055da4047442c4a8dcb8f621f810dbea
[root@docker ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
f769af3e9847        nginx:latest        "nginx -g 'daemon ..."   3 seconds ago       Up 2 seconds        0.0.0.0:32768->80/tcp   nginx_1
[root@docker ~]#

  經過docker ps能夠看到nginx_1容器的80端口被映射到本機的32768端口上。訪問宿主主機的32768端口就能夠訪問容器內的應用程序提供的Web界面:nginx

 



 

 

 

 

 

 

 

 

 

 

 

 

   

  一樣,能夠經過docker logs命令查看應用信息:web

[root@docker ~]# docker logs nginx_1
10.0.0.253 - - [29/Nov/2017:06:25:38 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0" "-"
10.0.0.253 - - [29/Nov/2017:06:25:39 +0000] "GET /favicon.ico HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0" "-"
2017/11/29 06:25:39 [error] 5#5: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 10.0.0.253, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "10.0.0.31:32768"
10.0.0.253 - - [29/Nov/2017:06:25:39 +0000] "GET /favicon.ico HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0" "-"
2017/11/29 06:25:39 [error] 5#5: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 10.0.0.253, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "10.0.0.31:32768"
10.0.0.253 - - [29/Nov/2017:06:26:55 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36" "-"
10.0.0.253 - - [29/Nov/2017:06:26:56 +0000] "GET /favicon.ico HTTP/1.1" 404 571 "http://10.0.0.31:32768/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36" "-"
2017/11/29 06:26:56 [error] 5#5: *2 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 10.0.0.253, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "10.0.0.31:32768", referrer: "http://10.0.0.31:32768/"
[root@docker ~]# 

  -p(小寫p)能夠指定要映射的端口,而且在一個指定的端口上只能夠綁定一個容器。支持的格式有:IP:HostPort:ContainerPort | IP::ContainerPort | HostPort:ContainerPort 。docker

2.映射全部接口地址

   使用HostPort:ContainerPort格式將本地的5000端口映射到容器的5000端口:數據庫

[root@docker ~]# docker run -itd -p 5000:5000 --name nginx_2 nginx:latest 
5bdca2bde33d7db72861399ca49e82f0d209d13289d20b181843da5b10e6f2d3
[root@docker ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES
5bdca2bde33d        nginx:latest        "nginx -g 'daemon ..."   8 seconds ago       Up 7 seconds        80/tcp, 0.0.0.0:5000->5000/tcp   nginx_2
f769af3e9847        nginx:latest        "nginx -g 'daemon ..."   15 minutes ago      Up 15 minutes       0.0.0.0:32768->80/tcp            nginx_1
[root@docker ~]# 

  此時默認會綁定本地全部接口上的全部地址。屢次使用-p參數能夠綁定多個端口:centos

[root@docker ~]# docker run -itd -p 3000:2700 -p 2389:8863 --name nginx_3 nginx:latest 
65fbfbe9761eb5146501311016d681f210b1891ca5f5af62dc978ad6f2a22750
[root@docker ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                    NAMES
65fbfbe9761e        nginx:latest        "nginx -g 'daemon ..."   3 seconds ago       Up 2 seconds        80/tcp, 0.0.0.0:3000->2700/tcp, 0.0.0.0:2389->8863/tcp   nginx_3
5bdca2bde33d        nginx:latest        "nginx -g 'daemon ..."   2 minutes ago       Up 2 minutes        80/tcp, 0.0.0.0:5000->5000/tcp                           nginx_2
f769af3e9847        nginx:latest        "nginx -g 'daemon ..."   18 minutes ago      Up 18 minutes       0.0.0.0:32768->80/tcp                                    nginx_1
[root@docker ~]# 

3.映射到指定地址的指定端口

   可使用IP:HostPort:ContainerPort格式指定映射使用一個特定地址:安全

[root@docker ~]# docker run -itd -p 10.0.0.31:89:8081 --name nginx_4 nginx:latest 
16a476837222d413926053e1c8175c993b0495732073fbc6251dfd4696db8242
[root@docker ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                    NAMES
16a476837222        nginx:latest        "nginx -g 'daemon ..."   4 seconds ago       Up 3 seconds        80/tcp, 10.0.0.31:89->8081/tcp                           nginx_4
65fbfbe9761e        nginx:latest        "nginx -g 'daemon ..."   2 minutes ago       Up 2 minutes        80/tcp, 0.0.0.0:3000->2700/tcp, 0.0.0.0:2389->8863/tcp   nginx_3
5bdca2bde33d        nginx:latest        "nginx -g 'daemon ..."   5 minutes ago       Up 5 minutes        80/tcp, 0.0.0.0:5000->5000/tcp                           nginx_2
f769af3e9847        nginx:latest        "nginx -g 'daemon ..."   20 minutes ago      Up 20 minutes       0.0.0.0:32768->80/tcp                                    nginx_1
[root@docker ~]# 

4.映射到指定地址的任意端口

   使用IP::ContainerPort格式綁定本機的任意端口到容器的指定端口:bash

[root@docker ~]# docker run -itd -p 10.0.0.31::8082 --name nginx_5 nginx:latest 
3436fd5fbdca6529c70c664f42edfd10d51edb0fb541b096b47c9b168887b2ca
[root@docker ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                    NAMES
3436fd5fbdca        nginx:latest        "nginx -g 'daemon ..."   2 seconds ago       Up 2 seconds        80/tcp, 10.0.0.31:32769->8082/tcp                        nginx_5
16a476837222        nginx:latest        "nginx -g 'daemon ..."   2 minutes ago       Up 2 minutes        80/tcp, 10.0.0.31:89->8081/tcp                           nginx_4
65fbfbe9761e        nginx:latest        "nginx -g 'daemon ..."   4 minutes ago       Up 4 minutes        80/tcp, 0.0.0.0:3000->2700/tcp, 0.0.0.0:2389->8863/tcp   nginx_3
5bdca2bde33d        nginx:latest        "nginx -g 'daemon ..."   7 minutes ago       Up 7 minutes        80/tcp, 0.0.0.0:5000->5000/tcp                           nginx_2
f769af3e9847        nginx:latest        "nginx -g 'daemon ..."   22 minutes ago      Up 22 minutes       0.0.0.0:32768->80/tcp                                    nginx_1
[root@docker ~]# 

  容器啓動後,本機會隨機自動分配一個未被佔用的端口。網絡

 5.查看映射端口配置

   使用docker port命令來查看當前映射的端口配置,也能夠查看綁定的地址tcp

[root@docker ~]# docker port nginx_1
80/tcp -> 0.0.0.0:32768
[root@docker ~]# docker port nginx_2
5000/tcp -> 0.0.0.0:5000
[root@docker ~]# docker port nginx_3
2700/tcp -> 0.0.0.0:3000
8863/tcp -> 0.0.0.0:2389
[root@docker ~]# docker port nginx_4
8081/tcp -> 10.0.0.31:89
[root@docker ~]# docker port nginx_5
8082/tcp -> 10.0.0.31:32769
[root@docker ~]#

  注意:

    容器有本身的內部網絡和IP地址,使用docker inspect +容器ID能夠獲取容器的具體信息。

 

二、互聯機制實現便捷訪問

   容器的互聯是一種讓多個容器中應用進行快速交互的方式,它會在源和接收容器之間創建鏈接關係,接收容器能夠經過容器名快速訪問到源容器,而不用指定具體的IP地址。

1.自定義容器命名

   鏈接系統依據容器的名稱來執行。所以,首先要給容器定義一個簡單好記的名字。在容器建立的時候,系統會隨機建立一個容器名,可是並無特殊的意義也不便於記憶,全部自定義容器名有一下亮點好處:

1.自定義的命名比較好記,好比一個Web應用容器,就能夠起名web,既方便記憶也方便理解容器的做用;
2.當要鏈接其餘容器時,即便重啓,也可使用自定義的容器名,,好比web容器鏈接到db容器。

  使用--name參數能夠爲容器自定義命名:

[root@docker ~]# docker run -itd --name centos_1 centos:latest 
4d58a9f6f324185caf53dbe5eaee85f35e853842ffb037cf272c2a92cee89716
[root@docker ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                    NAMES
4d58a9f6f324        centos:latest       "/bin/bash"              6 seconds ago       Up 5 seconds                                                                 centos_1
3436fd5fbdca        nginx:latest        "nginx -g 'daemon ..."   11 minutes ago      Up 11 minutes       80/tcp, 10.0.0.31:32769->8082/tcp                        nginx_5
16a476837222        nginx:latest        "nginx -g 'daemon ..."   13 minutes ago      Up 13 minutes       80/tcp, 10.0.0.31:89->8081/tcp                           nginx_4
65fbfbe9761e        nginx:latest        "nginx -g 'daemon ..."   15 minutes ago      Up 15 minutes       80/tcp, 0.0.0.0:3000->2700/tcp, 0.0.0.0:2389->8863/tcp   nginx_3
5bdca2bde33d        nginx:latest        "nginx -g 'daemon ..."   18 minutes ago      Up 18 minutes       80/tcp, 0.0.0.0:5000->5000/tcp                           nginx_2
f769af3e9847        nginx:latest        "nginx -g 'daemon ..."   34 minutes ago      Up 34 minutes       0.0.0.0:32768->80/tcp                                    nginx_1
[root@docker ~]# 

  經過docker ps或者docker ps -a能夠查看到容器的自定義名字,利用docker inspect也能夠獲取到容器自定義名字:

[root@docker ~]# docker inspect -f "{{.Name}}" 4d58a9f6f324
/centos_1
[root@docker ~]#

  注意:

    容器的名稱是惟一的。若是已經命名了一個web的容器,當再次使用web這個命名的時候會報錯,若是必定要使用,須要先用docker rm刪除以前建立的web容器。

    在執行docker run的時候若是添加--rm參數,則容器終止後會馬上刪除。--rm參數和-d參數不能同時使用。

 

二、容器互聯

   使用--link參數可讓容器之間安全地進行交互。

  建立一個數據庫容器:

[root@docker ~]# docker run -itd --name db --env MYSQL_ROOT_PASSWORD=example  mariadb
b239b124946c99b7da63e00c22df802e9612fbe8bc636389205baf6c2f6963bd
[root@docker ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
b239b124946c        mariadb             "docker-entrypoint..."   3 seconds ago       Up 2 seconds        3306/tcp            db
[root@docker ~]#

  建立一個web容器並將它鏈接到db容器:

[root@docker ~]# docker run -itd -P --name web --link db:db nginx:latest 
42fa6662784010368b5e615d495e71920d85cc1bc089a5d181657514973ee90a
[root@docker ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
86ef0f632ffe        nginx:latest        "nginx -g 'daemon ..."   44 seconds ago       Up 43 seconds       80/tcp              web
b239b124946c        mariadb             "docker-entrypoint..."   About a minute ago   Up 59 seconds       3306/tcp            db
[root@docker ~]# 

  此時web容器已經和db容器創建互聯關係:--link參數的格式爲:--link name:alias,其中name是要鏈接的容器名稱,alias是這個鏈接的別名。

  Docker至關於在兩個互聯的容器之間建立了一個虛擬通道,而不用映射它們的端口到宿主機上。在啓動db容器的時候並無使用-p或者-P參數,從而避免了暴露數據庫服務端口到外部網絡上。

  Docker經過兩種方式爲容器公開鏈接信息:

1.更新環境變量;
2.更新/etc/hosts文件。

  使用env命令來查看web容器的環境變量:

[root@docker ~]# docker run --rm --name web3 --link db:db nginx:latest env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=7258de738125
DB_PORT=tcp://172.17.0.2:3306
DB_PORT_3306_TCP=tcp://172.17.0.2:3306
DB_PORT_3306_TCP_ADDR=172.17.0.2
DB_PORT_3306_TCP_PORT=3306
DB_PORT_3306_TCP_PROTO=tcp
DB_NAME=/web3/db
DB_ENV_MYSQL_ROOT_PASSWORD=example
DB_ENV_GOSU_VERSION=1.10
DB_ENV_GPG_KEYS=199369E5404BD5FC7D2FE43BCBCB082A1BB943DB     430BDF5C56E7C94E848EE60C1C4CBDCDCD2EFD2A     4D1BB29D63D98E422B2113B19334A25F8507EFA5
DB_ENV_MARIADB_MAJOR=10.2
DB_ENV_MARIADB_VERSION=10.2.11+maria~jessie
NGINX_VERSION=1.13.7-1~stretch
NJS_VERSION=1.13.7.0.1.15-1~stretch
HOME=/root
[root@docker ~]# 

  其中DB_開頭的環境變量是提供web容器鏈接db容器使用的,前綴採用大寫的鏈接別名。

  除了環境變量以外,Docker還添加host信息到父容器的/etc/hosts文件。

[root@docker ~]# docker run -it --rm --link db:db nginx:latest /bin/bash
root@16b8e6fde27f:/# cat /etc/hosts 
172.17.0.2    db b239b124946c
172.17.0.5    16b8e6fde27f
root@16b8e6fde27f:/#

  這裏有兩個hosts信息,第一個是db容器的IP和容器名+容器ID,第二個是web本身的IP和容器ID,web容器中hosts文件採用容器的ID做爲主機名。

  互聯的容器之間是能夠ping通的。

相關文章
相關標籤/搜索