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

Juno3550發表於2022-01-18


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://registry.docker-cn.com"]
}

# 過載 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:刪除容器

如果容器是執行狀態則刪除失敗,需要停止容器才能刪除。

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 容器的資料卷(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 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 \
-e MYSQL_ROOT_PASSWORD=123456 \
  • 引數說明:
    • -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
    • -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

部署 Nginx

  1. 搜尋 nginx 映象:
docker search nginx
  1. 拉取 nginx 映象:
docker pull nginx
  1. 建立容器,設定埠對映、目錄對映:
# 在 /root 目錄下建立 nginx 目錄用於儲存 nginx 資料資訊
mkdir ~/nginx
cd ~/nginx
mkdir conf
cd conf
# 在 ~/nginx/conf/ 下建立 nginx.conf 檔案,貼上以下內容
vi nginx.conf
  • nginx.conf 配置:
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
  • 建立容器:
docker run -id --name=c_nginx \
-p 80:80 \
-v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf \
-v $PWD/logs:/var/log/nginx \
-v $PWD/html:/usr/share/nginx/html \
nginx
  • 引數說明:
    • -p 80:80:將容器的 80 埠對映到宿主機的 80 埠
    • -v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf:將主機當前目錄下的 /conf/nginx.conf 掛載到容器的 /etc/nginx/nginx.conf
    • -v $PWD/logs:/var/log/nginx:將主機當前目錄下的 logs 目錄掛載到容器的/var/log/nginx
  1. 使用外部機器訪問 nginx :
    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

相關文章