歡迎訪問我的個人網站,查看更多信息;www.wanglichun.tech
在程序開發過程中,經常需要我們去配置各種開發環境,而本地與線上還可能存在環境依賴的不同,導致出現一些不知名的bug,這個時候不要抓頭,是時候使用docker來幫你排憂解難了,下面我通過下面幾個篇章來介紹Docker.
原理介紹篇
Docker是什麼
docker是linux容器的一種封裝,提供簡單易用的容器使用接口。它是最流行的Linux容器解決方案。
簡單來說就是,docker可以將你的環境進行封裝,並且程序在docker內運行,有了docker,你就再也不用擔心環境問題了。
Docker的優勢
更高效的利用系統資源
由於容器不需要進行硬件虛擬以及運行完整操作系統等額外開銷,Docker 對系統 資源的利用率更高。
無論是應用執行速度、內存損耗或者文件存儲速度,都要比傳 統虛擬機技術更高效。因此,相比虛擬機技術,一個相同配置的主機,往往可以運 行更多數量的應用。
更快速的啓動時間
傳統的虛擬機技術啓動應用服務往往需要數分鐘,而 Docker 容器應用,由於直接 運行於宿主內核,無需啓動完整的操作系統,因此可以做到秒級、甚至毫秒級的啓 動時間。大大的節約了開發、測試、部署的時間。
一致的運行環境
開發過程中一個常見的問題是環境一致性問題。由於開發環境、測試環境、生產環 境不一致,導致有些 bug 並未在開發過程中被發現。
而 Docker 的鏡像提供了除內 核外完整的運行時環境,確保了應用運行環境一致性,從而不會再出現 “這段代碼 在我機器上沒問題啊” 這類問題。
持續交付和部署
對開發和運維(DevOps)人員來說,最希望的就是一次創建或配置,可以在任意 地方正常運行。
使用 Docker 可以通過定製應用鏡像來實現持續集成、持續交付、部署。開發人員 可以通過 Dockerfile 來進行鏡像構建,並結合持續集成(Continuous Integration) 系 統進行集成測試,而運維人員則可以直接在生產環境中快速部署該鏡像,甚至結合 持續部署(Continuous Delivery/Deployment) 系統進行自動部署。
而且使用 Dockerfile 使鏡像構建透明化,不僅僅開發團隊可以理解應用運行環 境,也方便運維團隊理解應用運行所需條件,幫助更好的生產環境中部署該鏡像。
更輕鬆的遷移
由於 Docker 確保了執行環境的一致性,使得應用的遷移更加容易。Docker 可以在 很多平臺上運行,無論是物理機、虛擬機、公有云、私有云,甚至是筆記本,其運 行結果是一致的。
因此用戶可以很輕易的將在一個平臺上運行的應用,遷移到另一 個平臺上,而不用擔心運行環境的變化導致應用無法正常運行的情況。
安裝篇
一般,如果使用GPU,一般要安裝Docker, Nvidia-Docker,Docker-Compose,Nvidia-Docker-Compse
Docker的安裝
參考官方安裝鏈接: https://docs.docker.com/install/linux/docker-ce/ubuntu/
按官方教程docker ce(community edtion),並按教程測試docker是否成功安裝。比如我們以Ubuntu Xenial 16.04 (LTS)爲例:
下載Docker安裝包,在這裏https://download.docker.com/linux/ubuntu/dists/xenial/pool/stable/amd64/挑選最新的Docker版本。
安裝:sudo dpkg -i /path/to/package.deb
測試:sudo docker run hello-world
(可選)Linux環境下的權限變更,這樣不用每次docker命令都加sudo,自己沒服務器權限找管理員變更。
Nvidia-Docker 的安裝
參考官方安裝鏈接: https://github.com/NVIDIA/nvidia-docker
nvidia-docker已經升級到nvidia-docker2,本測試是在nvidia-docker 1.0基礎上完成的,1.0的安裝方法請看上面教程鏈接。
Test nvidia-smi with the latest official CUDA image
docker run --runtime=nvidia --rm nvidia/cuda nvidia-smi
docker-compose的安裝
參考官方安裝鏈接:https://docs.docker.com/compose/install/
到https://github.com/docker/compose/releases下載linux版本。
重命名爲docker-compose並放到/usr/local/bin/下面
增加執行權限:sudo chmod +x /usr/local/bin/docker-compose
測試: docker-compose --version
nvidia-docker-compose的安裝
sudo pip install nvidia-docker-compose
注意:nvidia-docker-compose和nvidia-docker2不兼容,如果安裝了nvidia-docker2,那就不需要安裝這個compose了
使用篇
使用容器必然需要容器鏡像,鏡像是容器環境的存儲形式。容器的運行要從鏡像開始。
如何構建鏡像?
1.簡單方法,docker pull
dockerhub上面存在很多別人上傳好的鏡像,如果有合適的可以自己從上面直接拉,很方便。命令如下:
docker pull pytorch/pytorch:1.3-cuda10.1-cudnn7-runtime
2.在docker內直接安裝
如果在dockerhub上面拉下來的鏡像滿足了你大部分的需求,但是缺少了幾個環境怎麼辦呢?可以在已經拉下來的鏡像中直接安裝,安裝完對應的庫之後,commit就可以了。
例子如下:
在ubuntu容器中安裝vim後保存。
docker run -it ubuntu # 運行docker
yum install -y vim # 安裝vim
exit # 退出
docker container ls -a # 查看容器,找到剛纔安裝後的容器
docker commit 059fdea031ba chaoyu/centos-vim # 提交容器,前面參數是id,後面參數是名字
但是這種方式不推薦,因爲安裝了哪些東西,容易忘記,不好復現
3.通過Dockerfile安裝
Dockerfile可以幫助你解決2中,時間長,容易忘記,不好復現的問題,通過Dockerfile,你可以從你的基礎鏡像開始,一步一步的安裝,得到最終的結果。
就像下面這樣:
FROM centos
RUN yum install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
以上執行會創建 3 層鏡像。可簡化爲以下格式:
FROM centos
RUN yum install wget \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz
下面是構建Dockerfile常用命令的一些解釋
FROM ubuntu:14.04 #帶有tag的base image
LABEL version=“1.0” #容器元信息,幫助信息,Metadata,類似於代碼註釋
LABEL maintainer=“[email protected]"
#對於複雜的RUN命令,避免無用的分層,多條命令用反斜線換行,合成一條命令!
RUN yum update && yum install -y vim \
Python-dev #反斜線換行
RUN /bin/bash -c "source $HOME/.bashrc;echo $HOME”
WORKDIR /app #相當於linux的cd命令,改變目錄,儘量使用絕對路徑!!!不要用RUN cd
RUN pwd # 打印結果應該是/test/demo
ADD and COPY
ADD hello / # 把本地文件添加到鏡像中,吧本地的hello可執行文件拷貝到鏡像的/目錄
ADD test.tar.gz / # 添加到根目錄並解壓
WORKDIR /root
ADD hello test/ # 進入/root/ 添加hello可執行命令到test目錄下,也就是/root/test/hello 一個絕對路徑
COPY hello test/ # 等同於上述ADD效果
ADD與COPY
- 優先使用COPY命令
-ADD除了COPY功能還有解壓功能
添加遠程文件/目錄使用curl或wget
ENV # 環境變量,儘可能使用ENV增加可維護性
ENV MYSQL_VERSION 5.6 # 設置一個mysql常量
RUN yum install -y mysql-server=“${MYSQL_VERSION}”
構建好Dockerfile之後,就可以使用下面的命令構建鏡像了
docker build -t [docker name] .
docker build --network=host -t [docker name] . ### 修改網絡,使用本機網絡,如果有些庫安裝的時候下載不下來可以試試這個參數。
鏡像的運行
- 啓動一個bash終端,允許用戶進行交互
docker run --rm -it -v $HOME/history:/history/ dockername /bin/bash
或者指定運行網絡爲主機網絡:
docker run --net=host --rm -it -v $HOME/history:/history/ pytorch:nightly-gpu /bin/bash
# --name 給容器定義一個名稱
# -i 讓容器的標準輸入保持打開。
# -t 讓Docker分配一個僞終端,並綁定到容器的標準輸入上。
# -v 將本機路徑映射到容器中,實現在容器中的操作。
# /bin/bash 指定docker容器,用shell解釋器交互。
- 利用docker-compose運行docker服務
上面1中的命令好長,如果映射多個路徑豈不很麻煩,而且啓動容器後,沒有辦法與本地文件進行交互,有沒有更方便的使用容器的方法?當然有
使用docker-compose,docker-compose可以實現本地文件到docker內的映射,這樣你在本地直接修改程序,docker內就同步修改了,比較方便。
使用docker-compose首先要創建docker-compose.yml文件,參考如下:
# yml配置文件格式版本爲2, 鏡像名字爲webspring
version: '2'
services:
webspring:
build: . # 如果沒有下面image的鏡像,默認在當前路徑下的Dockerfile運行
image: tf-demo/docker:0.0.1 # 默認運行的鏡像
# 映射端口
shm_size: '2gb' ## 代表交換空間,可省略
ports:
- "8888:8888"
- "8887:6006"
# 映射文件路徑
volumes:
- .:/app
創建好後,運行下面的命令啓動服務就可以啦。
docker-compose run --rm webspring bash
停止容器
- 在運行的容器中,使用exits退出
- 直接將對應的docker stop掉
這裏一般先使用docker ps查看docker的運行情況,然後使用 docker stop xxxx 來將對應的容器停止掉。
記得經常去清一下緩存(很重要):
docker rm $(docker ps -qf status=exited)
發佈到倉庫
docker提供了一個類似於github的倉庫docker hub,官方網站(需註冊使用)
https://hub.docker.com/
# 註冊docker id後,在linux中登錄dockerhub
docker login
# 注意要保證image的tag是賬戶名,如果鏡像名字不對,需要改一下tag
docker tag haha/vim springwang/vim
# 語法是: docker tag 倉庫名 springwang/倉庫名
# 推送docker image到dockerhub
docker push springwang/vim:latest
# 去dockerhub中檢查鏡像
# 先刪除本地鏡像,然後再測試下載pull 鏡像文件
docker pull springwang/vim:latest
多用戶使用docker
1. 創建docker用戶組
sudo groupadd docker
2. 應用用戶加入docker用戶組
sudo usermod -aG docker ${USER}
3. 重啓docker服務
sudo systemctl restart docker
4.查看docker信息
docker info
Docker 常用命令總結
docker search hello-docker # 搜索hello-docker的鏡像
docker search centos # 搜索centos鏡像
docker pull hello-docker # 獲取centos鏡像
docker run hello-world #運行一個docker鏡像,產生一個容器實例(也可以通過鏡像id前三位運行)
docker image ls # 查看本地所有鏡像
docker images # 查看docker鏡像
docker image rmi -f hello-docker # 刪除centos鏡像
docker ps #列出正在運行的容器(如果創建容器中沒有進程正在運行,容器就會立即停止)
docker ps -a # 列出所有運行過的容器記錄
docker save centos > /opt/centos.tar.gz # 導出docker鏡像至本地
docker load < /opt/centos.tar.gz #導入本地鏡像到docker鏡像庫
docker stop `docker ps -aq` # 停止所有正在運行的容器
docker rm `docker ps -aq` # 一次性刪除所有容器記錄
docker rmi `docker images -aq` # 一次性刪除所有本地的鏡像記錄
docker container ls -a # 檢查運行中的容器
docker tag id new_name # 重命名docker images
docker system prune # 清楚docker緩存
其他
1.dockerignore容易被.gitignore給忽略掉,所以需要使用如下代碼上傳才行:
git add -f .dockerignore
2.在pycharm中使用docker進行操作:https://zhuanlan.zhihu.com/p/27114995