1. 程式人生 > 其它 >Docker簡介&&使用手冊

Docker簡介&&使用手冊

1、引言

1.1 Docker 是什麼

Docker 最初是 dotCloud 公司創始人 Solomon Hykes 在法國期間發起的一個公司內部專案,於 2013 年 3 月以 Apache 2.0 授權協議開源,主要專案程式碼在 GitHub 上進行維護。

Docker 使用 Google 公司推出的 Go 語言 進行開發實現。

docker是linux容器的一種封裝,提供簡單易用的容器使用介面。它是最流行的Linux容器解決方案。

docker的介面相當簡單,使用者可以方便的建立、銷燬容器。

docker將應用程式與程式的依賴,打包在一個檔案裡面。執行這個檔案就會生成一個虛擬容器。

程式執行在虛擬容器裡,如同在真實物理機上執行一樣,有了docker,就不用擔心環境問題了。

1.2 應用場景

  • web應用的自動化打包和釋出
  • 自動化測試和持續整合、釋出
  • 在服務型環境中部署和調整資料庫或其他應用

1.3 區別

  • 物理機--別墅
  • 虛擬機器--單元樓--獨立衛浴
  • docker--膠囊房子--共享衛浴

1.4 Docker的三大概念及優勢

  • 映象 image
  • 容器 container
  • 倉庫 repository

1. docker容器的優勢

# 1、更高效的利用系統資源

由於容器不需要進行硬體虛擬以及執行完整作業系統等額外開銷,Docker 對系統 資源的利用率更高。

無論是應用執行速度、記憶體損耗或者檔案儲存速度,都要比傳 統虛擬機器技術更高效。因此,相比虛擬機器技術,一個相同配置的主機,往往可以運 行更多數量的應用。

# 2、更快速的啟動時間

傳統的虛擬機器技術啟動應用服務往往需要數分鐘,而 Docker 容器應用,由於直接 運行於宿主核心,無需啟動完整的作業系統,因此可以做到秒級、甚至毫秒級的啟 動時間。大大的節約了開發、測試、部署的時間。

# 3、一致的執行環境

開發過程中一個常見的問題是環境一致性問題。由於開發環境、測試環境、生產環 境不一致,導致有些 bug 並未在開發過程中被發現。

而 Docker 的映象提供了除內 核外完整的執行時環境,確保了應用執行環境一致性,從而不會再出現 “這段程式碼 在我機器上沒問題啊” 這類問題。

# 4、持續交付和部署

對開發和運維(DevOps)人員來說,最希望的就是一次建立或配置,可以在任意 地方正常執行。

使用 Docker 可以通過定製應用映象來實現持續整合、持續交付、部署。開發人員 可以通過 Dockerfile 來進行映象構建,並結合持續整合(Continuous Integration) 系 統進行整合測試,而運維人員則可以直接在生產環境中快速部署該映象,甚至結合 持續部署(Continuous Delivery/Deployment) 系統進行自動部署。

而且使用 Dockerfile 使映象構建透明化,不僅僅開發團隊可以理解應用執行環 境,也方便運維團隊理解應用執行所需條件,幫助更好的生產環境中部署該映象。

# 5、更輕鬆的遷移

由於 Docker 確保了執行環境的一致性,使得應用的遷移更加容易。Docker 可以在 很多平臺上執行,無論是物理機、虛擬機器、公有云、私有云,甚至是筆記本,其運 行結果是一致的。

因此使用者可以很輕易的將在一個平臺上執行的應用,遷移到另一 個平臺上,而不用擔心執行環境的變化導致應用無法正常執行的情況。

2、Docker安裝

系統環境:docker最低支援centos7且在64位平臺上,核心版本在3.10以上
版本:社群版,企業版(包含了一些收費服務)

官方版安裝教程(英文)
https://docs.docker.com/install/linux/docker-ce/centos/#upgrade-docker-after-using-the-convenience-script

# 安裝docker
yum install docker
# 啟動docker 
systemctl start/status docker 
# 檢視docker啟動狀態
docker version 
配置加速器

簡介:DaoCloud 加速器 是廣受歡迎的 Docker 工具,解決了國內使用者訪問 Docker Hub 緩慢的問題。DaoCloud 加速器結合國內的 CDN 服務與協議層優化,成倍的提升了下載速度。

DaoCloud官網:
https://www.daocloud.io/mirror#accelerator-doc


# 一條命令加速(記得重啟docker
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://95822026.m.daocloud.io

3、Docker基礎命令

docker --help(中文註解)

Usage:
docker [OPTIONS] COMMAND [arg...]

       docker daemon [ --help | ... ]

       docker [ --help | -v | --version ]



A
self-sufficient runtime for containers.



Options:



  --config=~/.docker              Location of client config files  #客戶端配置檔案的位置

  -D, --debug=false               Enable debug mode  #啟用Debug除錯模式

  -H, --host=[]                   Daemon socket(s) to connect to  #守護程序的套接字(Socket)連線

  -h, --help=false                Print usage  #列印使用

  -l, --log-level=info            Set the logging level  #設定日誌級別

  --tls=false                     Use TLS; implied by--tlsverify  #

  --tlscacert=~/.docker/ca.pem    Trust certs signed only by this CA  #信任證書籤名CA

  --tlscert=~/.docker/cert.pem    Path to TLS certificate file  #TLS證書檔案路徑

  --tlskey=~/.docker/key.pem      Path to TLS key file  #TLS金鑰檔案路徑

  --tlsverify=false               Use TLS and verify the remote  #使用TLS驗證遠端

  -v, --version=false             Print version information and quit  #列印版本資訊並退出



Commands:

    attach    Attach to a running container  #當前shell下attach連線指定執行映象

    build     Build an image from a Dockerfile  #通過Dockerfile定製映象

    commit    Create a new image from a container's changes  #提交當前容器為新的映象

    cp    Copy files/folders from a container to a HOSTDIR or to STDOUT  #從容器中拷貝指定檔案或者目錄到宿主機中

    create    Create a new container  #建立一個新的容器,同run 但不啟動容器

    diff    Inspect changes on a container's filesystem  #檢視docker容器變化

    events    Get real time events from the server#從docker服務獲取容器實時事件

    exec    Run a command in a running container#在已存在的容器上執行命令

    export    Export a container's filesystem as a tar archive  #匯出容器的內容流作為一個tar歸檔檔案(對應import)

    history    Show the history of an image  #展示一個映象形成歷史

    images    List images  #列出系統當前映象

    import    Import the contents from a tarball to create a filesystem image  #從tar包中的內容建立一個新的檔案系統映像(對應export)

    info    Display system-wide information  #顯示系統相關資訊

    inspect    Return low-level information on a container or image  #檢視容器詳細資訊

    kill    Kill a running container  #kill指定docker容器

    load    Load an image from a tar archive or STDIN  #從一個tar包中載入一個映象(對應save)

    login    Register or log in to a Docker registry#註冊或者登陸一個docker源伺服器

    logout    Log out from a Docker registry  #從當前Docker registry退出

    logs    Fetch the logs of a container  #輸出當前容器日誌資訊

    pause    Pause all processes within a container#暫停容器

    port    List port mappings or a specific mapping for the CONTAINER  #檢視對映埠對應的容器內部源埠

    ps    List containers  #列出容器列表

    pull    Pull an image or a repository from a registry  #從docker映象源伺服器拉取指定映象或者庫映象

    push    Push an image or a repository to a registry  #推送指定映象或者庫映象至docker源伺服器

    rename    Rename a container  #重新命名容器

    restart    Restart a running container  #重啟執行的容器

    rm    Remove one or more containers  #移除一個或者多個容器

    rmi    Remove one or more images  #移除一個或多個映象(無容器使用該映象才可以刪除,否則需要刪除相關容器才可以繼續或者-f強制刪除)

    run    Run a command in a new container  #建立一個新的容器並執行一個命令

    save    Save an image(s) to a tar archive#儲存一個映象為一個tar包(對應load)

    search    Search the Docker Hub for images  #在docker
hub中搜索映象

    start    Start one or more stopped containers#啟動容器

    stats    Display a live stream of container(s) resource usage statistics  #統計容器使用資源

    stop    Stop a running container  #停止容器

    tag         Tag an image into a repository  #給源中映象打標籤

    top       Display the running processes of a container #檢視容器中執行的程序資訊

    unpause    Unpause all processes within a container  #取消暫停容器

    version    Show the Docker version information#檢視容器版本號

    wait         Block until a container stops, then print its exit code  #擷取容器停止時的退出狀態值



Run 'docker COMMAND --help' for more information on a command.  #執行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 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`   # 一次性刪除所有本地的映象記錄

3.1 啟動容器的兩種方式

容器是執行應用程式的,所以必須得先有一個作業系統為基礎

1、基於映象新建一個容器並啟動

# 1. 後臺執行一個docker
docker run -d centos /bin/sh -c "while true;do echo 正在執行; sleep 1;done"
    # -d  後臺執行容器
    # /bin/sh  指定使用centos的bash直譯器
    # -c 執行一段shell命令
    # "while true;do echo 正在執行; sleep 1;done"  在linux後臺,每秒中列印一次正在執行
docker ps  # 檢查容器程序
docker  logs  -f  容器id/名稱  # 不間斷列印容器的日誌資訊 
docker stop centos  # 停止容器

# 2. 啟動一個bash終端,允許使用者進行互動
docker run --name mydocker -it centos /bin/bash  
    # --name  給容器定義一個名稱
    # -i  讓容器的標準輸入保持開啟
    # -t 讓Docker分配一個偽終端,並繫結到容器的標準輸入上
    # /bin/bash 指定docker容器,用shell直譯器互動

當利用docker run來建立容器時,Docker在後臺執行的步驟如下:

# 1. 檢查本地是否存在指定的映象,不存在就從公有倉庫下載
# 2. 利用映象建立並啟動一個容器
# 3. 分配一個檔案系統,並在只讀的映象層外面掛在一層可讀寫層
# 4. 從宿主主機配置的網橋介面中橋接一個虛擬介面到容器中去
# 5. 從地址池配置一個ip地址給容器
# 6. 執行使用者指定的應用程式
# 7. 執行完畢後容器被終止

2、將一個終止狀態(stopped)的容器重新啟動

# 1.我們進入互動式的centos容器中,發現沒有vim命令
    docker run -it centos
# 2.在當前容器中,安裝一個vim
    yum install -y vim
# 3.安裝好vim之後,exit退出容器
    exit
# 4.檢視剛才安裝好vim的容器記錄
    docker container ls -a
# 5.提交這個容器,建立新的image
    docker commit 059fdea031ba chaoyu/centos-vim
# 6.檢視映象檔案
    docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
chaoyu/centos-vim   latest              fd2685ae25fe        5 minutes ago       348MB

3.3 外部訪問容器

容器中可以執行網路應用,但是要讓外部也可以訪問這些應用,可以通過-p或-P引數指定埠對映。

docker run -d -P training/webapp python app.py
  # -P 引數會隨機對映埠到容器開放的網路埠

# 檢查對映的埠
docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED            STATUS              PORTS                     NAMES
cfd632821d7a        training/webapp     "python app.py"     21 seconds ago      Up 20 seconds       0.0.0.0:32768->5000/tcp   brave_fermi
#宿主機ip:32768 對映容器的5000埠

# 檢視容器日誌資訊
docker logs -f cfd  # #不間斷顯示log

# 也可以通過-p引數指定對映埠
docker run -d -p 9000:5000 training/webapp python app.py

開啟瀏覽器訪問伺服器的9000埠, 內容顯示 Hello world!表示正常啟動

(如果訪問失敗的話,檢查自己的防火牆,以及雲伺服器的安全組)

4、利用dockerfile定製映象

映象是容器的基礎,每次執行docker run的時候都會指定哪個映象作為容器執行的基礎。我們之前的例子都是使用來自docker hub的映象,直接使用這些映象只能滿足一定的需求,當映象無法滿足我們的需求時,就得自定製這些映象。

# 映象的定製就是定製每一層所新增的配置、檔案。如果可以吧每一層修改、安裝、構建、操作的命令都寫入到一個指令碼,用指令碼來構建、定製映象,這個指令碼就是dockerfile。
# Dockerfile 是一個文字檔案,其內包含了一條條的指令(Instruction),每一條指令 構建一層,因此每一條指令的內容,就是描述該層應當如何構建。

引數詳解

FROM scratch #製作base image 基礎映象,儘量使用官方的image作為base image
FROM centos #使用base image
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 /root #相當於linux的cd命令,改變目錄,儘量使用絕對路徑!!!不要用RUN cd
WORKDIR /test # 如果沒有就自動建立
WORKDIR demo # 再進入demo資料夾
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}” 

進階知識(瞭解)

VOLUME and EXPOSE 
儲存和網路

RUN and CMD and ENTRYPOINT
RUN:執行命令並建立新的Image Layer
CMD:設定容器啟動後預設執行的命令和引數
ENTRYPOINT:設定容器啟動時執行的命令

Shell格式和Exec格式
RUN yum install -y vim
CMD echo ”hello docker”
ENTRYPOINT echo “hello docker”

Exec格式
RUN [“apt-get”,”install”,”-y”,”vim”]
CMD [“/bin/echo”,”hello docker”]
ENTRYPOINT [“/bin/echo”,”hello docker”]


通過shell格式去執行命令,會讀取$name指令,而exec格式是僅僅的執行一個命令,而不是shell指令
cat Dockerfile
    FROM centos
    ENV name Docker
    ENTRYPOINT [“/bin/echo”,”hello $name”]#這個僅僅是執行echo命令,讀取不了shell變數
    ENTRYPOINT  [“/bin/bash”,”-c”,”echo hello $name"]

CMD
容器啟動時預設執行的命令
如果docker run指定了其他命令(docker run -it [image] /bin/bash ),CMD命令被忽略
如果定義多個CMD,只有最後一個執行

ENTRYPOINT
讓容器以應用程式或服務形式執行
不會被忽略,一定會執行
最佳實踐:寫一個shell指令碼作為entrypoint
COPY docker-entrypoint.sh /usr/local/bin
ENTRYPOINT [“docker-entrypoint.sh]
EXPOSE 27017
CMD [“mongod”]

[root@master home]# more Dockerfile
FROm centos
ENV name Docker
#CMD ["/bin/bash","-c","echo hello $name"]
ENTRYPOINT ["/bin/bash","-c","echo hello $name”]

5、釋出到倉庫

5.1 docker hub共有映象釋出

docker提供了一個類似於github的倉庫docker hub,官方網站(需註冊使用)
https://hub.docker.com/

# 註冊docker id後,在linux中登入dockerhub
    docker login

# 注意要保證image的tag是賬戶名,如果映象名字不對,需要改一下tag
    docker tag chaoyu/centos-vim peng104/centos-vim
    # 語法是:  docker tag   倉庫名   peng104/倉庫名

# 推送docker image到dockerhub
    docker push peng104/centps-cmd-exec:latest

# 去dockerhub中檢查映象
# 先刪除本地映象,然後再測試下載pull 映象檔案
    docker pull peng104/centos-entrypoint-exec

5.2 私有倉庫

docker hub 是公開的,其他人也是可以下載,並不安全,因此還可以使用docker registry官方提供的私有倉庫

用法詳解:
https://yeasy.gitbooks.io/docker_practice/repository/registry.html

# 1.下載一個docker官方私有倉庫映象
    docker pull registry
# 2.執行一個docker私有容器倉庫
docker run -d -p 5000:5000 -v /opt/data/registry:/var/lib/registry  registry
    -d 後臺執行 
    -p  埠對映 宿主機的5000:容器內的5000
    -v  資料卷掛載  宿主機的 /opt/data/registry :/var/lib/registry 
    registry  映象名
    /var/lib/registry  存放私有倉庫位置
# Docker 預設不允許非 HTTPS 方式推送映象。我們可以通過 Docker 的配置選項來取消這個限制
# 3.修改docker的配置檔案,讓他支援http方式,上傳私有映象
    vim /etc/docker/daemon.json 
    # 寫入如下內容
    {
        "registry-mirrors": ["http://f1361db2.m.daocloud.io"],
        "insecure-registries":["192.168.11.37:5000"]
    }
# 4.修改docker的服務配置檔案
    vim /lib/systemd/system/docker.service
# 找到[service]這一程式碼區域塊,寫入如下引數
    [Service]
    EnvironmentFile=-/etc/docker/daemon.json
# 5.重新載入docker服務
    systemctl daemon-reload
# 6.重啟docker服務
    systemctl restart docker
    # 注意:重啟docker服務,所有的容器都會掛掉

# 7.修改本地映象的tag標記,往自己的私有倉庫推送
    docker tag docker.io/peng104/hello-world-docker 192.168.11.37:5000/peng-hello
    # 瀏覽器訪問http://192.168.119.10:5000/v2/_catalog檢視倉庫
    docker push 192.168.11.37:5000/peng-flaskweb
# 8.下載私有倉庫的映象
    docker pull 192.168.11.37:5000/peng-hello

6、例項演示

編寫dockerfile,構建自己的映象,執行flask程式。

確保app.py和dockerfile在同一個目錄!


# 1.準備好app.py的flask程式
    [root@localhost ~]# cat app.py
    from flask import Flask
    app=Flask(__name__)
    @app.route('/')
    def hello():
        return "hello docker"
    if __name__=="__main__":
        app.run(host='0.0.0.0',port=8080)
    [root@master home]# ls
    app.py  Dockerfile

# 2.編寫dockerfile
    [root@localhost ~]# cat Dockerfile
    FROM python:2.7
    LABEL maintainer="溫而新"
    RUN pip install flask
    COPY app.py /app/
    WORKDIR /app
    EXPOSE 8080
    CMD ["python","app.py"]

# 3.構建映象image,找到當前目錄的Dockerfile,開始構建
    docker build -t peng104/flask-hello-docker .

# 4.檢視建立好的images
    docker image ls

# 5.啟動此flask-hello-docker容器,對映一個埠供外部訪問
    docker run -d -p 8080:8080 peng104/flask-hello-docker

# 6.檢查執行的容器
    docker container ls

# 7.推送這個映象到私有倉庫
    docker tag  peng104/flask-hello-docker   192.168.11.37:5000/peng-flaskweb
    docker push 192.168.11.37:5000/peng-flaskweb