Docker 及 nvidia-docker 使用


Docker 基本用法

1. 安裝社區版docker-ce 及 nvidia-docker2 插件

通過官網介紹的軟件源的方式安裝. 如果要安裝nvidia-docker,由於其需要與docker-ce的版本匹配,所以如果是手動下載安裝的話需要注意版本號.
nvidia-docker對宿主機的要求是安裝了nvidia驅動程序和docker程序,而CUDA toolkit安裝在容器里邊,而不必安裝在宿主機上. 因此包含cuda toolkit的鏡像通常都很大.
安裝之后重載Docker daemon: sudo pkill -SIGHUP dockerd
運行示例: docker run --runtime=nvidia --rm nvidia/cuda nvidia-smi
離線安裝: ubuntu下借助apt-rdepends找出所有的遞歸依賴: apt-get download $(apt-rdepends docker-ce|grep -v "^ ")
CentOS等其它版本的安裝參考: https://github.com/gzvincen/docker-offline-install-package

nvidia深度學習開發棧如下圖所示:

nvidia-docker-stack

2. 鏡像加速

對於使用 upstart 的系統而言,編輯 /etc/default/docker 文件,在其中的 DOCKER_OPTS 中配置加速器地址:
DOCKER_OPTS="--registry-mirror=https://registry.docker-cn.com"
或者daocloud的http://4ce12ab7.m.daocloud.io
重新啟動服務:
sudo service docker restart

3. 建立 docker 用戶組

默認情況下,docker 命令會使用 Unix socket 與 Docker 引擎通訊。而只有 root 用戶和 docker 組的用戶才可以訪問 Docker 引擎的 Unix socket。出於安全考慮,一般 Linux 系統上不會直接使用 root 用戶。因此,更好地做法是將需要使用 docker 的用戶加入 docker 用戶組。
建立 docker 組:
sudo groupadd docker
將當前用戶加入 docker 組:
sudo usermod -aG docker $USER
退出當前終端並重新登錄才可生效(如果急用,運行docker時加sudo)。

4. 運行容器

docker run -dit ubuntu
加--rm參數,在容器終止運行后自動刪除容器文件。

5. 進入容器命令行

docker attach 243c # 如果鏡像的入口並非shell,則不能夠進入shell,需要執行 docker exec
docker exec -it 69d1 bash

6. 容器與宿主機互相拷貝文件: docker cp

Usage: docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH

7. 將容器保存為鏡像:

docker commit 容器id 鏡像名稱

8. 上傳鏡像到倉庫:

打tag: docker tag 鏡像名稱 遠程鏡像名稱tag
docker image ls 進行查看
上傳docker push 遠程鏡像名稱tag
為了加速, 可以使用HTTPS_PROXY=https://xxx docker push

9. 停止容器: docker stop --time=20 container_name 會發送信號SIGTERM並等待一定時間后終止.

docker kill 發出SIGKILL 強制終止

10. 刪除已停止的容器: 較新版的刪除所有已停止的容器快捷方式: docker container prune

查出容器的 ID: docker container ls --all
刪除指定的容器文件 docker container rm [containerID]
刪除鏡像 docker rmi -f [image ID] 如果有對應的啟動的容器需要-f(force)一並刪除

11. 列出容器: 正在運行中的程序: docker ps, 使用-a包括已停止的容器.

12. 鏡像無法聯網, 可嘗試在docker run時加 --net host

13. 啟動已經終止的容器: docker start 容器id

14. detach 即退出容器shell而不終止容器: Ctrl+p + Ctrl+q

15. 容器導出/導入到文件

docker export -o project-image.tar 45589e5912ce 導入容器鏡像用import : docker import my_ubuntu_v3.tar runoob/ubuntu:v4 可以將導入的鏡像命名為后者, 如果不命名,則是<none>. 另外,還可以用save命令將鏡像完整保存,包括歷史版本和元數據信息,所以文件可能比較大。相應的用load命令導入: docker load < project-image.tar
導入之后通過docker images命令可以看到新導入的鏡像.
區別是export導出的是容器, save導出的是鏡像, 另外,最好用save導出比較完整,否則容易出現cuda與驅動不匹配的問題.
另外,導出到文件時進行壓縮可節省空間:
導出鏡像: docker save ubuntu:v4 | gzip -c > ubuntu-v4.tgz
導入鏡像: gunzip -c project-v2.tgz | docker load

16. 移除所有的容器和鏡像(大掃除):

docker kill $(docker ps -q) ; docker rm $(docker ps -a -q) ; docker rmi $(docker images -q -a)

17. 驗證GPU可用性: docker run --runtime=nvidia --rm nvidia/cuda nvidia-smi

--rm 表示運行完畢就刪除容器, -dit -d表示以daemon后台運行, -i交互式-t新的偽終端.
如果不加-it運行的時候無法接受ctrl+c等輸入.
容器的啟動方式: nvidia-docker start 071b0b

Docker 更多介紹

關於網絡配置

在使用默認的橋接模式下,容器啟動后會被分配一個與docker0在同一網段的地址,在容器內部默認顯示為eth0,在宿主機上產生一個臨時的vethXXX接口。

端口映射

在主機上查看端口映射的方式為docker ps(橋接方式會顯示端口)、docker inspect [id]、netstat -nlp

netstat可能只會顯示出tcp6的監聽狀態,實際上ipv4的地址也監聽了。

在訪問容器內的服務時,如將mysql的3306端口映射到主機上的13306端口,則通過13306端口通信時客戶端使用的是docker0的地址,需要配置mysql容許建立連接的ip地址。除了設置bind-address外,可能還需要設置特定用戶的權限:
update user set host='%或者ip' where xxx;
flush privileges;
可以通過命令
telnet localhost 13306
來檢測是否能夠建立tcp連接

容器連接

由於容器間應用程序被相互隔離,在不使用--link連接容器時難以從一個容器內建立到另外一個容器內的進程的連接,除非使用共享的socket文件來實現unix socket通信(掛載相同的卷或者同樣具有對某一系統目錄的寫權限)。在知道容器的ip時可以發送ping ICMP數據包
要建立容器之間的鏈接,必須在啟動時通過參數--name $container_name給容器命名
--link name:alias Docker在兩個容器之間創建了一個安全的隧道,這是鏈接的巨大優勢, 通過連接,我們不需要向外部網絡暴露端口.
在連接了目標容器后,我們可以在源容器中查看到/etc/hosts文件中多了一個目標容器的host解析:
172.17.0.2 alias 13065893a1dd name
執行netstat -nlt不能夠看到目標容器中開放的端口,但是可以訪問。

容器的hostname

在用docker運行一個鏡像時如果使用橋接方式,沒有用-h指定hostname,則使用產生的容器id的一部分作為hostname,解析為容器內eth0的地址。如果需要連接兩個容器,最好是指定hostname而不是ip的形式來建立tcp連接。
如果通過--net='host'指定容器使用host的網絡配置,那么hostname、網絡接口、dns等信息完全一樣。
容器內的網絡配置是只讀的,如果想要在容器內修改配置,需要在運行時加上參數--cap-add=NET_ADMIN來賦予修改權限(如果采用了host方式會影響到host主機的網絡配置)。

數據存儲

容器停止后再次運行時(docker start)上次修改后的數據得以保留,不會丟失。而從鏡像重新創建一個容器運行時是鏡像原本的數據。
將數據從容器中拷出來:
docker cp containerId:/file/path/within/container /host/path/target
更方便的方式可能就是使用-v掛載外部卷了,直接在容器外部的文件中讀寫。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM