本文作為Docker基礎系列第一篇文章,將詳細闡述和分析三個問題:Docker是什么?為什么要用Docker?如何快速掌握Docker技術?
本系列文章中Docker的用法演示是基於CentOS7進行,因此假設讀者已經掌握了初步的Linux知識,如果你對Linux最基本的常用命令及操作還不太熟悉,請參考我之前寫的Linux入門系列教程。
一、Docker是什么
用簡單的一句話來概況:Docker就是一種容器虛擬化技術。
要了解Docker為什么會出現,它解決了什么樣的問題,那就要回顧下虛擬化技術及Docker的發展歷程。
1.1 虛擬化技術及分類
ps:相信大家如果安裝或使用過虛擬機VMware,或許你已經遇到過虛擬化技術的問題。正如我的Linux入門系列文章中的“linux入門系列1--環境准備及linux安裝”中的3.2.1提到,你可能會遇到“此主機至此Interl VT-x,但Interl VT-x處於禁用狀態“這個問題,如果要在VMware中安裝Linux,那就要在BIOS中開啟虛擬化支持。
虛擬化技術是一個通用的概念,不同領域可以有不同的理解。而在計算機領域中通常是指計算虛擬化或服務器虛擬化,它的核心是對資源進行抽象,以能在同一個主機上同時運行多個系統或軟件應用為目標,從而提高服務器系統資源的利用率,降低成本,方便對應用的生命周期進行管理。
虛擬化技術分類總體上分為2大類:基於硬件的虛擬化和基於軟件的虛擬化。
真正意義上基於硬件的虛擬化並不多見,而基於軟件的虛擬化從對象所在的層次,又可以分為應用虛擬化和平台虛擬化。應用虛擬化一般是指通過軟件去模擬設備,而我們通常所說的虛擬化技術大多數情況下指的是平台虛擬化技術。
平台虛擬化又可以細分為以下幾類:
- 完全虛擬化
虛擬機模擬完的底層硬件環境和特權指的執行過程,客戶操作系統無須進行修改。比如:VirtualBox、VMware Workstation
- 硬件輔助虛擬化
利用硬件主要是CPU來輔助支持處理敏感指令來實現完全虛擬化的功能,客戶操作系統無須修改 。目前86體系結構上可用的硬件輔助虛擬化技術包括Intel-VT和AMD-V。 比如:VMware Workstation、Xen、KVM
- 部分虛擬化
只針對部分硬件資源進行虛擬化,客戶操作系統需要進行修改。
- 超虛擬化
部分硬件接口以軟件的形式提供給客戶機操作系統, 客戶操作系統需要進行修改。
- 操作系統級別虛擬化
內核通過創建多個虛擬的操作系統實例(包括內核和庫)來隔離不同的進程。我們通常所說的容器相關技術屬於此分類,而Docker則是這眾多容器技術中的一種。
如果要說Docker與虛擬化技術之間的關系,我認為可以概括為:虛擬化技術經過發展,從以前通過硬件層面來實現虛擬化的傳統方式,逐步演變為當今流行的基於操作系統層面的容器化方式。而Docker則作為容器化技術的佼佼者脫穎而出。
1.2 Docker的前世今生
Docker是基於Go語言實現的開源容器項目,Docker項目已加入Linux基金會,並遵循Apache協議, 全部開源代碼均在https://github.com/docker項目倉庫進行維護。
正如官方網站所說,Docker的理念就是“Build Ship and Run Any App, Anywhere”,即通過對應用的封裝( Packaging )、分發( Distribution )、部署( Deployment )、運行( Runtime )生命周期進行管理,簡單說就是一次封裝 ,到處運行。
Docker目前已得到各大主流操作系統的支持,包括Linux各大發行版、Windows、MacOS等均可以安裝使用。同時各大雲服務提供商如IBM、Amazon、Azure等雲平台均提供對Docker的集成支持。
那么Docker為什么會發展的如此迅速呢?
正如Docker創始人說的,Docker只是在正確的時間和正確的地點做了正確的事情,它的出現並非偶然,它其實也是站在了前人LXC的肩膀上發展而來。LXC(Linux Containers)也就是平常說的Linux容器技術,對於LXC更多細節就不多說了,簡單說就是LXC經過長期的發展,踩了很多坑,然后被集成到了主流Linux的內容中,正是這樣才為Docker的誕生鋪平了前期的道路。
Docker在LXC的基礎上,進一步優化了容器的使用體驗,才使得容器化技術得到普及。比如它提供了各種容器管理工具來實現應用的分發、版本移植等,讓用戶無需關注底層操作;同時也引入分層文件系統和高效的鏡像機制,極大的降低遷移難度。早期Docker是直接基於LXC的,到0.9版本之后開發了libcon-tainer項目作為更廣泛的容器驅動實現,從而替換掉了LXC的實現,,試圖讓容器的支持不再局限於Linux操作系統,而是更安全、更開放、更具擴展性。
正是基於Linux平台上的多項開源技術,Docker提供了高效、敏捷和輕量級的容器方案,並支持部署到本地環境和多種主流雲平台。可以說Docker首次為應用的開發 、運行和部署提供了“ 一站式”的實用解決方案。
1.3 Docker核心概念
Docker包含三大核心概念:鏡像、容器、倉庫,基礎部分功能都是圍繞他們進行展開,因此先有個簡單的印象即可。
- 鏡像
可以簡單理解為一個只讀的模板或者應用程序及其環境的打包,后邊的容器就是通過它來進行創建。它類似於虛擬機鏡像,如果你有面向對象的編程經驗,也可以把它理解為一個實體類(Class)。
- 容器
簡單理解為一個沙盒,用來運行和隔離我們開發的應用程序。你可以理解為正在運行的一個虛擬機,也可以理解為通過實體類Clss創建的一個對象。鏡像是靜態的,容器是動態的。
- 倉庫
倉庫就是集成存放鏡像的地方,Docker倉庫類似於代碼倉庫,如果你有Git和Maven的使用經驗,那就很好理解了。
官方提供的倉庫為Docker Hub,但有時候國外網速不太理想,因此國內雲廠商如阿里雲、網易雲等也提供了鏡像倉庫的本地源,當然也可以自己搭建私有倉庫。
二、為什么用Docker
要搞清楚我們為什么要用Docker,那就來先看看Docker都能干些啥?
2.1 Docker快速部署和分發
正如Docker的理念宣言:一次打包,處處運行。由於Docker鏡像是將我們開發的應用程序和他運行所需的環境一起打包,它帶來的好處非常明顯,尤其是快速部署和分發能力。
舉個簡單的例子,假設我們之前開發了某個軟件部署在了某一台服務器上,但是因為種種原因,我們希望把該軟件部署到另外一台服務器上。通常情況下我們需要怎么做呢?我們需要登錄到新的服務器上,按照之前的方法重復部署一次運行環境,然后運行觀察結果,還擔心環境的變化帶來未知的影響。那如果是用Docker會怎么樣呢?我們只需要把相應的鏡像下載下來然后運行起來即可。快速且省心。
還記得前面系列文章的LNMP環境搭建嗎?“linux入門系列20--Web服務之LNMP架構實戰”,是不是感覺非常麻煩呢?這個過程少說也得半小時,如果我們換為Docker進行部署的話,也就分分鍾就可以搞定。后文會演示采用Docker的方式來部署LNMP,到時候會有一個非常直觀的對比,相信你一定會愛上Docker。
2.2 Docker在開發運維DevOps中的優勢
采用Docker可以做到一次打包,處處運行。
由於鏡像中已經包含了環境,因此不會存在開發人員本地開發運行沒問題,但是交給運維人員運行就有問題的情況。同時它使得遷移、擴展和更新管理變得更加容易,極大減少了重復勞動、有效解放了運維人員。
2.3 Docker與虛擬機對比
容器化技術在性能上完勝虛擬機。
Docker容器除了運行其中的應用外,基本不消耗額外的系統資源,在保證應用性能的同時,盡量減小系統開銷。
傳統虛擬機方式運行N個不同的應用就要啟用N個虛擬機,每個虛擬機需要單獨分配獨占的內存、磁盤等資源,而Docker只需要啟動N個容器,並將應用放進容器內即可。
它的啟動速度、性能、內存代價、遷移性等都完勝虛擬機。
2.4 Docker在微服務中的應用
微服務架構是當前軟件開發領域的熱點技術之一,如果你是開發人員或者了解開發技術,相信你一定聽過單體應用和微服務這二個名詞。
在軟件架構演進過程中,曾經一個歸檔包(如war包)包含了所有應用程序的功能,比如一個Web系統我們所有功能模塊都放在一起,通常就稱為單體應用。盡管你可以在項目內部進行了模塊化開發,但是所有業務功能都包含在一個項目中,這樣復雜度高、部署麻煩,可靠性也差。比如只修改了其中很小一個功能也得重新部署;其中某一小部分出現問題也會導致整個系統出現問題。
為了解決這些情況,於是就產生了微服務架構。如果是Java開發,那主要就是指Spring Boot和Spring Cloud技術棧。微服務就是要求功能拆分,業務單一,把復雜系統拆分為各個可靠的小模塊,這雖然有很多優勢,但同時也增加了運維和管理的難度。
雖然微服務架構容器一旦非常多的時候,管理起來有點麻煩,但Docker能很好的對各個容器進行管理、彈性擴容等,因此往往會采用SpringBoot+SpringCloud+Docker的微服務架構模式。
2.5 Docker在大數據中的應用
在傳統的大數據架構中都通常會部署Hadoop、Hbase、Kafka、Zookeeper、Flink、Spark等等集群,如果都手動或者采用腳本去進行管理效率非常低,並且應對彈性擴容或縮容、遷移的情景是控制還需要做些額外的工作,而如果采用Docker進行管理和容器化的部署,這一切將會變得更加簡單。
這一部分的演示將會在后續分享完大數據相關知識后在返回來進行對比,敬請期待。
2.6 Docker各大企業中的應用案例
Docker容器技術以及在各大企業中得到了充分的驗證,如:京東618、美團點評、騰訊、新浪、蘑菇街等等。
- Docker在京東618的應用
2016年京東彈性雲團隊,從1萬Docker到15萬,從試水部分應用到承擔全部流量,經過了618的嚴格考驗。
- Docker在美團點評中的應用
2015年,美團雲團隊開始試水Docker容器集群管理平台,經過一些列的優化和完善,前該平台為美團點評的外賣、酒店、到店、貓眼等十幾個事業部提供容器計算服務,承載線上業務數百個,業務類型涵蓋Web、數據庫、緩存、消息隊列等。
- Docker在騰訊的應用
騰訊2014年10月份正式上線 Docker,其基於 Yarn 的代號為Gaia的調度平台可以同時兼容 Docker 和非Docker 類型的應用,其上層業務包括離線、實時以及在線 service 服務,如 Hadoop MR、Spark、Storm、Hive 以及騰訊內部的 Lhotse、Hermes、廣點通等業務。
- Docker在新浪微博中的應用
新浪微博的DCP是基於Docker的混合雲架構,在2014年做了Docker容器化,2015年做了私有雲+混合雲以及還有動態調度,在2016年從容應對十億級PV、千億級數據、2000台以上的服務器規模、20個以上的大小服務模塊、百億級數據Hbase存儲、千台以上的Docker混合雲集群。
- Docker在蘑菇街的應用
蘑菇街的私有雲項目於2014年聖誕節期間上線,把應用進行拆分,變成一個個微服務,實現PaaS基於應用的部署和發布。經歷了 幾次雙11大促,已經逐漸形成了一定的規模。
三、Docker怎么用
3.1 相關網站
- 官網
從官網可以看到Docker分為社區版(CE)和企業版(EE),一般情況下使用社區版即可。
- 在線Docker練習
https://labs.play-with-docker.com/
該網站是Docker船長為了幫助大家學習Docker而花了幾天時間開發的一款基於瀏覽器的產品,play-with-docker,人稱PWD,它是一個Docker的演練場。
它可以讓用戶在幾秒鍾內在瀏覽器中體驗免費的Alpine Linux虛擬機,運行Docker命令,可以構建、運行Docker容器,甚至可以在Docker Swarm模式下創建集群,除了演練場之外,PWD還包含了一個由大量Docker labs實例和測試。
如果你只是想快速體驗一下Docker,你甚至都不用本地裝環境就可以馬上體驗,注冊一個賬戶或者直接用Docker Hub的賬戶即可登錄進入體驗。
3.2 Docker安裝
正如前文提到支持Linux、Windows、MacOS等,但生產環境我們一般是在Linux中使用,因此本文將演示在Centos7下Docker的安裝和使用。
Docker的安裝也非常簡單,只需要按照官網提示操作即可。
官網介紹的安裝有三種:rpm、yum、腳本方式
接下來采用YUM的方式進行安裝
3.2.1 准備虛擬機
配置好IP地址,同時為了減少干擾,關閉防火牆和SELinux。
如果你的系統比較老舊需要yum更新一下,此步驟不是必須的。
[root@docker ~]# yum update -y
3.2.2 安裝必須的包
[root@docker ~]# yum install -y yum-utils \ device-mapper-persistent-data \ lvm2
...省略部分輸出內容
Complete!
[root@docker ~]#
3.2.3 設置倉庫
[root@docker ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
...省略部分輸出內容
repo saved to /etc/yum.repos.d/docker-ce.repo
[root@docker ~]#
此處直接用官方的倉庫https://download.docker.com/linux/centos/docker-ce.repo,如果你網速慢也可以換成國內的倉庫,如阿里雲的。
3.2.4 安裝Docker
[root@docker ~]# yum install docker-ce
...省略部分輸出內容
Complete!
[root@docker ~]#
安裝過程中按3次y進行確認即可。此過程跟網速有關,一般10多分鍾即可安裝完成。
由於該命令后沒有帶具體的版本號,因此默認的tag為lastest,所以不同時間去執行有可能版本會不一樣,生產環境建議帶上指定的版本號。
3.2.5 啟動Docker
安裝完成后Docker是沒有啟動的,因此需要先啟動Docker,並設為開機啟動。可以通過systemctl status docker查看Docker的狀態。
[root@docker ~]# systemctl start docker
[root@docker ~]# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
[root@docker ~]# systemctl status docker
docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2020-02-26 21:39:22 CST; 1min 30s ago
Docs: https://docs.docker.com
Main PID: 57003 (dockerd)
CGroup: /system.slice/docker.service
...省略部分內容
可以看到處於running狀態,至此docker安裝並啟動成功。
3.2.6 查看版本及Docker信息
查看版本信息
[root@docker ~]# docker -v
Docker version 19.03.6, build 369ce74a3c
查看docker安裝信息
[root@docker ~]# docker info
...省略部分內容
Docker Root Dir: /var/lib/docker
...省略部分內容
可以看到默認的安裝路徑為/var/lib/docker。
3.3 運行第一個容器HelloWorld
3.3.1 創建第一個容器
我們通過Docker Hub上官方提供的現成的hello-world鏡像來創建一個容器,創建容器使用docker run 命令,該容器的功能就是創建並啟動后輸出helloworld字樣。
[root@docker ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:fc6a51919cfeb2e6763f62b6d9e8815acbf7cd2e476ea353743570610737b752
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
[root@docker ~]#
可以看到容器成功運行了,並且輸出了hello from docker!
此時采用docker images命令查看本地的鏡像,可以看到一個名為hello-world的鏡像。
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 14 months ago 1.84kB
[root@docker ~]#
3.3.2 hello-world容器原理分析
運行一個容器,實際上就是運行容器內部的程序,就像我們平時做helloworld程序,我們需要用java或者其他語言進行開發,然后打包為jar文件,然后通過java命令執行。每次需要運行該程序都需要做手動執行命令,而在docker中,我們把helloworld對應的jar包打包到容器中,只需要run容器,程序就可以立即執行,是不是很方便呢?
我們分析一下hello-world容器運行的原理:首先我們看到“Unable to find image 'hello-world:latest' locally”這樣的提示,說明本地沒有這個hello-world鏡像,他會自動從Docker Hub倉庫去下載該鏡像,然后在創建容器並運行容器內的helloworld程序,這個過程都是自動化完成的。
並且啟動的這個容器其實就相當於是一個小型的linux系統,但是啟動的非常快,幾秒鍾就啟動並運行了,這也正是之前談到的和虛擬機相比的優勢。
至於它為什么這么快?以及這個容器內究竟有什么東西?可以執行哪些docker命令?在后續文章中你將找到答案。
這樣Docker環境就准備好了,下一篇文章開始,我們正式來演示Docker中各種命令的使用方法。