開箱即用的 SQL Server Docker

dbLenis發表於2018-09-03

SQL Server 真是越來越有看頭。當我們還在為 Linux 上執行 SQL Server 而興奮的時候,SQL Server 已經開啟了 容器化之路,至此才能看清微軟的胸懷,開始擁抱更大的世界。當我越來越深入去閱讀有關 Docker 容器的文件,已然發現曾經部署上千臺 Linux MySQL 的場景,如今在 Docker 的幫助下,SQL Server 也是手到擒來。如果 SQL Server 再匹配一個分散式計算引擎,那也是分分鐘即可打造一個計算怪獸,和小象 Hadoop 分庭抗禮。屆時玩 SQL 的朋友們不用分心去折騰 Hadoop/Spark, 僅用 T-SQL 依然可以笑傲江湖。因為人工智慧,機器學習演算法本就是資料集合操作,天生和 SQL 結合緊密。不信看我的這篇: [機器學習演算法之 KNN 的 SQL 實現](https://blog.csdn.net/wujiandao/article/details/80685641) 當然,理想是要有的,目前還是將心放一放,迴歸這次的主題, Docker. 接觸容器化實踐,始於團隊 2017 的 CRM 產品釋出流程改革,微服務化。

現將整個過程梳理一下,對 SQL Server 容器化程式做一個明晰的總結。

  • Docker 概念以及作用

  • Docker 用來發布 SQL Server 部署的方法和優勢

Docker 的概念以及作用

Docker 的安裝

安裝的必備條件:
  1. 64位 CPU
  2. Linux 3.8 以上版本
  3. 核心必須支援一種合適的儲存驅動(storage driver),如:
Device Manager
AUFS
vfs
btrfs
預設儲存驅動是 Device Mapper
  1. 核心必須支援並開啟 cgroup 和名稱空間功能
檢查 Centos 版本:
[root@centos00 log]# uname -a
Linux centos00 3.10.0-514.el7.x86_64 #1 SMP Tue Nov 22 16:42:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
檢查儲存驅動:
[root@centos00 log]# ls -l /sys/class/misc/device-mapper
lrwxrwxrwx. 1 root root 0 Aug 22 18:33 /sys/class/misc/device-mapper -> ../../devices/virtual/misc/device-mapper

或者直接查當前執行的裝置

[root@centos00 log]# grep device-mapper /proc/devices
253 device-mapper

若沒有則執行下面指令碼安裝

yum install -y device-mapper
modprobe dm_mod
安裝 EPEL 軟體包倉庫

此倉庫只是在 centos 上安裝 Docker 的時候需要,當然 RedHat 也是同門。而 Fedora 則不需要,因為 EPEL 是 Fedora 出品,已經包含了此庫。

https://fedoraproject.org/wiki/EPEL

EPEL: Extra Packages For Enterprise Linux

顧名思義,這是專門為企業版 Linux 打造的擴充套件功能庫。

CentOS 6/7 安裝路徑各不相同:

yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

而正式的安裝則簡單的多:

yum install -y docker
Docker 執行時檢查:
[root@centos00 log]# docker info
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

以上指令碼可用來檢查 Docker 執行時資訊,亦可用來檢查 Docker 是否執行

啟動 Docker 程式以及配置開機執行 Docker :

systemctl start docker
systemctl enable docker
[root@centos00 log]# systemctl start docker
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.
[root@centos00 log]# systemctl status docker.service -l
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Thu 2018-08-30 07:45:41 CST; 2min 19s ago
     Docs: http://docs.docker.com
  Process: 31489 ExecStart=/usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current --init-path=/usr/libexec/docker/docker-init-current --seccomp-profile=/etc/docker/seccomp.json $OPTIONS</span>&nbsp;<span class="hljs-variable" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(98, 151, 85); word-wrap: inherit !important; word-break: inherit !important;">$DOCKER_STORAGE_OPTIONS $DOCKER_NETWORK_OPTIONS</span>&nbsp;<span class="hljs-variable" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(98, 151, 85); word-wrap: inherit !important; word-break: inherit !important;">$ADD_REGISTRY $BLOCK_REGISTRY</span>&nbsp;<span class="hljs-variable" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(98, 151, 85); word-wrap: inherit !important; word-break: inherit !important;">$INSECURE_REGISTRY $REGISTRIES (code=exited, status=1/FAILURE)
 Main PID: 31489 (code=exited, status=1/FAILURE)

Aug 30 07:45:38 centos00 systemd[1]: Starting Docker Application Container Engine...
Aug 30 07:45:38 centos00 dockerd-current[31489]: time="2018-08-30T07:45:38.949026762+08:00" level=warning msg="could not change group /var/run/docker.sock to docker: group docker not found"
Aug 30 07:45:38 centos00 dockerd-current[31489]: time="2018-08-30T07:45:38.954488551+08:00" level=info msg="libcontainerd: new containerd process, pid: 31496"
Aug 30 07:45:41 centos00 dockerd-current[31489]: Error starting daemon: SELinux is not supported with the overlay2 graph driver on this kernel. Either boot into a newer kernel or disable selinux in docker (--selinux-enabled=false)
Aug 30 07:45:41 centos00 systemd[1]: docker.service: main process exited, code=exited, status=1/FAILURE
Aug 30 07:45:41 centos00 systemd[1]: Failed to start Docker Application Container Engine.
Aug 30 07:45:41 centos00 systemd[1]: Unit docker.service entered failed state.
Aug 30 07:45:41 centos00 systemd[1]: docker.service failed.

參考這篇文章:

https://stackoverflow.com/questions/45461307/selinux-is-not-supported-with-the-overlay-graph-driver

執行命令:

[root@centos00 log]#  cat /etc/sysconfig/docker-storage
DOCKER_STORAGE_OPTIONS="--storage-driver overlay2 "

修改其 storage driver,使其應用 devicemapper :

[root@centos00 log]#  cat /etc/sysconfig/docker-storage
DOCKER_STORAGE_OPTIONS="--storage-driver devicemapper "

再次啟動 docker, 並檢查 Docker 的狀態

[root@centos00 log]# docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 1.13.1
Storage Driver: devicemapper
 Pool Name: docker-253:0-101679883-pool
 Pool Blocksize: 65.54 kB
 Base Device Size: 10.74 GB
 Backing Filesystem: xfs
 Data file: /dev/loop0
 Metadata file: /dev/loop1
 Data Space Used: 11.8 MB
 Data Space Total: 107.4 GB
 Data Space Available: 29.25 GB
 Metadata Space Used: 581.6 kB
 Metadata Space Total: 2.147 GB
 Metadata Space Available: 2.147 GB
 Thin Pool Minimum Free Space: 10.74 GB
 Udev Sync Supported: true
 Deferred Removal Enabled: true
 Deferred Deletion Enabled: true
 Deferred Deleted Device Count: 0
 Data loop file: /var/lib/docker/devicemapper/devicemapper/data
 WARNING: Usage of loopback devices is strongly discouraged for production use. Use `--storage-opt dm.thinpooldev` to specify a custom block storage device.
 Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata
 Library Version1.02.135-RHEL7 (2016-09-28)
Logging Driver: journald
Cgroup Driver: systemd
Plugins: 
 Volume: local
 Network: bridge host macvlan null overlay
Swarm: inactive
Runtimes: runc docker-runc
Default Runtime: docker-runc
Init Binary: /usr/libexec/docker/docker-init-current
containerd version:  (expected: aa8187dbd3b7ad67d8e5e3a15115d3eef43a7ed1)
runc version5eda6f6fd0c2884c2c8e78a6e7119e8d0ecedb77 (expected: 9df8b306d01f59d3a8029be411de015b7304dd8f)
init version: fec3683b971d9c3ef73f284f176672c44b448662 (expected: 949e6facb77383876aeff8a6944dde66b3089574)
Security Options:
 seccomp
  WARNING: You're not using the default seccomp profile
  Profile: /etc/docker/seccomp.json
 selinux
Kernel Version: 3.10.0-514.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
Number of Docker Hooks: 3
CPUs: 4
Total Memory: 3.699 GiB
Name: centos00
ID: DORM:3S6Z:Y33P:TWDH:MT52:NRJR:T5LY:MZYT:37MU:HP3O:JDTS:OFRE
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false
Registries: docker.io (secure)
建立一個容器:
[root@centos00 log]# docker run -i -t ubuntu /bin/bash
Unable to find image 'ubuntu:latest' locally
Trying to pull repository docker.io/library/ubuntu ... 
latest: Pulling from docker.io/library/ubuntu
124c757242f8: Downloading [===============================>                   ] 19.84 MB/31.76 MB
2ebc019eb4e2: Download complete 
dac0825f7ffb: Download complete 
82b0bb65d1bf: Download complete 
ef3b655c7f88: Download complete

這是簡易版本的建立新容器的方式。如果容器不是遠端伺服器維護的,而在本地區域網(為了安全,放在本地區域網快取),創立新容器的方法又有稍微不同。

當命令執行完畢,此時我們已經在 Docker 新建的容器裡面:

root@ecb9d7b74b07:~# cat /etc/hosts
127.0.0.1    localhost
::1    localhost ip6-localhost ip6-loopback
fe00::0    ip6-localnet
ff00::0    ip6-mcastprefix
ff02::1    ip6-allnodes
ff02::2    ip6-allrouters
172.17.0.2    ecb9d7b74b07

另起一個視窗,檢查開啟的容器

[root@centos00 huangyun]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
ecb9d7b74b07        ubuntu              "/bin/bash"         9 minutes ago       Up 9 minutes                            vibrant_thompson

這是一個臨時起的容器,一旦退出執行了 docker run -i -t ubuntu /bin/bash 的視窗,容器就隨之關閉了。

如果要建立一個長久不關閉的容器,就需要執行面的命令來安裝守護容器:

docker run --name daemon_dave -d ubuntu /bin/sh -c "while true ;
do echo hello world; sleep 1 ; done"

-d 標識了此容器執行在後臺,命令執行完之後,返回主機。

可以執行下面的命令,連線後臺執行的容器:

[root@centos00 huangyun]# docker exec -i -t daemon_dave /bin/bash
root@eb6cb2a3b7b6:/# top



top - 14:19:01 up 16:17,  0 users,  load average: 0.290.210.20
Tasks:   4 total,   1 running,   3 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.6 us,  1.2 sy,  0.0 ni, 98.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  3878288 total,   114852 free,  2647828 used,  1115608 buff/cache
KiB Swap:  2097148 total,  2092540 free,     4608 used.   831552 avail Mem
關閉一個容器:

執行下面命令即可關閉一個正在執行的容器:

[root@centos00 website]# docker stop  nginx_server_1
nginx_server_1
[root@centos00 website]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@centos00 website]#

docker ps 可以用來檢查當前執行著的容器。

以特定名字執行一個容器之後,這名字就一直儲存著,下次執行,如果再以這份名字執行相應的執行程式,會報如下的錯誤:

[root@centos00 website]# docker run -d -p 80 --name nginx_server_1 -v /var/www/html/website:/var/www/html/website:rw ubuntu/nginx3 
/usr/bin/docker-current: Error response from daemon: Conflict. The container name "/nginx_server_1" is already in use by container f40d10674908782758915399d3f16f1c5207e2907cb90e25f3689bccb9449d34. You have to remove (or rename) that container to be able to reuse that name..
See '/usr/bin/docker-current run --help'.

不知道為什麼 Docker 主程會一直儲存著執行過的 docker 名字:

[root@centos00 website]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
17f8ba709f49        ubuntu/nginx3       "nginx"                  4 minutes ago       Exited (03 minutes ago                        hardcore_pare
f40d10674908        ubuntu/nginx3       "nginx"                  10 hours ago        Exited (06 minutes ago                        nginx_server_1
7baea86e09b2        ubuntu/nginx2       "/bin/sh"                10 hours ago        Exited (210 hours ago                         determined_bartik
a4a3348bf5b4        ubuntu/nginx2       "/bin/sh"                10 hours ago        Exited (010 hours ago                         quirky_keller
d944f39ba4b5        ubuntu/nginx2       "nginx"                  10 hours ago        Exited (110 hours ago                         amazing_wozniak
498f38dab68d        ubuntu/nginx2       "nginx"                  10 hours ago        Exited (110 hours ago                         website
e91147812d90        ubuntu/nginx2       "/bin/sh"                11 hours ago        Exited (010 hours ago                         reverent_golick
b2dc934e76cb        ubuntu/nginx2       "/bin/sh"                11 hours ago        Exited (011 hours ago                         nginx2
4389f303f89f        ubuntu/ping         "/bin/sh"                11 hours ago        Exited (011 hours ago                         dockernginx1
425db7295d54        ubuntu/ping         "/bin/sh"                11 hours ago        Exited (011 hours ago                         dockernginx
4092ee432cdc        ubuntu/ping         "/bin/sh"                11 hours ago        Exited (011 hours ago                         ubuntu00
2eedc14e316f        c58e6a4eb329        "/bin/sh -c 'apt-g..."   11 hours ago        Exited (10011 hours ago                       nervous_stallman
8393f330888c        ubuntu/nginx        "/bin/bash"              12 hours ago        Exited (012 hours ago                         gracious_leavitt
b106b1b31c84        ubuntu/nginx        "/bin/bash"              13 hours ago        Exited (12712 hours ago                       nginx_server
6f748f358454        ubuntu/ping         "/bin/bash"              15 hours ago        Exited (015 hours ago                         compassionate_brahmagupta
e4a3a8acc032        centos:7.4.1708     "/bin/sh"                17 hours ago        Exited (017 hours ago                         centos7
eb6cb2a3b7b6        ubuntu              "/bin/sh -c 'while..."   2 days ago          Exited (13712 hours ago                       daemon_dave
ecb9d7b74b07        ubuntu              "/bin/bash"              2 days ago          Exited (12712 hours ago                       vibrant_thompson
[root@centos00 website]#

當再一次使用其中之一執行容器時,名字會因為重複而被拒絕執行。

針對這種需要使用同一個名字重啟容器的情況,一般的解決方法有3種:

  1. 在每次執行容器時,指定關閉容器之後,銷燬
# docker run -d -p 80 --rm --name nginx_server_1 -v /var/www/html/website:/var/www/html/website:rw ubuntu/nginx3
  1. 先關閉容器,再移除容器名字
# docker stop nginx_server_1
# docker rm nginx_server_1
  1. 重啟容器而不用先銷燬
# docker restart nginx_server_1
Docker 的映象與倉庫

Docker 公司出版了自己維護和運營的一些映象,官方網站維護了這份列表:

https://hub.docker.com/

註冊一個 Docker 官網的賬戶 , dblenis, l*w*6.

每個倉庫中都存放著各種映象,執行命令,可以將這些映象都拉到本地儲存:

[root@centos00 containers]# docker pull centos
Using default tag: latest
Trying to pull repository docker.io/library/centos ... 
latest: Pulling from docker.io/library/centos
256b176beaff: Pull complete 
Digest: sha256:6f6d986d425aeabdc3a02cb61c02abb2e78e57357e92417d6d58332856024faf
Status: Downloaded newer image for docker.io/centos:latest
[root@centos00 containers]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/ubuntu    latest              16508e5c265d        9 days ago          84.1 MB
docker.io/centos    latest              5182e96772bf        3 weeks ago         200 MB
[root@centos00 containers]#

每個映象都會帶有自己的標籤,在建立新容器的時候帶上這份標籤,會讓我們更明白操作的物件是什麼,會有什麼異常:

[root@centos00 containers]# docker run --name centos7 -d centos:centos7.4.1708   /bin/sh

如果不指定特定標籤,在拉取官網映象時,則拉取的是最新的。

構建映象

兩種方法:

使用 Docker Commit 命令

使用 Docker build 命令和 Dockerfile 檔案

通過前面新建的 ubuntu 沒有 ping 的功能,我希望可以將 ping 功能安裝進去,然後打包一個新的映象,放在 Docker 上分享。

# apt-get install iputils-ping
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  libcap2 libcap2-bin libidn11 libpam-cap
The following NEW packages will be installed:
  iputils-ping libcap2 libcap2-bin libidn11 libpam-cap
0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.
Need to get 140 kB of archives.
After this operation, 537 kB of additional disk space will be used.
Do you want to continue? [Y/n] y

apt-get 安裝一些其他軟體,方便以後使用,提交這些更改,將其完整的做成一個容器映象。以後若要新建容器,只需要在此映象基礎上新建便可。

[root@centos00 huangyun]# docker commit daemon_dave ubuntu/ping

若此時檢視映象庫:

[root@centos00 huangyun]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu/ping         latest              2eb12722cb2f        2 minutes ago       186 MB
docker.io/ubuntu    latest              16508e5c265d        9 days ago          84.1 MB
docker.io/centos    7.4.1708            d3949e34634c        3 weeks ago         197 MB
docker.io/centos    centos7.4.1708      d3949e34634c        3 weeks ago         197 MB
docker.io/centos    latest              5182e96772bf        3 weeks ago         200 MB

發現 repository 裡面多了一個 ubuntu/ping 的映象。

就像是虛擬機器多儲存了一個 snapshot 一樣,更方便的是我們居然可以依據這份 snapshot 來構建一個新的虛擬機器。

官方更推薦使用 Dockerfile 和 Docker build 來構建新容器映象

Dockerfile 是一種特殊的檔案,用來編寫 DSL 指令,這些指令可以被 Docker 程式識別,並根據這些指令進行處理,最終完成一個可用的映象製作。每一個映象都是從基礎映象之上,一點點新增其他映象組成的。一開始的基礎映象只是符合最低執行庫的核心,比如 ubuntu 的基礎映象,居然連 ping, vi 都沒有。如果需要這些功能作為新映象的一部分,那麼就要在 Dockerfile 裡面新加。

更多的 Dockerfile 支援的指令:
http://docs.docker.com/reference/builder

Docker build 就是基於 Dockerfile ,將其中的指令傳送給 Docker 程式,使其進行構建新映象。Docker 程式可以看做是服務程式,提供一系列的後臺服務,docker build 就是客戶端,傳送請求給 Docker ,Docker 統一排程工作完成 build 的請求。

[root@centos00 DockerWeb]# cat Dockerfile
# version : 0.0.1

FROM ubuntu:14.04

MAINTAINER Lenis Huang "huangyun_122@163.com"
RUN apt-get update
RUN apt-get install -y nginx
RUN echo "Hello, World!" > /usr/share/nginx/html/index.html
EXPOSE 80

上面的指令碼安裝了 nginx 服務,並且建立了一個簡單的靜態網頁,最後允許 80 開放給外界訪問。

構建開始:

[root@centos00 DockerWeb]# docker build -t="ubuntu/nginx" .
Sending build context to Docker daemon 2.048 kB
Step 1/6 : FROM ubuntu:14.04
Trying to pull repository docker.io/library/ubuntu ... 
14.04: Pulling from docker.io/library/ubuntu
72c01b436656: Extracting [=====>                                             ] 7.799 MB/67.13 MB
944f9cf63457: Download complete 
6856614e8780: Download complete 
9d0e4b6507f2: Download complete 
c00913272b9b: Download complete

正在 build 之中的映象,這一步步看的更詳細:

[root@centos00 DockerWeb]# docker build -t="ubuntu/nginx" .
Sending build context to Docker daemon 2.048 kB
Step 1/6 : FROM ubuntu:14.04
Trying to pull repository docker.io/library/ubuntu ... 
14.04: Pulling from docker.io/library/ubuntu
72c01b436656: Pull complete 
944f9cf63457: Pull complete 
6856614e8780: Pull complete 
9d0e4b6507f2: Pull complete 
c00913272b9b: Pull complete 
Digest: sha256:d6b8e25d0f3073bad48fda3f28d01ac0e8bd0e2a6d034c7f462619591a72c791
Status: Downloaded newer image for docker.io/ubuntu:14.04
 ---> 8789038981bc
Step 2/6 : MAINTAINER Lenis Huang "huangyun_122@163.com"
 ---> Running in 6a16f9906861
 ---> aacb0d62260f
Removing intermediate container 6a16f9906861
Step 3/6 : RUN apt-get update
 ---> Running in ed843eeaf662

Ign http://archive.ubuntu.com trusty InRelease
Get:1 http://security.ubuntu.com trusty-security InRelease [65.9 kB]
Get:2 http://archive.ubuntu.com trusty-updates InRelease [65.9 kB]
Get:3 http://archive.ubuntu.com trusty-backports InRelease [65.9 kB]
Get:4 http://archive.ubuntu.com trusty Release.gpg [933 B]
Get:5 http://security.ubuntu.com trusty-security/main amd64 Packages [952 kB]
Get:6 http://archive.ubuntu.com trusty-updates/universe Sources [260 kB]
Get:7 http://security.ubuntu.com trusty-security/universe Sources [96.3 kB]
Get:8 http://archive.ubuntu.com trusty-updates/main amd64 Packages [1372 kB]
Get:9 http://archive.ubuntu.com trusty-updates/restricted amd64 Packages [21.4 kB]
Get:10 http://archive.ubuntu.com trusty-updates/universe amd64 Packages [606 kB]
Get:11 http://archive.ubuntu.com trusty-updates/multiverse amd64 Packages [16.0 kB]
Get:12 http://security.ubuntu.com trusty-security/restricted amd64 Packages [18.1 kB]
Get:13 http://archive.ubuntu.com trusty-backports/main amd64 Packages [14.7 kB]
Get:14 http://archive.ubuntu.com trusty-backports/restricted amd64 Packages [40 B]
Get:15 http://archive.ubuntu.com trusty-backports/universe amd64 Packages [52.5 kB]
Get:16 http://archive.ubuntu.com trusty-backports/multiverse amd64 Packages [1392 B]
Get:17 http://archive.ubuntu.com trusty Release [58.5 kB]
Get:18 http://archive.ubuntu.com trusty/universe Sources [7926 kB]
Get:19 http://archive.ubuntu.com trusty/main amd64 Packages [1743 kB]
Get:20 http://archive.ubuntu.com trusty/restricted amd64 Packages [16.0 kB]
Get:21 http://archive.ubuntu.com trusty/universe amd64 Packages [7589 kB]
Get:22 http://archive.ubuntu.com trusty/multiverse amd64 Packages [169 kB]
Get:23 http://security.ubuntu.com trusty-security/multiverse amd64 Packages [4721 B]
Get:24 http://security.ubuntu.com trusty-security/universe amd64 Packages [311 kB]
Fetched 21.4 MB in 11s (1822 kB/s)
Reading package lists...
 ---> 582a2a0c6fb9
Removing intermediate container ed843eeaf662
Step 4/6 : RUN apt-get install -y nginx
 ---> Running in 7199f88e91ef

Reading package lists...
Building dependency tree...
Reading state information...
The following extra packages will be installed:
  fontconfig-config fonts-dejavu-core geoip-database libfontconfig1
  libfreetype6 libgd3 libgeoip1 libjbig0 libjpeg-turbo8 libjpeg8 libtiff5
  libvpx1 libx11-6 libx11-data libxau6 libxcb1 libxdmcp6 libxml2 libxpm4
  libxslt1.1 nginx-common nginx-core sgml-base xml-core
Suggested packages:
  libgd-tools geoip-bin fcgiwrap nginx-doc sgml-base-doc debhelper
The following NEW packages will be installed:
  fontconfig-config fonts-dejavu-core geoip-database libfontconfig1
  libfreetype6 libgd3 libgeoip1 libjbig0 libjpeg-turbo8 libjpeg8 libtiff5
  libvpx1 libx11-6 libx11-data libxau6 libxcb1 libxdmcp6 libxml2 libxpm4
  libxslt1.1 nginx nginx-common nginx-core sgml-base xml-core
0 upgraded, 25 newly installed, 0 to remove and 0 not upgraded.
Need to get 5593 kB of archives.
After this operation, 19.8 MB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu/ trusty/main libgeoip1 amd64 1.6.0-1 [71.0 kB]
Get:2 http://archive.ubuntu.com/ubuntu/ trusty/main libxau6 amd64 1:1.0.8-1 [8376 B]
Get:3 http://archive.ubuntu.com/ubuntu/ trusty/main libxdmcp6 amd64 1:1.1.1-1 [12.8 kB]
Get:4 http://archive.ubuntu.com/ubuntu/ trusty/main libxcb1 amd64 1.10-2ubuntu1 [38.0 kB]
Get:5 http://archive.ubuntu.com/ubuntu/ trusty-updates/main libx11-data all 2:1.6.2-1ubuntu2.1 [111 kB]
Get:6 http://archive.ubuntu.com/ubuntu/ trusty-updates/main libx11-6 amd64 2:1.6.2-1ubuntu2.1 [561 kB]
Get:7 http://archive.ubuntu.com/ubuntu/ trusty-updates/main libxml2 amd64 2.9.1+dfsg1-3ubuntu4.13 [573 kB]
Get:8 http://archive.ubuntu.com/ubuntu/ trusty/main sgml-base all 1.26+nmu4ubuntu1 [12.5 kB]
Get:9 http://archive.ubuntu.com/ubuntu/ trusty/main fonts-dejavu-core all 2.34-1ubuntu1 [1024 kB]
Get:10 http://archive.ubuntu.com/ubuntu/ trusty-updates/main fontconfig-config all 2.11.0-0ubuntu4.2 [47.4 kB]
Get:11 http://archive.ubuntu.com/ubuntu/ trusty-updates/main libfreetype6 amd64 2.5.2-1ubuntu2.8 [304 kB]
Get:12 http://archive.ubuntu.com/ubuntu/ trusty-updates/main libfontconfig1 amd64 2.11.0-0ubuntu4.2 [123 kB]
Get:13 http://archive.ubuntu.com/ubuntu/ trusty-updates/main libjpeg-turbo8 amd64 1.3.0-0ubuntu2.1 [104 kB]
Get:14 http://archive.ubuntu.com/ubuntu/ trusty/main libjpeg8 amd64 8c-2ubuntu8 [2194 B]
Get:15 http://archive.ubuntu.com/ubuntu/ trusty-updates/main libjbig0 amd64 2.0-2ubuntu4.1 [26.1 kB]
Get:16 http://archive.ubuntu.com/ubuntu/ trusty-updates/main libtiff5 amd64 4.0.3-7ubuntu0.9 [147 kB]
Get:17 http://archive.ubuntu.com/ubuntu/ trusty/main libvpx1 amd64 1.3.0-2 [556 kB]
Get:18 http://archive.ubuntu.com/ubuntu/ trusty-updates/main libxpm4 amd64 1:3.5.10-1ubuntu0.1 [33.2 kB]
Get:19 http://archive.ubuntu.com/ubuntu/ trusty-updates/main libgd3 amd64 2.1.0-3ubuntu0.10 [123 kB]
Get:20 http://archive.ubuntu.com/ubuntu/ trusty-updates/main libxslt1.1 amd64 1.1.28-2ubuntu0.1 [145 kB]
Get:21 http://archive.ubuntu.com/ubuntu/ trusty/main geoip-database all 20140313-1 [1196 kB]
Get:22 http://archive.ubuntu.com/ubuntu/ trusty/main xml-core all 0.13+nmu2 [23.3 kB]
Get:23 http://archive.ubuntu.com/ubuntu/ trusty-updates/main nginx-common all 1.4.6-1ubuntu3.8 [19.1 kB]
Get:24 http://archive.ubuntu.com/ubuntu/ trusty-updates/main nginx-core amd64 1.4.6-1ubuntu3.8 [325 kB]
Get:25 http://archive.ubuntu.com/ubuntu/ trusty-updates/main nginx all 1.4.6-1ubuntu3.8 [5394 B]
debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
dpkg-preconfigure: unable to re-open stdin: 
Fetched 5593 kB in 6min 9s (15.2 kB/s)
Selecting previously unselected package libgeoip1:amd64.
(Reading database ... 11571 files and directories currently installed.)
Preparing to unpack .../libgeoip1_1.6.0-1_amd64.deb ...
Unpacking libgeoip1:amd64 (1.6.0-1) ...
Selecting previously unselected package libxau6:amd64.
Preparing to unpack .../libxau6_1%3a1.0.8-1_amd64.deb ...
Unpacking libxau6:amd64 (1:1.0.8-1) ...
Selecting previously unselected package libxdmcp6:amd64.
Preparing to unpack .../libxdmcp6_1%3a1.1.1-1_amd64.deb ...
Unpacking libxdmcp6:amd64 (1:1.1.1-1) ...
Selecting previously unselected package libxcb1:amd64.
Preparing to unpack .../libxcb1_1.10-2ubuntu1_amd64.deb ...
Unpacking libxcb1:amd64 (1.10-2ubuntu1) ...
Selecting previously unselected package libx11-data.
Preparing to unpack .../libx11-data_2%3a1.6.2-1ubuntu2.1_all.deb ...
Unpacking libx11-data (2:1.6.2-1ubuntu2.1) ...
Selecting previously unselected package libx11-6:amd64.
Preparing to unpack .../libx11-6_2%3a1.6.2-1ubuntu2.1_amd64.deb ...
Unpacking libx11-6:amd64 (2:1.6.2-1ubuntu2.1) ...
Selecting previously unselected package libxml2:amd64.
Preparing to unpack .../libxml2_2.9.1+dfsg1-3ubuntu4.13_amd64.deb ...
Unpacking libxml2:amd64 (2.9.1+dfsg1-3ubuntu4.13) ...
Selecting previously unselected package sgml-base.
Preparing to unpack .../sgml-base_1.26+nmu4ubuntu1_all.deb ...
Unpacking sgml-base (1.26+nmu4ubuntu1) ...
Selecting previously unselected package fonts-dejavu-core.
Preparing to unpack .../fonts-dejavu-core_2.34-1ubuntu1_all.deb ...
Unpacking fonts-dejavu-core (2.34-1ubuntu1) ...
Selecting previously unselected package fontconfig-config.
Preparing to unpack .../fontconfig-config_2.11.0-0ubuntu4.2_all.deb ...
Unpacking fontconfig-config (2.11.0-0ubuntu4.2) ...
Selecting previously unselected package libfreetype6:amd64.
Preparing to unpack .../libfreetype6_2.5.2-1ubuntu2.8_amd64.deb ...
Unpacking libfreetype6:amd64 (2.5.2-1ubuntu2.8) ...
Selecting previously unselected package libfontconfig1:amd64.
Preparing to unpack .../libfontconfig1_2.11.0-0ubuntu4.2_amd64.deb ...
Unpacking libfontconfig1:amd64 (2.11.0-0ubuntu4.2) ...
Selecting previously unselected package libjpeg-turbo8:amd64.
Preparing to unpack .../libjpeg-turbo8_1.3.0-0ubuntu2.1_amd64.deb ...
Unpacking libjpeg-turbo8:amd64 (1.3.0-0ubuntu2.1) ...
Selecting previously unselected package libjpeg8:amd64.
Preparing to unpack .../libjpeg8_8c-2ubuntu8_amd64.deb ...
Unpacking libjpeg8:amd64 (8c-2ubuntu8) ...
Selecting previously unselected package libjbig0:amd64.
Preparing to unpack .../libjbig0_2.0-2ubuntu4.1_amd64.deb ...
Unpacking libjbig0:amd64 (2.0-2ubuntu4.1) ...
Selecting previously unselected package libtiff5:amd64.
Preparing to unpack .../libtiff5_4.0.3-7ubuntu0.9_amd64.deb ...
Unpacking libtiff5:amd64 (4.0.3-7ubuntu0.9) ...
Selecting previously unselected package libvpx1:amd64.
Preparing to unpack .../libvpx1_1.3.0-2_amd64.deb ...
Unpacking libvpx1:amd64 (1.3.0-2) ...
Selecting previously unselected package libxpm4:amd64.
Preparing to unpack .../libxpm4_1%3a3.5.10-1ubuntu0.1_amd64.deb ...
Unpacking libxpm4:amd64 (1:3.5.10-1ubuntu0.1) ...
Selecting previously unselected package libgd3:amd64.
Preparing to unpack .../libgd3_2.1.0-3ubuntu0.10_amd64.deb ...
Unpacking libgd3:amd64 (2.1.0-3ubuntu0.10) ...
Selecting previously unselected package libxslt1.1:amd64.
Preparing to unpack .../libxslt1.1_1.1.28-2ubuntu0.1_amd64.deb ...
Unpacking libxslt1.1:amd64 (1.1.28-2ubuntu0.1) ...
Selecting previously unselected package geoip-database.
Preparing to unpack .../geoip-database_20140313-1_all.deb ...
Unpacking geoip-database (20140313-1) ...
Selecting previously unselected package xml-core.
Preparing to unpack .../xml-core_0.13+nmu2_all.deb ...
Unpacking xml-core (0.13+nmu2) ...
Selecting previously unselected package nginx-common.
Preparing to unpack .../nginx-common_1.4.6-1ubuntu3.8_all.deb ...
Unpacking nginx-common (1.4.6-1ubuntu3.8) ...
Selecting previously unselected package nginx-core.
Preparing to unpack .../nginx-core_1.4.6-1ubuntu3.8_amd64.deb ...
Unpacking nginx-core (1.4.6-1ubuntu3.8) ...
Selecting previously unselected package nginx.
Preparing to unpack .../nginx_1.4.6-1ubuntu3.8_all.deb ...
Unpacking nginx (1.4.6-1ubuntu3.8) ...
Processing triggers for ureadahead (0.100.0-16) ...
Setting up libgeoip1:amd64 (1.6.0-1) ...
Setting up libxau6:amd64 (1:1.0.8-1) ...
Setting up libxdmcp6:amd64 (1:1.1.1-1) ...
Setting up libxcb1:amd64 (1.10-2ubuntu1) ...
Setting up libx11-data (2:1.6.2-1ubuntu2.1) ...
Setting up libx11-6:amd64 (2:1.6.2-1ubuntu2.1) ...
Setting up libxml2:amd64 (2.9.1+dfsg1-3ubuntu4.13) ...
Setting up sgml-base (1.26+nmu4ubuntu1) ...
Setting up fonts-dejavu-core (2.34-1ubuntu1) ...
Setting up fontconfig-config (2.11.0-0ubuntu4.2) ...
Setting up libfreetype6:amd64 (2.5.2-1ubuntu2.8) ...
Setting up libfontconfig1:amd64 (2.11.0-0ubuntu4.2) ...
Setting up libjpeg-turbo8:amd64 (1.3.0-0ubuntu2.1) ...
Setting up libjpeg8:amd64 (8c-2ubuntu8) ...
Setting up libjbig0:amd64 (2.0-2ubuntu4.1) ...
Setting up libtiff5:amd64 (4.0.3-7ubuntu0.9) ...
Setting up libvpx1:amd64 (1.3.0-2) ...
Setting up libxpm4:amd64 (1:3.5.10-1ubuntu0.1) ...
Setting up libgd3:amd64 (2.1.0-3ubuntu0.10) ...
Setting up libxslt1.1:amd64 (1.1.28-2ubuntu0.1) ...
Setting up geoip-database (20140313-1) ...
Setting up xml-core (0.13+nmu2) ...
Setting up nginx-common (1.4.6-1ubuntu3.8) ...
debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
Processing triggers for ureadahead (0.100.0-16) ...
Setting up nginx-core (1.4.6-1ubuntu3.8) ...
invoke-rc.d: policy-rc.d denied execution of start.
Setting up nginx (1.4.6-1ubuntu3.8) ...
Processing triggers for libc-bin (2.19-0ubuntu6.14) ...
Processing triggers for sgml-base (1.26+nmu4ubuntu1) ...
 ---> 3e46f256a08d
Removing intermediate container 7199f88e91ef
Step 5/6 : RUN echo "Hello, World!" > /usr/share/nginx/html/index.html
 ---> Running in 7478088422e9

 ---> e7cab50d7846
Removing intermediate container 7478088422e9
Step 6/6 : EXPOSE 80
 ---> Running in fadc982b2846
 ---> a99888e05c01
Removing intermediate container fadc982b2846
Successfully built a99888e05c01

似乎中間也出現了一些異常:

debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype

似乎也沒有影響繼續 build 的程式。

Setting up nginx (1.4.6-1ubuntu3.8) ...
Processing triggers for libc-bin (2.19-0ubuntu6.14) ...
Processing triggers for sgml-base (1.26+nmu4ubuntu1) ...
 ---> 3e46f256a08d
Removing intermediate container 7199f88e91ef
Step 5/6 : RUN echo "Hello, World!" > /usr/share/nginx/html/index.html
 ---> Running in 7478088422e9

 ---> e7cab50d7846
Removing intermediate container 7478088422e9
Step 6/6 : EXPOSE 80
 ---> Running in fadc982b2846
 ---> a99888e05c01
Removing intermediate container fadc982b2846
Successfully built a99888e05c01

中間層的映象,在順利 build 完之後,被移除,而只保留了最後一個順利完成 build 的映象,而這正是我們需要的。

檢視剛才 Build 完之後的映象,基於這份映象再新建一個新的容器:

[root@centos00 DockerWeb]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu/nginx        latest              a99888e05c01        6 minutes ago       230 MB
ubuntu/ping         latest              2eb12722cb2f        2 hours ago         186 MB
docker.io/ubuntu    14.04               8789038981bc        9 days ago          188 MB
docker.io/ubuntu    latest              16508e5c265d        9 days ago          84.1 MB
docker.io/centos    7.4.1708            d3949e34634c        3 weeks ago         197 MB
docker.io/centos    centos7.4.1708      d3949e34634c        3 weeks ago         197 MB
docker.io/centos    latest              5182e96772bf        3 weeks ago         200 MB
Docker 測試網站

先按照書上的程式碼敲一遍,看看效果如何。但在 Linux 下安裝配置 nginx 是必知必會的東西。我覺得有必要另開一篇好好說道。

新建一份 Dockerfile :

[root@centos00 DockerNginx]# cat Dockerfile
FROM ubuntu
MAINTAINER Lenis Huang "huangyun_122@163.com"
ENV REFRESHED_AT 2018-09-01
RUN apt-get update
RUN apt-get install -y -q nginx
RUN mkdir -p /var/www/html
ADD nginx/global.conf /etc/nginx/conf.d/
ADD nginx/nginx.conf /etc/nginx/nginx.conf
EXPOSE 80

Nginx 的兩個配置檔案:

# global.conf

server    {
    listen      0.0.0.0:80;
    server_name _;

    root        /var/www/html/website;
    index       index.html  index.htm

    access_log  /var/log/nginx/default_access.log;
    error_log   /var/log/nginx/default_error.log;
}
# nginx.conf
user www-data;
worker_processes 4;
pid /run/nginx.pid;
daemon off;


events {}

http {
    sendfile on ;
    tcp_nopush on ;
    tcp_nodelay on ;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    gzip on;
    gzip_disable "msie6";
    include /etc/nginx/conf.d/*.conf;
}

Dockerfile 和 nginx 目錄是平級的,docker build 在構建的時候,會依據相對路徑找到對應的檔案進行操作。docker build 命令會在指定的路徑下尋找 dockerfile ,所以最簡單的方式便是指定當前目錄為 Build 起始路徑:

[root@centos00 DockerNginx]# docker build -t ubuntu/nginx2 .

很不幸的是遇到一些問題:

E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/libx/libxau/libxau6_1.0.8-1_amd64.deb  Connection failed [IP: 91.189.88.152 80]
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
The command '/bin/sh -c apt-get install -y -q nginx' returned a non-zero code: 100

再一次執行 build 命令這個錯誤消失,我認為這是一次簡單的連結失效問題。

雖然安裝了 nginx,但是在主機訪問容器中的 web 服務,卻是訪問不了的。要登入 docker 虛擬機器,開啟 Nginx.

還記得配置 Nginx 的時候,指定了 root 檔案吧:

# global.conf

server    {
    listen      0.0.0.0:80;
    server_name _;

    root        /var/www/html/website;
    index       index.html  index.htm

    access_log  /var/log/nginx/default_access.log;
    error_log   /var/log/nginx/default_error.log;
}

在這裡,只要簡單的編寫 html 檔案,放在 /var/www/html/website/目錄下,以 index.html 命名即可。

在本地建立一個資料夾 website,專門放置需要在容器 nginx 服務下託管的網頁。再指定容器開啟時直接執行 nginx ,保持後臺執行的容器可以一直處於執行狀態而不退出。

[root@centos00 html]# docker run -d -p 80 --name website -v $PWD/website:/var/www/html/website ubuntu/nginx2 nginx
498f38dab68d3f5bc7166b2f92aeb344a795af7462081b68ca1cbeaa2f433b7d

但是親測, Nginx 命令寫在 docker run 之後不管用,還是要寫在 dockerfile 之中:

FROM ubuntu
MAINTAINER Lenis Huang "huangyun_122@163.com"
ENV REFRESHED_AT 2018-09-01
RUN apt-get update
RUN apt-get install -y -q nginx
RUN mkdir -p /var/www/html
ADD nginx/global.conf /etc/nginx/conf.d/
ADD nginx/nginx.conf /etc/nginx/nginx.conf
CMD ["nginx"]
EXPOSE 80

在本地的資料夾 $PWD/website 下面編寫簡單的 index.html 檔案:

[root@centos00 html]# cat index.html
This web page is built up outside of docker nginx.
But it is hosted by docer nginx.
It's amazing, like shared folder in vmware!

訪問虛擬機器,即可看到 index.html 中所寫的內容。

非常利索的一個借殼託管網頁的 docker 程式就那麼完成了!

Docker 構建 Web 應用程式
# Dockerfile

FROM ubuntu
MAINTAINER Lenis Huang huangyun_122@163.com

RUN apt-get update
RUN apt-get -y install ruby ruby-dev build-essential redis-tools
RUN gem install --no-rdoc --no-ri sinatra json redis


RUN mkdir -p /opt/webapp

ADD webapp/bin /opt/webapp/bin
ADD webapp/lib /opt/webapp/lib


EXPOSE 4567

CMD ["/opt/webapp/bin/webapp"]
# webapp

#!/usr/bin/ruby

$:.unshift(FIle.expand_path(File.join(File.dirname(__FILE__),"..","lib")))

require 'app'

App.run!
# app.rb

require "rubygems"
require "sinatra"
require "json"

class App < Sinatra::Application

    set :bind'0.0.0.0'

    get '/' do 
        "<h1>DockerBook TEst Sinatra app</h1>"
    end

    post '/json/?' do 
        params.to_json
    end

end

新建容器,開啟服務:

# docker run -i -t -p 4567 --rm --name sinatrapp ubuntu/sinatra3 /bin/sh

傳入引數,返回 json:

# curl -i -H 'Accept:application/json' -d 'name=Foo&status=Bar' http://127.0.0.1:32781/json
HTTP/1.1 200 OK 
Content-Type: text/html;charset=utf-8
Content-Length: 29
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Server: WEBrick/1.4.2 (Ruby/2.5.1/2018-03-29)
Date: Sun, 02 Sep 2018 07:27:23 GMT
Connection: Keep-Alive

{"name":"Foo","status":"Bar"}
Redis on Docker

有意義的應用離不開資料庫,用 Redis 為 Sinatra 應用來提供儲存。

新建一臺 Redis 資料庫容器

# Dockerfile

FROM ubuntu

MAINTAINER Lenis Huang huangyun_122@163.com

RUN apt-get update
RUN apt-get -y install redis-server redis-tools

EXPOSE 6379
ENTRYPOINT ["/usr/bin/redis-server"]

CMD []

開啟 Redis 容器之後,驗證 Redis 是否可用:

redis-cli -h 127.0.0.1 -p 32783

這裡的埠 32783 是通過 docker ps 看來的:

[root@centos00 Redis]# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
e324f0fd3d31        ubuntu/redis        "/usr/bin/redis-se..."   9 minutes ago       Up 9 minutes        0.0.0.0:32783->6379/tcp   redis
9ccf74ce181d        ubuntu/sinatra3     "/bin/sh"                25 minutes ago      Up 25 minutes       0.0.0.0:32781->4567/tcp   sinatrapp
bbef28a8db2b        ubuntu/nginx3       "nginx"                  7 hours ago         Up 7 hours          0.0.0.0:32775->80/tcp     nginx_server_1
[root@centos00 Redis]#

0.0.0.0:32783->6379/tcp 就是宿主機埠與容器埠的對映。

Web App Sinatra 與 Redis 的連線

連線 Redis 有多種方法:

基於宿主機與容器之間埠對映

在執行容器的時候,通常會暴露一個埠 (docker run -p 80), 此時容器埠預設會對映到宿主機中的隨機一個埠,比如33728. 外部計算機通過訪問宿主機的對映埠(33728)就可以訪問容器所提供的(80)服務了。

基於 Docker 棧的連線

Docker 在安裝完畢之後,分配一個 172.16.X.X - 172.30.X.X IP 地址,也 就是所有宿主機可分配給新建容器的 IP 地址範圍。Docker 服務程式自佔一個 IP 作為路由,與宿主機進行通訊的 IP,比如 172.17.0.1.

通過 docker 命令 inspect 來檢視 redis 分配的 IP 地址

# docker inspect redis
 "NetworkSettings": {
            "Bridge""",
            "SandboxID""2f679e6d9361654ec54f0e2c4c26cf358e008394580920921e106a66bb619c77",
            "HairpinMode"false,
            "LinkLocalIPv6Address""",
            "LinkLocalIPv6PrefixLen"0,
            "Ports": {
                "6379/tcp": [
                    {
                        "HostIp""0.0.0.0",
                        "HostPort""32783"
                    }
                ]
            },
            "SandboxKey""/var/run/docker/netns/2f679e6d9361",
            "SecondaryIPAddresses"null,
            "SecondaryIPv6Addresses"null,
            "EndpointID""5d4467ebd24ce1ab75ec0f8c7df7411cd157c8f1305b6ea9fa08363d6d7781fc",
            "Gateway""172.17.0.1",
            "GlobalIPv6Address""",
            "GlobalIPv6PrefixLen"0,
            "IPAddress""172.17.0.4",
            "IPPrefixLen"16,
            "IPv6Gateway""",
            "MacAddress""02:42:ac:11:00:04",
            "Networks": {
                "bridge": {
                    "IPAMConfig"null,
                    "Links"null,
                    "Aliases"null,
                    "NetworkID""6416f1f801bd82855cc4ffaf4c8086a61d5b56a3311b900ebfc12b70c9bd0775",
                    "EndpointID""5d4467ebd24ce1ab75ec0f8c7df7411cd157c8f1305b6ea9fa08363d6d7781fc",
                    "Gateway""172.17.0.1",
                    "IPAddress""172.17.0.4",
                    "IPPrefixLen"16,
                    "IPv6Gateway""",
                    "GlobalIPv6Address""",
                    "GlobalIPv6PrefixLen"0,
                    "MacAddress""02:42:ac:11:00:04"
                }
            }
        }

分配的 IP 可能下一次啟動的時候會變,所以通過 IP 來連線 redis 不是很穩定。

這時候就需要 docker link 了

這是一個令人興奮的功能。不僅僅是省去了暴露埠的步驟,更讚的是絕對的安全。只要使用 link 連線了兩個容器,不需要將埠暴露給宿主機,而兩臺容器之間依然可以相互通訊。

# docker run -p 4567 --name webapp --link redis:db -t -i ubuntu/sinatra3 /bin/bash
root@3e140f12028b:/# cat /etc/hosts
127.0.0.1    localhost
::1    localhost ip6-localhost ip6-loopback
fe00::0    ip6-localnet
ff00::0    ip6-mcastprefix
ff02::1    ip6-allnodes
ff02::2    ip6-allrouters
172.17.0.2    db b078287c5cb9 redis
172.17.0.3    3e140f12028b

–link redis:db : redis 容器名,db 是別名,反應在父容器(指定–link的容器)的 hosts 檔案中。

有了這個別名也就徹底解決了 Redis 伺服器 IP 硬編碼和 IP 地址不穩定的因素。

劃了個簡單的草圖,理解 Docker 網路

這裡寫圖片描述

相關文章