Docker是什麼,有什麼用?一看就明白

千鋒雲端計算發表於2019-06-20

Docker是什麼,有什麼用?一看就明白

Docker是一個基於輕量級虛擬化技術的容器,整個專案基於Go語言開發,並採用了Apache 2.0協議。Docker可以將我們的應用程式打包封裝到一個容器中,該容器包含了應用程式的程式碼、執行環境、依賴庫、配置檔案等必需的資源,透過容器就可以實現方便快速並且與平臺解耦的自動化部署方式,無論你部署時的環境如何,容器中的應用程式都會執行在同一種環境下。

舉個例子,小明寫了一個CMS系統,該系統的技術棧非常廣,需要依賴於各種開源庫和中介軟體。如果按照純手動的部署方式,小明需要安裝各種開源軟體,還需要寫好每個開源軟體的配置檔案。如果只是部署一次,這點時間開銷還是可以接受的,但如果小明每隔幾天就需要換個伺服器去部署他的程式,那麼這些繁瑣的重複工作無疑是會令人發狂的。這時候,Docker的用處就派上場了,小明只需要根據應用程式的部署步驟編寫一份Dockerfile檔案(將安裝、配置等操作交由Docker自動化處理),然後構建併發布他的映象,這樣,不管在什麼機器上,小明都只需要拉取他需要的映象,然後就可以直接部署執行了,這正是Docker的魅力所在。

那麼映象又是什麼呢?映象是Docker中的一個重要概念:

  • Image(映象):它類似於虛擬機器中使用到的映象,由於任何應用程式都需要有它自己的執行環境,Image就是用來提供所需執行環境的一個模板。
  • Container(容器):Container是Docker提供的一個抽象層,它就像一個輕量級的沙盒,其中包含了一個極簡的Linux系統環境與執行在其中的應用程式。Container是Image的執行例項(Image本身是隻讀的,Container啟動時,Docker會在Image的上層建立一個可寫層,任何在Container中的修改都不會影響到Image,如果想要在Image儲存Container中的修改,Docker採用了基於Container生成新的Image層的策略),Docker引擎利用Container來操作並隔離每個應用(也就是說,每個容器中的應用都是互相獨立的)。

其實從Docker與Container的英文單詞原意中就可以體會出Docker的思想。Container可以釋義為集裝箱,集裝箱是一個可以便於機械裝置裝卸的封裝貨物的通用標準規格,它的發明簡化了物流運輸的機械化過程,使其建立起了一套標準化的物流運輸體系。而Docker的意思為碼頭工人,可以認為,Docker就像是在碼頭上辛勤工作的工人,把應用打包成一個個具有某種標準化規格的"集裝箱"(其實這裡指出的集裝箱對應的是Image,在Docker中Container更像是一個執行中的沙盒),當貨物運輸到目的地後,碼頭工人們(Docker)就可以把集裝箱拆開取出其中的貨物(基於Image來建立Container並執行)。這種標準化與隔離性可以很方便地組合使用多個Image來構建你的應用環境(Docker也提倡每個Image都遵循單一職責原則,也就是隻做好一件事),或者與其他人共享你的Image。

本文作者為SylvanasSun(sylvanas.sun@gmail.com),首發於SylvanasSun’s Blog。
原文連結:sylvanassun.github.io/2017/11/19/…
(轉載請務必保留本段宣告,並且保留超連結。)

Docker VS 虛擬機器

在上文中我們提到了Docker是基於輕量級虛擬化技術的,所以它與我們平常使用的虛擬機器是不一樣的。虛擬機器技術可以分成以下兩類:

系統虛擬機器

  • 系統虛擬機器:透過軟體對計算機系統的模擬來提供一個真實計算機的替代品。它是物理硬體的抽象並提供了執行完整作業系統所需的功能。虛擬機器透過物理機器來管理和共享硬體,這樣實現了多個虛擬機器環境彼此之間的隔離,一臺機器上可以執行多個虛擬機器,每個虛擬機器包括一個作業系統的完整副本。在系統虛擬機器中,所執行的所有軟體或操作都只會影響到該虛擬機器的環境。我們經常使用的VMWare就是系統虛擬機器的實現。
  • 程式虛擬機器:允許程式獨立執行在平臺之外。比較典型的例子就是JVM,Java透過JVM這一抽象層使得Java程式與作業系統和硬體平臺解耦(因為每個Java程式都是執行在JVM中的),因此實現了所謂的compile once, run everywhere。

Docker所用到的技術與上述兩種都不相同,它使用了更輕量級的虛擬化技術,多個Container共享了同一個作業系統核心,並且就像執行在本地上一樣。Container技術相對於虛擬機器來說,只是一個應用程式層的抽象,它將程式碼與依賴關係打包到一起,多個Container可以在同一臺機器上執行(意味著一個虛擬機器上也可以執行多個Container),並與其它Container共享作業系統核心,每一個Container都在使用者空間中作為一個獨立的程式執行,這些特性都證明了Container要比虛擬機器更加靈活與輕量(一般都是結合虛擬機器與Docker一起使用)。

Container技術其實並不是個新鮮事物,最早可以追溯到UNIX中的chroot(在1979年的V7 Unix中引入),它可以改變當前正在執行的程式及其子目錄的根目錄,在這種修改過的環境下執行的程式不能在指定的目錄樹之外訪問檔案,從而限制使用者的活動範圍,為程式提供了隔離空間。

之後各種Unix版本湧現出很多Container技術,在2006年,Google提出了"Process Containers"期望在Linux核心中實現程式資源隔離的相關特性,由於Container在Linux核心中的定義過於寬泛混亂,後來該專案改名為CGroups(Control Groups),實現了對程式的資源限制。

2008年,LXC(Linux Containers)釋出,它是一種在作業系統層級上的虛擬化方法,用於在Linux系統上透過共享一個核心來執行多個互相隔離的程式(Container)。LXC正是結合了Linux核心中的CGroups和對分離的名稱空間的支援來為應用程式提供了一個隔離的環境。而Docker也是基於LXC實現的(Docker的前身是dotClound公司中的內部專案,它是一家提供PaaS服務的公司。),並作出了許多改進。

使用Docker

在使用Docker之前你需要先安裝Docker(這好像是一句廢話。。。),根據不同的平臺安裝方法都不相同,可以去參考Install Docker | Docker Documentation或者自行Google。

安裝完畢之後,輸入docker --version來確認是否安裝成功。

$ docker --version

Docker version 17.05.0-ce-rc1, build 2878a85複製程式碼

從Docker Hub中可以pull到其他人釋出的Image,我們也可以註冊一個賬號去釋出自己的Image與他人共享。

[root@Jack ~]# docker search redis # 檢視redis映象是否存在

[root@Jack ~]# docker pull redis # 拉取redis映象到本機

Using default tag: latest

Trying to pull repository docker.io/library/redis ...

latest: Pulling from docker.io/library/redis

Digest: sha256:cd277716dbff2c0211c8366687d275d2b53112fecbf9d6c86e9853edb0900956

[root@Jack ~]# docker images # 檢視映象資訊

REPOSITORY TAG IMAGE ID CREATED SIZE

docker.io/python 3.6-onbuild 7195f9298ffb 2 weeks ago 691.1 MB

docker.io/mongo latest d22888af0ce0 2 weeks ago 360.9 MB

docker.io/redis latest 8f2e175b3bd1 2 weeks ago 106.6 MB複製程式碼

有了Image,之後就可以在其之上執行一個Container了,命令如下。

[root@Jack ~]# docker run -d -p 6379:6379 redis # 執行redis,-p代表將本機上6379埠對映到Container的6379埠 -d代表在後臺啟動

[root@Jack ~]# docker ps -a # 檢視容器資訊,如果不加-a只會顯示當前執行中的容器

# 如果想要進入容器中,那麼需要執行以下命令

[root@Jack ~]# docker ps # 先獲得容器的id

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

1f928073b7eb redis "docker-entrypoint.sh" 45 seconds ago Up 44 seconds 0.0.0.0:6379->6379/tcp desperate_khorana

[root@Jack ~]# docker exec -it 1f928073b7eb /bin/bash # 然後再執行該命令進入到容器中

root@1f928073b7eb:/data# touch hello_docker.txt # 在容器中建立一個檔案

root@1f928073b7eb:/data# exit # 退出

exit

[root@Jack ~]#

# 也可以在啟動時直接進入 命令如下

[root@Jack ~]# docker run -d -it -p 6379:6379 redis /bin/bash複製程式碼

我們對Container做出了修改,如果想要保留這個修改,可以透過commit命令來生成一個新的Image。

# -m為描述資訊 -a為作者 1f9是你要儲存的容器id 取前3個字元 docker可以自行識別

# sylvanassun/redis為映象名 :test 為一個tag 一般用於標識版本

[root@Jack ~]# docker commit -m "test" -a "SylvanasSun" 1f9 sylvanassun/redis:test

sha256:e7073e8e5bd70b8d58092fd6bd8c2551e65dd29241c235eddf2a7f4b4b25cbbd

[root@Jack ~]# docker images

REPOSITORY TAG IMAGE ID CREATED SIZE

sylvanassun/redis test e7073e8e5bd7 2 seconds ago 106.6 MB

docker.io/python 3.6-onbuild 7195f9298ffb 2 weeks ago 691.1 MB

docker.io/mongo latest d22888af0ce0 2 weeks ago 360.9 MB

docker.io/redis latest 8f2e175b3bd1 2 weeks ago 106.6 MB複製程式碼

想刪除一個容器或映象也很簡單,但在刪除映象前需要先刪除依賴於它的容器。

[root@Jack ~]# docker stop 1f9 # 關閉執行中的容器,相應的也有docker start id命令來啟動一個容器

1f9

[root@Jack ~]# docker rm 1f9 # 刪除容器

1f9

[root@Jack ~]# docker rmi e70 # 刪除上面儲存的映象

Untagged: sylvanassun/redis:test

Deleted: sha256:e7073e8e5bd70b8d58092fd6bd8c2551e65dd29241c235eddf2a7f4b4b25cbbd

Deleted: sha256:751db4a870e5f703082b31c1614a19c86e0c967334a61f5d22b2511072aef56d複製程式碼

如果想要自己構建一個映象,那麼需要編寫Dockerfile檔案,該檔案描述了映象的依賴環境以及如何配置你的應用環境。

# 使用python:2.7-slim 作為父映象

FROM python:2.7-slim

# 跳轉到/app 其實就是cd命令

WORKDIR /app

# 將當前目錄的內容(.)複製到映象的/app目錄下

ADD . /app

# RUN代表執行的shell命令,下面這條命令是根據requirements.txt安裝python應用的依賴包

RUN pip install --trusted-host pypi.python.org -r requirements.txt

# 暴露80埠讓外界訪問

EXPOSE 80

# 定義環境變數

ENV NAME World

# 當容器啟動時執行的命令,它與RUN不同,只在容器啟動時執行一次

CMD ["python", "app.py"]複製程式碼

然後就可以透過docker build -t xxx/xxxx .命令來構建映象,-t後面是映象名與tag等資訊,注意.表示在當前目錄下尋找Dockerfile檔案。

學會如何構建自己的映象之後,你是否也想將它釋出到Docker Hub上與他人分享呢?要想做到這一點,需要先註冊一個Docker Hub賬號,之後透過docker login命令登入,然後再docker push image name,就像在使用Git一樣簡單。

關於Docker的更多命令與使用方法,請參考Docker Documentation | Docker Documentation,另外我還推薦使用Docker Compose來構建映象,它可以很方便地組合管理多個映象。

Docker提供了非常強大的自動化部署方式與靈活性,對多個應用程式之間做到了解耦,提供了開發上的敏捷性、可控性以及可移植性。同時,Docker也在不斷地幫助越來越多的企業實現了向雲端遷移、向微服務轉型以及向DevOps模式的實踐。

如今,微服務與DevOps火爆程度日益漸高,你又有何理由選擇拒絕Docker呢?讓我們一起選擇擁抱Docker,擁抱未來!


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69916964/viewspace-2648134/,如需轉載,請註明出處,否則將追究法律責任。

相關文章