轉了雲方向,程式碼都少寫了
1. 為什麼出現Docker
以前開發專案有開發的環境、測試的環境、還有生產的環境,每經過一階段就要遷移專案。不同的環境有不同的配置,可能導致不可預估的錯誤,運維要經常性的改動
世界陷入了混亂,於是上帝說,讓Docker來吧,於是一切光明。Dokcer 把初始的環境一模一樣地複製過來,那麼就消除了協作編碼時,我的機器能執行,而其他機器不能執行的困境
Docker是基於Go語言的開源專案,Docker可實現應用層的隔離,共享宿主機核心、而虛擬機器是隔離系統,連核心,硬體都是各自模擬的
2. Docker的結構
Docker_Host (宿主機):安裝了Docker程式的主機,形式為一個守護程式
Client (客戶端):連線docker主機進行操作(與守護程式通訊)
Registry (倉庫):儲存各種打包好的映象(類似Github)
Images (映象):軟體打包好的映象,放進倉庫中(筆者理解為類,可以派生物件)
Containers (容器):映象啟動後的例項成為容器(筆者理解按照類建立的物件)
3. 解除安裝、安裝
3.1 解除安裝
# 解除安裝舊版本
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engin
# 解除安裝新版本
$ sudo rm -rf /var/lib/docker
$ sudo rm -rf /var/lib/containerd
$ yum remove docker-ce docker-ce-cli containerd.io
主機上的映象、容器、卷、自定義配置是不會自動刪除的需要手動
3.2 配置Docker庫
$ yum install -y yum-utils
$ yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
安裝yum工具包,裡面包含yum-config-manager,用來設定yum配置
首次安裝Docker需在yum中設定的Docker儲存庫,之後就可從Docker儲存庫中安裝和更新
3.3 安裝
$ yum install docker-ce docker-ce-cli containerd.io
docker-ce引擎(社群免費版)、cli(可遠端連線守護程式)、containerd(提供容器管理服務)
3.4 啟動
$ systemctl start docker
$ systemctl enable docker
$ docker version # 檢視版本
3.5 設定映象加速
$ vim /etc/docker/daemon.json
# 去阿里雲開發平臺檢視自己的倉庫地址
{
"registry-mirrors": ["https://XXXXXXXX.mirror.aliyuncs.com"]
}
$ systemctl daemon-reload
$ systemctl restart docker
梯子加速你懂的 —_—
4. 啟動案例
下面舉幾個例子,現在看不懂沒關係,看看使用Docker有多快速
4.1 Hello-World
# 輸入命令並執行
$ docker run hello-world
閱讀執行之後的說明,裡面有步驟與相關資訊,對理解其原理有很大的幫助
4.2 啟動Tomcat
以前執行Tomcat,要安裝設定啟動jdk、tomcat,期間還需到weget、tar等命令
現在使用了Docker,只需幾個命令
# 拉取映象,不加後面的標籤預設拉取最新版
$ docker pull tomcat
# 啟動容器
$ docker run -d -p 8080:8080 --name mytomcat -v /root/aria2-downloads:/usr/local/tomcat/webapps tomcat
# 訪問
# 訪問結果是404,因為映象的webapps空的,意思是沒有html頁面給我們訪問
# 其實最新的映象將wepapps改名為webapps.dist,那麼我們只需複製內容過去就可
# 不怕有解決方法,還是按著下面步驟輸入:
$ docker exec -it mytomcat /bin/bash
$ cp -r webapps.dist/* webapps
$ exit
# 再次訪問即可
4.3 啟動MySQL
去Docker官網搜尋MySQL,跟著其步驟走 MySQL的Docker地址,下面的密碼設定官網也都有詳細介紹
因為使用Navicat連線時會發生身份驗證器錯誤,所以我們得進去容器修改驗證器外掛
# 啟動並設定密碼
$ docker run -d -p 3306:3306 --name howlmysql -e MYSQL_ROOT_PASSWORD=123456 mysql
# 進入容器內部
docker exec -it containerId /bin/bash
# 登入容器內的MySQL
mysql -uroot -p 123456
# 修改身份驗證外掛
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
# 重新整理許可權
flush privileges;
4.4 啟動Aria2
一個基於命令列的下載工具
# Aria2本體
$ docker run -d \
--name aria2-pro \
--restart unless-stopped \
--log-opt max-size=1m \
-e PUID=$UID \
-e PGID=$GID \
-e UMASK_SET=022 \
-e RPC_SECRET=<secret> \
-e RPC_PORT=6800 \
-p 6800:6800 \
-e LISTEN_PORT=6888 \
-p 6888:6888 \
-p 6888:6888/udp \
-v $PWD/aria2-config:/config \
-v $PWD/aria2-downloads:/downloads \
p3terx/aria2-pro
# Web介面
$ docker run -d \
--name ariang \
--log-opt max-size=1m \
--restart unless-stopped \
-p 6880:6880 \
p3terx/ariang
5. 常用命令
5.1 幫助命令
$ docker version
$ docker info # 更詳細資訊,客戶端,伺服器執行狀況
$ docker [命令] --help # 幫助命令
5.2 映象命令
$ docker pull name[:tag] # 拉映象
$ docker rmi name|id # 刪映象
$ docker images # 列出本地映象
$ docker search # 官網查詢映象
5.3 容器命令
# 新建並啟動容器
$ docker run [可選引數] image
--name # 重新命名
-d # 守護容器後臺
-p # 埠對映
-v # 檔案掛載
-i # 互動模式
-t # 分配一個偽終端,後面跟分配的終端 /bin/bash
-e # 環境配置
--rm # 用完就刪包括卷,測試用(docker run --rm -it -p 80:80 nginx)
--restart=always # docker重啟,容器也會跟著啟動
# 列出正在執行的容器
$ docker ps [可選引數]
-a # 顯示包括未執行的
-l # 顯示最近建立的容器
-n # 顯示最近建立的n個容器
-q # 只顯示id
# 生命週期命令
$ docker start name|id
$ docker restart
$ docker stop
$ docker kill
$ docker rm [-f] # 強制刪除執行中的容器
# 容器互動命令
$ docker exec # 在執行的容器裡執行命令
$ docker exec -it id /bin/bash # 進入容器開一個新的終端,exit後不會停止容器執行
$ docker attach id # 進入正在執行的終端
$ ctrl + P + Q # 互動中容器不停止退出
$ docker exit # 互動中停止容器並退出
# 快捷操作
$ docker container prune 刪除所有容器
$ docker rmi $(docker images -q) 刪除所有映象
$ docker rm $(docker ps -aq)
5.4 其他命令
$ docker logs id # 檢視容器的日誌
$ docker top id # 檢視容器裡執行的程式
$ docker inspect id # 檢視映象詳細資訊(層、掛載目錄)
$ docker cp id:容器路徑 宿主機路徑 # 拷貝容器檔案到宿主機
$ docker cp 宿主機路徑 id:容器路徑 # 拷貝宿主機檔案到容器
$ docker volume create|inspect|ls|prue|rm # 資料卷操作
$ docker build id # 由dockerfile生成映象
$ docker history id # 檢視映象如何構建
$ docker save id # 備份映象成.tar檔案
$ docker load id # 載入備份映象.tar檔案,建議上傳倉庫
6. Dockers和虛擬機器的區別
6.1 虛擬機器
模擬出完整的計算機系統(Guest OS),模擬的系統都是完全隔離的,且執行在監視器(Hypervisor)中,這個監視器是軟體、硬體或韌體
Infrastructure (基礎設施):是硬體設施,理解為主機,即筆記本,雲伺服器
Host Operating System (主機作業系統):是主機的物理作業系統,即日常說的作業系統,Linxu、Windows
Hypervisor (虛擬機器監視器):是執行在基礎物理伺服器和虛擬作業系統間的中間軟體層,各應用和虛擬系統可共享硬體
Guest OS (宿主系統):虛擬的作業系統,虛擬機器內部執行的作業系統,有完整的硬體和核心(Docker是共享)
Bins/Libs (命令/資源):二進位制命令和資源庫
APP (應用程式):使用者安裝的程式
缺點:要執行幾個隔離的應用,就要監視器啟動幾個宿主系統,也就是幾個虛擬機器。虛擬機器模擬了多個隔離的系統,佔用了很多的硬碟、CPU、記憶體,所以啟動也很緩慢。
6.2 Docker
Docker是執行容器的引擎,我們將 作業系統的基礎庫檔案、應用程式、所需的依賴等打包到映象中,然後通過映象建立容器(類和物件),而容器就在Docker中執行
Docker Daemon (守護程式):守護程式取代Hypervisor,是個程式,負責管理Docker容器
守護程式與宿主機通訊,為容器分配資源
使用宿主機的硬體資源,無需虛擬化硬體資源,所以容器無需載入核心,因此是秒級
Docker使用了cgroup + namespace,前者限制資源集,後者限制可訪問許可權
Docker是Client-Server結構,守護程式在宿主機上,客戶端socket連線程式管理執行在主機上的容器
6.3 對比
虛擬機器:徹底隔離整個執行環境,每個執行的虛擬系統都是完全隔離的
Docker:隔離不同的應用程式,比如資料庫,後端,前端等
比對項 | Container(容器) | VM(虛擬機器) |
---|---|---|
啟動速度 | 秒級 | 分鐘級 |
執行效能 | 接近原生 | 有所損失 |
磁碟佔用 | MB | GB |
數量 | 成百上千 | 一般幾十臺 |
隔離性 | 程式級別 | 系統級別 |
作業系統 | 只支援Linux | 幾乎所有 |
封裝程度 | 只打包專案程式碼和依賴關係,共享宿主機核心 | 完整的作業系統 |
7. 圖形化介面
筆者瞭解到的圖形化管理工具是Portainer,也是在Docker上執行的程式,建議跟著倉庫文件走
# 必須掛載
$ docker run -d -p 9000:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce
具體各位去摸索一下把~
8. 映象 image
映象一種輕量級、可執行的獨立軟體包,用來打包軟體的執行環境和基於執行環境開發的技術。它包含執行某個軟體需要的所有內容(包括程式碼、執行庫、環境變數和配置檔案)
8.1 聯合檔案系統
聯合檔案系統(UnionFS):是一個分層的、輕量級並且高效能的檔案系統,它支援對檔案系統的修改作為一次提交來一層層疊加(類似Git),同時可以將不同目錄掛載到同一虛擬檔案系統下(-v 檔案掛載)
UnionFS是Docker映象的基礎,映象可以通過分層來進行繼承(分層可以共用),基於基礎映象可以製作各種具體的應用映象
一次同時載入多個檔案系統,但從外面看只能看到一個檔案系統,聯合載入會把各層檔案系統疊加起來,這樣最終的檔案系統會包含所有的底層檔案和目錄
8.2 映象載入原理
Docker使用UnionFS進行分層,底層是bootfs檔案系統(bootloader載入最基礎的核心、kernvel)
bootfs的上一層是rootfs,也就是 /dev,/bin,/etc等標準目錄和檔案
不同的映象中有相同的分層,那宿主機只需在磁碟、記憶體中儲存一份,這些映象共享這些分層
8.3 映象層的疊加
假如我們在Docker上安裝tomcat,首先底層是bootfs層,然後在上面安裝centos (rootfs),意思是修改了檔案系統,那就會疊加一層檔案系統、依次類推,還有jdk8層、tomcat層。最終打包成tomcat這個映象,對外則是一個整體
映象都是隻讀的,當容器啟動時,一個新的可寫層被載入到映象的頂部(容器層,之下叫映象層)
若我們在容器層刪除了檔案,那麼會生成一個wihteout檔案,將對應的下層檔案隱藏掉
8.4 提交生成映象
上面tomcat的案例我們已經修改過webapps的內容,因修改了聯合檔案系統,所以可作為一次提交來層層疊加
# 提交到本地倉庫,沒有add行為了
# name[:tag] 是 自己命名的 映象名[tag] 作為映象名
$ docker commit -m "提交資訊" -a "作者" id name[:tag]
# eg:
$ docker commit -m "add webapps files" -a "Howl" 9c8524bxxxx mytomcat:1.0
# 然後就可看到自己打包的映象了
$ docker images
9. 資料卷
資料卷(volume)是由docker掛載到容器(不屬於UFS)存在於一個或多個容器中的目錄或檔案,因此能繞過UFS一些用於持續儲存或共享資料的特性
卷的出現是為了資料的持久化和同步操作,其完全獨立於容器的生存週期,因此在刪除容器時其掛載的資料卷不會被刪除。簡單來說:使容器和宿主機共享獨立於docker生命週期的資料、亦或者:獨立於docker生命週期的目錄掛載
特點:
- 資料卷可以容器之間共享或重用
- 卷中的更改直接生效
- 卷中的更改不會包含在映象的更新中
- 資料卷的生命週期持續到沒有容器使用為止
9.1 具名、匿名掛載
資料卷的預設地址 /var/lib/docker/volumes/xxx
$ docker run -v /宿主機絕對路徑:/容器內目錄 name[tag] # 具名掛載(不加"/",在預設地址下起個名字而已)
$ docker run -v /容器內目錄 name[tag] # 匿名掛載,宿主機用預設地址(會生成唯一的32位id)
# 還有隻讀,讀寫許可權
$ docker run -v /宿主機絕對路徑:/容器內目錄:ro|rw name[tag]
# 還有先建立資料卷,後面再掛載
$ docker volume create mysql_data
$ docker run -d -p 3306:3360 -v mysql_data:/root/mysql_data
9.2 Dockerfile掛載
這裡說明有這種掛載方式,什麼是dockerfile下面會講
$ FROM centos
# 沒有"/",是匿名掛載,宿主機的預設地址
# 容器內直接在根目錄下
$ VOLUME ["volume01","volume02"]
$ CMD echo "----Howl write dockerfile----"
$ CMD /bin/bash
9.3 容器資料卷
容器資料卷是用於容器間的資料共享,操作方式還是命令列: --volume-from
# centos01就叫資料卷容器
$ docker run -d --name centos01 howl/centos:1.0
$ docker run -d --name centos02 --volume-from centos01 howl/centos:1.0
這是資料卷,不和容器同生命週期,所以哪怕父容器刪了,其餘容器也能訪問同步
10. Dockerfile
Dockerfile是有一系列命令和引數的指令碼,通過這個指令碼我們可以構建一個映象
10.1 Dockerfile指令
指令必須都是大寫,從上往下執行,且每個指令都會建立一層(可用&&
將命令連起來只生成一層)
命令 | 語法 | 解釋 |
---|---|---|
FROM | FROM image[:tag] | 指定基礎映象,必須第一條。FROM scratch表示不以任何映象為基礎 |
MAINTAINER | 維護者資訊 | |
RUN | 映象構建時需要執行的命令 | |
ADD | 複製本地壓縮檔案,會自動解壓 | |
WORKDIR | 映象工作目錄 | |
VOLUME | 設定容器卷 | |
EXPOSE | 指定堆外埠 | |
CMD | 指定容器執行中的命令,會被覆蓋 | |
ENTRYPOINT | 指定容器啟動時執行的命令,可以追加命令 | |
ONBUILD | 當構建一個被繼承Dockerfile時會執行該指令 | |
COPY | COPY 宿主檔案地址 容器檔案地址 | 將檔案拷貝到映象中 |
ENV | 構建時設定環境變數 |
10.1 編寫Dockerfile
舉例做個tomcat映象,需要準備tomcat壓縮包、jdk壓縮包、readme檔案
$ FROM centos
$ MAINTAINER howl
$ COPY readme.txt /usr/local/readme.txt
$ ADD jdk-8u291-linux-x64.tar.gz /usr/local
$ ADD apache-tomcat-8.5.68.tar.gz /usr/local
$ RUN yum -y install vim
$ ENV MYPATH /usr/local
$ WORKDIR $MYPATH
# JAVA_HOME 目錄安裝之後才知道
$ ENV JAVA_HOME /usr/local/jdk1.8.0_291
$ ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
$ ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.68
$ ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.68
$ ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib
$ EXPOSE 8080
$ CMD /usr/local/apache-tomcat-8.5.68/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.68/bin/logs/catalina.out
每條指令都會建立一個新的映象層,並對映象進行提交
若構建名為Dockerfile那麼就會自動查詢,不用-f去指定了
Docker執行得有前臺應用在執行,不然會自動結束,tail就是為了前臺執行,比如top等命令
注意:根據linux位數,arm,aarch64來安裝jdk,筆者安裝錯了,走了很多彎路
10.2 Build製作映象
# -f 指定dockerfile的路徑
# -t 生成的映象名字[:tag] 生成映象的地址
# . 表示當前目錄
$ docker build -t howl/tomcat .
10.3 執行製作的映象
$ docker run -d -p 8080:8080 howl/tomcat
有個注意的地方,webapps下要新建目錄才能訪問的,不能放入已有資料夾內,也不能直接放入webapps裡面
10.4 釋出映象
映象的釋出有兩種途徑,分別是:
- DockerHub
# 首先需要登入
$ docker login -u loadingkiller
$ Password: "輸入密碼"
# 推送名字得是自己DockerHub上的賬號名,所以得先改標籤
# 本來 howl/centos 改成 loadingkiller/tomcat
$ docker tag howl/tomcat:latest loadingkiller/tomcat:1.0
# 推送,速度慢等吧
$ docker push loadingkiller/centos:1.0
- 阿里雲映象倉庫
進入阿里雲映象管理可以建立映象倉庫,然後跟著裡面的提示走
# 登入
docker login -u=XXX registry.cn-hongkong.aliyuncs.com
# 選擇分支對應關係
docker tag [ImageId] registry.cn-hongkong.aliyuncs.com/howlet/mytomcat:[映象版本號]
# 推送上去
docker push registry.cn-hongkong.aliyuncs.com/howlet/mytomcat:[映象版本號]
# 拉取
docker pull registry.cn-hongkong.aliyuncs.com/howlet/mytomcat:[映象版本號]