1. 概述#
本文介紹 Docker 的相關知識,重點是 Docker 的 3 大核心:鏡像、容器、倉庫
2. Docker 的介紹#
- Docker 是世界領先的軟體容器平台
- Docker 使用 Google 公司推出的 Go 語言進行開發實現,基於 Linux 內核的 cgroup,namespace,以及 AUFS 類的 UnionFS 等技術,對進程進行封裝隔離,屬於操作系統層面的虛擬化技術。由於隔離的進程獨立於宿主和其他的隔離的進程,因此也稱其為容器。Docker 最初實現是基於 LXC
- Docker 能夠自動執行重複性任務,例如搭建和配置開發環境,從而解放了開發人員以便他們專注在真正重要的事情上:構建傑出的軟體
- 用戶可以方便地創建和使用容器,把自己的應用放入容器。容器還可以進行版本管理、複製、分享、修改,就像管理普通的代碼一樣
Docker 設計時,充分利用 Union FS 的技術,將其設計為分層存儲的架構
3. Docker 的思想#
- 集裝箱:將所有需要的內容放到不同的集裝箱中,誰需要某些內容(環境)就直接拿對應的集裝箱就行了
- 標準化:
- 運輸的標準化:Docker 有一個碼頭,所有上傳的集裝箱都放在這個碼頭上,當有人需要某一個環境時,就直接派 [小藍鯨]^(Docker 的吉祥物) 去搬運這個集裝箱就行
- 命令的標準化:Docker 提供了一系列命令,幫助我們去獲取集裝箱的相關操作
- 提供了 REST 的 API:衍生出了很多圖形化界面,如: [Rancher]^(一個開源的企業級容器管理平台)
- 隔離性:Docker 在運行集裝箱裡的內容時,會在 Linux 的內核中,單獨開闢一片空間,這片空間不會影響到其他程序
- 中央倉庫 / 註冊中心:超級碼頭,上面放的都是集裝箱
- 鏡像:就是集裝箱
- 容器:運行起來的鏡像(就是將軟體打包成標準化單元,以用於開發、交付和部署。通俗的描述就是:容器就是一個存放東西的地方,就像書包可以裝各種文具、衣櫃可以放各種衣服、鞋架可以放各種鞋子一樣)
4. 容器 VS 虛擬機#
容器是一個應用層抽象,用於將代碼和依賴資源打包在一起。多個容器可以在同一台機器上運行,共享操作系統內核,但各自作為獨立的進程在用戶空間中運行。與虛擬機相比,容器佔用的空間較少(容器鏡像大小通常只有幾十兆),瞬間就能完成啟動
虛擬機(VM)是一個物理硬體層抽象,用於將一台伺服器變成多台伺服器。管理程序允許多個 VM 在一台機器上運行。每個 VM 都包含一整套操作系統、一個或多個應用、必要的二進制文件和庫資源,因此佔用大量空間。而且 VM 啟動也十分緩慢
5. Docker 的安裝#
- 安裝依賴包
yum install -y yum-utils device-mapper-persistent-data lvm2
- 指定 Docker 鏡像源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 安裝 Docker
yum makecache fast
yum -y install docker-ce
- 啟動 Docker
systemctl start docker
systemctl enable docker
docker run hello-world
6. Docker 中央倉庫#
Docker 官方的中央倉庫:(這個倉庫的鏡像是最全的,但下載速度較慢)
國內的鏡像網站:
鏡像構建完成後,可以在當前宿主機上運行,但是,如果需要在其他伺服器上使用這個鏡像,就需要一個集中存儲、分發鏡像的服務,Docker Registry 就是這樣的服務
一個 Docker Registry 中可以包含多個倉庫(Repository),每個倉庫可以包含多個標籤(Tag);每個標籤對應一個鏡像
通常,一個倉庫會包含同一個軟體的不同版本的鏡像,而標籤就常用於對應該軟體的各個版本
Docker Registry 公開服務和私有 Docker Registry 的概念:
-
Docker Registry 公開服務是開放給用戶使用、允許用戶管理鏡像的 Registry 服務
一般這類公開服務允許用戶免費上傳、下載公開的鏡像,並可能提供收費服務供用戶管理私有鏡像。
最常使用的 Registry 公開服務是官方的 Docker Hub ,這也是默認的 Registry,並擁有大量的高質量的官方鏡像
-
除了使用公開服務外,用戶還可以在本地搭建私有 Docker Registry 。Docker 官方提供了 Docker Registry 鏡像,可以直接使用作為私有 Registry 服務
開源的 Docker Registry 鏡像只提供了 Docker Registry API 的服務端實現,足以支持 Docker 命令,不影響使用。但不包含圖形界面,以及鏡像維護、用戶管理、訪問控制等高級功能
7. 鏡像#
鏡像:
一個特殊的文件系統(實際是由多層文件系統聯合組成的)
操作系統分為內核和用戶空間,對於 Linux 而言,內核啟動後,會掛載 root 文件系統為其提供用戶空間的支持,而 Docker 鏡像就相當於是一個 root 文件系統
Docker 鏡像除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些為運行時準備的一些配置參數,如:匿名卷、環境變量、用戶
鏡像不包含任何動態數據,其內容在構建之後也不會改變
鏡像構建時,會 一層一層構建 ,前一層是后一層的基礎,每一層構建完成後就不會再發生變化,后一層的任何改變都只發生在自己這一層
- 拉取鏡像(從中央倉庫拉取鏡像到本地)
docker pull 鏡像名稱[:tag]
- 查看本地全部鏡像(查看本地已經安裝過的鏡像信息,包含標識,名稱,版本,更新時間,大小)
docker images
- 刪除本地鏡像(鏡像會佔用磁碟空間,可以直接收到刪除)
docker rmi 鏡像的標識
- 鏡像的導入導出
# 將本地的鏡像導出
docker save -o 導出的路徑 鏡像id
# 加載本地的鏡像文件
docker load -i 鏡像文件
# 修改鏡像名稱
docker tag 鏡像id 新鏡像名稱:版本
8. 容器#
容器:
運行起來的鏡像
鏡像(Image)和容器(Container)的關係,就像是面向對象程序設計中的 類和實例 一樣
鏡像是靜態的定義,容器是鏡像運行時的實體。容器可以被創建、啟動、停止、刪除、暫停等
容器的實質是進程 ,但與直接在宿主執行的進程不同,容器進程運行於屬於自己的獨立的命名空間。前面講過鏡像使用的是分層存儲,容器也是如此
容器存儲層的生存週期和容器一樣,容器消亡時,容器存儲層也隨之消亡。因此,任何保存於容器存儲層的信息都會隨容器刪除而丟失
按照 Docker 最佳實踐的要求,容器不應該向其存儲層內寫入任何數據 ,容器存儲層要保持無狀態化
所有的文件寫入操作,都應該使用數據卷(Volume)、或者綁定宿主目錄,在這些位置的讀寫會跳過容器存儲層,直接對宿主(或網絡存儲)發生讀寫,其性能和穩定性更高
數據卷的生存週期獨立於容器,容器消亡,數據卷不會消亡。因此, 使用數據卷後,容器可以隨意刪除、重新 run,數據卻不會丟失
- 運行容器(運行容器需要指定具體鏡像,如果鏡像不存在,會直接下載)
# 簡單操作
docker run 鏡像的標識|鏡像名稱[:tag]
# 常用的參數
docker run -d -p 宿主機端口:容器端口 --name 容器名稱 鏡像的標識|鏡像名稱[:tag]
# -d: 代表後台運行容器
# -p: 宿主機端口:容器端口: 為了映射當前Linux的端口和容器的端口
# --name: 容器名稱: 指定容器的名稱
- 查看正在運行的容器
docker ps [-qa]
# -a: 查看全部的容器,包含沒有運行的
# -q: 只查看容器的標識
- 查看容器日誌(查看容器的日誌,以查看運行的信息)
docker logs -f 容器id
# -f: 可以滾動查看日誌的最後幾行
- 進入容器內部(可以進入容器內部進行操作)
docker exec -it 容器id bash
- 複製內容到容器(將宿主機的文件複製到內部的指定目錄)
docker cp 文件名稱 容器id:容器內部路徑
- 重啟 / 啟動 / 停止 / 刪除容器(容器的啟動、停止、刪除等操作會經常用到)
# 重新啟動容器
docker restart 容器id
# 啟動停止運行的容器
docker start 容器id
# 停止指定的容器(刪除容器前,需要先停止容器)
docker stop 容器id
# 停止全部容器
docker stop $(docker ps -qa)
# 刪除指定容器
docker rm 容器id
# 刪除全部容器
docker rm $(docker ps -qa)
9. Docker 的應用#
- Docker 安裝 Tomcat
docker run -d -p 8080:8080 --name tomcat daocloud.io/library:8.5.15-jre8
- Docker 安裝 MySQL
docker run -d -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=root daocloud.io/library/mysql:5.7.4
10. 數據卷#
思考:
Docker 容器刪除後,在容器中產生的數據也會隨之銷毀
Docker 容器和外部機器可以直接交換文件嗎?
容器之間想要進行數據交互?
數據卷:
數據卷是宿主機中的一個目錄或文件
當容器目錄和數據卷目錄綁定後,對方的修改會立即同步
一個數據卷可以被多個容器同時掛載
一個容器也可以被掛載多個數據卷
- 創建數據卷(創建數據卷後,默認會存放在一個目錄下 /var/lib/docker/volumes/ 數據卷名稱 /_data)
docker volume create 數據卷名稱
- 查看數據卷詳情(查看數據卷的詳細信息,可以查詢到存放路徑,創建時間等)
docker volume inspect 數據卷名稱
- 查看全部數據卷
docker volume ls
- 刪除數據卷
docker volume rm 數據卷名稱
- 容器映射數據卷
映射有兩種方式:
- 通過數據卷名稱映射,如果數據卷不存在,Docker 會幫你自動創建,會將容器內部自帶的文件,存儲在默認的存放路徑
- 通過路徑映射數據卷,直接指定一個路徑作為數據卷的存放位置,但是這個路徑下是空的
# 通過數據卷名稱映射
docker run -v 數據卷名稱:容器內部的路徑 鏡像id
# 通過路徑映射數據卷
docker run -v 路徑:容器內部的路徑 鏡像id
11. Dockerfile 自定義鏡像#
我們可以從中央倉庫下載一個鏡像,也可以自己手動去製作一個鏡像,需要通過 Dockerfile 去指定自定義鏡像信息
12. Docker-Compose#
之前運行一個鏡像,需要添加大量的參數,可以通過 Docker-Compose 編寫這些參數
而且 Docker-Compose 可以幫助我們批量的管理容器
這些信息只需要通過一個 docker-compose.yml 文件去維護即可
12.1 下載安裝 Docker-Compose#
-
設置權限(需要將 DockerCompose 文件的名稱修改一下,賦予 DockerCompose 文件一個可執行權限)
mv docker-compose-linux-x86_64 docker-compose
chmod 777 docker-compose
- 配置環境變量(方便後期操作,配置一個環境變量)
mv docker-compose /usr/local/bin
vim /etc/profile
# 添加內容 export PATH=$JAVA_HOME:/usr/local/bin:$PATH
source /etc/profile
- 測試(在任意目錄下輸入 docker-compose 命令)
12.2 Docker-Compose 管理 MySQL 和 Tomcat 容器#
yml 文件以 key 方式來指定配置信息
多個配置信息以換行 + 縮進的方式來區分
在 docker-compose.yml 文件中,不要使用制表符
version: '3.1'
services:
mysql: #服務的名稱
restart: always #代表只要docker啟動,那麼這個容器就跟著一起啟動
image: daocloud.io/library/mysql:5.7.4 #指定鏡像路徑
container_name: mysql #指定容器名稱
ports:
- 3306:3306 #指定端口號的映射
environment:
MYSQL_ROOT_PASSWORD: root #指定MySQL的root用戶登錄密碼
TZ: Asia/Shanghai #指定時區
volumes:
- /opt/docker_mysql_tomcat/mysql_data:/var/lib/mysql #映射數據卷
tomcat:
restart: always
image: daocloud.io/library/tomcat:8.5.15-jre8
container_name: tomcat
ports:
- 8080:8080
environment:
TZ: Asia/Shanghai
volumes:
- /opt/docker_mysql_tomcat/tomcat_webapps:/usr/local/tomcat/webapps
- /opt/docker_mysql_tomcat/tomcat_logs:/usr/local/tomcat/logs
12.3 使用 docker-compose 命令管理容器#
使用 docker-compose 命令時,默認會在當前目錄下找 docker-compose.yml 文件
# 1. 基於docker-compose.yml 啟動管理的容器
docker-compose up -d
# 2. 關閉並刪除容器
docker-compose down
# 3. 開啟|關閉|重新啟動已存在的由docker-compose維護的容器
docker-compose start|stop|restart
# 4. 查看有docker-compose管理的容器
docker-compose ps
# 5. 查看日誌
docker-compose logs -f
12.4 docker-compose 配合 Dockerfile 使用#
使用 docker-compose.yml 文件以及 Dockerfile 文件在生成自定義的鏡像的同時啟動當前鏡像,並且由 docker-compose 去管理容器
- docker-compose 文件(編寫 docker-compose.yml 文件)
# yml文件
version: '3.1'
services:
ssm:
restart: always
build: #構建自定義鏡像
context: ../ #指定dockerfile文件的所在路徑
dockerfile: Dockerfile #指定Dockerfile文件名稱
image: ssm:1.0.1
container_name: ssm
ports:
- 8081:8080
environment:
TZ: Asia/Shanghai
- Dockerfile 文件(編寫 Dockerfile)
from daocloud.io/library/tomcat:8.5.15-jre8
copy ssm.war /usr/local/tomcat/webapps
- 運行(測試效果)
# 可以直接啟動基於docker-compose.yml以及Dockerfile文件構建的自定義鏡像
docker-compose up -d
#如果自定義鏡像不存在,會幫助我們構建出自定義鏡像,如果自定義鏡像已經存在,會直接運行這個自定義鏡像
#重新構建自定義鏡像
docker-compose build
#運行當前內容,並重新構建
docker-compose up -d --build
13. 總結#
本文主要把 Docker 中的一些常見概念做了詳細的闡述