Docke--基礎篇

什麼是Docker?

Docker 最初是dotCloud公司創始人Solomon Hykes在法國期間發起的一個公司內部項目,它是基於dotCloud公司多年雲服務技術的一次革新,並與2013年3月以Apache 2.0受權協議開源),主要項目代碼在GitHub上進行維護。Docker項目後來還加入了Linux基金會,併成立推進開放容器聯盟php

Docker 自開源後受到普遍的關注和討論,至今其GitHub項目已經超過3萬6千個星際和一萬多個fork。甚至因爲Docker項目的火爆,在2013年末,dotCloud公司決定更名爲Docker。Docker最初在Ubuntu12.04上開發實現的;Redhat則從RHEL6.5開始對Docker進行支持;Google也在其PaaS產品中普遍應用Docker。Docker使用Google公司推出的Go語言進行開發實現,基於Linux內核的cgroup,namespace,以及AUFS類的Union FS等技術,對進程進行封裝隔離,屬於操做系統層面的虛擬化技術。因爲隔離的進程獨立於宿主和其它的隔離的進程,所以也稱其爲容器。最初實現是基於LXC,從0.7之後開始去除LXC,轉而使用自行開發的libcontainer,從1.11開始,則進一步演進爲使用runCcontainerdhtml

Docker 的基本概念

Docker 容器是資源分割和調度的基本單位,封裝整個服務的運行時環境,用於構建、發佈和運行發佈式應用的一個框架。它是一個跨平臺,可移植而且簡單易用的容器解決方案。node

Docker 容器能夠快速自動化地部署應用,並經過操做系統內核技術(namespaces、cgroups等)爲容器提供資源隔離與安全保障。Docker 做爲輕量級的虛擬化方式,實現了PaaS平臺高效部署、運行和維護。mysql

Docker 在容器的基礎上,進行了進一步的封裝,從文件系統、網絡互聯到進程隔離等待,極大的簡化了容器的建立和維護。使得Docker技術比虛擬機技術更爲輕便,快捷。linux

  • 傳統虛擬機技術是虛擬出一套硬件後,在其上運行一個完整操做系統,在該系統上再運行所需應用進程;
  • 而容器內的應用進程直接運行於宿主的內核,容器內沒有本身的內核,並且也沒有進行硬件虛擬化。所以容器要比傳統虛擬機更爲輕便。

傳統虛擬化結構對比Docker結構nginx

爲何要使用Docker?

  • 更高效的利用系統資源

  因爲容器不須要進行硬件虛擬化以及運行完整操做系統等額外開銷,Docker對系統資源的利用率更高。不管是應用執行速度、內存損耗或者文件存儲速度,都要比傳統虛擬機技術更高效。所以,相比虛擬機技術,一個相同配置的主機,每每能夠運行更多數量的應用。git

  • 更快速的啓動時間

  傳統的虛擬機技術啓動應用服務每每須要數分鐘,而Docker容器應用,因爲直接運行於宿主機,無需啓動完整的操做系統,所以能夠作到秒級、甚至毫秒級的啓動時間。大大的節約了開發、測試、部署的時間。web

  • 一致的運行環境

  開發過程當中一個常見的問題是環境一致性問題。因爲開發環境、測試環境、生產環境不一致,致使有些bug並未在開發過程當中被發現。而Docker的鏡像提供了除內核外完整的運行時環境,確保了應用運行環境一致性,從而不會再出現「這段代碼在我機器上沒問題啊」這類問題。sql

  • 持續交付和部署

  對開發和運維(DevOps)人員來講,最但願的就是一次建立或配置,能夠在任意地方正常運行。docker

  使用Docker能夠經過定製應用鏡像來實現持續集成、持續交付、部署。開發人員能夠經過Dockerfile來進行鏡像構建,並結合持續集成(Continuous lntegration)系統持續進行集成測試,而運維人員則能夠直接在生產環境中快速部署該鏡像,甚至結合持續部署(Continuous Delivery/Deployment)系統進行自動部署。而使用Dockerfile使鏡像構建透明化,不只僅開發團隊能夠理解應用運行環境,也方便運維團隊理解應用運行所需條件,幫助更好的生產環境中部署該鏡像。

  • 更輕鬆的遷移

  因爲Docker確保了執行環境的一致性,使得應用的遷移更加容易。Docker能夠在不少平臺上運行,不管是物理機、虛擬機、公有云、私有云,甚至是筆記本,其運行結果是一致的。所以用戶能夠很輕易的將在一個平臺上運行的應用,遷移到另外一個平臺上,而不用擔憂運行環境的變化致使應用沒法正常運行的狀況。

  • 更輕鬆的維護和擴展

  Docker使用的分層存儲以及鏡像的技術,使得應用重複部分的複用更爲容易,也使得應用的維護更新更加簡單,基於基礎鏡像進一步擴展鏡像也變得很是簡單。此外,Docker團隊同各個開源項目團隊一塊兒維護了一大批高質量的官方鏡像,既能夠直接在生產環境使用,又能夠做爲基礎進一步定製,大大下降了應用服務的鏡像製做成本。

Docker對比傳統虛擬機

特性 容器 虛擬機
啓動 秒級 分鐘級
磁盤使用 通常爲MB 通常爲GB
性能 接近原生 弱於
系統支持量 單機支持上千個容器 通常幾十個

Docker 體系結構簡介

 

 

Docker 是一個客戶/服務器(Client/Server,CS)架構(見上圖)。Docker客戶端是遠程控制器,可經過TCP RESTDocker Host 發送請求,包括建立容器、運行容器、保存容器、刪除容器等請求。Docker服務端的Daemon 對客戶端的請求進行相應的管理,隨後經過 driver轉發至容器中的libcontainer執行環境。libcontainer提供與不一樣Linux內核隔離的接口,相似命名空間及控制組。這種架構容許多個容器在共享同一個Linux內核的狀況下徹底隔離的運行。

Docker 鏡像(Images) Docker 鏡像是用於建立 Docker 容器的模板。
Docker 容器(Container) 容器是獨立運行的一個或一組應用。
Docker 客戶端(Client) Docker 客戶端經過命令行或其餘工具使用 Docker API (https://docs.docker.com/reference/api/docker_remote_api)與Docker 的守護進程通訊。
Docker 主機(Host) 一個物理或者虛擬的機器用來執行 Docker 守護進程和容器。
Docker 倉庫(Registry) Docker 倉庫用來保存鏡像,能夠理解爲代碼控制中的代碼倉庫。Docker Hub(https://hub.docker.com)提供了龐大的鏡像集合供使用。
Docker Machine Docker Machine 是一個簡化Docker安裝的命令行工具,經過一個簡單的命令便可在響應的平臺上安裝Docker,好比VirtualBox、Digital Ocean、Microsoft Azure。

Docker 8大應用場景

 

(1)、簡化配置

這是Docker公司宣傳的 Docker 的主要使用場景。Docker 能將運行環境和配置放在代碼中而後部署,同一個 Docker 的配置能夠在不一樣的環境中使用,這樣就下降了硬件要求和應用環境之間耦合度。

(2)、代碼流水線(Code Pipeline)管理

代碼從開發者的機器到最終生產環境上的部署,須要通過不少的中間環境。而每個中間環境都有微小的差異,Docker 給應用提供了一個從開發到上線均一致的環境,讓代碼的流水線變得簡單很多。

(3)、提升開發效率

Docker 能提高開發者的開發效率。不一樣的開發環境中,Docker 均可以把兩件事作好,一是能夠在開發環境、生產環境之間直接遷移,二是可讓咱們快速搭建開發環境。開發環境的機器一般內存比較小,以前使用虛擬機的時候,咱們常常須要爲開發環境的機器加內存,而使用Docker能夠輕易的讓幾十個服務在Docker中跑起來。

(4)、隔離應用

有不少緣由會讓咱們選擇在一個機器上運行不一樣的應用,Docker 很是適合在較低的成本下實現多種應用的隔離。

(5)、整合服務器

Docker 隔離應用的能力使得Docker能夠整合多個服務器以下降成本。因爲沒有操做系統的內存佔用,以及能在多個實例之間共享沒有使用的內存,Docker 能夠比虛擬機提供更好的服務器整合解決方案。一般數據中心的服務器資源利用率只有30%,經過使用Docker 並進行有效的資源分配能夠大幅度提升服務器資源的利用率。

(6)、調適能力

Docker 提供了不少的工具,包括能夠爲容器設置檢查點、設置版本和查看兩個容器之間的差異,這些特性能夠幫助調試Bug。

(7)、多租戶環境

另一個Docker 的使用場景是在多租戶的應用中,它能夠避免關鍵應用的重寫。咱們一個特別的關於這個場景的例子是爲物聯網的應用開發一個快速、易用的多租戶環境。這種多租戶的基本代碼很是複雜,很難處理,從新規劃這樣一個應用不但消耗時間,也浪費金錢。
使用Docker,能夠爲每個租戶的應用層的多個實例建立隔離的環境,這不只簡單並且成本低廉,固然這一切得益於Docker環境的啓動速度和高效的diff命令。

(8)、快速部署

在虛擬機以前,購入部署新的硬件資源須要消耗幾天的時間。虛擬化技術(Virtualization)將這個時間縮短到了分鐘級別。而Docker 經過爲進程僅僅建立一個容器而無需啓動一個操做系統,再次將這個過程縮短到了秒級。這正式Google和Facebook 都看重的特性。咱們能夠建立銷燬Docker 容器而無需擔憂從新啓動帶來的開銷。

Docker 三大核心概念

 Docker 包括三個基本概念

  • 鏡像(Image)
  • 容器(Container)
  • 倉庫(Repository)

Docker 鏡像(Image)

  Docker 鏡像相似於虛擬機鏡像,能夠將它理解爲一個只讀的模板。例如,一個鏡像能夠包含一個基本的操做系統環境,裏面僅安裝了 Apache 應用程序(或用戶須要的其餘軟件)。能夠把它稱爲一個 Apache鏡像。

  鏡像是建立Docker 容器的基礎。經過版本管理和增量的文件系統,Docker提供了一套十分簡單的機制來建立和更新現有的鏡像,用戶甚至能夠從網上下載一個已經作好的應用鏡像,並直接使用。

Docker 容器(Container)

  Docker 容器相似於一個輕量級的沙箱,Docker 利用容器來運行和隔離應用。容器是從鏡像建立的應用運行實例。能夠將其啓動、開始、中止、刪除,而這些容器都是彼此相互隔離的、互不相見的。

  能夠把容器看作是一個簡易版的Linux系統環境(包括root用戶權限、進程空間、用戶空間和網絡空間等)以及運行在其中的應用程序打包而成的盒子

Docker 倉庫(Repository)

  Docker 倉庫相似於代碼倉庫,它是Docker集中存放鏡像文件的場所。

  倉庫註冊服務器是存放倉庫的地方,其上每每存放着多個地方。每一個倉庫集中存放某一類鏡像,每每包括多個鏡像文件,經過不一樣的標籤(tag)來進行區分。一個倉庫會包含同一個軟件不一樣版本的鏡像,而標籤就經常使用於對應改軟件的各個版本。咱們能夠經過 <倉庫名>:<標籤>的格式來指定具體是這個軟件哪一個版本的鏡像。若是不給出標籤,將以 latest 做爲默認標籤。以Nginx鏡像爲例,nginx 是倉庫的名字,其內包含有不一樣的版本標籤,如,1.12.2,咱們能夠經過 nginx:1.12.2來指定須要哪一個版本的鏡像。若是忽略了標籤,好比nginx ,那將視爲 nginx:latest。

  Docker 倉庫能夠分爲公開倉庫(Public)和私有倉庫(Private)兩種形式。目前最大的公開倉庫是Docker Hub, 存放了數量龐大的鏡像供用戶下載。國內還有(時速雲、阿里雲)等公開倉庫。

    當用戶不但願公開本身的鏡像文件,Docker 也支持用戶在本地網絡內建立一個只能本身訪問的私有倉庫。當用戶建立了本身的鏡像以後就可使用push命令將其上傳到指定的公有或者私有倉庫。這樣下次在另一臺機器上使用該鏡像時,只須要將其從倉庫上pull 下來就能夠了。

Docker 實戰

Docker安裝

系統要求

Docker 對CentOS的版本:
CentOS 764-bit)
CentOS 6.564-bit)或者更高的版本
前提條件:
Docker 運行在CentOS 7 上,要求系統爲64位、系統內核爲3.10以上
Docker 運行在CentOS-6.5 或更高的版本的 CentOS 上,要求系統爲64位、系統內核版本爲2.6.32-431 或者更高版本。
[root@server ~]# cat /etc/redhat-release     # 查看系統版本號
CentOS Linux release 7.3.1611 (Core)
 
[root@server ~]# uname -r        # 查看內核
3.10.0-514.el7.x86_64

ps:使用yum直接安裝的是docker version 1.13.1

[root@server ~]# yum -y install docker        # 安裝Docker(CentOS7系統CentOS-Extras庫中已帶Docker)
[root@server ~]# systemctl start docker        # 啓動Docker
[root@server ~]# systemctl enable docker    # 加入開機自啓動

yum安裝高版本

[root@server ~]# vim /etc/yum.repos.d/docker-ce.repo    # 配置yum源
[root@server ~]# yum -y install docker-ce         # 安裝docker
[root@server ~]# systemctl start docker        # 啓動Docker
[root@server ~]# systemctl enable docker       # 加入開機自啓動
[docker-ce-stable]
name=Docker CE Stable - $basearch
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/$basearch/stable
enabled=1
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-stable-debuginfo]
name=Docker CE Stable - Debuginfo $basearch
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/debug-$basearch/stable
enabled=0
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-stable-source]
name=Docker CE Stable - Sources
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/source/stable
enabled=0
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-edge]
name=Docker CE Edge - $basearch
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/$basearch/edge
enabled=0
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-edge-debuginfo]
name=Docker CE Edge - Debuginfo $basearch
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/debug-$basearch/edge
enabled=0
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-edge-source]
name=Docker CE Edge - Sources
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/source/edge
enabled=0
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-test]
name=Docker CE Test - $basearch
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/$basearch/test
enabled=0
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-test-debuginfo]
name=Docker CE Test - Debuginfo $basearch
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/debug-$basearch/test
enabled=0
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-test-source]
name=Docker CE Test - Sources
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/source/test
enabled=0
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-nightly]
name=Docker CE Nightly - $basearch
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/$basearch/nightly
enabled=0
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-nightly-debuginfo]
name=Docker CE Nightly - Debuginfo $basearch
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/debug-$basearch/nightly
enabled=0
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/gpg

[docker-ce-nightly-source]
name=Docker CE Nightly - Sources
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/source/nightly
enabled=0
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/gpg
docker-re.repo
[root@server ~]# docker version        # 查看docker版本信息
Client:    # docker客戶端版本信息
 Version:           18.09.0
 API version:       1.39
 Go version:        go1.10.4
 Git commit:        4d60db4
 Built:             Wed Nov  7 00:48:22 2018
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:    # docker服務端版本信息
  Version:          18.09.0
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.4
  Git commit:       4d60db4
  Built:            Wed Nov  7 00:19:08 2018
  OS/Arch:          linux/amd64
  Experimental:     false

centos6.x安裝:

[root@linux ~]# cat /etc/redhat-release 
CentOS release 6.9 (Final)
[root@linux ~]# uname -r
2.6.32-696.el6.x86_64

[root@linux ~]# wget https://yum.dockerproject.org/repo/main/centos/6/Packages/docker-engine-1.7.0-1.el6.x86_64.rpm     #下載軟件包

[root@linux ~]# yum -y install docker-engine-1.7.0-1.el6.x86_64.rpm     #安裝   

Docker 基礎命令

[root@docker ~]# docker --help
Usage:
docker [OPTIONS] COMMAND [arg...]
       docker daemon [ --help | ... ]
       docker [ --help | -v | --version ]

A
self-sufficient runtime for containers.

Options:
      --config string      Location of client config files (default "/root/.docker")    #客戶端配置文件的位置 -D, --debug=false               Enable debug mode  #啓用Debug調試模式 -H, --host=[]                   Daemon socket(s) to connect to  #守護進程的套接字(Socket)鏈接 -h, --help=false                Print usage  #打印使用 -l, --log-level string   Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")    #設置日誌級別 --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default "/root/.docker/ca.pem")    #信任證書籤名CA --tlscert string     Path to TLS certificate file (default "/root/.docker/cert.pem")    #TLS證書文件路徑 --tlskey string      Path to TLS key file (default "/root/.docker/key.pem")    #TLS密鑰文件路徑 --tlsverify          Use TLS and verify the remote    #使用TLS驗證遠程 -v, --version            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 鏡像管理

搜索鏡像 docker search

[root@server ~]# docker search centos   #搜索全部的centos的docker鏡像
NAME(名稱)                          DESCRIPTION(描述)                               STARS(下載次數)       OFFICIAL(官方)       AUTOMATED(自動化)
centos                             The official build of CentOS.                   5091                [OK]                
ansible/centos7-ansible            Ansible on Centos7                              119                                     [OK]
docker search 參數說明:
--automated=true I false:僅顯示自動建立的鏡像,默認爲否; 
--no-trunc=true | false:輸出信息不截斷顯示,默認爲否;
-s,--stars=X:指定僅顯示評價爲指定星級以上的鏡像,默認爲 0,即輸出全部鏡像。
例如,搜索全部自動建立的評價爲 3+的帶 nginx 關鍵字的鏡像,以下所示:

[root@server ~]# docker search --automated -s 3 nginx 
docker search 其它用法

獲取鏡像 docker pull

鏡像是運行容器的前提,官方的Docker Hub 網站已經提供了數十萬個鏡像供咱們下載。可使用Docker  pull 從鏡像倉庫拉取鏡像

docker pull 

docker    pull    [選項]    [Docker    Registry地址]<倉庫名>:<標籤>
[root@server ~]# docker pull centos  #獲取centos鏡像
Using default tag: latest
latest: Pulling from library/centos
a02a4930cb5d: Pull complete 
Digest: sha256:184e5f35598e333bfa7de10d8fb1cebb5ee4df5bc0f970bf2b1e7c7345136426
Status: Downloaded newer image for centos:latest
# 新版本獲取鏡像
[root@server ~]# docker image pull nginx:1.11

查看鏡像 docker images

[root@server ~]# docker images  #查看docker鏡像
REPOSITORY(來自哪一個倉庫)   TAG(標籤)           IMAGE ID(惟一ID)    CREATED(建立時間)     SIZE(大小)
nginx                    latest              7042885a156a        7 days ago          109MB
centos                   latest              1e1148e4cc2c        4 weeks ago         202MB
# 新版本查看鏡像
[root@server ~]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              7042885a156a        7 days ago          109MB
centos              latest              1e1148e4cc2c        4 weeks ago         202MB

列表包括了倉庫名、標籤、鏡像ID、建立時間以及所佔用的空間。

鏡像ID則是鏡像的惟一標識,一個鏡像能夠對應多個標籤。

刪除鏡像 docker rmi 

docker    rmi    [選項]    <鏡像1>    [<鏡像2>    ...]

使用docker rmi 刪除本地鏡像,後面能夠跟鏡像ID或者標籤。(刪除鏡像以前先用docker rm 刪除依賴於這個鏡像的全部容器)。注意docker rm 命令是移除容器。

[root@server ~]# docker rmi imageID/imageName/  # 刪除docker鏡像

導出鏡像 docker save

若是要導出鏡像到本地,提供給另一臺機使用,可使用docker save 或者docker image save 命令。

[root@server ~]# docker save centos > /tmp/docker_centos.tar    #導出docker鏡像到本地
[root@server ~]# ll /tmp/docker_centos.tar 
-rw-r--r-- 1 root root 210186752 1月   5 16:05 /tmp/docker_centos.tar

# 新版本也可用下面這種方法
[root@server ~]# docker image save nginx > /tmp/docker_nginx.tar    #導出docker鏡像到本地
[root@server ~]# ll /tmp/docker_nginx.tar 
-rw-r--r-- 1 root root 190512640 1月   5 16:06 /tmp/docker_nginx.tar

導入鏡像 docker load

從本地文件中導入docker鏡像庫

[root@server ~]# docker load < /tmp/docker_centos.tar    #導入本地鏡像到docker鏡像庫
[root@server ~]# docker image load < /tmp/docker_nginx.tar  #新版本也能夠用這種方法導入
[root@server ~]# docker image ls  #查看導入的狀況
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        4 weeks ago         202MB
nginx               1.11                5766334bdaa0        21 months ago       183MB

給鏡像打標籤 docker tag

利用docker tag能夠給鏡像添加一個新的標籤,docker tag 原標籤 新標籤

[root@server ~]# docker image ls    #打標籤前查看
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        4 weeks ago         202MB
nginx               1.11                5766334bdaa0        21 months ago       183MB
[root@server ~]# docker tag centos centos:7.2    #給centos打一個新的標籤
[root@server ~]# docker image tag nginx:1.11 nginx:1.12    #給nginx打一個新的標籤
[root@server ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              7.2                 1e1148e4cc2c        4 weeks ago         202MB
centos              latest              1e1148e4cc2c        4 weeks ago         202MB
nginx               1.11                5766334bdaa0        21 months ago       183MB
nginx               1.12                5766334bdaa0        21 months ago       183MB

Docker 容器管理

啓動容器 

啓動容器有兩種方式,一種是基於鏡像新建一個容器並啓動,另一種是將在終止狀態(stopped)的容器從新啓動。

由於Docker的容器實在過輕量級了,不少時候用戶都是隨時刪除和新建立容器。因此主要命令仍是docker run

新建容器 docker create

[root@server ~]# docker create -it centos /bin/bash     #建立一個容器
a661c9dd447066f326e13389b4e11222f1430e1cbd56ef4c38416fdd51b1394e
[root@server ~]# docker ps -a  #查看容器狀態,能夠看到經過create建立的容器處於中止狀態
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
a661c9dd4470        centos              "/bin/bash"         39 seconds ago      Created                                 angry_wu
[root@server ~]# docker start a661c9dd4470    #根據ID啓動上面建立的容器
a661c9dd4470
[root@server ~]# docker ps -a  #查看容器狀態,處於運行狀態
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
a661c9dd4470        centos              "/bin/bash"         About a minute ago   Up 3 seconds                            angry_wu
[root@server ~]# docker attach a661c9dd4470    #根據ID進入到啓動的容器中
[root@a661c9dd4470 /]# ls    
anaconda-post.log  bin  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@a661c9dd4470 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 08:35 pts/0    00:00:00 /bin/bash
root        15     1  0 08:38 pts/0    00:00:00 ps -ef
[root@a661c9dd4470 /]# exit    #退出容器
exit
[root@server ~]# 

新建容器並啓動 docker run

-i, --interactive 交互式
-t, --tty 分配一個僞終端
-d, --detach 運行容器到後臺
-a, --attach list 附加到運行的容器
--dns list 設置DNS服務器
-e, --env list 設置環境變量
--env-file list 從文件讀取環境變量
-p, --publish list 發佈容器端口到主機
-P, --publish-all 發佈容器全部EXPOSE的端口到宿主機隨機端口
-h, --hostname string 設置容器主機名
--ip string 指定容器IP,只能用於自定義網絡
--link list 添加鏈接到另外一個容器
--network 鏈接容器到一個網絡
--mount mount 掛載宿主機分區到容器
-v, --volume list 掛載宿主機目錄到容器
--restart string,容器退出時重啓策略,默認no [always|on-failure]
--add-host list 添加其餘主機到容器中/etc/hosts
-m,--memory 容器可使用的最大內存量
--memory-swap 容許交換到磁盤的內存量--memory-swappiness=<0-100> 容器使用SWAP分區交換的百分比(0-100,默認爲-1--memory-reservation 內存軟限制,Docker檢測主機容器爭用或內存不足時所激活的軟 限制,使用此選項,值必須設置低於—memory,以使其優先
--oom-kill-disable當宿主機內存不足時,內核會殺死容器中的進程。建議設置了memory選項再禁用OOM。若是沒有設置,主機可能會耗盡內存
--cpus 限制容器可使用多少可用的CPU資源
--cpuset-cpus 限制容器可使用特定的CPU
--cpu-shares  此值設置爲大於或小於默認1024值,以增長或減小容器的權重, 並使其能夠訪問主機CPU週期的更大或更小比例
docker run 建立容器經常使用選項

 

例如,下面的命令輸出一個「Hello World」,以後容器自動終止。

[root@server ~]# docker run centos /bin/echo "Hello World"    #這跟在本地直接運行/bin/echo "Hello World" 幾乎感受不出任何差異
Hello World

啓動一個bash終端,容許用戶進行交互

[root@server ~]# docker run --name mydocker -t -i centos /bin/bash
[root@8bad1a6db7b2 /]# pwd
/
[root@8bad1a6db7b2 /]# ls
anaconda-post.log  bin  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

--name: 給容器定義一個名稱
-t:讓Docker分配一個僞終端並綁定到容器的標準輸入上
-i:讓容器的標準輸入保持打開
/bin/bash:執行一個命令

當利用docker run 來建立容器時,Docker在後臺運行的標準操做包括:

 檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載;
 利用鏡像建立一個容器,並啓動該容器;
 分配一個文件系統給容器,並在只讀的鏡像層外面掛載一層可讀寫層;
 從宿主主機配置的網橋接口中橋接一個虛擬接口到容器中;
 從網橋的地址池配置一個 IP 地址給容器;
 執行用戶指定的應用程序;
 執行完畢後容器被自動終止。

啓動已終止的容器 docker start

容器的核心爲所執行的應用程序,所須要的資源都是應用程序運行所必需的。除此以外,並無其餘的資源。能夠在僞終端利用 ps 或 top 來查看進程信息

docker ps -a  能夠查看全部容器的狀況,docker ps 查看已啓動容器的狀況

[root@server ~]# docker ps -a   #查看全部的容器
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                          PORTS               NAMES
8bad1a6db7b2        centos              "/bin/bash"              8 minutes ago       Exited (0) About a minute ago                       mydocker
4d18a48ee315        centos              "/bin/bash"              9 minutes ago       Exited (0) 9 minutes ago                            amazing_herschel
b3918347393a        centos              "/bin/echo 'Hello Wo…"   12 minutes ago      Exited (0) 12 minutes ago                           competent_lovelace
a661c9dd4470        centos              "/bin/bash"              24 minutes ago      Exited (0) 20 minutes ago                           angry_wu
[root@server ~]# docker start 8bad1a6db7b2   #啓動一個終止的容器
8bad1a6db7b2
[root@server ~]# docker ps  #查看已經啓動的容器
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
8bad1a6db7b2        centos              "/bin/bash"         8 minutes ago       Up 4 seconds                            mydocker

守護進程運行(後臺運行)

更多的時候,須要讓Docker容器在後臺運行,而不是直接把執行命令的結果輸出在當前宿主機下。此時能夠加 -d 參數來實現。

例以下面的命令會在後臺運行容器:

[root@server ~]# docker run -d centos /bin/bash -c "while true; do echo hello world; sleep 1; done" 
0ca1770a1fd0b21ae05f2f6bd9befbb9eef55576ab0a0b51fc6dc7e427128174
[root@server ~]# docker ps  #查看正在運行的docker容器
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
0ca1770a1fd0        centos              "/bin/bash -c 'while…"   27 seconds ago      Up 25 seconds                           ecstatic_wu
8bad1a6db7b2        centos              "/bin/bash"              18 minutes ago      Up 10 minutes                           mydocker
[root@server ~]# docker logs 0ca1770a1fd0  #獲取容器輸出信息,經過docker logs命令
hello world
hello world
hello world

中止容器

可使用 docker stop 來終止一個正在運行的容器。

此外,當Docker容器中指定的應用終結時,容器也會自動終結,例如啓動一個終端容器,用戶經過exit命令或者Ctrl+d 來退出終端時,所建立的容器馬上終止。

終止狀態的容器能夠用 docker ps -a 命令看到,也能夠經過 docker start 命令來從新啓動

[root@server ~]# docker ps -a   #查看全部的容器
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
0ca1770a1fd0        centos              "/bin/bash -c 'while…"   8 minutes ago       Up 7 minutes                                    ecstatic_wu
8bad1a6db7b2        centos              "/bin/bash"              26 minutes ago      Up 17 minutes                                   mydocker
[root@server ~]# docker stop 8bad1a6db7b2   #中止容器
8bad1a6db7b2
[root@server ~]# docker stop 0ca1770a1fd0   #中止容器
0ca1770a1fd0
[root@server ~]# docker ps -a 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                        PORTS               NAMES
0ca1770a1fd0        centos              "/bin/bash -c 'while…"   8 minutes ago       Exited (137) 3 seconds ago                        ecstatic_wu
8bad1a6db7b2        centos              "/bin/bash"              27 minutes ago      Exited (137) 26 seconds ago                       mydocker

進入容器

在使用 -d 參數時,容器啓動後會進入後臺,某些時候須要進入容器進行操做,有不少種房,包括 docker attach 命令 或者 nsenter 工具 或者 docker exec命令等。

attach 命令

docker attach 是Docker自帶的命令,示例:

[root@server ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                       PORTS               NAMES
8bad1a6db7b2        centos              "/bin/bash"              32 minutes ago      Exited (137) 5 minutes ago                       mydocker
[root@server ~]# docker start mydocker  #啓動已經中止的容器,start能夠跟容器ID,也能夠是名字
mydocker
[root@server ~]# docker attach mydocker  #經過docker attach進入容器
[root@8bad1a6db7b2 /]# 

可是使用attach命令有時候並不方便,當多個窗口同時 attach 到同一個容器的時候,全部窗口都會同步顯示,當某個窗口因命令阻塞,其餘窗口也沒法執行操做了。且經過exit退出後容器就自動終止了。

nsenter 命令

nsenter 啓動一個新的shell進程(默認是/bin/bash),同時會把這個新進程切換到和目標(target)進程相同的命名空間,這樣就至關於進入了容器內部。nsenter 要正常工做須要root 權限。

[root@server ~]# yum install -y util-linux  #centos自帶yum源有,直接安裝便可
[root@server ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                         PORTS               NAMES
8bad1a6db7b2        centos              "/bin/bash"              43 minutes ago      Exited (0) 3 minutes ago                           mydocker
[root@server ~]# docker start mydocker  #啓動已經關閉的容器
mydocker
[root@server ~]# docker inspect -f "{{.State.Pid}}" 8bad1a6db7b2  #找到容器的第一個進程ID,說明:後面跟容器ID,容器名字均可以
21176
[root@server ~]# nsenter -t 21176 -m -u -i -n -p  #經過這個PID鏈接到容器
[root@8bad1a6db7b2 /]# ls
anaconda-post.log  bin  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@8bad1a6db7b2 /]# pwd
/
[root@8bad1a6db7b2 /]# exit
logout
[root@server ~]# docker ps  #經過nsenter進入後再退出,咱們能夠看到容器仍是處於後臺運行中
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
8bad1a6db7b2        centos              "/bin/bash"         About an hour ago   Up 4 minutes                            mydocker

因爲上面兩條命令都太長,不方便,因此咱們編寫一個腳本進入,只需在腳本後面跟容器ID或者容器名字便可

[root@server ~]# cat in_docker.sh 
#!/bin/bash # Use nsenter to access docker

docker_in() { NAME_ID=$1
    PID=$(docker inspect -f "{{.State.Pid}}" $NAME_ID)
    nsenter -t $PID -m -u -i -n -p
}

docker_in $1
[root@server ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
8bad1a6db7b2        centos              "/bin/bash"         About an hour ago   Up 10 minutes                           mydocker
[root@server ~]# ./in_docker.sh mydocker    #執行腳本加上容器ID快速進入
[root@8bad1a6db7b2 /]# 

exec 命令

exec 能夠在容器內直接執行任意命令,此處咱們也可使用它進入到容器裏面

[root@server ~]# docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
8bad1a6db7b2        centos              "/bin/bash"         About an hour ago   Up 13 minutes                           mydocker
[root@server ~]# docker exec -it mydocker /bin/bash
[root@8bad1a6db7b2 /]# exit
exit
[root@server ~]# docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
8bad1a6db7b2        centos              "/bin/bash"         About an hour ago   Up 14 minutes                           mydocker

導出和導入容器

某些時候,須要將容器從一個系統遷移到另一個系統,此時可使用Docker的導入和導出功能。這也是Docker 自身提供的一個重要特性

導出容器

若是要導出本地某個容器,可使用 docker export 命令,導出容器是指導出一個已經建立的容器到一個文件,無論此時這個容器是否處於運行狀態。export後面跟須要導出的 容器ID 或者 容器名字 均可以

[root@server ~]# docker export mydocker > centos.tar  #導出一個容器,也可使用docker export -o centos.tar mydocker。 -o 指定導出的名字
[root@server ~]# ll centos.tar 
-rw-r--r-- 1 root root 209473024 1月   5 17:56 centos.tar

導入容器

導出的文件又可使用 docker import 命令導入變成鏡像,例如

[root@server ~]# cat centos.tar | docker import - test/centos:7.3
sha256:a8375a86d721a718d70dc99a49005d70ce6a7b65423c1bbd1ce34b23ec787aa9
[root@server ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
test/centos         7.3                 a8375a86d721        7 seconds ago       202MB

刪除容器

可使用 docker rm 來刪除一個處於終止狀態的容器。例如

[root@server ~]# docker ps -a   #查看全部容器當前狀態
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                           PORTS               NAMES
0ca1770a1fd0        centos              "/bin/bash -c 'while…"   About an hour ago   Exited (137) About an hour ago                       ecstatic_wu
a661c9dd4470        centos              "/bin/bash"              2 hours ago         Exited (0) 2 hours ago                               angry_wu
[root@server ~]# docker rm a661c9dd4470   #刪除已經中止的容器
a661c9dd4470

若是要刪除一個運行中的容器,能夠添加 -f 參數。 Docker會發送 STGKILL信號給容器,再進行刪除。

清理全部處於終止狀態的的容器(慎用)

[root@server ~]# docker ps -a   
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                           PORTS               NAMES
0ca1770a1fd0        centos              "/bin/bash -c 'while…"   About an hour ago   Exited (137) About an hour ago                       ecstatic_wu
4d18a48ee315        centos              "/bin/bash"              About an hour ago   Exited (0) About an hour ago                         amazing_herschel
b3918347393a        centos              "/bin/echo 'Hello Wo…"   About an hour ago   Exited (0) About an hour ago                         competent_lovelace
[root@server ~]# docker rm $(docker ps -a -q)   # 獲取所有容器的ID,進行刪除 
0ca1770a1fd0
4d18a48ee315
b3918347393a
[root@server ~]# docker ps -a 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@server ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

Docker 數據管理

Docker 容器中管理數據主要有兩種方式:

  • 數據卷(Data volumes)
  • 數據卷容器(Data volumes containers)

數據卷

數據卷是一個可供一個或者多個容器使用的特殊目錄,它繞過UFS,能夠提供不少有用的特性:

  • 數據卷能夠在容器之間共享和重用
  • 對數據卷的修改會立馬生效
  • 對數據卷的更新,不會影響鏡像
  • 數據卷默認會一直存在,即時容器被刪除

管理卷 docker volume:

[root@server ~]# docker volume create myvolume  #建立一個數據卷
myvolume
[root@server ~]# docker volume inspect myvolume  #查看數據卷的信息
[
    {
        "CreatedAt": "2019-01-05T22:45:46+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/myvolume/_data",  #能夠看到數據卷建立在宿主機的/var/lib/docker/volume目錄下 "Name": "myvolume",
        "Options": {},
        "Scope": "local"
    }
]
[root@server ~]# docker volume ls  #查看數據卷列表
DRIVER              VOLUME NAME
local               myvolume

用卷建立一個容器:

[root@server ~]# docker run -d -it --name myCentos --mount src=myvolume,dst=/data centos  #建立一個myCentos容器,並將myvolume數據卷掛載到myCentos容器的/data目錄
[root@server ~]# docker exec -it myCentos /bin/bash  #進入容器
[root@8f3094a730af /]# ls /data  #查看目錄爲空
[root@8f3094a730af /]# ls /data  #當在另一個終端建立文件後再次進行查看有文件
test.txt
[root@8f3094a730af /]# cat /data/test.txt   #查看文件內容
hello world
[root@server
~]# cd /var/lib/docker/volumes/myvolume/_data  #在另一個終端進入到數據目錄裏面 [root@server _data]# echo "hello world" >> test.txt    #在數據目錄建立一個文件

src:數據卷名字
dst:須要掛載的目錄路徑
注意:若是沒有指定卷,則自動建立。

 此時開啓另一個終端再次建立一個容器,而且掛載一樣的數據卷,能夠發現這種方式能夠在容器之間共享和重用

[root@server ~]# docker run -d -it --name myCentos01 --mount src=myvolume,dst=/data centos  #新開一個終端建立新的一個容器,掛載一樣的數據卷
[root@server ~]# docker exec -it myCentos01 /bin/bash
[root@45c3ca27ddad /]# ls /data/  
test.txt

 上面建立容器並掛載數據卷,還可使用下面這種方法 -v 數據卷名字:掛載路徑,Docker掛載數據卷默認權限是讀寫,也能夠經過 :ro 指定爲只讀。

[root@server ~]# docker run -d -it --name myCentos02 -v  myvolume:/test:ro centos  #建立一個myCentos02的容器,並將數據卷myvolume掛載到容器的/test目錄,而且爲只讀模式
[root@server ~]# docker exec -it myCentos02 /bin/bash
[root@784f03496b07 /]# ls /test
test.txt

刪除數據卷

Docker 不會在容器被刪除後自動刪除數據卷。且若是要刪除數據卷,必須先將使用數據卷的容器中止,刪除後,才能刪除數據卷

[root@server ~]# docker rm myCentos myCentos01 myCentos02  #刪除容器
myCentos
myCentos01
myCentos02
[root@server ~]# docker volume rm myvolume  #刪除數據卷
myvolume

掛載一個主機目錄做爲數據卷

使用 -v 參數也能夠指定掛載一個本地主機的目錄到容器中

[root@server ~]# docker run -d -ti --name web -v /webapp:/opt/webapp centos  #建立一個名字叫web的容器,而且將宿主機的/webapp目錄 掛載到容器的/opt/webapp目錄
[root@server ~]# ls /webapp/  #查看宿主機的目錄,若是沒有該目錄,會自動建立
[root@server ~]# echo "hello" >> /webapp/index.html  #追加一個文件進去
[root@server ~]# docker exec -ti web /bin/bash   #進入容器
[root@16c66fe42017 /]# cat /opt/webapp/index.html   #查看容器/opt/webapp目錄下的數據
hello

掛載一個宿主機文件做爲數據卷

-v 參數也能夠從主機掛載單個文件到容器中

[root@server ~]# docker run --rm -it -v ~/.bash_history:/.bash_history centos /bin/bash  #建立一個容器,並將宿主機的~./bash_history文件掛載到容器的/.bash_history文件
--rm:建立容器時若是帶上--rm表示容器終止時自動刪除

數據卷容器

若是有一些持續更新的數據須要在容器之間共享,最好建立數據卷容器。

數據卷容器其實就是一個正常的容器,專門用來提供數據卷供其它容器掛載的。

[root@server ~]# docker run -d -v /dbdata --name dbdata centos  #建立一個數據卷容器

[root@server ~]# docker run -d -it --volumes-from dbdata --name db1 centos  #建立一個db1容器, 使用 --volumes-from 來掛載 dbdata 容器中的數據卷
[root@server ~]# docker exec -it db1  /bin/bash  #進入db1容器中
[root@1863842f0c16 /]# ls  #查看已成功掛載dbdata數據卷
anaconda-post.log  dbdata  etc   lib    media  opt   root  sbin  sys  usr
bin                dev     home  lib64  mnt    proc  run   srv   tmp  var
[root@1863842f0c16 /]# touch dbdata/file1  #在dbdata目錄中建立一個文件
[root@server
~]# docker run -d -it --volumes-from dbdata --name db2 centos  #再建立一個db2容器,使用 --volumes-from 來掛載 dbdata 容器中的數據卷 [root@server ~]# docker exec -it db2 /bin/bash  #進入db2容器中 [root@0fca0699a7c7 /]# ls  #查看也成功掛載dbdata數據卷 anaconda-post.log dbdata etc lib media opt root sbin sys usr bin dev home lib64 mnt proc run srv tmp var [root@0fca0699a7c7 /]# ls dbdata/  #而且還查看到了db1容器建立的file1文件,說明容器之間的數據共享了 file1

從上面能夠看出可使用超過一個 --volumes-from 參數來指定從多個容器掛載不一樣的數據卷,也能夠從其餘已經掛載了數據卷的容器來級聯掛載數據卷,示例:

[root@server ~]# docker run -d -ti --name db3 --volumes-from db1 centos  #建立一個db3容器,經過 --volumes-from 級聯掛載上面的db1容器
[root@server ~]# docker exec -it db3 /bin/bash  #進入db3容器中
[root@1d2d8c30fccf /]# ls  #查看也有dbdata目錄
anaconda-post.log  dbdata  etc   lib    media  opt   root  sbin  sys  usr
bin                dev     home  lib64  mnt    proc  run   srv   tmp  var
[root@1d2d8c30fccf /]# ls dbdata/  #查看目錄,一樣有文件
file1

注意:使用 --volumes-from 參數所掛載數據卷的容器本身並須要保持在運行狀態。若是刪除了掛載的容器(包括dbdata、db1和db2),數據卷也不會被自動刪除。若是要刪除一個數據卷,必須在刪除最後一個還掛載着它的容器時使用 docker rm -v 命令來指定同時刪除關聯的容器。

Docker 網絡管理

Docker 容許經過外部訪問容器或容器互聯的方式來提供網絡服務。

外部訪問容器

容器中能夠運行一些網絡應用,好比(nginx,apache,php等),要讓外部訪問這些應用能夠經過 -P 或者 -p 參數來制定端口映射

使用 -P 參數時,Docker 會隨機映射一個 端口到內部容器開放的網絡端口。

[root@server ~]# docker run -d -P --name myNginx nginx:1.11  #建立一個容器,並經過-P隨機映射端口到容器的網絡端口
[root@server ~]# docker ps  #查看容器信息,能夠發現宿主機的32769端口映射到容器的80端口了,以及32768映射至443端口
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                           NAMES
5ee2527dd496        nginx:1.11          "nginx -g 'daemon of…"   42 seconds ago      Up 40 seconds       0.0.0.0:32769->80/tcp, 0.0.0.0:32768->443/tcp   myNginx
[root@server ~]# curl localhost:32769  #訪問宿主機的32769便能訪問到容器
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

一樣,能夠經過 docker logs 命令查看應用的信息, -f 參數 動態查看

[root@server ~]# docker logs -f myNginx
172.17.0.1 - - [06/Jan/2019:02:25:17 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
172.17.0.1 - - [06/Jan/2019:02:38:04 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"

-p (小寫的)則能夠指定要映射的端口,而且,在一個指定端口上只能夠綁定一個容器。格式有:

ip:hostPort:containerPort     | ip::containerPort    | hostPort:containerPort

映射全部的接口地址

[root@server ~]# docker run -d -p 88:80 --name myNginx01 nginx:1.11  #使用hostPort:containerPort 格式宿主機的88端口映射到容器的80端口,默認會綁定宿主機全部接口上的全部地址
[root@server ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                           NAMES
fab763a9ec68        nginx:1.11          "nginx -g 'daemon of…"   50 seconds ago      Up 48 seconds       443/tcp, 0.0.0.0:88->80/tcp                     myNginx01

映射到指定地址的指定端口

[root@server ~]# docker run -d -p 127.0.0.1:89:80 --name myNginx02 nginx:1.11  #使用ip:hostPort:containerPort 格式指定映射使用一個特定地址,如localhost地址127.0.0.1
913f0cad940155978825b40f8e4c2bf23a4872bbd06e441ced4b8043b72c683e
[root@server ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                           NAMES
913f0cad9401        nginx:1.11          "nginx -g 'daemon of…"   6 seconds ago       Up 5 seconds        443/tcp, 127.0.0.1:89->80/tcp                   myNginx02

映射到指定地址的任意端口

[root@server ~]# docker run -d -p 127.0.0.1::80 --name myNginx03 nginx:1.11  #使用ip:containerPort 綁定localhost的任意端口到容器的80端口,宿主機會自動分配一個端口
[root@server ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                           NAMES
16b17ccf83cf        nginx:1.11          "nginx -g 'daemon of…"   4 seconds ago       Up 3 seconds        443/tcp, 127.0.0.1:32770->80/tcp                myNginx03

還可使用 udp 標記來指定 udp 端口

[root@server ~]# docker run -d -p 127.0.0.1:82:80/udp --name myNginx04 nginx:1.11  #將localhost的82端口映射到容器的80端口,並指定udp
[root@server ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                           NAMES
79d14927ef84        nginx:1.11          "nginx -g 'daemon of…"   4 seconds ago       Up 2 seconds        80/tcp, 443/tcp, 127.0.0.1:82->80/udp           myNginx04

查看映射端口配置

使用 docker port 查看當前映射的端口配置,也能夠查看到綁定的地址

[root@server ~]# docker port myNginx
443/tcp -> 0.0.0.0:32768
80/tcp -> 0.0.0.0:32769
[root@server ~]# docker port myNginx01
80/tcp -> 0.0.0.0:88

注意:

  • 容器有本身內部網絡地址和ip地址(使用 docker inspect 能夠獲取全部變量,Docker 還能夠有一個可變的網絡配置)
  • -p 標記能夠屢次使用來綁定多個端口

例如

[root@server ~]# docker run -d --name myNginx05 -p 8088:80 -p 8089:443 nginx:1.11  #將宿主機的8088和8089端口分別映射到容器的80/443端口
[root@server ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                           NAMES
f0f18691e88e        nginx:1.11          "nginx -g 'daemon of…"   4 seconds ago       Up 3 seconds        0.0.0.0:8088->80/tcp, 0.0.0.0:8089->443/tcp     myNginx05

容器互聯

容器的鏈接(linking)系統除了端口映射外,另外一種是容器中應用交互的方式。該系統會在源和接收容器之間建立一個隧道,接受容器能夠看到源容器指定的信息。

使用 --link 參數可讓容器之間安全的進行交互

[root@server ~]# docker run -e MYSQL_ROOT_PASSWORD=123456 -d --name myDB mysql  #先建立一個新的數據庫容器
[root@server ~]# docker run -d -P --name myWeb --link myDB:db nginx:1.11  #再建立一個web容器,並將它鏈接到 myDB 數據庫容器
[root@server ~]# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                           NAMES
28bcc258fc47        nginx:1.11          "nginx -g 'daemon of…"   37 seconds ago       Up 34 seconds       0.0.0.0:32771->80/tcp, 0.0.0.0:32770->443/tcp   myWeb
49a6b11e2178        mysql               "docker-entrypoint.s…"   About a minute ago   Up About a minute   3306/tcp, 33060/tcp                             myDB

此時,myDB 容器和 myWeb 容器創建互聯關係。

--link 參數的格式: --link name:alias
name:是要連接的容器的名稱,
alias:是這個連接的別名

Docker 在兩個互聯的容器之間建立了一個安全的隧道,並且不用映射它們的端口到宿主機上,在啓動myDB 容器時候沒有使用 -p 和 -P 參數,從而避免了暴露數據庫端口到外部網絡上。

Docker 經過2種方式爲容器公開鏈接信息:

  • 環境變量
  • 更新 /etc/hosts 文件

使用 env 命令能夠查看環境變量

[root@server ~]# docker run --rm --name myWeb1 --link myDB:DB nginx:1.11 env  #建立一個web容器鏈接到上面的myDB,查看web容器的環境變量...
DB_PORT=tcp://172.17.0.2:3306
DB_PORT_3306_TCP=tcp://172.17.0.2:3306  
DB_PORT_3306_TCP_ADDR=172.17.0.2
DB_PORT_3306_TCP_PORT=3306
DB_PORT_3306_TCP_PROTO=tcp
DB_PORT_33060_TCP=tcp://172.17.0.2:33060
DB_PORT_33060_TCP_ADDR=172.17.0.2
DB_PORT_33060_TCP_PORT=33060
DB_PORT_33060_TCP_PROTO=tcp
DB_NAME=/myWeb1/DB
DB_ENV_MYSQL_ROOT_PASSWORD=123456

其中DB_開頭的環境變量是供web容器鏈接 DB 容器使用的。能夠看到鏈接容器的協議,端口,密碼等

除了環境變量,Docker 還添加host信息到父容器的 /etc/hosts 的文件:

[root@server ~]# docker run --rm -ti --name myWeb2 --link myDB:DB nginx:1.11 /bin/bash  #建立一個web容器,一樣鏈接到myDB容器
root@9397b6ca77bd:/# cat /etc/hosts  #查看hosts文件信息 127.0.0.1    localhost
::1    localhost ip6-localhost ip6-loopback
fe00::0    ip6-localnet
ff00::0    ip6-mcastprefix
ff02::1    ip6-allnodes
ff02::2    ip6-allrouters
172.17.0.2    DB 49a6b11e2178 myDB
172.17.0.4    9397b6ca77bd
root@9397b6ca77bd:/# ping myDB
PING DB (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.142 ms

能夠看到這裏有2個hosts,第一個是 web 容器,web容器用id做爲他的主機名,第二個是 DB 容器的 ip 和主機名。能夠在web 容器中使用ping命令來測試跟 DB 容器的連通。

更多docker 高級網絡配置參考:https://www.cnblogs.com/yanjieli/articles/10229623.html

 

 

 

 

 

 

 

 

未完待續...

相關文章
相關標籤/搜索