重學Docker


轉了雲方向,代碼都少寫了



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:[鏡像版本號]






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM