前端之路:緊跟潮流,docker簡單應用

蟈蟈同志發表於2019-05-01

Docker

what is docker ?

  • 根據官網描述,docker 是一個容器平臺,是標準化的軟體單元,使用了虛擬化技術(cgroup:提供容器隔離;UnionFS:儲存映象並使容器變得短暫),基於Google推出的go語言實現的開源專案,程式碼在 GitHub 上進行維護。

why use docker ?

  • 快速交付和部署

    • 輕快:一次建立或配置,可在任意地方正常執行,秒級啟動,節約開發、測試、部署時間。
  • 高效虛擬化

    • 基於核心的虛擬化,不需要額外hypervisor支援,CPU/記憶體的低消耗,更高效。
  • 可移植、可擴充套件

    • 物理機、虛擬機器、公有云、私有云、個人電腦、伺服器等平臺均可以執行
  • 對比傳統虛擬機器

    特性 容器 虛擬機器
    啟動 秒級 分鐘級
    硬碟使用 一般MB 一般GB
    效能 接近原生 弱於原生
    系統支援量 單機上千個容器 一般幾十個

    compare

  • 可以總結出,docker可以實現:

    • 隔離應用依賴
    • 建立應用映象並進行復制
    • 建立易分發的即啟即用的應用
    • 允許例項簡單、快速擴充套件
    • 測試應用並隨後銷燬

可見docker的 野心 是建立 ===軟體程式可移植的輕量容器===,讓其可以在任何安裝了docker的機器上執行,而不用關心底層作業系統。

how to use docker ?

先了解一下幾個基本概念:

映象:是一個只讀的模版,用來建立docker容器,容器在啟動的時候建立一層可寫層作為最上層


容器:從映象建立的執行例項,可以被啟動、開始、停止、刪除。容器間是相互隔離的,看上去是一個簡易版的Linux環境(包括root使用者許可權、程式空間、使用者空間和網路空間等)和執行在其中的應用程式


倉庫:類似 git,集中存放映象檔案的場所,分為公開倉庫(Public)和私有倉庫(Private),最大的公開倉庫是 Docker Hub


註冊伺服器:類似GitHub 這樣的託管服務,存放著多個倉庫


宿主機:docker所在的伺服器


資料卷:可供一個或多個容器使用的特殊目錄,類似於 Linux 下對目錄或檔案進行 mount,它繞過 UFS,可以提供很多有用的特性:

  • 在容器之間共享和重用
  • 對資料卷的修改會立馬生效
  • 對資料卷的更新,不會影響映象
  • 卷會一直存在,直到沒有容器使用

網路模式:用來實現容器的網路通訊,大概包括五種:

  • bridge模式,--net=bridge(預設)
  • host模式,--net=host
  • none模式,--net=none
  • 其他容器模式(即container模式),--net=container:NAME_or_ID
  • 使用者自定義:docker 1.9版本以後新增的特性

瞭解更多


Dockerfile:易於自動化的命令,包含建立映象所需的全部指令,基於dockerfile中的指令,我們可以使用 $ docker build 命令來建立映象,通過減少映象和容器的建立過程來簡化部署。語法命令:

  • INSTRUCTION argument 指令不區分大小寫,但命名約定為全部大寫
  • FROM
    • 格式為 FROM <image>FROM <image>:<tag>
    • 第一條指令必須為 FROM 指令。並且,如果在同一個Dockerfile中建立多個映象時,可以使用多個 FROM 指令(每個映象一次)
  • MAINTAINER
    • 格式為 MAINTAINER <name>,指定維護者資訊
  • RUN
    • 格式為 RUN <command>RUN ["executable", "param1", "param2"]
    • 前者將在 shell 終端中執行命令,即 /bin/sh -c;後者則使用 exec 執行。指定使用其它終端可以通過第二種方式實現,例如 RUN ["/bin/bash", "-c", "echo hello"]
    • 每條 RUN 指令將在當前映象基礎上執行指定命令,並提交為新的映象。當命令較長時可以使用 \ 來換行
  • CMD
    • CMD ["executable","param1","param2"] 使用 exec 執行,推薦方式
    • CMD command param1 param2/bin/sh 中執行,提供給需要互動的應用
    • CMD ["param1","param2"] 提供給 ENTRYPOINT 的預設引數
    • 指定啟動容器時執行的命令,每個 Dockerfile 只能有一條 CMD 命令。如果指定了多條命令,只有最後一條會被執行
    • 如果使用者啟動容器時候指定了執行的命令,則會覆蓋掉 CMD 指定的命令
  • EXPOSE
    • 格式為 EXPOSE <port> [<port>...]
    • 告訴 Docker 服務端容器暴露的埠號,供互聯絡統使用。在啟動容器時需要通過 -P,Docker 主機會自動分配一個埠轉發到指定的埠
  • ENV
    • 格式為 ENV <key> <value>。 指定一個環境變數,會被後續 RUN 指令使用,並在容器執行時保持。
  • ADD
    • 格式為 ADD <src> <dest>
    • 該命令將複製指定的 <src> 到容器中的 <dest>。 其中 <src> 可以是Dockerfile所在目錄的一個相對路徑;也可以是一個 URL;還可以是一個 tar 檔案(自動解壓為目錄)
  • COPY
    • 格式為 COPY <src> <dest>
    • 複製本地主機的 <src>(為 Dockerfile 所在目錄的相對路徑)到容器中的 <dest>。當使用本地目錄為源目錄時,推薦使用 COPY,能用 COPY 的情況下不用 ADD
  • ENTRYPOINT
    • ENTRYPOINT ["executable", "param1", "param2"]
    • ENTRYPOINT command param1 param2(shell中執行)
    • 配置容器啟動後執行的命令,並且不可被 docker run 提供的引數覆蓋
    • 每個 Dockerfile 中只能有一個 ENTRYPOINT,當指定多個時,只有最後一個起效
  • VOLUME
    • 格式為 VOLUME ["/data"]
    • 建立一個可以從本地主機或其他容器掛載的掛載點,一般用來存放資料庫和需要保持的資料等
  • USER
    • 格式為 USER daemon
    • 指定執行容器時的使用者名稱或 UID,後續的 RUN 也會使用指定使用者
    • 當服務不需要管理員許可權時,可以通過該命令指定執行使用者。並且可以在之前建立所需要的使用者,例如:RUN groupadd -r postgres && useradd -r -g postgres postgres。要臨時獲取管理員許可權可以使用 gosu,而不推薦 sudo
  • WORKDIR
    • 格式為 WORKDIR /path/to/workdir

    • 為後續的 RUN、CMD、ENTRYPOINT 指令配置工作目錄

    • 可以使用多個 WORKDIR 指令,後續命令如果引數是相對路徑,則會基於之前命令指定的路徑。例如:

    • WORKDIR /a

    • WORKDIR b

    • WORKDIR c

      則最終路徑為 /a/b/c

  • ONBUILD
    • 格式為 ONBUILD [INSTRUCTION]

    • 配置當所建立的映象作為其它新建立映象的基礎映象時,所執行的操作指令

    • 例如,Dockerfile 使用如下的內容建立了映象 image-A

        [...]
        ONBUILD ADD . /app/src
        ONBUILD RUN /usr/local/bin/node-build --dir /app/src
        [...]
      複製程式碼

      如果基於 image-A 建立新的映象時,新的Dockerfile中使用 FROM image-A指定基礎映象時,會自動執行 ONBUILD 指令內容,等價於在後面新增了兩條指令:

        FROM image-A
      
        #Automatically run the following
        ADD . /app/src
        RUN /usr/local/bin/node-build --dir /app/src
      複製程式碼

      使用 ONBUILD 指令的映象,推薦在標籤中註明,例如 ruby:1.9-onbuild

編寫完成 Dockerfile 之後,可以通過 $ docker build 命令來建立映象

  • 基本的格式為 $ docker build [選項] 路徑,該命令將讀取指定路徑下(包括子目錄)的 Dockerfile,並將該路徑下所有內容傳送給 Docker 服務端,由服務端來建立映象。因此一般建議放置 Dockerfile 的目錄為空目錄。也可以通過 .dockerignore 檔案(每一行新增一條匹配模式)來讓 Docker 忽略路徑下的目錄和檔案
  • 例如:$ docker build -t ${dockerImageName} --force-rm -f ./Dockerfile .

=========================================================

以上是一些基本概念,現在ubuntu下開始安裝docker並啟動一個nginx容器(其實大多數場景下nginx沒必要跑在容器裡,這裡只是舉個例子)

=========================================================

$ cat /etc/issue
Ubuntu 16.04.6 LTS \n \l
複製程式碼
  1. 通過shell命令安裝:

    1. $ curl -sSL https://get.docker.com/ | sh
    2. 更多平臺及安裝方式
  2. 檢驗安裝,顯示版本資訊,說明已成功安裝:

    $ docker -v
    Docker version 18.09.5, build e8ff056
    複製程式碼

    ps:$ docker info可檢視更多資訊

  3. 下面開始建立一個容器:

     $ docker run❶ \
     -d❷ \
     --name=demo❸ \
     -u root❹ \
     -p 8002:80❺ \
     -v /var/demo:/var/demo❻ \
     nginx:latest❼
    複製程式碼

    該命令表示:基於nginx:latest這個映象,建立一個名稱為demo的容器,並把容器內部的80埠與宿主機上的8002埠做對映,使得通過宿主機8002埠的流量轉發到容器內部的80埠上

    ❶:run 新建並啟動容器,更多選項,其標準過程:

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

    ❷:-d Daemonized模式,以守護態形式在後臺執行容器


    ❸:--name=demo 為容器起一個名字


    ❹:-u 指定容器的使用者


    ❺:-p 埠對映,規則是 -p 宿主機埠:容器埠,可多次使用對映多個埠


    ❻:-v 掛載資料卷,規則是 -v 宿主機目錄:容器目錄,可多次使用掛載多個資料卷


    ❼:映象名,該容器所用的映象名,可通過 $ docker images 檢視本地映象

  4. 檢視正在執行的容器:

    $ docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                         NAMES
    c24cfee8226a        nginx:latest        "nginx -g 'daemon of…"   6 minutes ago       Up 6 minutes        0.0.0.0:8002->80/tcp          demo
    複製程式碼

    ps:$ docker ps -a檢視所有容器(包括正在執行的、已停止的)

    現在訪問宿主機的8002埠(安全組開通),即可看到nginx的歡迎頁面:

    nginx:welcom

  5. 進入容器:

    執行 $ docker exec -it demo bash ,demo也可以換成容器的id即:$ docker exec -it c24cfee8226a bash

    shell

    在容器內可執行 $ netstat -lntp 檢視埠使用情況:

     Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
     tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1/nginx: master pro
    複製程式碼

    若發現netstat not found,先執行 $ apt update && apt install net-tools

    執行 $ exit 退出容器

    ps:

    • $ docker inspect demo 可以檢視該容器更多資訊
    • $ docker stop 容器名/id 終止容器
    • $ docker rm 容器名/id 刪除未執行的容器
    • $ docker rmi 映象名/id 刪除未佔用(無容器正在執行)的映象
    • $ docker rmi $(docker images -f "dangling=true" -q) 批量刪除為 none(無容器正在執行)的映象

【參考】:

  1. www.kancloud.cn/kancloud/do…
  2. leilux.github.io/lou/docker_…
  3. docs.docker.com
  4. blog.csdn.net/ithaibianti…

===?? 文中不足,歡迎指正 ??===

最後:下一次講一下,基於docker,搭建ci(jenkins)構建部署前端專案

相關文章