ubuntu 16.04 (+) Docker 安裝——入門實戰

轉自:https://blog.csdn.net/bskfnvjtlyzmv867/article/details/81044217

簡介

Docker是一種新興的虛擬化技術,能夠一定程度上的代替傳統虛擬機。不過,Docker 跟傳統的虛擬化方式相比具有衆多的優勢。我也將Docker類比於Python虛擬環境,可以有效的配置各個版本的開發環境,比如深度學習與Java環境。

其他的Docker簡介也不需要過多介紹,可以參考很流行的《Docker — 從入門到實踐》。關於博客,文末列出了最近在掘金上看到的一些入門類型文章。

優勢

本人主要想用來配置開發環境,由於實驗室機器系統環境版本等衝突的問題。

先用一張Docker — 從入門到實踐裏的圖整體感受一下其獨特的優勢:

對比傳統虛擬機

由於本人才疏學淺,這裏便再節選一些原文中話具體描述Docker強大所在。個人感覺在入門完Docker再回頭重新認識一下下面所述的五個優勢相關解釋,會對Docker的認識有更深的理解。

  • 更高效的利用系統資源:由於容器不需要進行硬件虛擬以及運行完整操作系統等額外開銷,Docker 對系統資源的利用率更高。無論是應用執行速度、內存損耗或者文件存儲速度,都要比傳統虛擬機技術更高效。因此,相比虛擬機技術,一個相同配置的主機,往往可以運行更多數量的應用。
  • 更快速的啓動時間:傳統的虛擬機技術啓動應用服務往往需要數分鐘,而Docker 容器應用,由於直接運行於宿主內核,無需啓動完整的操作系統,因此可以做到秒級、甚至毫秒級的啓動時間。大大的節約了開發、測試、部署的時間。
  • 一致的運行環境:開發過程中一個常見的問題是環境一致性問題。由於開發環境、測試環境、生產環境不一
    致,導致有些bug 並未在開發過程中被發現。而Docker 的鏡像提供了除內核外完整的運行時環境,確保了應用運行環境一致性,從而不會再出現「這段代碼在我機器上沒問題啊」這類問題。
  • 持續交付和部署:Docker是build once,run everywhere. 使用Docker 可以通過定製應用鏡像來實現持續集成、持續交付、部署。開發人員可以通過Dockerfile 來進行鏡像構建,並結合持續集成(Continuous Integration) 系統進行集成測試,而運維人員則可以直接在生產環境中快速部署該鏡像,甚至結合持續部署(Continuous Delivery/Deployment) 系統進行自動部署。
  • 更輕鬆的遷移:Docker 使用的分層存儲以及鏡像的技術,使得應用重複部分的複用更爲容易,也使得應用的維護更新更加簡單,基於基礎鏡像進一步擴展鏡像也變得非常簡單。此外,Docker 團隊同各個開源項目團隊一起維護了一大批高質量的官方鏡像,既可以直接在生產環境使用,又可以作爲基礎進一步定製,大大的降低了應用服務的鏡像製作成本。使用Dockerfile 使鏡像構建透明化,不僅僅開發團隊可以理解應用運行環境,也方便運維團隊理解應用運行所需條件,幫助更好的生產環境中部署該鏡像。

II. Docker中基本概念

鏡像(Image)

鏡像,從認識上簡單的來說,就是面向對象中的類,相當於一個模板。從本質上來說,鏡像相當於一個文件系統。Docker 鏡像是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些爲運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。鏡像不包含任何動態數據,其內容在構建之後也不會被改變。

容器(Container)

容器,從認識上來說,就是類創建的實例,就是依據鏡像這個模板創建出來的實體。容器的實質是進程,但與直接在宿主執行的進程不同,容器進程運行於屬於自己的獨立的命名空間。因此容器可以擁有自己的root 文件系統、自己的網絡配置、自己的進程空間,甚至自己的用戶ID 空間。容器內的進程是運行在一個隔離的環境裏,使用起來,就好像是在一個獨立於宿主的系統下操作一樣。這種特性使得容器封裝的應用比直接在宿主運行更加安全。

倉庫(Repository)

倉庫,從認識上來說,就好像軟件包上傳下載站,有各種軟件的不同版本被上傳供用戶下載。鏡像構建完成後,可以很容易的在當前宿主機上運行,但是,如果需要在其它服務器上使用這個鏡像,我們就需要一個集中的存儲、分發鏡像的服務,Docker Registry 就是這樣的服務。

Docker版本

Docker 劃分爲CE 和EE。CE 即社區版(免費,支持週期三個月),EE 即企業版,強調安全,付費使用。Docker在1.13 版本之後,從2017年的3月1日開始,版本命名規則變爲如下:

項目 說明
版本格式 YY.MM
Stable版本 每個季度發行
Edge版本 每個月髮型

Docker CE 每月發佈一個Edge 版本(17.03, 17.04, 17.05…),每三個月發佈一個Stable 版本(17.03, 17.06, 17.09…),Docker EE 和Stable 版本號保持一致,但每個版本提供一年維護。

分層存儲

因爲鏡像包含操作系統完整的root 文件系統,其體積往往是龐大的,因此在Docker設計時,就充分利用Union FS 的技術,將其設計爲分層存儲的架構。所以嚴格來說,鏡像並非是像一個ISO 那樣的打包文件,鏡像只是一個虛擬的概念,其實際體現並非由一個文件組成,而是由一組文件系統組成,或者說,由多層文件系統聯合組成

鏡像構建時,會一層層構建,前一層是後一層的基礎。每一層構建完就不會再發生改變,後一層上的任何改變只發生在自己這一層。比如,刪除前一層文件的操作,實際不是真的刪除前一層的文件,而是僅在當前層標記爲該文件已刪除。在最終容器運行的時候,雖然不會看到這個文件,但是實際上該文件會一直跟隨鏡像。因此,在構建鏡像的時候,需要額外小心,每一層儘量只包含該層需要添加的東西,任何額外的東西應該在該層構建結束前清理掉。

分層存儲的特徵還使得鏡像的複用、定製變的更爲容易。甚至可以用之前構建好的鏡像作爲基礎層,然後進一步添加新的層,以定製自己所需的內容,構建新的鏡像。

III. 安裝Docker

Win10

下載:https://docs.docker.com/docker-for-windows/install/

Docker支持64 位版本的Windows 10 Pro,且必須開啓Hyper-V。開啓方式爲:打開“控制面板”->“程序”-> “啓動或關閉Windows功能”,找到Hyper-V並勾選,確定重啓電腦。

開啓Hyper-V

安裝下載好的Docker for Windows Installer.exe,如下:

安裝完畢

鑑於國內網絡問題,後續拉取Docker鏡像十分緩慢,需要配置國內鏡像加速,在系統右下角托盤Docker 圖標內右鍵菜單選擇Settings,打開配置窗口後左側導航菜單選擇Daemon,在Registry mirrors 一欄中填寫加速器地址
https://registry.docker-cn.com ,之後點擊Apply保存後Docker就會重啓並應用配置的鏡像地址了。

配置鏡像加速

Ubuntu16.04+

在Ubuntu系統中安裝較爲簡單,官方提供了腳本供我們進行安裝。

sudo apt install curl
curl -fsSL get.docker.com -o get-docker.sh
sudo sh get-docker.sh --mirror Aliyun
  • 1
  • 2
  • 3

執行這個命令後,腳本就會自動的將一切準備工作做好,並且把Docker CE 的Edge版本安裝在系統中。

啓動Docker CE

sudo systemctl enable docker
sudo systemctl start docker
  • 1
  • 2

建立docker 用戶組

默認情況下,docker 命令會使用Unix socket 與Docker 引擎通訊。而只有root 用戶和docker 組的用戶纔可以訪問Docker 引擎的Unix socket。出於安全考慮,一般Ubuntu系統上不會直接使用root 用戶。因此,更好地做法是將需要使用docker 的用戶加入docker用戶組。

# 建立docker組
sudo groupadd docker
# 將當前用戶加入docker組
sudo usermod -aG docker $USER
  • 1
  • 2
  • 3
  • 4

註銷當前用戶,重新登錄Ubuntu,輸入docker info,此時可以直接出現信息。

docker info

配置國內鏡像加速

在/etc/docker/daemon.json 中寫入如下內容(如果文件不存在請新建該文件)

{
    "registry-mirrors": [
        "https://registry.docker-cn.com"
    ]
}
  • 1
  • 2
  • 3
  • 4
  • 5

重新啓動服務

sudo systemctl daemon-reload
sudo systemctl restart docker
  • 1
  • 2

IV. Docker的C/S模式

Docker 採用了C/S 架構,包括客戶端和服務端。Docker 守護進程(Daemon)作爲服務端
接受來自客戶端的請求,並處理這些請求(創建、運行、分發容器)。

Docker基本架構

Docker 守護進程一般在宿主主機後臺運行,等待接收來自客戶端的消息;Docker 客戶端則爲用戶提供一系列可執行命令,用戶用這些命令實現跟Docker 守護進程交互。我們之前在Win10的命令行中便是最主要的客戶端:

Docker也爲我們提供了Remote API來操作Docker的守護進程,也意味着我們可以通過自己的程序來控制Docker的運行。客戶端和服務端既可以運行在一個機器上,也可通過socket 或者RESTful API 來進行通信:

至於Docker的客戶端與守護進程之間的通信,其連接方式爲socket連接。主要有三種socket連接方式:

  • unix:///var/run/docker.sock
  • tcp://host:port
  • fd://socketfd

完整的Docker的C/S連接方式的本質可以一般表示爲如下:

V. 使用Docker

容器的基操

  • 啓動一次操作容器docker run IMAGE_NAME [COMMAND] [ARG…]

例如,啓動一個容器輸出hello world。由於剛裝上Docker,沒有任何鏡像,所以會先下載一個最新的ubuntu18.04的docker鏡像。一次操作容器在處理完操作後會立即關閉容器。

docker run ubuntu echo 'hello world'
  • 1

啓動一次操作容器

  • 啓動交互式容器docker run -t -i –name=自定義名稱 IMAGE_NAME /bin/bash

  • -i –interactive=true | false,默認是false

    -t –tty=true | false,默認是false

    –name 給啓動的容器自定義名稱,方便後續的容器選擇操作

    啓動交互式的容器,就是類似虛擬機、雲主機的操作方式,操作完一個命令後仍然可以繼續

    docker run -i -t ubuntu /bin/bash
    • 1

    啓動交互式容器

  • 查看容器docker ps [-a] [-l]

  • 省略 列出正在運行的容器

    -a all 列出所有容器

    -l latest 列出最近的容器

    查看所有容器

  • 查看指定容器docker inspect name | id

  • name指代具體的容器名稱,id則是容器的唯一id標識。inspect命令可以詳細的展示出容器的具體信息。

    docker inspect haha
    • 1

    查看指定容器

  • 重新啓動停止的容器docker start [-i] 容器名

  • 實際使用時,沒必要每次都重新啓動一個新的容器,我們可以重新啓動之前創建的容器,現實情況也需要我們這樣使用。

    docker start -i haha
    • 1

    重啓停止的容器

  • 刪除停止的容器docker rm name | id

  • docker rm thirsty_kepler
    docker rm upbeat_albattani
    • 1
    • 2

    刪除停止的容器

    守護式容器

    交互式容器在運行完命令退出後即停止,而實際中我們常常需要能夠長時間運行,即使退出也能後臺運行的容器,而守護式容器具備這一功能。守護式容器具有:

    1. 能夠長期運行;
    2. 沒有交互式會話;
    3. 適合於運行應用程序和服務。

    以守護形式運行容器

    我們執行完需要的操作退出容器時,不要使用exit退出,可以利用Ctrl+P Ctrl+Q代替,以守護式形式推出容器。

    守護形式運行容器

    附加到運行中的容器

    退出正在運行的容器,想要再次進入,需要使用attach命令:docker attach name | id

    docker attach haha
    • 1

    啓動守護式容器

    啓動守護式容器,可以在後臺爲我們執行操作:docker run -d IMAGE_NAME [COMMAND] [ARG…]

    當命令在後臺執行完畢,容器還是會關閉。這裏防止容器立刻退出,寫一個腳本循環輸出“hello world”。

    docker run --name hiahia -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
    • 1

    啓動守護式容器

    查看容器日誌

    當守護式容器在後臺運行時,我們可以利用docker的日誌命令查看其輸出:docker logs [-f] [-t] [–tail] IMAGE_NAME

    -f –follows=true | false,默認是false,顯示更新

    -t –timestamps=true | false,默認是false,顯示時間戳

    –tail=“all” | 行數,顯示最新行數的日誌

    查看容器日誌

    查看容器內進程

    對運行的容器查看其進程:docker top IMAGE_NAME

    查看容器內進程

    運行中容器啓動新進程

    Docker的理念是一個容器運行一個服務,但是往往需要對一個服務進行監控,所以也需要在已經運行服務的容器啓動新的進程:docker exec [-d] [-i] [-t] IMAGE_NAME [COMMAND] [ARG…]

    docker exec -i -t hiahia /bin/bash
    • 1

    啓動新進程

    停止守護式容器

    發送信號停止容器:docker stop 容器名

    強制停止:docker kill 容器名

    VI. 案例:在容器中部署靜態網站

    容器的端口映射

    命令run [-P] [-p]

    -P,–publish-all=true | false,大寫的P表示爲容器暴露的所有端口進行映射;

    -p,–publish=[],小寫的p表示爲容器指定的端口進行映射,有四種形式:

    • containerPort:只指定容器的端口,宿主機端口隨機映射;
    • hostPort:containerPort:同時指定容器與宿主機端口一一映射;
    • ip::containerPort:指定ip和容器的端口;
    • ip:hostPort:containerPort:指定ip、宿主機端口以及容器端口。

    例如:

    docker run -p 80 -i -t ubuntu /bin/bash
    docker run -p 8080:80 -i -t ubuntu /bin/bash
    docker run -p 0.0.0.0::80 -i -t ubuntu /bin/bash
    docker run -p 0.0.0.0:8080:80 -i -t ubuntu /bin/bash
    • 1
    • 2
    • 3
    • 4

    容器中部署Nginx服務

    準備環境:

    # 1. 創建映射80端口的交互式容器
    docker run -p 80 --name web -i -t ubuntu /bin/bash
    # 2. 更新源
    apt-get update
    # 3. 安裝Nginx
    apt-get install -y nginx
    # 4. 安裝Vim
    apt-get install -y vim
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    創建靜態頁面:

    mkdir -p /var/www/html
    cd /var/www/html
    vim index.html
    • 1
    • 2
    • 3

    index.html

    修改Nginx配置文件:

    # 查看Nginx安裝位置
    whereis nginx
    # 修改配置文件
    vim /etc/nginx/sites-enabled/default
    • 1
    • 2
    • 3
    • 4

    修改Nginx配置文件

    運行Nginx:

    # 啓動nginx
    nginx
    # 查看進程
    ps -ef
    • 1
    • 2
    • 3
    • 4

    運行Nginx

    驗證網站訪問:

    # 退出容器
    Ctrl+P Ctrl+Q
    # 查看容器進程
    docker top web
    # 查看容器端口映射情況
    docker port web
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    查看進程和端口

    通過宿主機地址加映射端口訪問:

    訪問網站

    VII. 鏡像基操

    查看刪除鏡像

    • 列出鏡像docker images [OPTIONS] [REPOSITORY]

    -a,–all=false,顯示所有鏡像

    -f,–filter=[],顯示時過濾條件

    –no-trunc=false,指定不使用截斷的形式顯示數據

    -q,–quiet=false,只顯示鏡像的唯一id

    查看鏡像

  • 查看鏡像docker inspect [OPTIONS] CONTAINER|IMAGE [CONTAINER|IMAGE]

  • -f,–format=“”

    查看鏡像

  • 刪除鏡像docker rmi [OPTIONS] IMAGE [IMAGE]

  • -f,–force=false,強制刪除鏡像

    –no-prune=false,保留未打標籤的父鏡像

  • 虛懸鏡像:既沒有倉庫名,也沒有標籤,均爲\

  • 獲取推送鏡像

    • 查找鏡像docker search [OPTIONS] TEAM

    –automated=false,僅顯示自動化構建的鏡像

    –no-trunc=false,不以截斷的方式輸出

    –filter,添加過濾條件

    查找ubuntu鏡像

  • 拉取鏡像docker pull [OPTIONS] NAME [:TAG]

  • -a,–all-tags=false,下載所有的鏡像(包含所有TAG)

    拉取鏡像

  • 推送鏡像:docker push NAME [:TAG]

  • Docker允許上傳我們自己構建的鏡像,需要註冊DockerHub的賬戶。也可以上傳到阿里雲,地址:https://cr.console.aliyun.com/#/namespace/index

    構建鏡像

    構建Docker鏡像,可以保存對容器的修改,並且再次使用。構建鏡像提供了自定義鏡像的能力,以軟件的形式打包並分發服務及其運行環境。Docker中提供了兩種方式來構建鏡像:

    • 通過容器構建:docker commit
    • 通過Dockerfile:docker build

    使用commit命令構建鏡像

    命令:docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

    參數:-a,–author=“”,指定鏡像的作者信息

    ​ -m,–message=“”,提交信息

    ​ -p,–pause=true,commit時是否暫停容器

    commit命令構建鏡像

    使用Dockerfile文件構建鏡像

    Docker允許我們利用一個類似配置文件的形式來進行構建自定義鏡像,在文件中可以指定原始的鏡像,自定義鏡像的維護人信息,對原始鏡像採取的操作以及暴露的端口等信息。比如:

    # Sample Dockerfile
    FROM ubuntu:16.04
    MAINTAINER wgp "[email protected]"
    RUN apt-get update
    RUN apt-get install -y nginx
    EXPOSE 80
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    命令:docker build [OPTIONS] DockerFile_PATH | URL | -

    參數:–force-rm=false

    ​ –no-cache=false

    ​ –pull=false

    ​ -q,quite=false,構建時不輸出信息

    ​ –rm=true

    ​ -t,tag=“”,指定輸出的鏡像名稱信息

    Dockerfile文件構建鏡像

    VIII. 鏡像遷移

    我們製作好的鏡像,一般會遷移或分享給其他需要的人。Docker提供了幾種將我們的鏡像遷移、分享給其他人的方式。推薦鏡像遷移應該直接使用Docker Registry,無論是直接使用Docker Hub還是使用內網私有Registry都可以。使用鏡像頻率不高,鏡像數量不多的情況下,我們可以選擇以下兩種方式。

    上傳Docker Hub

    首先,需要在Docker Hub上申請註冊一個帳號(人機驗證時需要科學上網)。然後我們需要創建倉庫,指定倉庫名稱。

    新建倉庫

    在終端中登錄你的Docker Hub賬戶,輸入docker login,輸入用戶名密碼即可登錄成功。

    登錄docker賬戶

    查看需要上傳的鏡像,並將選擇的鏡像打上標籤,標籤名需和Docker Hub上新建的倉庫名稱一致,否則上傳失敗。給鏡像打標籤的命令如下。

    docker tag <existing-image> <hub-user>/<repo-name>[:<tag>]
    • 1

    其中existing-image代表本地待上傳的鏡像名加tag,後面<hub-user>/<repo-name>[:<tag>]則是爲上傳更改的標籤名,tag不指定則爲latest。

    打上標籤

    可以看到,我們重新爲ubuntu:16.04的鏡像打上標籤,觀察IMAGE ID可知,同一鏡像可以擁有不同的標籤名。接下來,我們利用push命令直接上傳鏡像。

    docker push <hub-user>/<repo-name>:<tag>
    • 1

    如圖,我們已經上傳成功。由於之前介紹的分層存儲系統,我們這裏是直接對已有的ubuntu鏡像進行上傳,只是重新打了標籤,所以真正上傳的只是變化的部分。

    上傳成功

    Hub查看

    導出文件互傳

    Docker 還提供了 docker loaddocker save 命令,用以將鏡像保存爲一個tar文件。比如這次我們將ubuntu:latest這個鏡像保存爲tar文件。

    docker save

    查看本地磁盤,即可看見名爲ubuntu18.04的tar包。我們可以將其拷貝給其他PC,利用load命令重新導入。

    重新導入鏡像

    推薦閱讀

    發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章