Docker基礎用法

Docker基礎用法

1、Docker為什麼會出現?

一款軟件產品必須經過:開發 -> 上線

開發人員負責將應用程序開發製作出來。
運維人員負責上線,配置應用程序。

在這裡存在一個問題:開發環境和上線環境不一致;可能會導致,開發人員在自己的電腦上可以正常運行代碼,運維人員將服務程序上線到服務器後,由於環境不一致可能會導致運行失敗,服務不可用。

如何解決上述問題?

  • 對上線的服務器系統進行環境配置,但環境配置十分麻煩特別是集群部署時,集群中的每一台機器都需要部署環境。
  • 將開發環境和程序代碼一起打包到服務器中運行。

Docker就是將開發環境和程序代碼一起打包到服務器中運行的技術。

java語言 --> apk程序 --> 發佈到應用商店 --> 客戶下載apk --> 安裝使用(必須要有環境才能安裝成功)

java語言 --> jar環境 --> 打包項目和環境(鏡像) --> 上傳到docker倉庫(商店) --> 下載倉庫中的鏡像 --> 運行使用

2、Docker介紹

Docker是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的鏡像中,然後發佈到任何流行的Linux或Windows機器上,也可以實現虛擬化。容器是完全使用沙箱機制,相互之間不會有任何接口。

docker_logo.jpg

Docker的核心思想就是來自集裝箱;集裝箱的概念是隔離貨物,所以docker的核心就是隔離機制。同時docker使用可移植鏡像所以部署以及運維極其方便快捷。

2.1 Docker發展史

2010年,幾個熱愛IT的年輕人,在美國成立了一家公司叫做dotCloud,主要做一些Paas的雲計算服務和LXC有關的容器技術賺錢盈利,他們將自己的容器技術命名為Docker!

Docker剛剛誕生的時候,並沒有引起行業的注意!這個時候 dotCloud公司難以在行業中存活,所以這幾個年輕人選擇開放Docker源代碼來引起注意!

2013年,Docker開源!越來越多的人發現docker的優點,救火了,docker每個月都會更新一個版本!

2014年4月9日,Docker1.0發佈!

Docker為什麼這麼火?十分的輕巧

在容器技術出來之前,我們都是使用虛擬機技術!
虛擬機:在window中裝一個Vmware,通過這個軟件我們可以虛擬出來一台或者多台電腦!(很笨重)
虛擬機也是屬於虛擬化技術,Docker容器技術,也是一種虛擬化技術!

vm:隔離,需要開啟多個虛擬機!linux centos原生鏡像(一個電腦!)需要幾個G內存空間,開啟需要幾分鐘!
docker:隔離,鏡像(最核心的環境4m內存)十分的小巧,運行鏡像就可以了!小巧!幾個M或KB的內存空間,秒級啟動!

2.2 容器和虛擬機的區別

虛擬機:通過虛擬化技術模擬真實的硬件從而創建出來的一台擁有完整功能的邏輯計算機。

Docker容器:docker容器也是一種虛擬化技術,和傳統虛擬化不一樣的是docker只模擬一個程序最核心的運行環境,所以十分小巧,啟動更快。

Docker虛擬化技術和傳統虛擬化技術架構對比:
vm_vs_docker.png

對比 特點
虛擬機 完整的系統功能,隔離性更好,佔用空間大(通常以G為單位),運行佔用資源較多,啟動慢(分鐘級啟動)
容器 只有程序運行的核心環境,不需要安裝直接運行鏡像即可,隔離性一般,十分小巧佔用空間極小(一般以M為單位),啟動快(秒級啟動)

2.3 Docker引擎架構

Docker 引擎(Docker Engine)是目前主流的容器引擎;Docker 引擎是一個包含以下組件的客戶/服務器 架構的應用程序,如圖所示:

Docker引擎組成:
docker_engine.png

  • 服務器:即Docker守護進程(Daemon),這是 Docker 的後台應用程序,可使用 dockerd 命令 進行管理。Docker守護進程監聽來自Docker API的請求,可用於創建和管理 Docker對象,如鏡 像、容器、網絡和卷。一台主機運行一個 Docker守護進程。
  • REST API:定義程序與 Docker守護進程交互的接口,便於編程操作 Docker 平台和容器。REST API是一套目前比較成熟的Internet 應用程序 API架構
  • 客戶端:即命令行接口(Command-Line Interface,CLI),可使用 docker 命令進行操作。命令 行接口又稱命令行界面,可以通過命令或腳本使用 Docker 的REST API 接口來控制Docker守護進 程,或者與Docker守護進程進行交互。當用戶使用 docker run 這樣的命令時,客戶端將這些命令 發送到Docker守護進程來執行。Docker客戶端可以與多個 Docker守護進程進行通信。許 多 D o c k e r 應 用程序都會使用底層的 API和命令行接口。

2.4 Docker 架構

Docker運行架構:
docker_framework.png

  • Docker客戶端與 Docker守護進程通信,而Docker守護進程相當於Docker服務器,負責構建、運 行和分發容器的繁重任務。Docker客戶端與守護進程可以在同一個系統上運行,也可以讓 Docker 客戶端連接到遠程主機上的 Docker守護進程。Docker客戶端和守護進程使用REST API通過UNIX 套接字(Socket)或網絡接口進行通信。D o c k e r守護進程和 Docker客戶端屬於 Docker 引擎的 一部分。
  • Docker 註冊中心用於存儲和分發 Docker 鏡像。Docker Hub和 Docker Cloud 是任何人都可以使 用的公開註冊中心,默認情況下,Docker守護進程會到Docker Hub中查找鏡像。除此之外,用戶 還可以運行自己的私有註冊中心。

2.5 Docker底層技術

  • 名稱空間(Namespace):又 稱命名空間,Linux 的名稱空間機制提供了一種資源隔離的解決方 案。Docker 通過名稱空間機製為容器提供隔離的工作空間,運行容器時,Docker會為該容器創建 一系列的名稱空間
  • 控制組(Control Group):Linux 可以通過控制組設置進程使用 CPU、內存和I/O資源的限額, Linux 上的 Docker 引擎正是依賴這種底層技術來限制容器使用的資源
  • 聯合文件系統(Union File System,UnionFS):這是為 Linux、FreeBSD 和NetBSD 操作系統設 計的一種文件系統,可以將其他文件系統合併到一個聯合掛載點。作為輕量級的高性能分層文件系 統,聯合文件系統支持將文件系統中的變更信息進行提交。聯合文件系統是實現 Docker 鏡像的 技術基礎,Docker 鏡像可以通過分層來實現繼承
  • 容器格式(Container Format):Docker 引擎將名稱空間、控制組和聯合文件系統打包到一起所 使用的就是容器格式。默認的容器格式是 Libcontainer。Docker 將來還可能會通過集成FreeBSD Jails或Solaris Zones 來支持其他的容器格式

2.6 Docker優勢

Docker優勢:

  • 應用程序快速、一致地交付
    • 開發人員在本地編寫應用程序代碼,通過Docker與同事進行共享。
    • 通過Docker將應用程序推送到測試環境中,執行自動測試和手動測試。
    • 開發人員發現程序錯誤時,可以在開發環境中進行修復,然後重新部署到測試環境來進行測試和驗證。
    • 完成應用程序測試之後,向客戶提供補丁程序非常簡單,只需將更新後的鏡像推送到生產環境中。
  • 響應式部署和伸縮應用程序
  • 更簡單的系統運維
    • 在容器化之後,我們的開發,測試環境都是高度一致的!
  • 更高效的計算資源利用
    • Docker是內核級別的虛擬化,可以再一個物理機上可以運行很多的容器實例!

2.7 Docker 名詞解釋

鏡像(image):
docker鏡像就好比是一個模板,可以通過這個模板來創建容器服務,tomcat鏡像=>run=>tomcat1容器(提供服務器),通過這個鏡像可以創建多個容器(最終服務運行或者項目運行就是在容器中的)。

容器(container):
Docker利用容器技術,獨立運行一個或者一個組應用,通過鏡像來創建的。
啟動,停止,刪除,基本命令!
目前就可以把這個容器理解為就是一個簡易的linux系統

倉庫(repository):
倉庫就是存放鏡像的地方!
倉庫分為公有倉庫和私有倉庫!

2.8 Docker中的容器

  • lxc –> libcontainer –> runC

OCI&OCF

OCI

Open Container-initiative

  • 由Linux基金會主導於2015年6月創立
  • 旨在圍繞容器格式和運行時制定一個開放的工業化標準
  • 包含兩個規格
    • 運行規範(runtime-spec)
    • 鏡像規格(image-spec)

OCF

Open Container Format

runC是一個命令行工具,用於根據OCI規範生成和運行容器

  • 容器作為runC的子進程啟動,並且可以嵌入到各種其他系統中,而無需運行守護進程
  • runC是建立在libcontainer之上的,libcontainer是一種支持數百萬Docker引擎安裝的容器技術

docker提供了一個專門容納容器鏡像的站點://hub.docker.com

3、Docker環境部署

# 1.首先配置yum倉庫
curl -o /etc/yum.repos.d/CentOS-Base.repo //mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo
sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo

# 2.卸載舊的版本
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
                  

# 3.設置鏡像的倉庫
yum-config-manager \
    --add-repo \
    //download.docker.com/linux/centos/docker-ce.repo # 默認是從國外的。
yum-config-manager \
    --add-repo \
    //mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 推薦使用阿里雲的。
    
# 4.安裝容器相關的。docker-ce(社區版)docker-ee(企業版)
yum install docker-ce 

# 5.啟動docker服務並設置開機自啟
systemctl start docker
systemctl enable docker
# 6.使用docker version查看是否安裝成功
docker version

# 7.測試hello-world
docker run hello-world

# 8.查看一下,下載的這個hello-world鏡像

docker加速

docker-ce的配置文件是/etc/docker/daemon.json,此文件默認不存在,需要我們手動創建並進行配置,而docker的加速就是通過配置此文件來實現的。

docker的加速有多種方式:

  • docker cn
  • 中國科技大學加速器
  • 阿里雲加速器

阿里雲加速器使用方法

打開瀏覽器,訪問阿里雲官網

登錄之後點擊右上角控制台,在點擊左上角產品與服務

彈性計算里找到容器鏡像服務

在/etc/docker目錄下新建文件daemon.json將加速器地址寫入

mkdir -p /etc/docker
vim /etc/docker/daemon.json
{
"registry-mirrors": ["//此處地址為自己阿里雲鏡像加速地址.mirror.aliyuncs.com"]
}

重啟服務

systemctl daemon-reload
systemctl restart docker

了解:卸載docker

# 1.卸載依賴
yum remove docker-ce 

# 2.刪除資源
rm -rf /var/lib/docker
rm -rf /var/lib/containerd

# /var/lib/docker  docker的默認工作路徑

4、Docker的常用命令

4.1 幫助命令

docker version         # 顯示docker的版本信息
docker info           # 顯示docker的系統信息,包括鏡像和容器的數量
docker 命令 --help      # 幫助命令

4.2 鏡像命令

docker images 查看所有本地的主機上的鏡像

[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    feb5d9fea6a5   10 months ago   13.3kB
# 解釋
REPOSITORY     //鏡像的倉庫源
TAG          //鏡像的標籤
IMAGE ID       //鏡像的id
CREATED        //鏡像的創建時間
SIZE          //鏡像的大小
# 命令參數可選項
 -a, --all         # 顯示所有鏡像 (docker images -a)
 --digests 		      #顯示鏡像的摘要信息(docker images --digests)
 -q, --quiet        # 僅顯示鏡像id (docker images -q)

docker search 搜索鏡像

[root@localhost ~]# docker search mysql
NAME      DESCRIPTION                            STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   12966     [OK]       
......
# 解釋
NAME			   //鏡像倉庫源的名稱
DESCRIPTION		//表示該鏡像的功能
STARS			   //表示下載熱度
OFFICIAL		  //是否docker官方發佈
AUTOMATED		  //自動構建
# 命令參數可選項 (通過搜索來過濾)
--filter=STARS=3000     # 搜索出來的鏡像就是stars大於3000的
[root@localhost ~]# docker search mysql --filter=STARS=3000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…             12966      [OK]       
mariadb   MariaDB Server is a high performing open sou…              4966      [OK]       

docker pull 下載鏡像

# 下載鏡像:docker pull 鏡像名[:tag]
[root@localhost ~]# docker pull mysql
Using default tag: latest						#如果不寫tag,默認就是latest,最新的版本
latest: Pulling from library/mysql
32c1bf40aba1: Pull complete 				 # 分層下載,docker image的核心,聯合文件下載
3ac22f3a638d: Pull complete 
b1e7273ed05e: Pull complete 
20be45a0c6ab: Pull complete 
410a229693ff: Pull complete 
1ce71e3a9b88: Pull complete 
c93c823af05b: Pull complete 
c6752c4d09c7: Pull complete 
d7f2cfe3efcb: Pull complete 
916f32cb0394: Pull complete 
0d62a5f9a14f: Pull complete 
Digest: sha256:ce2ae3bd3e9f001435c4671cf073d1d5ae55d138b16927268474fc54ba09ed79
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest			# 真實地址

# 指定版本下載
[root@localhost ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
72a69066d2fe: Already exists        # 聯合文件下載,已經存在的資源可以共用
93619dbc5b36: Already exists
99da31dd6142: Already exists
626033c43d70: Already exists
37d5d7efb64e: Already exists
ac563158d721: Already exists
d2ba16033dad: Already exists
0ceb82207cd7: Pull complete
37f2405cae96: Pull complete
e2482e017e53: Pull complete
70deed891d42: Pull complete
Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

docker rmi 刪除鏡像

[root@localhost ~]# docker rmi -f 鏡像id              # 刪除指定的鏡像
[root@localhost ~]# docker rmi -f 鏡像id 鏡像id 鏡像id    # 刪除多個鏡像(空格分隔)
[root@localhost ~]# docker rmi -f $(docker images -aq)    # 刪除全部的鏡像

docker inspect 獲取鏡像的詳細信息

[root@localhost ~]# docker inspect 鏡像名:標籤

docker tag 添加鏡像別名,類似於別名

[root@localhost ~]# docker tag 鏡像名:標籤 新鏡像名:新標籤

# 示例:
[root@localhost ~]# docker tag mysql:5.7 mysql:alone
[root@localhost ~]# docker images 
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
mysql        5.7      3147495b3a5c   8 days ago      431MB
mysql        alone     3147495b3a5c   8 days ago      431MB

4.3 容器命令

說明:我們有了鏡像才可以創建容器,下載一個centos 鏡像來測試學習。

docker pull centos

容器創建命令

docker create 創建新容器

[root@localhost ~]# docker create 鏡像名

# 示例:
[root@localhost ~]# docker create centos
1f8c0d836c2751fd39b46922d256505626925a7519154e2d0b811ede561bb097
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS    PORTS     NAMES
1f8c0d836c27   centos    "/bin/bash"   10 seconds ago   Created             jovial_chaum

docker run 容器創建並運行

docker run [可選參數] image
# 參數說明
--name="name"        容器名字:用來區分容器
-d                    後台方式運行:相當於nohup
-it                    使用交互式運行:進入容器查看內容
-p                    指定容器的端口(四種方式)小寫字母p
    -p ip:主機端口:容器端口
    -p 主機端口:容器端口
    -p 容器端口
    容器端口
-P                     隨機指定端口(大寫字母P)

#使用centos鏡像啟動一個名為centos0的容器
[root@localhost ~]# docker run --name centos0 centos

# 使用centos鏡像啟動容器並分配一個bash shell的終端進入容器
[root@localhost ~]# docker run -it centos /bin/bash
[root@6c39cc898c6c /]# ls		 # 查看容器內的centos(基礎版本,很多命令都是不完善的)
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@6c39cc898c6c /]# exit
exit
# 注意:
1.指定-it選項為容器分配shell後,啟動容器時運行的命令將會被shell替代
2.不加-d選項的容器一旦使用exit退出容器shell,容器就終止運行;ctrl+p+q可以退出shell,容器仍將繼續運行

# 使用 mysql鏡像啟動一個名為 mysql1的容器並在後台運行
[root@localhost ~]# docker run --name mysql1 -d mysql
867c0734a5f21ae1fb607f5cdf2eb03bb4494eb5dc1056caa164689d0a2dc76f

#使用 mysql鏡像啟動一個名為 mysql2的容器,該容器在後台運行,訪問宿主機的8080端口可以訪問到容器的80端口
[root@localhost ~]# docker run --name mysql2 -d -p 8080:80 mysql
c07b515d0041fbb6905990c9377971fd0353cdb63e1adb80f5f05648d850baf8

容器查看命令

docker ps 查看容器運行狀態

# 選項:
-a 			//顯示所有的容器,包括未運行的
-q			//只顯示容器id
-l			//顯示最近創建的容器。
-f "篩選條件"		//根據條件過濾顯示的內容

# 示例:
示例:
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE        COMMAND    CREATED          STATUS           PORTS     NAMES
c8af463c6e52   hello-world   "/hello"   14 seconds ago  Exited (0) 13 seconds ago     strange_cartwright

# 解釋
CONTAINER ID		 //容器 ID
IMAGE			     //使用的鏡像
COMMAND			   //啟動容器時運行的命令
CREATED			   //容器的創建時間
STATUS			  //容器狀態
# 容器狀態有7種:
	created(已創建)
	restarting(重啟中)
	running(運行中)
	removing(遷移中)
	paused(暫停)
	exited(停止)
	dead(死亡)
PORTS			//容器的端口信息和使用的連接類型(tcp\udp)。
NAMES			//容器名稱

docker inspect 查看容器詳細信息

# 示例:
[root@localhost ~]# docker inspect test
......略........

容器刪除命令

docker rm 刪除容器

docker rm 容器名			//刪除容器,無法刪除運行狀態下的容器
選項:
-f				//強制,可以刪除運行狀態下的容器

# 示例:
//刪除mysql1容器
[root@localhost ~]# docker rm nginx01
mysql1

//批量刪除所有容器
[root@localhost ~]# docker rm $(docker ps -qa)
9b2fa686b4ae
a4f41fb35ac3

容器生命周期管理命令

docker start   容器名	//開啟容器
docker stop    容器名	//停止容器
docker kill    容器名	//殺死容器
docker restart  容器名	 //重啟容器
docker pause   容器名	//暫停容器中所有的進程
docker unpause  容器名	 //恢復容器中所有的進程

容器佔用資源查看命令

docker stats  容器名	//查看容器使用資源信息
docker top    容器名	//查看容器中運行的進程信息,支持ps命令參數
docker port   容器名	//查看宿主機端口和容器端口之間的端口映射

容器日誌查看命令

# 當容器創建失敗時,因為容器沒有啟動成功則無法看到錯誤日誌,無法判斷問題所在,下面命令可以查看日誌,不管容器時候啟動成功

docker logs   容器名	//獲取容器的日誌信息
選項:
-f			//跟隨打印最新的日誌追加在最後面
-t			//顯示日誌打印的時間戳
--tail 數量		//只顯示最新的指定數量的幾條日誌信息

容器內進程連接和命令執行

docker attach 連接到正在運行的容器進程中,默認連接到容器啟動時啟動的進程

# 連接到httpd03容器中的nginx進程,此時可以看到httpd03工作日誌
[root@localhost ~]# docker attach httpd03
172.17.0.1 - - [04/Aug/2022:09:06:29 +0000] "GET / HTTP/1.1" 304 -
# 注意:使用attach連接到容器容器進程,一旦終止容器內的進程,容器就終止運行

# 如果容器啟動時運行的命令是shell進程,則連接shell終端
[root@localhost ~]# docker attach httpd04
root@6b830320e24a:/usr/local/apache2# exit
exit

docker exec 不進入容器執行容器中的命令

# docker exec 容器名 執行命令	
選項:
-d				//後台執行,不顯示結果
-it				//為容器分配一個始終運行的偽終端,需要指定shell;-i保持運行狀態,-t是分配偽終端

# 示例:
#不進入容器執行容器中的ls命令
[root@localhost ~]# docker exec httpd04 ls			
bin
build
cgi-bin
......

# 使用docker exec命令打開一個shell進入到容器中,使用exit退出shell,容器也不會終止運行
[root@localhost ~]# docker run --name httpd05 -it -d httpd /bin/bash	
1b656ba8a5b5689c0b2e688537358779964a9e43f174ce3ab5ff7196dac4e402
[root@localhost ~]# docker exec -it httpd05 /bin/bash
root@1b656ba8a5b5:/usr/local/apache2# exit
exit

注意:

# docker exex # 進入容器後開啟一個新的終端,可以再裏面操作(常用)

# docker attach # 進入容器正在執行的終端,不會啟動新的進程。

5、docker event state

Tags: