2016年6月2日 星期四

如何安裝 docker

Docker 官方網頁有介紹如何在 jessie 中安裝 docker,其網址如下:

https://docs.docker.com/engine/installation/linux/debian/#debian-jessie-80-64-bit

請編輯 /etc/apt/sources.list 檔案,新增底下這行:

# Docker
deb https://apt.dockerproject.org/repo debian-jessie main

然後以 root 權限執行

# apt-get update
# apt-get install docker-engine

安裝完畢後,理論上你的 docker 服務已經開始運轉,我們可以執行

# systemctl status docker

來觀察目前狀態。在此同時,我們如果執行

# ifconfig

的話,也會看到有一個新的網路介面叫 docker0 的,其狀態如底下所示:

docker0   Link encap:Ethernet  HWaddr 02:42:48:93:4b:a0
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


docker 之預設橋接網路介面為 docker0,其預設網段為 172.17.0.0/24,如果我們希望將網段改為 192.168.20.0/24,則在啟動 docker 前,我們要先設定 docker 的網段,請編輯 /etc/default/docker
這個檔案,將 DOCKER_OPTS 改成底下設定(其中一行):

南臺校外
DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4 --bip=192.168.20.0/24"

南臺校內
DOCKER_OPTS="--dns 120.117.2.1 --dns 120.117.2.2 --bip=192.168.20.0/24"

其中 --dns 是指 docker0 所提供 DNS 位址,而 --bip 則是所設定的網段。改完之後,要重新啟動 docker0,在那之前,要先將 docker 服務停止,指令如下:

# systemctl stop docker

關完之後可以執行

# systemctl status docker

來看目前 docker 狀態。

接著來修理 docker0,docker0 不是網路介面,而是橋接網路,因此使用底下指令可以看
到 docker0 的狀態。

# brctl show
bridge name     bridge id               STP enabled     interfaces
br10            8000.000000000000       no
docker0         8000.024248934ba0       no

現在執行底下指令可以看到 docker0 的 IP 還沒改過來。

# ifconfig docker0
docker0   Link encap:Ethernet  HWaddr 02:42:48:93:4b:a0
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

我們將 docker0 這個橋拿掉:

# brctl delbr docker0
bridge docker0 is still up; can't delete it

這表示 docker0 這個橋接網路介面還沒關掉,我們要執行底下指令才能關掉:

# ifconfig docker0 down
# ifdown docker0
# brctl delbr docker0

如此一來 docker0 就完全不見了,可以執行 ifconfig 來驗證看看。


編輯 /etc/sudoers 檔,為自己的帳號新增 sudo 的權限 (無需打密碼)

account  ALL=(ALL:ALL) NOPASSWD:ALL

上面的 account 是指你自己的帳號。


我們也可以新增一個 br20 的橋接網路介面,然後在 /etc/default/docker 中作底下修改:

DOCKER_OPTS="--dns 120.117.2.1 --dns 120.117.2.2 -b=br20"

如此一來會讓 docker 使用 br20 這個橋接網路介面,然後再重新啟動 docker 服務:

# systemctl restart docker

接著可以觀察網路上是否有現成的影像檔可以下載:

sudo docker search debian:jessie

此時會看到有很多現成的 docker 影像檔可以下載,在下載前我們先看一下目前有的
docker 影像檔:

$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

從此可以看到目前沒有下載任何 docker 影像檔,請執行底下指令下載 docker 影像檔:

$ sudo docker pull debian:jessie
jessie: Pulling from library/debian
51f5c6a04d83: Pull complete
a3ed95caeb02: Pull complete
Digest: sha256:2ca1d757fce75accad6ff84339c3327c7aa96ad6e7b7d6fdde22b2a537fac703
Status: Downloaded newer image for debian:jessie

下載完畢後再執行底下指令觀看目前是否已下載 docker image ?

herman@120:~$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
debian              jessie              1742affe03b5        10 days ago         125.1 MB

執行 docker jessie

$ sudo docker run -t -i debian:jessie /bin/bash
root@58abce6c9be8:/#

恭喜你,你已經啟動第一個 docker 容器了。但是這個容器相當陽春,連 ifconfig 指令
也沒有:
root@58abce6c9be8:/# ifconfig
bash: ifconfig: command not found

我們可以至 debian packages 網站查查看 ifconfig 屬於那個套件,再補裝上去,經過
查詢,ifconfig 屬於 net-tools 套件,在安裝此套件前要執行

# apt-get update
# apt-get install net-tools

安裝完畢後執行:

# ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:c0:a8:14:02
          inet addr:192.168.20.2  Bcast:0.0.0.0  Mask:255.255.255.0
          inet6 addr: fe80::42:c0ff:fea8:1402/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3058 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2603 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:26185005 (24.9 MiB)  TX bytes:180507 (176.2 KiB)

可以看到 eth0 的 IP 為 192.168.20.2,此時我們可以從實體機來 ping 192.168.20.2
看看是否能 ping 到這台主機:

$ ping 192.168.20.2
PING 192.168.20.2 (192.168.20.2) 56(84) bytes of data.
64 bytes from 192.168.20.2: icmp_seq=1 ttl=64 time=0.032 ms
64 bytes from 192.168.20.2: icmp_seq=2 ttl=64 time=0.026 ms
64 bytes from 192.168.20.2: icmp_seq=3 ttl=64 time=0.022 ms
64 bytes from 192.168.20.2: icmp_seq=4 ttl=64 time=0.022 ms
64 bytes from 192.168.20.2: icmp_seq=5 ttl=64 time=0.025 ms
64 bytes from 192.168.20.2: icmp_seq=6 ttl=64 time=0.022 ms
64 bytes from 192.168.20.2: icmp_seq=7 ttl=64 time=0.023 ms
^C
--- 192.168.20.2 ping statistics ---
7 packets transmitted, 7 received, 0% packet loss, time 5999ms
rtt min/avg/max/mdev = 0.022/0.024/0.032/0.006 ms

也可以從 docker 虛擬機 ping 192.168.20.1 來看看是否能 ping 到 docker0:

root@58abce6c9be8:/# ping 192.168.20.1
PING 192.168.20.1 (192.168.20.1): 56 data bytes
64 bytes from 192.168.20.1: icmp_seq=0 ttl=64 time=0.044 ms
64 bytes from 192.168.20.1: icmp_seq=1 ttl=64 time=0.031 ms
64 bytes from 192.168.20.1: icmp_seq=2 ttl=64 time=0.031 ms
^C--- 192.168.20.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.031/0.035/0.044/0.000 ms

到此為止,我們已經成功啟動一台 docker 的虛擬機,並且知道其網路設定了。接下來要
進行 apache 伺服器安裝,在那之前要先設定好鏡像站來源,否則下載軟體的速度會很慢

# apt-get install vim

接著編輯 /etc/apt/sources.list 檔案:

deb http://security.debian.org jessie/updates main

#deb http://httpredir.debian.org/debian jessie main
#deb http://httpredir.debian.org/debian jessie-updates main

deb ftp://192.168.20.1/debian jessie main contrib non-free
deb ftp://192.168.20.1/debian jessie-updates main

然後執行

# apt-get update

看看是否可以從實體主機的 debian 鏡站中下載套件,接下來安裝 apache 套件:

# apt-get install apache2

下載安裝完成後,可以自實體機以瀏覽器打開 http://192.168.20.2 來看是否有網頁,
如果沒有的話請執行:

# /etc/init.d/apache2 start
[....] Starting web server: apache2AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 192.168.20.2. Set the 'ServerName' directive globally to suppress this message
. ok

# /etc/init.d/apache2 status
[ ok ] apache2 is running.

來啟動並觀看 apache2 這個服務是否有執行,確定 apache2 有執行後可以再使用實體機
的瀏覽器打開 192.168.20.2 以驗證網頁服務是否有啟動。

=======================================
在實體機上如果要觀察目前有那些 docker 的容器正在執行的話,可以執行:

$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
58abce6c9be8        debian:jessie       "/bin/bash"         53 minutes ago      Up 53 minutes                           dreamy_heisenberg

=======================================
離開 docker 容器,請在 docker 中輸入 exit:

root@58abce6c9be8:/# exit
exit
~$

此時再在實體機中執行:

$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

會發現剛剛運行中之系統已經不見,這表示 docker 容器已經停止。

建立 chroot 環境

什麼是 chroot ?

chroot (change root) 是一個指令,它可以將某個小型的檔案系統變成一個 /  環境,而這個小型的檔案系統要用 debootstrap 這個指令來建立。

使用 debootstrap 指令

debootstrap 指令是用來建立小型 root 環境的一個指令,他對於建立嵌入式系統的根目錄或是我們現在要建立的小型 root 環境都非常有用,要安裝 debootstrap 請執行:

# apt-get install debootstrap


安裝完成後,請在 ~/virtualclassroom 底下建立一個 chroot 目錄,接著在此目錄新增一個 shell script,其檔名為 debootstrap.sh,內容如下所示:

SOURCEDIR=`pwd`/LEENIX
ARCH=amd64
DEBIAN_RELEASE=jessie
#DEBIAN_MIRROR=ftp://opensource.nchc.org.tw/debian
DEBIAN_MIRROR=file:///srv/ftp/debian

[ -d $SOURCEDIR ] && rm -rf $SOURCEDIR

mkdir -p $SOURCEDIR

time debootstrap --arch ${ARCH} ${DEBIAN_RELEASE} ${SOURCEDIR} ${DEBIAN_MIRROR}

建完 debootstrap.sh 後,請以 root 權限執行:

# sh debootstrap.sh

此時會看到 debootstrap 開始抓檔案並開始安裝一個最原始、最小型的 / 檔案系統。debootstrap.sh 執行完的畫面如下所示:

I: Configuring iputils-ping...
I: Configuring isc-dhcp-common...
I: Configuring isc-dhcp-client...
I: Configuring tasksel...
I: Configuring tasksel-data...
I: Configuring libc-bin...
I: Configuring systemd...
I: Base system installed successfully.

此時會有一個 LEENIX 的目錄,我們可以檢查此目錄來看其內容,這個目錄其實就是一個最精簡的 / 目錄。接下來我們可以使用 chroot 指令來切換至此目錄,請先編輯 chroot.sh 檔案,其內容如下所示:

SOURCEDIR=`pwd`/LEENIX

chroot ${SOURCEDIR} \
  /usr/bin/env -i \
  HOME=/root \
  TERM=$TERM \
  PS1='\u:\w\$ ' \
  PATH=/bin:/usr/bin:/sbin:/usr/sbin \
  /bin/bash --login

編輯完之後可以用 root 權限執行:

sh chroot.sh

此時你會發現你的目錄位置變成 /,如底下所示:

~/virtualclassroom/chroot# sh chroot.sh
root@120:/#

現在我們已經切換到剛剛那個小型的 root 目錄了,在這個目錄可以作一些事情,理論上不會傷害到實體主機。例如 apt-get 指令等均是在此小型 / 目錄中作修改。我們可以在這個目錄新增一個空的 aaa.txt 檔,指令如下所示:

/# touch aaa.txt

接著打 exit 離開 chroot 環境,再觀看 LEENIX 目錄中是否有 aaa.txt 這個檔案。

以上所完成的就是一個最簡單的 chroot 環境,它與我們接下來要教的 docker 有點類似,所以 docker 才號稱是「加了外掛的 chroot 環境」。