歡迎光臨
每天分享高質量文章

Docker簡介與簡單使用

前一段花了一段時間研究Log4j2的原始碼,現在這個專案基本也告一段落,也算是度過了初入職場這一個階段。之前在18年總結時說過19年自己要學會C++,所以接下來一段時間,會用一些文章和大家分享下自己學習C++過程中的新的,不過在正式寫關於C++內容前,想先介紹一下Docker,因為有了這個利器,自己搞個小開發環境會變得十分簡單。而且在雲化的時代,如果連Docker都沒用過甚至沒聽說過的話確實有點說不過去。所以我願意單獨拉出一篇文簡單介紹一下Docker的使用,後面的C++開發環境也會直接使用Docker進行部署。本文主要分為3部分,什麼是Docker,為什麼用Docker以及Docker的基本使用方法。閑言少敘,直奔主題~
什麼是Docker

 

至於給Docker的定義,我覺得還是直接取用吧,Docker是一個用Go語言開發的一個開源容器引擎,Docker 可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然後釋出到任何流行的 Linux 機器上,也可以實現虛擬化。容器是完全使用沙箱機制,相互之間不會有任何介面(類似iPhone的App),更重要的是容器效能開銷極低。
Docker作為虛擬化分支的一項重要的革新,有必要將Docker和其他虛擬化技術進行一下比較。下麵是介紹虛擬化過程中最常見的一張圖,它描述了計算機從軟到硬的一個層次關係。 
這個圖看似簡單,其實它很清晰的描述了計算機資源的一種層次關係。最底層是基礎設施層,基本都是硬體方面的構成,如CPU,記憶體,磁碟,這些支撐了計算機的基本執行,如果沒有這些硬體,計算機也就不存在了。在硬體層上運行了格式的作業系統,他能夠根據合理的將硬體資源合理的分配給上面的應用,並保證他們有條不紊的執行。在系統上自帶一些系統的lib和可執行命令,這些可執行命令就是我們常用的Linux命令(cd,cat,ls….太多了),Lib則包含了一些基本程式庫,供我們自己編寫的各種程式呼叫。最上面就是我們開發的各種Application了。
Docker與虛擬機器
說完了基本的分層關係,下麵就需要重點介紹兩種比較重要的虛擬化技術,虛擬機器和Docker,雖然感覺區別被講爛了不過為了介紹的完整性還是簡單提一句,還請大家耐心看完。
 
Hypervisor與虛擬機器
從本質上看,虛擬機器和Docker屬於在不同層次上的虛擬,虛擬機器則是虛擬到作業系統層次的,如下圖所示。 
在宿主機的作業系統中,抽象出了一個Hypervisor的概念,因為自己並沒有涉獵過這個領域,所以扒一些現成的資料給我自己掃掃盲。
首先是Hypervisor的定義,根據wiki上講,Hypervisor或者Virtual Machine Monitor(VMM)是創造並且執行虛擬機器的軟體、韌體、或者硬體,通俗的講,hypervisor是一種將作業系統和硬體分離的一種方式,使得宿主機的硬體上能夠同時執行多個虛擬機器。
Hypervisor具有如下的優點:
  • 提高主機硬體的使用率

  • 虛擬機器移動性較強

  • 資源的隔離性,某臺虛擬機器的宕機不影響其他虛擬機器的使用

  • 易保護,易恢復

Hypervisor種類: 
如上面兩張圖所示,Hypervisor分為兩類,一類是直接部署在硬體層面上(bare-metal hypervisors),另一類則是部署在宿主機的作業系統上,算是一種軟體(hosted hypervisors)。兩種方式的特點與典型系統如下:
    • bare-metal hypervisors 特點

      • 需要硬體支援

      • 虛擬機器monitor作為主作業系統

      • 執行效率高

 

  • 典型系統

    • VMware5.5+

    • Xen3.0+

    • KVM

 

  • hosted hypervisors 特點

    • 虛擬機器監視器作為應用程式執行在主作業系統環境內

    • 效率較低

  • 典型系統

    • Virtual Box

    • early VMware5.5

    • early Xen3.0

 
Docker
 
與虛擬機器不同,Docker是透過軟體層的虛擬化實現了更加輕量級的虛擬化,其架構圖如下: 
初步看來,Docker所在的層級與虛擬機器所在的層次相同,都是在宿主機的作業系統上部署,但是Docker完全是軟體,不需要硬體進行支援,它利用的是作業系統自帶的資源隔離機制對硬體資源進行隔離,例如Win中的Hyper-v,Linux中的cgroup等,由Docker的後端程式Docker Engine呼叫這些介面完成資源隔離。Docker在建立容器時並不執行完整的作業系統,使用的資源更少,部署,啟動更快。但提供的隔離粒度不足,所以Docker更加適合單個使用者使用,而虛擬機器則更適合在多個使用者混合的多租戶型別的場景中執行。
為什麼用Docker

 

其實這個問題我在介紹虛擬機器與Docker的區別時已經提到,Docker由於其使用了更加輕量級的隔離機制,不論是在部署,啟動恢覆上均比虛擬機器要快上數個數量級,因此,如果是個人使用者想要快速構建某個特定的環境,比如想要測試某個程式碼在linux的執行情況,而使用的是mac系統或win系統,或者練習搭建環境等,透過Docker可以快速滿足需求。
Docker簡單使用方法

 

Docker架構
介紹使用方法前,先明確Docker中的幾個基本元件以及這些元件的互動關係。 
  • Docker映象:Docker映象是用於建立Docker容器的模板

  • Docker容器(Container):容器是獨立執行的一個或一組應用

  • Docker客戶端(Client):Docker客戶端透過命令列或者其他工具使用Docker API與Docker的守護行程通訊。

  • Docker主機(Host):一個物理或者虛擬的機器用於執行Docker守護行程和容器

  • Docker倉庫(Registry):Docker倉庫用來儲存映象,可以理解為程式碼控制中的程式碼倉庫。Docker Hub提供了龐大的映象集合供使用。

  • Docker Machine:Docker Machine是一個簡化Docker安裝的命令列工具,透過一個簡單的命令列即可在相應的平臺上安裝Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure

終於到了實戰環節,在這一小節裡面,我們透過兩個具體案例介紹Docker的簡單使用方法,首先是Docker的Hello World,另一個則是按照Docker官方檔案部署一個Flask後端服務。
安裝Docker
Mac && Windows:直接下載安裝檔案進行安裝
Linux:
  1. yum install -y epel-release ##安裝倉庫
  2. yum install docker-io ##安裝Docker
  3. chkconfig docker on ## 加入開機自動啟動
  4. service docker start ## 啟動Docker
Docker Hello World
這個案例非常簡單,只有一個命令:
  1. docker run hello-world
如果看到下圖中的結果則說明成功。 
Docker複雜使用
這個應用主要是一個Python的Web服務,該服務用於統計使用者訪問量,使用者訪問量儲存在Redis中。下麵正式開始部署。
首先先寫一個Flask的Python程式,主要的統計邏輯和前端展示都由這個檔案提供,程式碼如下:
  1. from flask import Flask
  2. from redis import Redis, RedisError
  3. import os
  4. import socket
  5. # Connect to Redis
  6. redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)## 連線redis
  7. app = Flask(__name__)
  8. @app.route("/")
  9. def hello():
  10. try:
  11. visits = redis.incr("counter") ##獲取計數器當前值並將其+1
  12. except RedisError:
  13. visits = "cannot connect to Redis, counter disabled"
  14. html = "

    Hello {name}!

    \

  15. "Hostname: {hostname}
    "
    \
  16. "Visits: {visits}"
  17. return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits) ##網頁渲染
  18. if __name__ == "__main__":
  19. app.run(host='0.0.0.0', port=80) ## 服務的設定為80埠
然後編寫Python需要的依賴檔案requirements.txt。
  1. Redis
  2. Flask
最後寫出Docker的部署檔案Dockerfile:
  1. # 將官方 Python 執行時用作父映象
  2. FROM python:2.7-slim
  3. # 將工作目錄設定為 /app
  4. WORKDIR /app
  5. # 將當前目錄內容複製到位於 /app 中的容器中
  6. ADD . /app
  7. # 安裝 requirements.txt 中指定的任何所需軟體包
  8. RUN pip install -r requirements.txt
  9. # 使埠 80 可供此容器外的環境使用
  10. EXPOSE 80
  11. # 定義環境變數
  12. ENV NAME World
  13. # 在容器啟動時執行 app.py
  14. CMD ["python", "app.py"]
最後的目錄結構如下: 
完成之後開始構建,首先build映象:
  1. docker build -t bryantchangflasktest .
其中 -t 的作用是指定映象的名字。
完成構建後,結果如下:
 
使用docker images檢視已經構建的映象: 
完成構建後,接下來開始執行:
  1. docker run -p 4001:80 bryantchangflasktest ##將4001埠對映到80埠
執行結果: 
可以看到因為沒有配置Redis所以這裡面的異常是我們預期內的,為了做後面的配置方便,我們將映象上傳到公共映象,命令如下:
  1. docker build -t bryantchangxy/bryantchangflasktest .
  2. docker push bryantchangxy/bryantchangflasktest:latest
涉及的一些常見命令:
  1. docker build -t friendlyname .# 使用此目錄的 Dockerfile 建立映象
  2. docker run -p 4001:80 friendlyname # 執行埠 4001 到 80 的“友好名稱”對映
  3. docker run -d -p 4001:80 friendlyname # 內容相同,但在分離樣式下
  4. docker ps # 檢視所有正在執行的容器的串列
  5. docker stop # 平穩地停止指定的容器
  6. docker ps -a # 檢視所有容器的串列,甚至包含未執行的容器
  7. docker kill # 強制關閉指定的容器
  8. docker rm # 從此機器中刪除指定的容器
  9. docker rm $(docker ps -a -q) # 從此機器中刪除所有容器
  10. docker images -a # 顯示此機器上的所有映象
  11. docker rmi # 從此機器中刪除指定的映象
  12. docker rmi $(docker images -q) # 從此機器中刪除所有映象
  13. docker login # 使用您的 Docker 憑證登入此 CLI 會話
  14. docker tag username/repository:tag # 標記 以上傳到映象庫
  15. docker push username/repository:tag # 將已標記的映象上傳到映象庫
  16. docker run username/repository:tag
  17. docker stack ls # 列出此 Docker 主機上所有正在執行的應用
  18. docker stack deploy -c # 執行指定的 Compose 檔案
  19. docker stack services # 列出與應用關聯的服務
  20. docker stack ps # 列出與應用關聯的正在執行的容器
  21. docker stack rm # 清除應用
註意,下麵我不再繼續沿用那篇檔案裡面的內容,我直接將Flask和Redis整合,並使用Docker Compose部署,部署檔案為docker-compose.yml,內容如下:
  1. web:
  2. build: .
  3. command: python app.py
  4. ports:
  5. - "4001:80"
  6. volumes:
  7. - .:/app
  8. links:
  9. - redis
  10. redis:
  11. image: microbox/redis
最後部署映象,命令如下:
  1. docker-compose up -d
完成後,輸入localhost:4001,終於看到了最終的結果:
 
對於Docker Compose的使用,參見部落格:https://blog.csdn.net/u011781521/article/details/80464826。
原文連結:https://bryantchang.github.io/2019/02/17/docker-utilization/

贊(0)

分享創造快樂