瞭解【Docker】從這裡開始

我沒有三顆心臟發表於2019-05-29

瞭解【Docker】從這裡開始

一、環境配置的難題


軟體開發最大的難題之一就是環境配置的問題。現在使用者環境紛亂複雜,並且由於開源社群的進一步推廣和許多開源專案不停地迭代更新,專案可能會有越來越多的依賴以及越來越難管理的依賴版本,如何保證編寫的程式能不只是在“我的電腦上能執行”(It works on my machine)成了一個複雜麻煩的事情。

於是就有人提出:能不能從根本上解決問題,讓軟體可以自帶環境安裝?也就是說,安裝的時候,把原始環境一模一樣地複製過來。

虛擬機器

虛擬機器(virtual machine)就是一種自帶環境安裝的解決方案。它可以在一個作業系統裡面執行另一個作業系統,比如在 Windows 系統裡執行一個 Linux 的作業系統。

應用程式對虛擬機器是毫無感知的,因為虛擬機器看上去跟真實的作業系統一模一樣,而且對於底層的系統來說,虛擬機器就是一個普通檔案,不需要了就刪除,對其他部分毫無影響。

雖然使用者可以通過虛擬機器還原軟體的原始環境。但是,該方案有以下的幾個缺點:

1. 資源佔用多

虛擬機器會獨佔一部分本屬於作業系統的記憶體和硬碟空間。它執行的時候,其他程式就不能使用這些資源了。哪怕你想在虛擬機器裡面使用的應用程式它實際只會佔用 1MB 的記憶體,虛擬機器仍然需要幾百 MB 的記憶體才能執行。

2. 冗餘步驟多

虛擬機器是完整的作業系統,一些系統層面上的操作步驟,往往無法調過,比如使用者登入。

3. 啟動慢

啟動作業系統需要多久,啟動虛擬機器就需要多久。可能要等幾分鐘,才能讓應用程式真正的執行起來。

Linux 容器

由於虛擬機器存在上述的這些缺點,Linux 提出了另一種虛擬機器化技術:Linux 容器(Linux Containers,縮寫 LXC)。

Linux 容器不是模擬一個完整的作業系統,而是對程式進行隔離。或者說,在正常程式的外面套了一個保護層。對於容器裡面的程式來說,它接觸到的各種資源都是虛擬的,從而實現與底層系統的隔離。

由於容器是程式級別的,相比虛擬機器有很多優勢。

1. 啟動快

容器裡面的應用,直接就是底層系統的一個程式,而不是虛擬機器內部的程式。所以,啟動容器相當於啟動本機的一個程式,而不是啟動一個作業系統,速度就快很多。

2. 資源佔用少

容器只佔用需要的資源,不佔用那些沒有用到的資源;虛擬機器由於是完整的作業系統,不可避免要佔用所有資源。另外,多個容器可以共享資源,虛擬機器都是獨享資源。

3. 體積小

容器只要包含用到的元件即可,而虛擬機器是整個作業系統的打包,所以容器檔案比虛擬機器檔案要小很多。

總之,容器有點像輕量級的虛擬機器,能夠提供虛擬化的環境,但是成本開銷小得多。

二、什麼是 Docker?


Enterprise Container Platform for High-Velocity Innovation
Securely build, share and run any application, anywhere

譯:
企業高速容器平臺
在任何地方安全的建造、分享、執行你的應用程式

官方對 Docker 的定義是一個容器平臺。簡單來說,Docker 屬於 Linux 容器的一種封裝,提供簡單易用的容器使用介面。它是目前最流行的 Linux 容器解決方案。開發人員可以利用 Docker 來消除協作編碼時 “在我的電腦上可以正常工作” 的問題。

Docker 將應用程式與該程式的依賴,打包在一個檔案裡面。執行這個檔案,就會生成一個虛擬容器。程式在這個虛擬容器裡執行,就好像在真實的物理機上執行一樣。有了 Docker,就不用擔心環境問題。

總體來說,Docker 的介面相當簡單,使用者可以方便地建立和使用容器,把自己的應用放入容器。容器還可以進行版本管理、複製、分享、修改,就像管理普通的程式碼一樣。

為什麼要使用 Docker?

Docker 是一個為開發者和運維者去開發、釋出和在容器中執行應用的平臺。使用 Linux 容器來部署應用程式被稱為容器化。 容器不是新的概念,它的優勢在於很容易釋出一個應用。

瞭解【Docker】從這裡開始

容器化變得非常的流行,因為容器化具有以下的優點:

  • 靈活:即使最複雜的應用也能夠被容器化。
  • 輕量:容器最大化利用和分享主機的核心。
  • 可互換:你可以即時部署更新和升級應用。
  • 便捷:你可以在本地構建應用,並部署到容器雲,並在任何地方執行。
  • 可擴充套件:你可以增加和自動分發容器的個數。
  • 可堆疊:您可以垂直堆疊服務並即時堆疊服務。

容器除了執行其中應用外,基本不消耗額外的系統資源,使得應用的效能很高,同時系統的開銷儘量小。傳統虛擬機器方式執行 10 個不同的應用就要起 10 個虛擬機器,而Docker 只需要啟動 10 個隔離的應用即可。

具體說來,Docker 在如下幾個方面具有較大的優勢。

1. 更快速的交付和部署

對開發和運維(devop)人員來說,最希望的就是一次建立或配置,可以在任意地方正常執行。

開發者可以使用一個標準的映象來構建一套開發容器,開發完成之後,運維人員可以直接使用這個容器來部署程式碼。 Docker 可以快速建立容器,快速迭代應用程式,並讓整個過程全程可見,使團隊中的其他成員更容易理解應用程式是如何建立和工作的。 Docker 容器很輕很快!容器的啟動時間是秒級的,大量地節約開發、測試、部署的時間。

2. 更高效的虛擬化

Docker 容器的執行不需要額外的 hypervisor 支援,它是核心級的虛擬化,因此可以實現更高的效能和效率。

3. 更輕鬆的遷移和擴充套件

Docker 容器幾乎可以在任意的平臺上執行,包括物理機、虛擬機器、公有云、私有云、個人電腦、伺服器等。 這種相容性可以讓使用者把一個應用程式從一個平臺直接遷移到另外一個。

4. 更簡單的管理

使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分發和更新,從而實現自動化並且高效的管理。

Docker VS VM

容器和虛擬機器對資源的隔離和分配有相同的優勢,但不同的是容器虛擬化作業系統而不是硬體,這使得容器更加的方便和高效。

瞭解【Docker】從這裡開始

一個容器是在 Linux 服務本地執行,並和其他的容器共享主機的核心。它執行在一個獨立的程式中,相對於其他可執行的程式(比如虛擬機器)來說,容器的記憶體佔用空間更小,更加的輕量化。

相比之下,虛擬機器(VM)執行一個完整的“客戶”作業系統,通過虛擬機器管理程式虛擬訪問主機資源。 一般來說,虛擬機器提供的環境比大多數應用程式需要的資源更多。

由於 Docker 輕量、資源佔用少,使得 Docker 可以輕易的應用到構建標準化的應用中。但 Docker 目前還不夠完善,比如隔離效果不如 VM,共享宿主機作業系統的一些基礎庫等;網路配置功能相對簡單,主要以橋接方式為主;檢視日誌也不夠方便靈活。

Docker 的用途

Docker 的主要用途,目前有三大類。

1. 提供一次性的環境。比如,本地測試他人的軟體、持續整合的時候提供單元測試和構建的環境。

2. 提供彈性的雲服務。因為 Docker 容器可以隨開隨關,很適合動態擴容和縮容。

3. 組建微服務架構。通過多個容器,一臺機器可以跑多個服務,因此在本機就可以模擬出微服務架構。

三、Docker 基本概念


下面這張圖非常的經典,很形象地展示了,什麼是容器,什麼是映象,什麼是倉庫,以及三者之間的聯絡。

瞭解【Docker】從這裡開始

接下來我們來解釋一下這張圖。現在我們要造一間廚房,在造之前我們首先要乾的一件事,就是先列舉出我們造廚房需要的東西。我們可能需要一個通了水電煤的房子以及一些必需的廚房用具諸如鍋碗瓢勺、煤氣灶、冰箱、水槽等等這些東西。現在我們知道需要了什麼東西之後,我們就去找這些東西。首先我們先去京東購買一些廚房用具,這些用具就好比我們的Docker映象,我們廚房的用具到了之後得找個地方把它們放在,不可能隨處丟吧,不然後面用的時候就找不到它了,那麼我們Docker映象也是這樣,需要一個Docker倉庫去儲存這些映象。現在我們有了這些廚房用具之後就可以做飯了嗎?答案當然是不能,沒水沒電沒火啊!這時候我們得把廚房用具給裝到一個通了水電煤的房子才行,那麼Docker映象也是這樣,單純的Docker映象是不能用的,它得裝到Docker容器中通了水電煤才能使用。等我們裝好了廚房用具之後我們就可以開始做飯,那麼我們的Docker映象裝到Docker容器之後,我們應用就可以跑起來了。

概念詳解

Docker是CS架構,主要有兩個概念:

  • Docker daemon: 執行在宿主機上,Docker守護程式,使用者通過Docker client(Docker命令)與Docker daemon互動
  • Docker client: Docker 命令列工具,是使用者使用Docker的主要方式,Docker client與Docker daemon通訊並將結果返回給使用者,Docker client也可以通過socket或者RESTful api訪問遠端的Docker daemon

瞭解【Docker】從這裡開始

瞭解了Docker的組成,再來了解一下Docker的三個主要概念:

  • Docker image: 映象是隻讀的,映象中包含有需要執行的檔案。映象用來建立container,一個映象可以執行多個container;映象可以通過Dockerfile建立,也可以從Docker hub/registry上下載。
  • Docker container: 容器是Docker的執行元件,啟動一個映象就是一個容器,容器是一個隔離環境,多個容器之間不會相互影響,保證容器中的程式執行在一個相對安全的環境中。
  • Docker hub/registry: 共享和管理Docker映象,使用者可以上傳或者下載上面的映象,官方地址為https://registry.hub.docker.com/,也可以搭建自己私有的Docker registry。

映象就相當於打包好的版本,映象啟動之後執行在容器中,倉庫就是裝儲存映象的地方。

四、Docker 安裝


安裝過程都大同小異,這裡就不細說了,詳細的可以參考這裡:https://www.runoob.com/docker/macos-docker-install.html

唯一需要注意的就是由於國內網路問題,需要給 Docker 映象加個速(詳細的可以戳上面連結,最後有...)

五、Docker Hello World


首先,執行下面的命令,將 image 檔案從倉庫抓取到本地。

$ docker image pull library/hello-world

上面程式碼中,docker image pull是抓取 image 檔案的命令。library/hello-world是 image 檔案在倉庫裡面的位置,其中library是 image 檔案所在的組,hello-world是 image 檔案的名字。

由於 Docker 官方提供的 image 檔案,都放在library組裡面,所以它的是預設組,可以省略。因此,上面的命令可以寫成下面這樣。

$ docker image pull hello-world

抓取成功以後,就可以在本機看到這個 image 檔案了。

$ docker image ls

現在,執行這個 image 檔案

$ docker container run hello-world

docker container run 命令會從 image 檔案,生成一個正在執行的容器例項。

注意,docker container run 命令具有自動抓取 image 檔案的功能。如果發現本地沒有指定的 image 檔案,就會從倉庫自動抓取。因此,前面的 docker image pull 命令並不是必需的步驟。

如果執行成功,你會在螢幕上讀到下面的輸出。

$ docker container run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

... ...

輸出這段提示以後,hello world 就會停止執行,容器自動終止。

有些容器不會自動終止,因為提供的是服務。比如,安裝執行 Ubuntu 的 image,就可以在命令列體驗 Ubuntu 系統。

$ docker container run -it ubuntu bash

對於那些不會自動終止的容器,必須使用docker container kill 命令手動終止。

$ docker container kill [containID]

六、常用命令


  • 殺死所有正在執行的容器
    docker kill $(docker ps -a -q)
  • 刪除所有已經停止的容器
    docker rm $(docker ps -a -q)
  • 刪除所有映象
    docker rmi $(docker images -q)
  • 關閉容器
    docker stop CONTAINER ID或者NAMES
  • 重新啟動關閉的容器
    docker start CONTAINER ID或者NAMES
  • 移除本地容器
    docker rm CONTAINER ID或者NAMES
  • 檢視本地容器
    docker ps //檢視正在執行的容器
    docker ps -a //檢視所有容器
  • 檢視本地映象
    docker images
  • 建立映象
    docker build -t name:tag Dockerfile路徑
  • 修改本地映象標記
    docker tag IMAGE ID name:tag
    docker rmi name:tag
  • 刪除本地映象
    docker rmi name:tag或者IMAGE ID
  • 進入容器
    docker exec -it IMAGE ID或者NAMES /bin/bash
  • 獲取映象中心的映象
    docker pull name:tag
  • 獲取容器的埠對映配置
    docker port CONTAINER ID或者NAMES

# 參考資料

1. Docker入門教程(阮一峰) - http://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html
2. Docker(一):Docker入門教程(純潔的微笑) - https://www.cnblogs.com/ityouknow/p/8520296.html
3. Docker教程(菜鳥教程) - https://www.runoob.com/docker/docker-tutorial.html
4. - Docker入門,看這篇就夠了 - https://segmentfault.com/a/1190000009544565#articleHeader6
5. 官方文件 - https://www.docker.com


按照慣例黏一個尾巴:

歡迎轉載,轉載請註明出處!
簡書ID:@我沒有三顆心臟
github:wmyskxz
歡迎關注公眾微訊號:wmyskxz
分享自己的學習 & 學習資料 & 生活
想要交流的朋友也可以加qq群:3382693

相關文章