Docker學習筆記-(5)容器數據管理,鏈接容器,構建私有庫
五、容器數據管理,鏈接容器,構建私有庫
① 容器數據管理
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)容器數據管理,鏈接容器,構建私有庫