1. 程式人生 > >Docker學習筆記-(5)容器數據管理,鏈接容器,構建私有庫

Docker學習筆記-(5)容器數據管理,鏈接容器,構建私有庫

控制 st2 容器數據 pan 備份文件 data- 否則 所有 連接

五、容器數據管理,鏈接容器,構建私有庫

① 容器數據管理

docker管理數據的方式有兩種:

  • 數據卷
  • 數據卷容器

1. 數據卷

數據卷是一個或多個容器專門指定繞過Union File System的目錄,為持續性或共享數據提供一些有用的功能:

  • 數據卷可以在容器間共享和重用
  • 數據卷數據改變是直接修改的
  • 數據卷數據改變不會被包括在容器中
  • 數據卷是持續性的,直到沒有容器使用它們

添加一個數據卷

你可以使用-v選項添加一個數據卷,或者可以使用多次-v選項為一個 docker 容器運行掛載多個數據卷。

$ sudo docker run --name data -v /data -t -i ubuntu:14.04 /bin/bash #
創建數據卷綁定到到新建容器,新建容器中會創建 /data 數據卷
bash-4.1# ls -ld /data/
drwxr-xr-x 2 root root 4096 Jul 23 06:59 /data/ bash-4.1# df -Th Filesystem Type Size Used Avail Use% Mounted on ... ... ext4 91G 4.6G 82G 6% /data

創建的數據卷可以通過docker inspect獲取宿主機對應路徑

$ sudo docker inspect data
... ... "
Volumes": { "/data": "/var/lib/docker/vfs/dir/151de401d268226f96d824fdf444e77a4500aed74c495de5980c807a2ffb7ea9" }, # 可以看到創建的數據卷宿主機路徑 ... ...

或者直接指定獲取

$ sudo docker inspect --format="{{ .Volumes }}" data
map[/data: /var/lib/docker/vfs/dir/151de401d268226f96d824fdf444e77a4500aed74c495de5980c807a2ffb7ea9]

掛載宿主機目錄為一個數據卷

-v選項除了可以創建卷,也可以掛載當前主機的一個目錄到容器中。

$ sudo docker run --name web -v /source/:/web -t -i ubuntu:14.04 /bin/bash
bash-4.1# ls -ld /web/
drwxr-xr-x 2 root root 4096 Jul 23 06:59 /web/
bash-4.1# df -Th
... ...
              ext4     91G  4.6G   82G   6% /web
bash-4.1# exit 

默認掛載卷是可讀寫的,可以在掛載時指定只讀

$ sudo docker run --rm --name test -v /source/:/test:ro -t -i ubuntu:14.04 /bin/bash

2.創建和掛載一個數據卷容器

如果你有一些持久性的數據並且想在容器間共享,或者想用在非持久性的容器上,最好的方法是創建一個數據卷容器,然後從此容器上掛載數據。

創建數據卷容器

$ sudo docker run -t -i -d -v /test --name test ubuntu:14.04 echo hello

使用--volumes-from選項在另一個容器中掛載 /test 卷。不管 test 容器是否運行,其它容器都可以掛載該容器數據卷,當然如果只是單獨的數據卷是沒必要運行容器的。

$ sudo docker run -t -i -d --volumes-from test --name test1 ubuntu:14.04 /bin/bash

添加另一個容器

$ sudo docker run -t -i -d --volumes-from test --name test2 ubuntu:14.04 /bin/bash

也可以繼承其它掛載有 /test 卷的容器

$ sudo docker run -t -i -d --volumes-from test1 --name test3 ubuntu:14.04 /bin/bash

技術分享圖片

3. 備份、恢復或遷移數據卷

備份

$ sudo docker run --rm --volumes-from test -v $(pwd):/backup ubuntu:14.04 tar cvf /backup/test.tar /test
tar: Removing leading `/‘ from member names
/test/
/test/b
/test/d
/test/c
/test/a

啟動一個新的容器並且從test容器中掛載卷,然後掛載當前目錄到容器中為 backup,並備份 test 卷中所有的數據為 test.tar,執行完成之後刪除容器--rm,此時備份就在當前的目錄下,名為test.tar。

$ ls # 宿主機當前目錄下產生了 test 卷的備份文件 test.tar test.tar

恢復

你可以恢復給同一個容器或者另外的容器,新建容器並解壓備份文件到新的容器數據卷

$ sudo docker run -t -i -d -v /test --name test4 ubuntu:14.04  /bin/bash $ sudo docker run --rm --volumes-from test4 -v $(pwd):/backup ubuntu:14.04 tar xvf /backup/test.tar -C / 
# 恢復之前的文件到新建卷中,執行完後自動刪除容器 test/ test/b test/d test/c test/a

4.刪除 Volumes

Volume 只有在下列情況下才能被刪除:

  • docker rm -v刪除容器時添加了-v選項
  • docker run --rm運行容器時添加了--rm選項

否則,會在/var/lib/docker/vfs/dir目錄中遺留很多不明目錄。

參考文檔:

  • Managing Data in Containers
  • 深入理解Docker Volume(一)
  • 深入理解Docker Volume(二)

② 鏈接容器

docker 允許把多個容器連接在一起,相互交互信息。docker 鏈接會創建一種容器父子級別的關系,其中父容器可以看到其子容器提供的信息。

1. 容器命名

在創建容器時,如果不指定容器的名字,則默認會自動創建一個名字,這裏推薦給容器命名:

  • 1、給容器命名方便記憶,如命名運行 web 應用的容器為 web
  • 2、為 docker 容器提供一個參考,允許方便其他容器調用,如把容器 web 鏈接到容器 db

可以通過--name選項給容器自定義命名:

$ sudo docker run -d -t -i --name test ubuntu:14.04 bash              
$ sudo docker  inspect --format="{{ .Nmae }}" test
/test

註:容器名稱必須唯一,即你只能命名一個叫test的容器。如果你想復用容器名,則必須在創建新的容器前通過docker rm刪除舊的容器或者創建容器時添加--rm選項。

2 鏈接容器

鏈接允許容器間安全通信,使用--link選項創建鏈接。

$ sudo docker run -d --name db training/postgres

基於 training/postgres 鏡像創建一個名為 db 的容器,然後下面創建一個叫做 web 的容器,並且將它與 db 相互連接在一起

$ sudo docker run -d -P --name web --link db:db training/webapp python app.py

--link <name or id>:alias選項指定鏈接到的容器。

查看 web 容器的鏈接關系:

$ sudo docker inspect -f "{{ .HostConfig.Links }}" web
[/db:/web/db]

可以看到 web 容器被鏈接到 db 容器為/web/db,這允許 web 容器訪問 db 容器的信息。

容器之間的鏈接實際做了什麽?一個鏈接允許一個源容器提供信息訪問給一個接收容器。在本例中,web 容器作為一個接收者,允許訪問源容器 db 的相關服務信息。Docker 創建了一個安全隧道而不需要對外公開任何端口給外部容器,因此不需要在創建容器的時候添加-p或-P指定對外公開的端口,這也是鏈接容器的最大好處,本例為 PostgreSQL 數據庫。

Docker 主要通過以下兩個方式提供連接信息給接收容器:

  • 環境變量
  • 更新/etc/hosts文件

環境變量

當兩個容器鏈接,Docker 會在目標容器上設置一些環境變量,以獲取源容器的相關信息。

首先,Docker 會在每個通過--link選項指定別名的目標容器上設置一個<alias>_NAME環境變量。如果一個名為 web 的容器通過--link db:webdb被鏈接到一個名為 db 的數據庫容器,那麽 web 容器上會設置一個環境變量為WEBDB_NAME=/web/webdb.

以之前的為例,Docker 還會設置端口變量:

$ sudo docker run --rm --name web2 --link db:db training/webapp env
. . .
DB_NAME=/web2/db
DB_PORT=tcp://172.17.0.5:5432           
DB_PORT_5432_TCP=tcp://172.17.0.5:5432  # <name>_PORT_<port>_<protocol> 協議可以是 TCP 或 UDP
DB_PORT_5432_TCP_PROTO=tcp
DB_PORT_5432_TCP_PORT=5432
DB_PORT_5432_TCP_ADDR=172.17.0.5
. . .

註:這些環境變量只設置給容器中的第一個進程,類似一些守護進程 (如 sshd ) 當他們派生 shells 時會清除這些變量

更新/etc/hosts文件

除了環境變量,Docker 會在目標容器上添加相關主機條目到/etc/hosts中,上例中就是 web 容器。

$ sudo docker run -t -i --rm --link db:db training/webapp /bin/bash
root@aed84ee21bde:/opt/webapp# cat /etc/hosts
172.17.0.7  aed84ee21bde
. . .
172.17.0.5  db

/etc/host文件在源容器被重啟之後會自動更新 IP 地址,而環境變量中的 IP 地址則不會自動更新的。

③ 構建私有庫

Docker 官方提供了 docker registry 的構建方法 docker-registry

1. 快速構建

快速構建 docker registry 通過以下兩步:

  • 安裝 docker
  • 運行 registry:docker run -p 5000:5000 registry

這種方法通過 Docker hub 使用官方鏡像 official image from the Docker hub

2.不使用容器構建 registry

安裝必要的軟件

$ sudo apt-get install build-essential python-dev libevent-dev python-pip liblzma-dev

配置 docker-registry

sudo pip install docker-registry

或者 使用 github clone 手動安裝

$ git clone https://github.com/dotcloud/docker-registry.git
$ cd docker-registry/
$ cp config/config_sample.yml config/config.yml
$ mkdir /data/registry -p
$ pip install .

運行

docker-registry

高級啟動方式 [不推薦]

使用gunicorn控制:

gunicorn -c contrib/gunicorn_config.py docker_registry.wsgi:application

或者對外監聽開放

gunicorn --access-logfile - --error-logfile - -k gevent -b 0.0.0.0:5000 -w 4 --max-requests 100 docker_registry.wsgi:application

3. 提交指定容器到私有庫

$ docker tag ubuntu:12.04 私有庫IP:5000/ubuntu:12.04
$ docker push 私有庫IP:5000/ubuntu

更多的配置選項推薦閱讀官方文檔:

  • Docker-Registry README
  • Docker-Registry advanced use

Docker學習筆記-(5)容器數據管理,鏈接容器,構建私有庫