Docker 快速入門指引

本文最先發表於本人博客: Docker 快速入門指引html

Docker是什麼?

Docker是 Docker.Inc 公司開源的一個基於 LXC技術之上構建的Container容器引擎,基於Go語言並聽從Apache2.0協議開源。mysql

開發者能夠搭建他們的應用僅僅一次,就能保證讓這個應用保持一致的跑在任何地方。運營人員能夠將他們的服務器配置一遍,就能跑任何應用。git

What is Docker’s architecture?

Docker uses a client-server architecture. The Docker  client talks to the Docker daemon, which does the heavy lifting of building, running, and distributing your Docker containers. Both the Docker client and the daemon  can run on the same system, or you can connect a Docker client to a remote Docker daemon. The Docker client and daemon communicate via sockets or through a RESTful API.

和傳統虛擬主機的區別

傳統虛擬機經過硬件虛擬化來創造一整個虛擬系統。每個虛擬機內的應用不只僅包含這個應用的一些類庫代碼,並且還包含一整個操做系統。web

Docker全部的容器分享一個操做系統,他們顯然會比虛擬機更小一些,使得他們能夠存在100多個虛擬的系統在一個主機上(而不像一個嚴格限制數量的虛擬機)。sql

優勢和特色

  • 標準化應用發佈,docker容器包含了運行環境和可執行程序,能夠跨平臺和主機使用
  • 快速部署和啓動,VM啓動通常是分鐘級,docker容器啓動是秒級,即啓即用
  • 方便構建基於SOA架構或微服務架構的系統,經過服務編排,更好的鬆耦合
  • 輕量低成本,佔有更少的磁盤空間,一臺主機能夠啓動上千個容器
  • 方便持續集成,經過與代碼進行關聯使持續集成很是方便
  • 安全隔離的執行環境,每一個運行的容器互不影響docker

    • 文件系統分離,每個進程容器跑在徹底分離的root權限的文件系統下
    • 資源分離,系統資源(像CPU、內存)能被指定的分配給每個進程容器,使用cgroups
    • 網絡分離,使用一個虛擬的接口和IP地址,每個進程容器跑在它本身的網絡命名空間
  • 豐富的鏡像資源,用戶能夠方便的在此基礎上構建本身的容器運行
  • ......

一些概念和名稱

  • Docker Client 是用戶界面,它支持用戶與Docker Daemon之間通訊
  • Docker Daemon Docker最核心的後臺進程,運行於主機上,處理服務請求
  • Docker Index是中央registry,支持擁有公有與私有訪問權限的Docker容器鏡像的備份
  • Docker Containers負責應用程序的運行,包括操做系統、用戶添加的文件以及元數據
  • Docker Images是一個只讀模板,用來運行Docker容器
  • DockerFile是文件指令集,用來講明如何自動建立Docker鏡像

安裝

  • 如今已經支持Windows,Mac OS X,以及大多數Linux版本 -> Install Docker Engine
  • DaoCloud的安裝腳本
#Ubuntu
  curl -sSL https://get.daocloud.io/docker | sh
  #CentOS
  curl -sSL https://get.daocloud.io/docker | sh
  sudo chkconfig docker on
  sudo systemctl start docker

倉庫

倉庫(Repository)是集中存放鏡像文件的場所,倉庫註冊服務器(Registry)上每每存放着多個倉庫,每一個倉庫中又包含了多個鏡像,每一個鏡像有不一樣的標籤(tag),和倉庫(Repository)嚴格來說不是同一個概念。
倉庫分爲公開倉庫(Public)和私有倉庫(Private),官方的 Docker Hub提供大量鏡像提供下載,可是訪問很是的慢,可使用國內的公開倉庫 時速雲 、網易雲阿里雲 、DaoCloud加速器等
用戶也能夠在本地網絡內建立一個私有倉庫,建立了本身的鏡像以後就可使用 push 命令將它上傳到公有或者私有倉庫,其餘機器上使用只須要從倉庫上 pull 下來就能夠了。shell

鏡像

鏡像就是一堆文件的集合,並非像VM那樣的是一個操做系統。鏡像能夠簡單到只有一個程序文件。若是你寫一個helloworld 靜態編譯後放到一個空的Image中,那麼整個image的大小,就是你編譯後的二進制文件的大小。一個ubuntu:14.04的鏡像,提供了一個基本的ubuntu:14.04的發行版,鏡像是不包含操做系統Linux內核。
若是在Debian鏡像中安裝MySQL 5.6,就成了mysql:5.6鏡像。底層一個Debian操做系統鏡像,上面疊加一個 MySQL層,就完成了一個MySQL鏡像的構建。
Dockerfile構建出Docker鏡像,經過Docker鏡像運行Docker容器。Docker鏡像是Docker容器運行的基礎,沒有Docker鏡像,就不可能有Docker容器,這也是Docker的設計原則之一。ubuntu

經常使用命令

  • docker images 顯示本地已有鏡像
  • docker info 顯示docker系統信息
  • docker commit -m -a 提交更新後的鏡像
  • docker build 經過Dockerfile來構建鏡像
  • docker import 本地導入鏡像
  • docker search 查找倉庫中鏡像
  • docker push 將鏡像推送到倉庫
  • docker pull 將倉庫中鏡像下載到本地
  • docker save -o mysql_5.6.tar mysql:5.6 導出鏡像到本地
  • docker load < mysql_5.6.tar 載入鏡像
  • docker rmi 移除鏡像
  • docker attach 運行中容器的stdin,進行命令執行的動做
  • docker history 顯示鏡像的歷史

Dockerfile

Dockerfile是Docker用來構建鏡像的文本文件,包含自定義的指令和格式, 能夠經過docker build命令從Dockerfile中構建鏡像。安全

  • FROM
FROM <image>[:<tag>]
  設置要製做的鏡像基於哪一個鏡像,FROM指令必須是整個Dockerfile的第一個指令,若是指定的鏡像不存在默認會自動從Docker Hub上下載。
  • MAINTAINER
MAINTAINER <name>
  MAINTAINER指令容許你給將要製做的鏡像設置做者信息
  • RUN
RUN <command>        #將會調用/bin/sh -c <command>
  RUN ["executable", "param1", "param2"]   #將會調用exec執行,以免有些時候shell方式執行時的傳遞參數問題,並且有些基礎鏡像可能不包含/bin/sh
  RUN指令會在一個新的容器中執行任何命令,而後把執行後的改變提交到當前鏡像,提交後的鏡像會被用於Dockerfile中定義的下一步操做,RUN中定義的命令會按順序執行並提交,這正是Docker廉價的提交和能夠基於鏡像的任何一個歷史點建立容器的好處,就像版本控制工具同樣。
  • CMD
CMD ["executable", "param1", "param2"]    #將會調用exec執行,首選方式
  CMD ["param1", "param2"]        #當使用ENTRYPOINT指令時,爲該指令傳遞默認參數
  CMD <command> [ <param1>|<param2> ]        #將會調用/bin/sh -c執行
  CMD指令中指定的命令會在鏡像運行時執行,在Dockerfile中只能存在一個,若是使用了多個CMD指令,則只有最後一個CMD指令有效。
  當出現ENTRYPOINT指令時,CMD中定義的內容會做爲ENTRYPOINT指令的默認參數,也就是說可使用CMD指令給ENTRYPOINT傳遞參數。
  RUN和CMD都是執行命令,他們的差別在於RUN中定義的命令會在執行docker build命令建立鏡像時執行,而CMD中定義的命令會在執行docker run命令運行鏡像時執行,另外使用第一種語法也就是調用exec執行時,命令必須爲絕對路徑。
  • EXPOSE
EXPOSE <port> [ ...]
  EXPOSE指令用來告訴Docker這個容器在運行時會監聽哪些端口,Docker在鏈接不一樣的容器(使用–link參數)時使用這些信息。
  • ENV
ENV <key> <value>
  ENV指令用於設置環境變量,在Dockerfile中這些設置的環境變量也會影響到RUN指令,當運行生成的鏡像時這些環境變量依然有效,若是須要在運行時更改這些環境變量能夠在運行docker run時添加–env <key>=<value>參數來修改。
  最好不要定義那些可能和系統預約義的環境變量衝突的名字,不然可能會產生意想不到的結果。
  • ADD
ADD <src> <dest>
  ADD指令用於從指定路徑拷貝一個文件或目錄到容器的指定路徑中,<src>是一個文件或目錄的路徑,也能夠是一個url,路徑是相對於該Dockerfile文件所在位置的相對路徑,<dest>是目標容器的一個絕對路徑
  例如/home/yooke/Docker/Dockerfile這個文件中定義的,那麼ADD /data.txt /db/指令將會嘗試拷貝文件從/home/yooke/Docker/data.txt到將要生成的容器的/db/data.txt,且文件或目錄的屬組和屬主分別爲uid和gid爲0的用戶和組,若是是經過url方式獲取的文件,則權限是600。
  注意: ①若是執行docker build – < somefile即經過標準輸入來建立時,ADD指令只支持url方式,另外若是url須要認證,則能夠經過RUN wget …或RUN curl …來完成,ADD指令不支持認證。
        ②<src>路徑必須與Dockerfile在同級目錄或子目錄中,例如不能使用ADD ../somepath,由於在執行docker build時首先作的就是把Dockerfile所在目錄包含子目錄發送給docker的守護進程。
        ③若是<src>是一個url且<dest>不是以」/「結尾,則會下載文件並重命名爲<dest>。
        ④若是<src>是一個url且<dest>以「/」結尾,則會下載文件到<dest>/<filename>,url必須是一個正常的路徑形式,「http://example.com」像這樣的url是不能正常工做的。
        ⑤若是<src>是一個本地的壓縮包且<dest>是以「/」結尾的目錄,則會調用「tar -x」命令解壓縮,若是<dest>有同名文件則覆蓋,但<src>是一個url時不會執行解壓縮。
  • COPY
COPY <src> <dest>
  用法與ADD相同,<src>不支持使用url
  • ENTRYPOINT
ENTRYPOINT ["executable", "param1", "param2"]        #將會調用exec執行,首選方式
  ENTRYPOINT command param1 param2             #將會調用/bin/sh -c執行
  ENTRYPOINT指令中指定的命令會在鏡像運行時執行,在Dockerfile中只能存在一個,若是使用了多個則只有最後一個指令有效。
  ENTRYPOINT指令中指定的命令(exec執行的方式)能夠經過docker run來傳遞參數,例如docker run <images> -l啓動的容器將會把-l參數傳遞給ENTRYPOINT指令定義的命令並會覆蓋CMD指令中定義的默認參數(若是有的話),但不會覆蓋該指令定義的參數,例如ENTRYPOINT ["ls","-a"],CMD ["/etc"],當經過docker run <image>啓動容器時該容器會運行ls -a /etc命令,當使用docker run <image> -l啓動時該容器會運行ls -a -l命令,-l參數會覆蓋CMD指令中定義的/etc參數。
  當使用ENTRYPOINT指令時生成的鏡像運行時只會執行該指令指定的命令。
  當出現ENTRYPOINT指令時CMD指令只可能(當ENTRYPOINT指令使用exec方式執行時)被當作ENTRYPOINT指令的參數使用,其餘狀況則會被忽略。
  • VOLUME
VOLUME ["samepath"]
  VOLUME指令用來設置一個掛載點,能夠用來讓其餘容器掛載以實現數據共享或對容器數據的備份、恢復或遷移。
  • USER
USER [username|uid]
  USER指令用於設置用戶或uid來運行生成的鏡像和執行RUN指令。
  • WORKDIR
WORKDIR /path/to/workdir
  WORKDIR指令用於設置Dockerfile中的RUN、CMD和ENTRYPOINT指令執行命令的工做目錄(默認爲/目錄),該指令在Dockerfile文件中能夠出現屢次,若是使用相對路徑則爲相對於WORKDIR上一次的值,例如WORKDIR /data,WORKDIR logs,RUN pwd最終輸出的當前目錄是/data/logs。
  • ONBUILD
ONBUILD [INSTRUCTION]
  ONBUILD指令用來設置一些觸發的指令,用於在當該鏡像被做爲基礎鏡像來建立其餘鏡像時(也就是Dockerfile中的FROM爲當前鏡像時)執行一些操做,ONBUILD中定義的指令會在用於生成其餘鏡像的Dockerfile文件的FROM指令以後被執行,上述介紹的任何一個指令均可以用於ONBUILD指令,能夠用來執行一些由於環境而變化的操做,使鏡像更加通用。
  注意: ①ONBUILD中定義的指令在當前鏡像的build中不會被執行。
        ②能夠經過查看docker inspeat <image>命令執行結果的OnBuild鍵來查看某個鏡像ONBUILD指令定義的內容。
        ③ONBUILD中定義的指令會當作引用該鏡像的Dockerfile文件的FROM指令的一部分來執行,執行順序會按ONBUILD定義的前後順序執行,若是ONBUILD中定義的任何一個指令運行失敗,則會使FROM指令中斷並致使整個build失敗,當全部的ONBUILD中定義的指令成功完成後,會按正常順序繼續執行build。
        ④ONBUILD中定義的指令不會繼承到當前引用的鏡像中,也就是當引用ONBUILD的鏡像建立完成後將會清除全部引用的ONBUILD指令。
        ⑤ONBUILD指令不容許嵌套,例如ONBUILD ONBUILD ADD . /data是不容許的。
        ⑥ONBUILD指令不會執行其定義的FROM或MAINTAINER指令。

容器

容器 = 鏡像 + 可讀層
Docker容器就像是一個文件夾,它包含了一個應用程序運行所須要的全部內容。每一個容器都是基於Docker鏡像構建。咱們能夠運行、開始、中止、遷移或者是刪除Docker容器。每一個容器均是一個隔離的、安全的應用平臺。Docker容器是Docker的運行組件。bash

經常使用命令

  • docker run 新建並啓動容器

    • -d 容器運行在後臺,此時不能使用--rm選項
    • -i -t 和容器進行交互式操做
    • --name 命名容器,沒有該參數Docker deamon會生產UUID來標識
    • --cidfile 將容器ID輸入到指定文件中
    • --add-host 添加一行到/etc/hosts
    • --mac-address 設置MAC地址
    • --dns 覆蓋容器DNS設置
    • --rm 退出容器時自動清除數據
    • -m 調整容器的內存使用
    • -c 調整容器的CPU優先級
    • -e 設定環境變量
    • --expose 運行時暴露端口,不建立和宿主機的映射
    • -p 建立映射規則,將一個或者一組端口從容器裏綁定到宿主機上,可屢次使用

      • ip:hostPort:containerPort
      •  ip::containerPort  
      •  hostPort:containerPort  
      •  containerPort
    • -P 將Dockfile中暴露的端口映射動態映射到宿主機
    • --link 容器互聯 --link name:alias
    • -v 建立數據卷掛載到容器,一次run中可屢次使用
    • 可覆蓋Dockfile參數

      • CMD
      • ENTRYPOINT
      • EXPOSE
      • ENV
      • VOLUME
      • USER
      • WORKDIR
  • docker stop 中止運行中容器
  • docker stop $(docker ps -qa) 中止全部運行中的容器
  • docker restart 重啓容器
  • docker ps -a 查看全部容器
  • docker rm 移除處於終止狀態的容器

    • docker rm $(docker ps -qa) 移除處於終止狀態的容器
  • docker logs 從容器中去日誌
  • docker diff 列出容器中被改變的文件或者目錄
  • docker top 顯示運行容器的進程信息
  • docker cp 從容器中拷貝文件或者目錄到本地
  • docker inspect 查看容器詳細信息

Volume和Volume Containers

數據卷相似於 Linux 下對目錄或文件進行 mount,本質是容器中一個特殊的文件或目錄(掛載點)。在容器的建立過程當中,這個掛載點會被掛載一個宿主機上的指定的目錄 (一個以volumeID爲名稱的目錄 或者指定的宿主機目錄)。它的設計用來持久化數據的,生命週期獨立於容器。

  • docker run -i -t -v /data debian:jessie /bin/sh
    將宿主的/var/lib/docker/volumes/volume_id/_data 綁定掛載到 /data
  • docker run -i -t -v /var/www/:/data debian:jessie /bin/sh
    ​將宿主機的/var/www/ 綁定掛載到 /data
  • docker run -i -t -v /var/www/:/data:ro debian:jessie /bin/sh
    ​掛載爲只讀

數據卷容器,用來提供數據卷供其它容器掛載的正常容器。

  • 建立一個數據卷容器dbdata
docker run -d -v /var/www/:/dbdata --name dbdata debian:jessie
  • 其餘容器掛載 dbdata容器中的數據卷
docker run -d --volumes-from dbdata --name db1 debian:jessie
  • 也能夠從其餘已經掛載了數據卷的容器來級聯掛載數據卷
docker run -d --name db2 --volumes-from db1 debian:jessie

若是刪除了掛載的容器,數據卷並不會被自動刪除。若是要刪除一個數據卷,必須在刪除最後一個還掛載着它的容器時使用 docker rm -v 命令來指定同時刪除關聯的容器。

  • 備份數據卷,使用了 tar 命令來將 dbdata 卷備份爲容器中 /backup/backup.tar 文件,也就是主機當前目錄下的名爲 backup.tar 的文件。
docker run --volumes-from dbdata -v $(pwd):/backup debian:jessie tar cvf /backup/backup.tar /dbdata
  • 恢復數據卷
# 建立一個帶有空數據卷的容器
  docker run -v /dbdata --name dbdata2 debian:jessie /bin/bash
  # 建立另外一個容器,掛載 dbdata2 容器卷中的數據卷,並解壓備份文件到掛載的容器卷中。
  docker run --volumes-from dbdata2 -v $(pwd):/backup debian:jessie tar xvf /backup/backup.tar
  # 再啓動一個容器掛載一樣的容器捲來查看恢復的數據
  docker run --volumes-from dbdata2 debian:jessie /bin/ls /dbdata

參考

Docker Docs

Docker入門與實戰

若是以爲本篇文章對您十分有益,何不 打賞一下

謝謝打賞

謝謝打賞

相關文章
相關標籤/搜索