# 1.1 Docker 簡介與安裝
## 簡介
**Docker 容器其實就是一種特殊的進程**。
其實 Docker 容器只是使用了 Linux 內核的一些技術:
- [Namespace](https://coolshell.cn/articles/17010.html) 技術對進程進行隔離;
- [Cgroups](https://coolshell.cn/articles/17049.html) 技術對進程進行資源限制;
- [Union FS](https://coolshell.cn/articles/17061.html)(目前 Docker 主要使用 Overlay2,不過 Overlay 與 AUFS 差別不是很大,可以先了解一下 AUFS)技術為進程構建出一個完善的文件系統。
這樣這個進程看起來就像是獨立的操作系統了,這也是為什么很多人會把 Docker 項目稱為「輕量級」虛擬化技術的原因,實際上是把虛擬機的概念套在了容器上。
不過我一直很排斥將 Docker 視為輕量級虛擬機技術的說法。如果把容器當做虛擬機使用的話,要進入容器進行調試該怎么辦? SSH 要怎么配置? 一個容器里面是否應該啟動多個進程?是否需要備份容器?這些問題都不好處理。如果把容器當做虛擬機使用,不建議使用 Docker 技術,而是直接去使用虛擬機來運行你的服務。
所以我們要正確使用 Docker,就要建立起**容器化思維**。要意識到容器的本質其實就是一個進程。當理解了容器實際上是一個進程以后:
- 我們就不需要去備份容器了,而是應該把需要備份的數據放在容器外進行備份;
- 我們也不應該去在容器里啟動多個進程了(可以,但沒必要,除非特殊需要),因為容器本身就是一個單進程模型;
- 我們更不應該使用 SSH 的方式來進入容器了,只需要給容器并分配一個偽終端(必須說 bash 子進程、sh 子進程)即可。
所以 Docker 容器和虛擬機完全不同,在運行 Docker 時,并沒有一個真正的「Docker 容器」運行在宿主機上面。 Docker 幫你啟動的,還是原來的應用進程,只不過創建這些進程時,Docker 為它們加上了各種各樣的隔離與限制,這樣使用 Docker 運行的進程就仿佛運行在一個一個「容器」里面,與世隔絕。 其實只不過都是「障眼法」罷了。
下面是官方給出的 Docker 與傳統虛擬機的對比圖:

這幅圖的左邊為虛擬機的工作原理。其中 Hypervisor 的軟件是虛擬機最主要的部分。它通過硬件[虛擬化](https://www.redhat.com/zh/topics/virtualization/what-is-virtualization)功能,模擬出了運行一個操作系統所需要的各種硬件,比如 CPU、內存、I/O 設備等等。然后,它在這些虛擬的硬件上安裝了一個新的操作系統,即 Guest OS。
而這幅圖的右邊,則用了一個 Docker Engine 的軟件替換了 Hypervisor,屬于[操作系統層面的虛擬化技術](https://en.wikipedia.org/wiki/Container_virtualization),因為上層只是與系統其它部分隔離開的一系列進程,所以叫做[容器](https://www.redhat.com/zh/topics/containers/whats-a-linux-container)。
## Docker 的優勢
- **更高效的利用系統資源**。<br/>由于容器不需要進行硬件虛擬以及運行完整操作系統等額外開銷,Docker 對系統資源的利用率更高。
- **更快速的啟動時間**。<br/>啟動一個虛擬機需要數分鐘,而 Docker 容器應用由于直接運行于宿主內核,無需啟動完整的操作系統,因此可以做到秒級啟動。
- **一致的運行環境**。<br/>開發過程中一個常見的問題就是環境一致性的問題。由于開發環境、測試環境、生產環境不一致,導致有些 Bug 并未在開發過程中發現。而 Docker 的鏡像提供了除內核外完整的運行時環境(上面提到的 Union FS 文件系統),確保了應用運行環境一致行。
- **更輕松的遷移**。<br/>由于 Docker 確保了執行環境的一致性,使得應用的遷移更加容易。Docker 可以在很多平臺上運行:物理機、虛擬機、公有云、私有云、甚至是個人電腦(Windows 系統或 MAC OS),其運行結果是一致的。因此用戶可以很輕易的將一個平臺上運行的容器遷移到另一個平臺上。
- **持續交付和部署**。<br/>對開發和運維(DevOps)人員來說,最希望的就是一次創建和配置,可以在任意地方正常運行。使用 Docker 可以通過定制應用鏡像來實現持續集成、持續交付、部署。開發人員可以通過 Dockerfile 來進行鏡像構建,并結合持續集成(CI)系統進行集成測試,而運維人員則可以直接在生產環境中快速部署該鏡像,還能結合持續部署(CD)系統進行自動部署。而且開發人員使用 Dockerfile 使鏡像構建透明化,不僅僅開發團隊可以理解應用運行環境,也方便運維團隊理解應用運行所需條件。
## Docker 安裝
前往 [Docker 官方文檔](https://docs.docker.com/install/),選擇適合的平臺安裝即可。
比如這里我將在 CentOS 與 Windows 平臺上安裝 Docker。
### CentOS
這里使用的系統版本為 CentOS 7.6。
```bash
$ uname -r
3.10.0-957.el7.x86_64
$ cat /etc/centos-release
CentOS Linux release 7.6.1810 (Core)
```
有三種安裝方式:
- 配置 Docker Yum 源安裝
- 手動下載 RPM 軟件包安裝
- 使用 Docker 官方腳本安裝
這里使用 Docker Yum 源進行安裝。
1. 安裝依賴包
```bash
$ yum install -y yum-utils device-mapper-persistent-data lvm2
```
2. 配置 Docker Yum 源
```bash
$ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
```
3. 安裝 Docker CE
* 安裝最新版本的 Docker CE:
```bash
$ yum install -y docker-ce docker-ce-cli containerd.io
$ docker --version
Docker version 18.09.2, build 6247962
```
* 安裝指定版本的 Docker CE:
```bash
$ yum list docker-ce --showduplicates | sort -r
docker-ce.x86_64 3:18.09.2-3.el7 docker-ce-test
docker-ce.x86_64 3:18.09.2-3.el7 docker-ce-stable
docker-ce.x86_64 3:18.09.2-3.el7 @docker-ce-stable
docker-ce.x86_64 3:18.09.1-3.el7 docker-ce-test
docker-ce.x86_64 3:18.09.1-3.el7 docker-ce-stable
docker-ce.x86_64 3:18.09.1-2.1.rc1.el7 docker-ce-test
docker-ce.x86_64 3:18.09.1-1.2.beta2.el7 docker-ce-test
docker-ce.x86_64 3:18.09.1-1.1.beta1.el7 docker-ce-test
docker-ce.x86_64 3:18.09.0-3.el7 docker-ce-test
docker-ce.x86_64 3:18.09.0-3.el7 docker-ce-stable
...
$ yum install -y docker-ce-18.09.1 docker-ce-cli-18.09.1 containerd.io
```
4. 啟動 Docker
```bash
$ systemctl enable --now docker.service
$ docker info
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 18.09.2
Storage Driver: overlay2
Backing Filesystem: xfs
...
```
### Windows
開發人員想在自己的電腦上使用 Docker 方便開發測試使用,可以直接在 Windows 系統上安裝 Docker。
安裝 Docker 的 Windows 系統要求:
- Windows 10 64 位:Pro、Enterprise 或 Education(1607 版本,Build 14393 或更高版本);
- 在 BIOS 中啟用虛擬化;
- 具有 CPU SLAT 功能;
- 至少 4 GB 內存。
這里使用的是 Windows Pro 1803 版本。

安裝 Docker:
1. 下載適用于 Windows 的 [Docker Desktop](https://hub.docker.com/editions/community/docker-ce-desktop-windows)。
2. 雙擊 Docker for Windows Installer.exe 運行安裝程序。
3. 安裝完成后啟動 Docker Desktop。

4. 運行 Powershell 檢測是否安裝完成。

## 總結
1. 首先記住,容器的本質只是一個進程。要用看待進程的方式來看待一個容器,而不是用看待虛擬機的方式來看待容器。
2. 是否要用 Docker 也要考慮你的應用代碼是否面對經常的變更與解耦,可以參考現在流行的微服務。對于半年、一年或許才更新一次的應用來說,用虛擬機或者物理機部署會更加合適。
3. Docker 項目其實并沒有很復雜的技術實現,依賴的還是 Linux 底層技術,比如 Linux Namaspace 技術、Linux Cgroups 技術、以及類 Rootfs 技術實現的聯合文件系統(Union FS)。有興趣可以查閱這些 Linux 底層技術的資料。
4. 其實容器本身是沒有價值的,有價值的是「容器編排與調度」,比如說 Docker Swarm 、Kubernetes、Mesos 等。容器技術生態爆發的關于「容器編排」的戰爭,最終以 Kubernetes 項目和 CNCF 社區的勝利而告終。為什么 Docker 公司在這場戰爭中占據了很有利的先天條件(Docker 項目)還敗給了 Google 公司推出的 Kubernetes,以后我會介紹這兩種編排調度系統。有興趣的話也可以在網上查閱一下有關于[容器編排戰爭](https://zhuanlan.zhihu.com/p/35951990)的資料。
## 參考
- [什么是 Linux 容器?](https://www.redhat.com/zh/topics/containers/whats-a-linux-container)
- [何為虛擬化?](https://www.redhat.com/zh/topics/virtualization/what-is-virtualization)
- [Get Docker CE for CentOS](https://docs.docker.com/install/linux/docker-ce/centos/)
- [Install Docker Desktop for Windows](https://docs.docker.com/docker-for-windows/install/)
~~~