Docker 安裝、常用命令、應用部署



Docker 安裝

Docker 可支持在 Mac、Windows、Linux 系統上安裝,但是在 Windows 系統中 Docker 的安裝包目前僅有 win10 專業版和企業版的。win10 家庭版可以采用開啟 Hyper-V 偽裝成專業版繞過安裝檢測。還有一種方式是通過 Docker toolbox 來安裝(適用於 win7/win8/win10 家庭版),下載地址:http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/ (本質上相當於安裝了一個 linux 虛擬機)。

Docker 分為社區版和專業版,社區版本的官網:https://docs.docker.com/install/overview/

1)安裝

環境說明

這里以 Centos 8 安裝和使用 Docker 為演示示例(Docker 官網關於 centos 上如何安裝 Docker 的文章如下:https://docs.docker.com/install/linux/docker-ce/centos/)

Centos 8 安裝 Docker,在保證可以通外網的情況下,通過 yum 安裝(yum 是 Centos 和 Redhat 下便捷的管理安裝的軟件,如果是 ubuntu 系統則可以通過 apt)。

1)安裝前置包

yum install -y yum-utils device-mapper-persistent-data lvm2 libseccomp-devel

2)安裝 docker 的 yum 源

# 可以使用官方源,這個安裝過程可能會比較慢
yum-config-manager --add-repo  https://download.docker.com/linux/centos/docker-ce.repo

# 或者使用阿里雲的鏡像源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

image

docker-ce 是 Docker 的發行版本,yum 安裝的目標就是 docker-ce。

3)使用 yum list 查看可安裝版本

yum list docker-ce --showduplicates

image

yum install –y docker-ce-3:19.03.15-3.el8

這里選擇 19.03 版本,如果不加版本號,會默認安裝最新版本。

2)啟動

Docker 引擎啟停操作:

# 啟動
systemctl start docker
# 重啟
systemctl restart docker
# 開機自啟動
systemctl enable docker
# 運行狀態
systemctl status docker

3)鏡像加速器

默認情況下從 docker hub 上下載 docker 鏡像的速度太慢,因此一般都會配置鏡像加速器:

# 添加 registry-mirrors
vim /etc/docker/daemon.json

# 內容
{
  "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}

# 重載 docker 的配置文件
systemctl daemon-reload

# 重啟 Docker
systemctl restart docker 

# 查看配置
docker info 

Docker 常用命令

image


1)Docker 進程相關命令

Docker 信息相關命令

# Docker 版本信息
docker version
# Docker 系統信息
docker info

Docker 啟停相關命令

# 啟動 Docker 服務
systemctl start docker

# 停止 Docker 服務
systemctl stop docker

# 重啟 Docker 服務
systemctl restart docker

# 查看 Docker 服務狀態
systemctl status docker

# 設置開機啟動 Docker 服務
systemctl enable docker

2)Docker 鏡像相關命令

docker search:查找鏡像倉庫中的鏡像

# 比如想要搜索具有 nginx 功能的容器
docker search nginx

image

  1. 第一列鏡像名稱,如果沒有路徑符號”/”,說明在默認路徑中,如果有路徑,說明在子倉庫中。
  2. 第二列描述,簡要說明該鏡像的用途和特點。如果想要完整顯示說明,可以增加參數 --no-trunc。
  3. 第三列是點贊數,類似於 git 上的點贊。
  4. 第四列標明是否為官方發布。
  5. 第五列是自動構建,是用 webhook 探測源碼的變化,一旦有變化就自動生成新的版本鏡像。

docker pull:下載鏡像

從 Docker 倉庫下載鏡像到本地,鏡像名稱格式為名稱:版本號,如果版本號不指定則是最新的版本。

docker pull nginx

如下圖所示,將會下載該鏡像。注意看該鏡像會有多個分層,之后再下載其它鏡像的時候,有可能部分層級可以復用,不需要全部下載。

image

另外注意箭頭指的位置,由於 docker pull nginx 沒有指定 tag(版本),會使用默認的版本下載。

再嘗試下載 alpine 環境,alpine 是一款輕量級操作系統,只有 5M 左右。很多鏡像制作都會選擇 alpine 作為基礎鏡像。這里僅下載一個純凈的 alpine,作為后續演示使用。

docker pull alpine

注意查看下圖中,docker pull 命令后面的 nginx 跟了 tag,可以看出,tag 不僅僅包含了版本號,還包含了主要的特性。

另外看箭頭所指,之前下載過 alpine 的基本鏡像,所以基於 alpine 的 nginx 會省略下載 alpine,復用之前下載的已存在分層。

image


docker inspect:查看鏡像/容器的詳細信息

docker inspect 鏡像/容器名稱

Docker Inspect 語法參考


在 hub.docker.com 上查找鏡像

也可以在 hub.docker.com 網站上查找鏡像,同時還可以看到該鏡像的 tag 信息,選擇合適的 tag 下載。

image

image

image

image

如上述步驟,找到其它版本的 tag,可以點擊這個復制按鈕,直接將命令復制出來。


docker images:查看本地鏡像

docker images  # 查看本地所有的鏡像
docker images –q  # 僅顯示鏡像id,常用於批量刪除鏡像

image


docker rmi:刪除本地鏡像

docker rmi 鏡像id或鏡像名稱的前綴即可  # 刪除指定的本地鏡像
docker rmi `docker images -q`  # 刪除所有本地鏡像

本地鏡像或者遠程鏡像倉庫中的垃圾鏡像越來越多時,需要進行清理刪除。

image

圖中存在沒有 repository 和 tag 的鏡像的原因是:使用相同的鏡像名稱構建新鏡像時,由於 dockerfile 中的基礎鏡像或者 RUN 后面的命令有變化,就會導致舊的重名鏡像變成沒有 repository 和 tag 的情況。


docker history:查看鏡像構建歷史

docker history [options] IMAGE

通常只用一個參數 --no-trunc:不截斷輸出。

image

docker history 命令在查看自己構建的鏡像時會相對容易和方便一些。官方鏡像總要考慮大部分的需求,所以相對比較繁瑣。


docker save:導出鏡像

docker save 鏡像名稱 > 鏡像名稱.tar

docker load:導入鏡像

docker load < 鏡像名稱.tar

鏡像重命名

docker tag 鏡像原來名稱 鏡像新名稱

3)Docker 容器相關命令

  • 容器的本質是管理進程。啟動容器必定會伴隨容器內一個或者多個用戶進程的啟動,如果容器內的用戶進程在啟動后執行完畢或者崩潰,那么該容器就會退出。與虛擬機不同,虛擬機啟動的是操作系統,如果沒有用戶進程,則會等待用戶的登錄和操作。

  • 最好是一個容器只執行一個進程,完成單一任務。

  • 雖然容器可以被登錄,但最好不要登錄進去操作,除非是為了修改鏡像。


docker run:啟動容器

docker run 參數
# -it 創建的容器一般稱為交互式容器
# -id 創建的容器一般稱為守護式容器

參數說明

  • -i:保持容器運行
    • 通常與 -t 同時使用。加入 it 這兩個參數后,容器創建后會自動進入容器中。
    • 退出容器后,容器自動關閉。
  • -t:為容器重新分配一個偽輸入終端
    • 通常與 -i 同時使用。
  • -d:以守護(后台)模式運行容器
    • 創建一個容器並在后台運行,需要使用 docker exec 進入容器。
    • 退出容器后,容器不會關閉。
  • --name:為創建的容器命名。

示例:docker run -it alpine

image

如圖所示已經進入了容器的 shell,可以操作查看這個 shell:

  • uname -a 查到系統內核和宿主機的一致,說明容器使用底層宿主機的內核。
  • pwd 和 ls 可以看到此時 shell 的目錄結構和宿主機不一致。

容器是用來管理進程的,在虛擬機的宿主機中,執行 ps 是看不到虛擬機內部的進程的。但是容器不一樣,在容器的宿主機中執行 ps,是可以看到容器執行的進程的。從本質上看,容器僅僅是在宿主機中把進程啟動起來,並且進行資源隔離。


容器退出

  • 使用 ctrl+dexit 命令,容器都會退出。ctrl+d 或者 exit 相當於結束當前 shell,在未指定命令情況下啟動容器時,相當於僅啟動了 /bin/bash,退出后結束 bash,容器退出。

  • 使用 ctrl+q+p 退出,會保持該容器在后台運行,容器不會結束。


docker ps:查看當前容器狀態

docker ps  # 查看正在運行的容器
docker ps –a  # 查看所有容器
docker ps –qa  # 僅顯示 id 號,常用於批量刪除容器

image

如上圖所示,不加任何參數,查看正在運行的容器:目前沒有正在運行的容器。

  • CONTAINER ID:容器的 ID。
  • IMAGE:啟動使用的鏡像。
  • COMMAND:啟動容器時傳入的命令。
  • CREATED:創建時間。
  • STATUS:容器狀態。
  • PORTS:端口映射情況。
  • NAMES:容器的名稱,如果沒有指定,會隨機分配。

image

-a 參數可以查看所有狀態的容器,包括停止、退出等狀態的容器。

如上圖所示目前有一個容器,但狀態是已經退出。


docker pause:暫停容器

docker pause CONTAINER [CONTAINER]   # 暫停
docker unpause CONTAINER [CONTAINER]   # 恢復

image

如圖所示,docker pause 時用的容器 mynginx 進入了暫停狀態。恢復的時候用的容器 id,容器恢復正常狀態。注意恢復后的狀態開啟時間並沒有重新計時,而是繼續計時,暫停時間也會算進開機時間。

如果使用容器 id 則只要用 id 的前若干位即可,只要前幾位沒有沖突,通常使用三位。這個規則適用於整個 docker 的場景。

Paused 狀態意味着暫停、掛起,但是容器管理的進程並沒有停止。整體上更像是虛擬機的快照暫停方式,把當前容器做個快照放在磁盤中,然后釋放該容器的資源。等需要恢復的時候,把容器的內容從磁盤中讀出來重新進入內存。底層使用的是 cgroup 的 freezer 能力。


docker stop:停止容器

docker stop CONTAINER [CONTAINER]  # 停止
docker start CONTAINER [CONTAINER]  # 啟動
docker restart CONTAINER [CONTAINER]  # 重啟

image

這三個狀態類比虛擬機,就是關機、啟動和重啟。stop 后容器管理的進程會徹底停止、清理內存;start 啟動容器時會沿用容器 run 或者 create 時候的參數。

這和虛擬機類似的操作過程相同,磁盤中的內容會被保存,但是內存中的內容會被清理掉。


docker exec:進入容器

對於后台執行的容器或者容器的輸出日志,我們都有查看的需求。

方式一:docker attach(不推薦使用)

該命令使用不當的話,會導致容器中的進程結束運行,進而容器退出。使用的時候一定加上 --sig-proxy=false 參數。

方式二:docker exec(推薦使用)

docker exec [options] CONTAINER CMD

該命令用途是在運行中的容器里執行命令,當然也可以在運行的容器中執行 /bin/bash。

注意 exec 不默認傳參數,必須跟參數:

image

上圖中,首先在后台啟動一個交互式 alpine 容器,並查看這個容器狀態,確認運行中。后續操作需要用到容器名稱,所以重命名一下。接着讓這個容器執行一下 echo 命令。可以看到執行后容器輸出 hello,並且不會退出,仍然在運行狀態中。

執行 /bin/bash,就可以進到容器中進行操作,注意 /bin/bash 需要交互和打開標准輸入:

image

如上圖中的報錯,最初執行 docker exec -it myalpine /bin/bash,由於 alpine 中沒有 bash 這個命令,所以報錯。

使用 /bin/sh 后就可以進入容器執行命令了,退出后不影響原容器運行。

注意很多鏡像里面並不帶 kill 命令,但是如果帶 kill 命令並且在 exec 中執行 kill 主進程操作,或者執行了主進程的停止操作,會導致容器直接退出。


docker create:創建容器

docker create [option] IMAGE [CMD]

docker run 命令相當於執行了 create 和 start 兩個命令。


docker rename:容器重命名

docker rename 容器原來名稱 容器新名稱

docker log:查看容器日志

docker logs [options] CONTAINER

docker rm:刪除容器

不加 -f 參數時,如果容器是運行狀態則刪除失敗,需要停止容器才能刪除。

docker rm [OPTIONS] 容器名稱/id [CONTAINER...]

OPTIONS 說明:

  • 不加參數情況下,可以刪除已經停止的容器。
  • -f:通過 SIGKILL 信號刪除一個正在運行的容器。
  • -l:移除容器間的網絡,而非容器本身。
  • -v:刪除與容器映射的目錄。

宿主機運行一段時間后,會有大量已經停止的容器,如果需要批量刪除,可以使用以下命令:

docker rm $(docker ps -qa)

image

最終只剩下運行中的容器。當然也可以使用 -f 參數刪除所有容器,慎重使用。


docker commit:生成鏡像

若以交互模式修改了容器內容,需要 commit 成新的鏡像。

1)修改容器內容:

[root@MiWiFi-R3P-srv tmp]# docker  run -it centos
[root@e59e110aaf47 /]# yum install -y nginx
[root@e59e110aaf47 /]# vi /etc/nginx/nginx.conf  # 在全局配置中加入"daemon off;"

2)退出容器:

image

3)執行 commit 命令:

image

4)運行中的容器也可以 commit,並且容器層的數據也會保留:

image

  1. 注意上圖中,啟動 nginx:v7commit 需要以 nginx 的啟動命令,否則容器會退出;
  2. 使用 docker exec 進入容器,並編輯內容;
  3. 本次 commit 使用和之前完全一樣的鏡像名稱和 tag,所以在名稱前加一個 test 目錄;
  4. 接下來啟動這個鏡像,看 echo 修改的內容和文件會不會存在:

image


docker top:查看容器中運⾏的進程

docker top 容器名稱

docker stats:查看資源占⽤

docker stats 容器名稱

docker cp:拷貝宿主機/容器中的文件

該命令和存儲無關,但是可以把容器內的文件拷貝出來,或者把宿主機文件拷貝進容器。

docker cp CONTAINER:dir host_dir
docker cp host_dir CONTAIN:dir

整體寫法和 cp 一樣,只是要加上容器的 id 號或者名字。

如下示例,將容器中整個目錄拷貝出來,注意不需要加 -r 參數:


--restart:開機自啟動

在運行 docker 容器時可以加如下參數,來保證每次 docker 服務重啟后,容器會自動啟動。

docker run --restart=always CONTAINER_ID

如果已經啟動了則可以使用如下命令:

docker update --restart=always CONTAINER_ID  # 自動啟動
docker update --restart=no CONTAINER_ID  # 不自動啟動

Docker 容器的數據卷(Volumn)

什么是數據卷?

問題現象

  1. Docker 容器刪除后,在容器中產生的數據也會隨之銷毀。
  2. Docker 容器和外部機器可以直接交換文件嗎?不能。
  3. 容器之間想要進行數據交互?

上述問題的解決方案:數據卷

image

什么是數據卷?

  • 數據卷是宿主機中的一個目錄或文件。
  • 當容器目錄和數據卷目錄綁定后,對方的修改會立即同步。
  • 一個數據卷可以被多個容器同時掛載。
  • 一個容器也可以被掛載多個數據卷。

數據卷的作用

  1. 容器數據持久化。
  2. 容器和外部機器間接通信。
  3. 容器之間數據交換。

配置數據卷

創建啟動容器時,使用 –v 參數設置數據卷:

docker run ... –v 宿主機目錄(文件):容器內目錄(文件) ... 

注意:

  1. (兩邊)目錄必須是絕對路徑
  2. 如果(兩邊)目錄不存在,會自動創建

數據卷容器

多容器進行數據交換

image

  1. c1 和 c2 容器可以同時通過宿主機和 c3(數據卷容器)掛載數據卷。
  2. 即使 c3 掛了,也不影響 c1 和 c2 與宿主機同步數據。

配置方法:創建一個容器,掛載一個目錄,讓其他容器繼承自該容器(--volume-from)

# 創建啟動 c3 數據卷容器,使用 –v 參數設置數據卷
docker run –it --name=c3 –v /volume centos:7 /bin/bash  # 注意這里只需要容器目錄即可,宿主機會隨機分配掛載目錄

# 創建啟動 c1 c2 容器,使用 –-volumes-from 參數設置數據卷
docker run –it --name=c1 --volumes-from c3 centos:7 /bin/bash
docker run –it --name=c2 --volumes-from c3 centos:7 /bin/bash

Docker 應用部署

端口映射問題

如果外部機器要訪問到容器中的應用,首先需要解決端口映射問題(容器需要映射端口才能和外部通信)。提到端口映射,就涉及到容器的網絡和主機網絡之間的關系。

  1. 容器內的網絡服務和外部機器不能直接通信
  2. 外部機器和宿主機可以直接通信
  3. 宿主機和容器可以直接通信
  4. 因此,當容器中的網絡服務需要被外部機器訪問時,可以將容器中提供服務的端口映射到宿主機的端口上,外部機器訪問宿主機的該端口,從而間接訪問容器的服務。這種操作稱為:端口映射

image


防火牆配置

示例:Centos 8 使用 firewalld 服務管理轉發規則。firewalld 服務必須打開,不然 docker 無法創建端口轉發,但是打開后會攔截 80、8080 和 32000 以上的端口,導致 web 端口全都無法通過,所以需要用 firewalld 打開端口限制。

# 打開防火牆
systemctl start firewalld.service

# 防火牆開機啟動
systemctl enable firewalld.service

# 將主機網卡加入信任域
firewall-cmd --permanent --zone=trusted --change-interface=enp0s3 

# 增加80口信任
firewall-cmd --add-port=80/tcp --permanent

# 增加 8080 端口信任
firewall-cmd --add-port=8080/tcp --permanent

# 增加 32001--65010 口信任
firewall-cmd --add-port=32001-65010/tcp --permanent

# 重新加載配置文件
firewall-cmd --reload

端口映射配置

端口映射在 docker run 或 create 時配置,參數使用 -P(隨機映射)或 -p(指定映射)。

隨機映射:-P

docker 會給宿主機上所有 IP(0.0.0.0)分配一個 32000 以上的隨機端口,映射到容器內對外提供服務的端口。

image

如上圖所示,使用 docker ps,可以看到宿主機 32769 端口映射到容器 80 端口。

再查看宿主機 IP,用此 IP 加 32769 端口訪問 nginx 的默認頁面(注意宿主機的防火牆需要關閉或者設置):

image

image

可以看到通過宿主機 IP 加上隨機分配的端口,就可以訪問容器提供的 web 服務。


隨即映射:-P

image

注意事項:

  • 選擇指定端口進行映射時,宿主機端口不能被占用。
  • 如果容器啟動時綁定的僅是宿主機 IP,則宿主機本機訪問 127.0.0.1 的 80 端口是不通的(ps 中 0.0.0.0:80 才代表所有 IP 均被綁定)。

部署 MySQL

  1. 搜索 mysql 鏡像:
docker search mysql
  1. 拉取 mysql 鏡像:
docker pull mysql:5.6
  1. 創建容器,設置端口映射、目錄映射:
# 在/root目錄下創建mysql目錄用於存儲mysql數據信息
mkdir ~/mysql
cd ~/mysql
  • 從 docker hub 上可以找到 mysql 外掛配置和數據目錄的一些文檔說明:https://hub.docker.com/_/mysql

  • 從該文檔中可以了解到,mysql 的默認配置為 /etc/mysql/my.cnf,該文件中包含了一個額外的數據目錄 /etc/mysql/conf.d 或者 /etc/mysql/mysql.conf.d

docker run -id \
-p 3307:3306 \
--name=c_mysql \
-v $PWD/conf:/etc/mysql/conf.d \
-v $PWD/logs:/logs \
-v $PWD/data:/var/lib/mysql \
--privileged=true \
-u root \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.6
  • 參數說明:
    • -p 3307:3306:將容器的 3306 端口映射到宿主機的 3307 端口
    • -v $PWD/conf:/etc/mysql/conf.d:將主機當前目錄下的 conf/my.cnf 目錄掛載到容器的 /etc/mysql/my.cnf 目錄
    • -v $PWD/logs:/logs:將主機當前目錄下的 logs 目錄掛載到容器的 /logs
    • -v $PWD/data:/var/lib/mysql :將主機當前目錄下的 data 目錄掛載到容器的 /var/lib/mysql
    • --privileged=true:使得容器內的 root 擁有真正的 root 權限,否則容器內的 root 只是外部的一個普通用戶權限
    • -u root:以 root 用戶登錄數據庫
    • -e MYSQL_ROOT_PASSWORD=123456:初始化 root 用戶的密碼
  1. 進入容器,操作 mysql :
docker exec –it c_mysql /bin/bash
  1. 使用外部機器連接容器中的 mysql :
    image

部署 Tomcat

  1. 搜索 tomcat 鏡像:
docker search tomcat
  1. 拉取 tomcat 鏡像:
docker pull tomcat
  1. 創建容器,設置端口映射、目錄映射:
# 在 /root 目錄下創建 tomcat 目錄用於存儲 tomcat 數據信息
mkdir ~/tomcat
cd ~/tomcat
docker run -id --name=c_tomcat \
-p 8080:8080 \
-v $PWD:/usr/local/tomcat/webapps \
tomcat
  • 參數說明:

    • -p 8080:8080:將容器的 8080 端口映射到主機的 8080 端口

      -v $PWD:/usr/local/tomcat/webapps:將主機中當前目錄掛載到容器的 webapps

  1. 在宿主機掛載目錄下創建訪問文件,並使用外部機器訪問 tomcat 中的該文件:
    image

部署 Redis

  1. 搜索 redis 鏡像:
docker search redis
  1. 拉取 redis 鏡像:
docker pull redis:5.0
  1. 創建容器,設置端口映射:
docker run -id --name=c_redis -p 6379:6379 redis:5.0
  1. 使用外部機器連接 redis :
./redis-cli.exe -h 192.168.149.135 -p 6379


免責聲明!

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



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