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

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)

分享創造快樂