原文地址:http://accjiyun.cn/wan-zhuan-dockerzhi-chang-yong-ming-ling-pian-san/python
首先咱們來解決一個小問題,使用docker每次都要用sudo,爲了讓非root用戶使用docker,可將當前用戶添加到docker用戶組:mysql
sudo groupadd docker sudo gpasswd -a ${USER} docker # 當前用戶添加到docker group
而後從新登入下用戶就能夠直接使用docker命令了。git
# 查看docker版本 docker version # 顯示docker系統的信息 docker info # 全部Docker命令幫助 docker help
# 檢索image docker search image_name # 下載image docker pull image_name # 列出鏡像列表; -a, --all=false Show all images; --no-trunc=false Don't truncate output; -q, --quiet=false Only show numeric IDs docker images # 刪除一個或者多個鏡像; -f, --force=false Force; --no-prune=false Do not delete untagged parents docker rmi image_name # 顯示一個鏡像的歷史; --no-trunc=false Don't truncate output; -q, --quiet=false Only show numeric IDs docker history image_name # 保存鏡像到一個tar包; -o, --output="" Write to an file docker save image_name -o file_path # 加載一個tar包格式的鏡像; -i, --input="" Read from a tar archive file docker load -i file_path # 機器a docker save image_name > /home/save.tar # 使用scp將save.tar拷到機器b上,而後: docker load < /home/save.tar
# 在容器中運行"echo"命令,輸出"hello word" docker run image_name echo "hello word" # 交互式進入容器中 docker run -i -t image_name /bin/bash # 在容器中安裝新的程序 docker run image_name apt-get install -y app_name # 運行一個新容器,同時爲它命名、端口映射、文件夾映射。以redmine鏡像爲例 docker run --name redmine -p 9003:80 -p 9023:22 -d -v /var/redmine/files:/redmine/files -v /var/redmine/mysql:/var/lib/mysql sameersbn/redmine # 一個容器鏈接到另外一個容器 docker run -i -t --name sonar -d -link mmysql:db tpires/sonar-server sonar
-d:以守護進程方式運行(後臺),並返回容器ID;
-P:默認匹配docker容器的5000端口號到宿主機的49153 to 65535端口
-p
--name: 指定容器的名稱
--rm:退出時刪除容器
-a stdin 指定標準輸入輸出內容類型,可選 STDIN/STDOUT / STDERR 三項;
-i 以交互模式運行容器,一般與 -t 同時使用;
-t 爲容器從新分配一個僞輸入終端,一般與 -i 同時使用;
--dns 8.8.8.8 指定容器使用的DNS服務器,默認和宿主一致;
--dns-search example.com 指定容器DNS搜索域名,默認和宿主一致;
-h "mars" 指定容器的hostname;
-e username="ritchie" 設置環境變量;
--env-file=[] 從指定文件讀入環境變量;
--cpuset="0-2" or --cpuset="0,1,2"
綁定容器到指定CPU運行;
# 列出當前全部正在運行的container docker ps # 列出全部的container docker ps -a # 列出最近一次啓動的container docker ps -l
# 保存對容器的修改; -a, --author="" Author; -m, --message="" Commit message docker commit ID new_image_name
# 刪除全部容器 docker rm `docker ps -a -q` # 刪除單個容器; -f, --force=false; -l, --link=false Remove the specified link and not the underlying container; -v, --volumes=false Remove the volumes associated to the container docker rm Name/ID # 中止、啓動、殺死一個容器 docker stop Name/ID docker start Name/ID docker kill Name/ID # 從一個容器中取日誌; -f, --follow=false Follow log output; -t, --timestamps=false Show timestamps docker logs Name/ID # 列出一個容器裏面被改變的文件或者目錄,list列表會顯示出三種事件,A 增長的,D 刪除的,C 被改變的 docker diff Name/ID # 顯示一個運行的容器裏面的進程信息 docker top Name/ID # 從容器裏面拷貝文件/目錄到本地一個路徑 docker cp Name:/container_path to_path docker cp ID:/container_path to_path # 重啓一個正在運行的容器; -t, --time=10 Number of seconds to try to stop for before killing the container, Default=10 docker restart Name/ID # 附加到一個運行的容器上面; --no-stdin=false Do not attach stdin; --sig-proxy=true Proxify all received signal to the process docker attach ID
# 登錄registry server; -e, --email="" Email; -p, --password="" Password; -u, --username="" Username docker login # 發佈docker鏡像 docker push new_image_name
docker run -P:隨機分配端口號 docker run -p 5000:5000:綁定特定端口號(主機的全部網絡接口的5000端口均綁定容器的5000端口) docker run -p 127.0.0.1:5000:5000:綁定主機的特定接口的端口號 docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py:綁定udp端口號 docker port <CONTAINER_ID> 5000:查看容器的5000端口對應本地機器的IP和端口號 # 使用Docker Linking鏈接容器: Docker爲源容器和接收容器建立一個安全的通道,容器之間不須要暴露端口,接收的容器能夠訪問源容器的數據 docker run -d -P --name <CONTAINER_NAME> --link <CONTAINER_NAME_TO_LINK>:<ALIAS>
Data Volumes:volume是在一個或多個容器裏指定的特殊目錄web
能夠在容器啓動的時候添加-v參數指定容器卷,也能夠在Dockerfile裏用VOLUMN命令添加sql
docker run -d -P --name web -v /webapp training/webapp python app.py
也能夠將容器卷掛載到宿主機目錄或宿主機的文件上, <容器目錄或文件> 的內容會被替換爲 <宿主機目錄或文件> 的內容,默認容器對這個目錄有可讀寫權限 docker
docker run -d -P --name web -v <宿主機目錄>:<容器目錄> training/webapp python app.py
能夠經過指定ro,將權限改成只讀數據庫
docker run -d -P --name web -v <宿主機目錄>:<容器目錄>:ro training/webapp python app.py
在一個容器建立容器卷後,其餘容器即可以經過--volumes-from共享這個容器卷數據,以下:ubuntu
docker run -d -v /dbdata --name db1 training/postgres echo Data-only container for postgres
首先啓動了一個容器,併爲這個容器增長一個數據卷/dbdata,而後啓動另外一個容器,共享這個數據卷安全
docker run -d --volumes-from db1 --name db2 training/postgres
此時db2使用了db1的容器卷,當容器db1被刪除時,容器卷也不會被刪除,只有全部容器再也不使用此容器卷時,纔會被刪除
docker rm -v:刪除容器卷
除了共享數據外,容器卷另外一個做用是用來備份、恢復和遷移數據
docker run --volumes-from db1 -v /home/backup:/backup ubuntu tar cvf /backup/backup.tar /dbdata
啓動一個容器數據卷使用db1容器的數據卷,同時新創建一個數據卷指向宿主機目錄/home/backup,將/dbdata目錄的數據壓縮爲/backup/backup.tar
docker run -v /dbdata --name dbdata2 ubuntu /bin/bash docker run --volumes-from dbdata2 -v /home/backup:/backup busybox tar xvf /backup/backup.tar
啓動一個容器,同時把backup.tar的內容解壓到容器的backup
使用命令行的方式建立 Docker 鏡像一般難以自動化操做。在更多的時候,咱們使用 Dockerfile 來建立 Docker 鏡像。Dockerfile 是一個純文本文件,它記載了從一個鏡像建立另外一個新鏡像的步驟。撰寫好 Dockerfile 文件以後,咱們就能夠垂手可得的使用 docker build
命令來建立鏡像了。
Dockerfile 很是簡單,僅有如下命令在 Dockerfile 中常被使用:
命令 | 參數 | 說明 |
---|---|---|
# | - | 註釋說明 |
FROM | <image>[:<tag>] | 從一個已有鏡像建立,例如ubuntu:latest |
MAINTAINER | Author <some-one@example.com> | 鏡像做者名字,如Max Liu <some-one@example.com> |
RUN | <cmd>或者['cmd1', 'cmd2'⋯] | 在鏡像建立用的臨時容器裏執行單行命令 |
ADD | <src> <dest> | 將本地的<src>添加到鏡像容器中的<dest>位置 |
VOLUME | <path>或者['/var', 'home'] | 將指定的路徑掛載爲數據卷 |
EXPOSE | <port> [<port>...] | 將指定的端口暴露給主機 |
ENV | <key> <value> 或者 <key> = <value> | 指定環境變量值 |
CMD | ["executable","param1","param2"] | 容器啓動時默認執行的命令。注意一個Dockerfile中只有最後一個CMD生效。 |
ENTRYPOINT | ["executable", "param1", "param2"] | 容器的進入點 |
下面是一個 Dockerfile 的例子:
# This is a comment FROM ubuntu:14.04 MAINTAINER Kate Smith <ksmith@example.com> RUN apt-get update && apt-get install -y ruby ruby-dev RUN gem install sinatra
這裏其餘命令都比較好理解,惟獨 CMD
和 ENTRYPOINT
我須要特殊說明一下。CMD
命令可用指定 Docker 容器啓動時默認的命令,例如咱們上面例子提到的 docker run -it ubuntu:latest sh -c '/bin/bash'
。其中 sh -c '/bin/bash'
就是經過手工指定傳入的 CMD。若是咱們不加這個參數,那麼容器將會默認使用 CMD 指定的命令啓動。ENTRYPOINT 是什麼呢?從字面看是進入點。沒錯,它就是進入點。ENTRYPOINT 用來指定特定的可執行文件、Shell 腳本,並把啓動參數或 CMD 指定的默認值,看成附加參數傳遞給 ENTRYPOINT。
很差理解是吧?咱們舉一個例子:
ENTRYPOINT ['/usr/bin/mysql'] CMD ['-h 192.168.100.128', '-p']
假設這個鏡像內已經準備好了 mysql-client,那麼經過這個鏡像,不加任何額外參數啓動容器,將會給咱們一個 mysql 的控制檯,默認鏈接到192.168.100.128 這個主機。然而咱們也能夠經過指定參數,來鏈接別的主機。可是無論不管如何,咱們都沒法啓動一個除了 mysql 客戶端之外的程序。由於這個容器的 ENTRYPOINT 就限定了咱們只能在 mysql 這個客戶端內作事情。這下是否是明白了~
所以,咱們在使用 Dockerfile 建立文件的時候,能夠建立一個 entrypoint.sh
腳本,做爲系統入口。在這個文件裏面,咱們能夠進行一些基礎性的自舉操做,好比檢查環境變量,根據須要初始化數據庫等等。下面兩個文件是我在平常工做的項目中添加的 Dockerfile 和 entrypoint.sh,僅供參考:
https://github.com/starlight36/SimpleOA/blob/master/Dockerfile
https://github.com/starlight36/SimpleOA/blob/master/docker-entrypoint.sh
在準備好 Dockerfile 以後,咱們就能夠建立鏡像了:
docker build -t starlight36/simpleoa .
關於 Dockerfile 的更詳細說明,請參考 https://docs.docker.com/reference/builder/。