Docker使用入門(一篇就夠了)
Docker 是一個開源的應用容器引擎,基於 Go 語言 開發。Docker 可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然後釋出到任何流行的 Linux 機器上,也可以實現虛擬化。容器是完全使用沙箱機制,相互之間不會有任何介面,容器效能開銷極低。Docker 從 17.03 版本之後分為 CE(Community Edition: 社群版) 和 EE(Enterprise Edition: 企業版)。
基本概念
在使用Docker前,首先要先知道Docker中這幾個常用的概念:
- 映象(image):映象是檔案,只讀的,提供了執行完整軟硬體應用程式的集裝箱。
- 容器(container):映象的例項,由Docker負責建立,容器之間彼此隔離,容器可以被建立,刪除,停止。
- 倉庫(hub):用來儲存映象,可以理解為程式碼控制中的程式碼倉庫,Docker官方倉庫名字是Docker Hub。
更多內容,通過訪問Docker官方網站獲取:https://www.docker.com/
安裝
Docker支援的平臺和作業系統很廣泛,支援Linux/Windows/Mac系統,下面基於Ubuntu 20.04LTS進行安裝。
如果已經安裝過舊版本的Docker,需要先移除相關依賴
sudo apt-get remove docker docker-engine docker.io containerd runc
安裝網路相關依賴包,用於通過HTTPS來獲取倉庫
sudo apt-get install \apt-transport-https \ca-certificates \curl \gnupg-agent \software-properties-common
新增 Docker 的官方 GPG 金鑰
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
新增倉庫安裝源
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
更新軟體包源並安裝Docker
sudo apt update && sudo apt install -y docker-ce
安裝完成後Docker會自動啟動,執行命令檢視Docker狀態
starsray@starsray:~/IdeaProjects$ systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2022-03-26 17:03:00 CST; 1 day 6h ago
Docs: https://docs.docker.com
Main PID: 2269 (dockerd)
Tasks: 55
Memory: 235.1M
CGroup: /system.slice/docker.service
├─ 2269 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
├─ 2754 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 3306 -container-ip 172.18.0.2 -container-port 330
├─29543 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 9200 -container-ip 192.168.112.2 -container-port
├─30233 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 12800 -container-ip 192.168.112.3 -container-port
├─30247 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 11800 -container-ip 192.168.112.3 -container-port
└─30360 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 39043 -container-ip 192.168.128.3 -container-port
Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.
如果提示沒有許可權
starslight@starslight:/etc/apt/sources.list.d$ docker search elasticGot permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.24/images/search?limit=25&term=elastic: dial unix /var/run/docker.sock: connect: permission denied
新建一個docker使用者組,並將登陸使用者新增到docker使用者組
sudo groupadd docker #新增docker使用者組
sudo gpasswd -a $USER docker #將登陸使用者加入到docker使用者組中
newgrp docker #更新使用者組
如果在下載過程中出現下載過慢的情況,可以配置阿里雲映象加速來提升下載速度,登入阿里雲控制檯,搜尋容器映象服務,此步驟為非必要步驟,對速度無要求可以忽略。
執行下面命令:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
建立配置檔案,重啟Docker服務就可以使用阿里雲幫我們提供的Docker映象加速服務了。
基本架構
- 基本結構
Docker使用客戶端-伺服器(C/S)架構模式,通過下面這個圖可以簡單清晰看出Server/Client通訊,容器和映象、資料之間的關係系,使用者無法直接和Docker Server進行互動。
Docker是提供應用打包,部署與執行應用的容器化平臺,Docker整體可以大致分為三部分:
- 內層:Server,可以是本地的也可以時遠端的,接收並分發Client端發起的請求。
- 中間層:REST API,使用HTTP協議簡歷Client與Server之間的通訊。
- 外層:Client 通過中間層向Docker Server發起請求,執行命令。
- Docker服務執行流程
Docker整個執行流程參與的角色可以分為三個部分,客戶端(Client)、服務端(Daemon)、倉庫(Registry),
其中客戶端與服務端通過REST API完成互動,通過docker命令完成映象、容器、倉庫構建、打包等操作。
- Docker Client:是使用者與 Docker 互動的主要方式。 當使用 docker run 等命令時,客戶端會將這些命令傳送給 守護程序,守護程序會執行這些命令。docker命令執行使用的是Docker API,Docker 客戶端可以與多個守護程序通過REST API進行通訊。
- Docker Daemon:監聽 Docker API 請求並管理 Docker 物件,例如映象、容器、網路和卷。 守護程序還可以與其他守護程序通訊以管理 Docker 服務。
- Docker Registry:倉庫中心儲存 Docker 映象, Docker 預設配置為在 Docker Hub 上查詢映象。 也可以搭建倉庫私服。當使用 docker pull 或 docker run 命令時,將從配置的登錄檔中提取所需的映象。 當使用 docker push 命令時,您的影象會被推送到您配置的倉庫中。
- 容器生命週期
執行docker命令會導致容器的生命週期進行變化,生命週期與命令的對應關係如下圖所示:
- docker run 命令包含 docker create 和 docker start兩個狀態
- docker create 單執行,則會進入停止狀態
- 執行docker start 進入開始狀態
- docker destroy 刪除容器
- docker kill 或者 docker stop 都置die狀態,緊接著進入stop狀態
- docker kill 後進行docker start 建立新程序
- docker stop 後進行docker start 進入恢復
- docker restart 可以重啟
- docker pause 進行暫停狀態
記憶體溢位OOM,會置die,可以使用docker ps -a檢視所有被啟用容器的狀態。
Docker file
Dockerfile是由一系列命令和引數構成的指令碼,Docker可以根據這個指令碼基於某個基礎映象建立一個新的定製化的映象,大大提高了我們部署的效率,使用Dockfile最終的結果是幫助我們定製化自己的映象。
基本命令
- FROM 指定基礎映象
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
指定基準映象,類似JAVA的繼承,FROM使用在其他指令之前,其他指令的操作依賴於FROM指令;如果不依賴於其他映象,構建初始映象可使用FROM scratch命令。
- LABEL 為映象新增元資料
LABEL <key>=<value> <key>=<value> ...
LABEL指令給映象新增元資料,也可以看作映象的標籤,對於映象資訊的描述。
LABEL指令是鍵值對形式的如果value中有空格,可以使用引號和\,例:LABEL desc="This is a test lable"。
一個映象可以有多個LABEL,新新增LABEL會覆蓋原有重名LABEL,並且LABEL是分層的,每個LABEL標籤都會構建一層映象,可以使用合併寫法,例如
LABEL multi.label1="value1"
multi.label2="value2"
other="value3"
或
LABEL multi.label1="value1" multi.label2="value2" other="value3"
映象的LABEL資訊可以使用 docker inspect image:來檢視
- MAINTAINER 指定映象維護者資訊
MAINTAINER <name>
該指令現在已經被廢棄,建議使用LABEL來指定,例:LABEL maintainer="starsray.cnblogs.com"。
- ADD 複製檔案
ADD <src> <dest>
ADD ["<src>","<dest>"]
從src路徑複製指定內容到dest路徑,src可以是Dockfile相對路徑,也可以是一個URL,還可以是一個壓縮包。
拷貝檔案時可識別壓縮包格式,docker會自動解壓。
若src是一個URL,dest不以斜槓結尾,dest將會被視為檔案,src對應內容將會被下載到dest檔案。
若src是一個URL,dest以斜槓結尾,dest將會被視為目錄,src對應內容將會被下載到dest目錄。
若src是一個目錄,整個目錄下的內容,包括檔案系統元資料將會被拷貝至dest目錄。
- WORKDIR 指定工作目錄
WORKDIR /path
指定工作目錄,相當於cd /path,path不存在可以自動建立,為指令RUN,CMD,ENTRYPOINT指定工作目錄,以WORKDIR目錄為當前目錄。
- ARG 設定構建引數
ARG <name>[=<default value>]
定義構建映象時需要的引數,可用於FROM指令前。
ARG指令定義的引數,在docker build命令中以--build-arg a_name=a_value形式賦值。
Dockerfile中可以使用ARG定義一個變數,也可以定義多個變數,變數定義時可設定預設值,在build時傳遞引數則使用引數,未傳遞引數則使用預設值。
ARG變數定義從在Dockerfile定義的行生效,而不是從在命令列引數的使用或其它地方。
RUN指令可執行使用ARG或ENV指令定義的變數。使用ENV定義的環境變數會覆蓋ARG指令定義的同名變數。
Dcoker中預設的一組ARG變數不需要預設即可使用,在執行docker --build-arg a_name=a_value即可使用。
HTTP_PROXY 、http_proxy 、HTTPS_PROXY、https_proxy、FTP_PROXY、ftp_proxy、NO_PROXY 、no_proxy
在構建映象過程中如果ARG傳遞的引數未定義會出現警告。
[root@starsraywebapps]# docker build --build-arg xxccx=conly -t conly .
Sending build context to Docker daemon 4.608kB
Step 1/5 : from tomcat:latest
---> 6408fdc94212
...
[Warning] One or more build-args [xxccx] were not consumed
Successfully built 61e9f6346096
Successfully tagged conly:latest
關於ARG的更多使用可以參考https://www.centos.bz/2016/12/dockerfile-arg-instruction/
- CMD 容器啟動指令
CMD ["executable", "param1", "param2"] (推薦使用)
CMD ["param1", "param2"] 為[ENTRYPOINT]指令提供預設引數
CMD command param1 param2 在shell中執行
用於在Docker容器建立時執行預設的命令,CMD命令可以有多個,但只會執行最後一個,CMD命令可以被覆蓋。
如果使用docker run 建立容器時附加了其他命令則預設的CMD命令不會被執行,執行附加命令。
- RUN 執行命令
RUN <command> shell命令格式
RUN ["executable", "param1", "param2"] exec命令格式
用於在Docker映象構建時執行命令,映象構建結束,RUN命令也就結束執行。
- COPY 複製檔案
COPY <src> <dest>
COPY ["<src>", "<dest>"]
複製本地的src檔案到dest目錄,功能類似於ADD,COPY不支援URL和壓縮包。
- ENTRYPOINT 入口點
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
用於在Docker容器建立時執行命令,ENTRYPOINT 可以存在多個,但只會執行最後一個,ENTRYPOINT執行的命令不可被覆蓋。
- ENV 設定環境變數
ENV <key> <value>
ENV <key>=<value> ...
設定環境變數,會被RUN指令使用,並在容器執行時保持。例:ENV JAVA_HOME /path/to/java。
- EXPOSE 宣告暴漏的埠
EXPOSE <port> [<port>...]
用於宣告容器執行時提供服務的埠,便於映象使用者檢視該映象服務的守護埠,執行時並不會因為宣告就開啟相應埠。
當執行時使用隨機對映時,會自動對映EXPOSE的埠。
例:docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 -d image:。
- USER 設定使用者
USER <daemon>
該指令用於指定容器執行時的使用者或者UID,RUN、CMD以及ENTRYPOINT指令都將使用該使用者執行命令。
例:RUN groupadd -r postgres && useradd -r -g postgres postgres
更多命令參考官方文件:https://docs.docker.com/engine/reference/builder/
相似命令解釋
Docker file中包含了很多含義近似的命令,但是在實際使用中還是有所不同的,下面對一些常用相似命令進行詳細分析:
- RUN、CMD、ENTRYPOINT的區別
- 執行時機不同,RUN指令在映象構建時使用,CMD | ENTRYPOINT在容器建立時使用。
- CMD是預設執行命令,可以被覆蓋,原有命令不一定執行,ENTRYPOINT不可以被覆蓋,一定會被執行。
- ENTRYPOINT和CMD命令可以組合使用,將CMD命令當作ENTRYPOINT命令的引數來執行,例:
ENTRYPOINT ["ps"] CMD ["-ef"]映象構建完成,如果使用docker run image -aux,則原有CMD命令在執行時會被替換為ps -aux,這種方式實現了動態傳參,不用修改Dockerfile重新構建映象就可以在建立容器上執行自定義命令。
- ARG和ENV的區別
- 從語義上看ARG是用來設定構建映象時引數的,設定引數僅在構建時期有用,ENV用來設定環境變數,可以儲存在容器執行時。
- Dockerfile中宣告ARG後可以設定預設值,也可以構建時傳參設定,ENV設定的環境變數可以覆蓋ARG宣告的同名引數。
- Dockerfile中ARG和ENV可以配合使用,類似於ENTRYPOINT和CMD指令。
# use the value to set the ENV var default
ARG A_VARIABLE
ENV an_env_var=$A_VARIABLE
- 需要注意的是雖然使用ARG設定的引數僅在構建時有效,但是使用docker history :
還是可以檢視構建記錄,儘量避免傳遞金鑰,password等敏感資訊。
[root@conly webapps]# docker build -t tomcat:0.1 .
Sending build context to Docker daemon 4.608kB
Step 1/7 : ARG user=test_user
...
Step 7/7 : ADD https://images.cnblogs.com/cnblogs_com/conly/1600508/o_191211120217min.png ./docker-web
Downloading [==================================================>] 230.1kB/230.1kB
---> Using cache
---> 61e9f6346096
Successfully built 61e9f6346096
Successfully tagged tomcat:0.1
[root@conly webapps]# docker history tomcat:0.1
IMAGE CREATED CREATED BY SIZE COMMENT
...
<missing> 2 weeks ago /bin/sh -c #(nop) EXPOSE 8080 0B
<missing> 2 weeks ago /bin/sh -c set -e && nativeLines="$(catalin… 0B
...
<missing> 2 weeks ago /bin/sh -c #(nop) ENV TOMCAT_MAJOR=8 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENV GPG_KEYS=05AB33110949… 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENV LD_LIBRARY_PATH=/usr/… 0B
...
- 完整資訊命令
docker history --format "table {{.ID}}\t{{.CreatedBy}}" --no-trunc image:<tag>
- ADD和COPY的區別
- ADD和COPY都可以用來拷貝原始檔到指定目錄,在這點上用法一致。
- ADD的源可以是本地也可以是遠端的,COPY只能是本地檔案。
- 使用ADD來拷貝可識別的壓縮檔案時,如.tar,.war可以自動解壓,COPY則不具備。
- COPY可用於multi-stage中,複製上一階段的映象,詳細內容看參考use multi-stage builds。此功能在Docker17.05以後才新增,極大方便了Dockerfile的維護者。
首次使用 COPY 和 ADD 命令時也沒有考慮過太多二者的區別,隨著對Docker的使用會發現 COPY 命令的設計是簡單,概念清晰的。而 ADD 命令是在COPY命令上的擴充套件,提高了使用的複雜度,尤其在使用ADD新增源為URL的情況,要注意dest路徑的結尾有沒有/,但這些設計在我們熟悉Docker後也會方便操作。
- shell和exec區別
- shell 在Linux系統中,使用shell執行時指令碼時,當前shell為父程序,會生成一個子程序來執行指令碼,執行完畢後會退出子程序回到當前shell。
- exec 使用exec執行時,exec程序會替換當前程序,程序PID保持不變執行結束直接退出,不會退出到程序執行之前的環境,官方推薦使用。
Docker應用
基本使用
以上介紹了Docker中基本概念、工作模式、以及Dockerfile的相關內容,接下來對Docker的基本使用做一下介紹。包括映象的拉取到容器的執行終止過程,以Tomcat映象為例:
- 查詢映象
搜尋Docker hub提供的Tomcat映象源:
root@starsray:~# docker search tomcat
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
tomcat Apache Tomcat is an open source implementati… 3294 [OK]
tomee Apache TomEE is an all-Apache Java EE certif… 95 [OK]
bitnami/tomcat Bitnami Tomcat Docker Image 44 [OK]
kubeguide/tomcat-app Tomcat image for Chapter 1 33
arm32v7/tomcat Apache Tomcat is an open source implementati… 11
arm64v8/tomcat Apache Tomcat is an open source implementati… 7
rightctrl/tomcat CentOS , Oracle Java, tomcat application ssl… 7 [OK]
amd64/tomcat Apache Tomcat is an open source implementati… 4
jelastic/tomcat An image of the Tomcat Java application serv… 3
tomcat2111/pisignage-server PiSignage Server 3 [OK]
cfje/tomcat-resource Tomcat Concourse Resource 2
...
使用search命令搜尋出的包含了官方和非官方的映象源,而且都是最新版本,如果想搜尋某個映象的歷史版本可以使用下面指令碼來輔助操作
sudo mkdir -p /opt/script
sudo tee /opt/script/docker-search-tag.sh <<-'EOF'
#!/bin/sh
#
# Simple script that will display docker repository tags.
#
# Usage:
# $ docker-show-repo-tags.sh ubuntu centos
for Repo in $* ; do
curl -s -S "https://registry.hub.docker.com/v2/repositories/library/$Repo/tags/" | \
sed -e 's/,/,\n/g' -e 's/\[/\[\n/g' | \
grep '"name"' | \
awk -F\" '{print $4;}' | \
sort -fu | \
sed -e "s/^/${Repo}:/"
done
EOF
授予指令碼可執行許可權,並且新增軟連線到可執行目錄
sudo chmod +x docker-search-tag.sh
sudo ln -s /opt/script/docker-search-tag.sh /usr/local/bin/
使用新增的指令碼命令搜尋Redis映象tag列表,相關tag都被展示出來了。
starsray@starsray:/usr/bin$ docker-search-tag.sh redis
redis:6.2
redis:6.2.6
redis:6.2.6-bullseye
redis:6.2-bullseye
redis:7.0-rc
redis:7.0-rc2
redis:7.0-rc2-bullseye
redis:7.0-rc-bullseye
redis:bullseye
redis:latest
- 拉取映象
執行拉取命令
docker pull tomcat
或者指定版本:
docker pull tomcat:8.5.49-jdk8-openjdk
- 建立容器
使用run命令通過映象來建立一個Tomcat容器
docker run tomcat
- 埠對映
直接使用docker run啟動的容器是在當前shell視窗前臺程序執行,如果沒有指定埠對映,宿主機和容器之間是無法進行通訊的,可以使用如下命令來重新啟動容器
docker run -p 8080:8080 -d tomcat
- -p 對映埠:容器埠
- -d 表示在後臺執行容器
需要注意的是,使用run啟動後的容器,無法再進行引數修改,容器的生命週期可以檢視上面部分的描述。此外埠對映解決的是宿主機與容器間的通訊,通常還需要容器間的通訊,下面介紹。
- 常用命令
docker中常用命令如下:
docker search imageName 搜尋映象資源
docker pull imageName<:tags> 抽取遠端倉庫映象
docker images 檢視已下載映象
docker run 建立容器,啟動應用
docker ps 檢視正在執行的映象
docker rm 刪除容器 新增-f引數強制刪除
docker rmi 刪除映象
docker logs containerID 檢視容器歷史記錄
docker cp <FROM> <TO> 宿主機與容器之間拷貝資源
- 容器內部結構
Docker建立的容器後,可以使用命令進入容器內部,檢視容器的資訊
docker exec [-it] 容器id 命令
- 其中,-t 選項讓Docker分配一個偽終端(pseudo-tty)並繫結到容器的標準輸入上, -i 則讓容器的標準輸入保持開啟。此處通常需要提供一個shell來執行,一般為/bin/bash。
進入容器後,就可以對Docker容器一探究竟,此處以tomcat容器為例,容器內部結構如圖所示:包含了tomcat執行的必備環境。
進入/usrl/ocal目錄,執行ls檢視容器內部包含的資源
root@3c7488f8d35a:/usr/local# ls /usr/local/ aegis bin etc games include lib man openjdk-8 sbin share src tomcat
在容器內部,建立在一個Linux系統基礎之上的,支援了應用程式所能執行的最小安裝,包含核心,網路等相關核心系統元件,以及應用執行所需要的JDK和Tomcat。
退出容器
exit
- 資料卷掛載
通過容器內部結構的檢視,會發現存在一個問題,應用執行所需要的配置資訊都在容器內部,且容器沒有啟動時無法進行修改,修改配置資訊時就很不方便,而且如果資料資訊儲存在容器內,當容器因為某些原因掛掉時,對於資料恢復也是災難性的,因此Docker提供了資料掛載的功能(Docker Volume:資料卷)。
Docker Volume是儲存由 Docker 容器生成和使用的資料的首選機制。 雖然繫結掛載依賴於主機的目錄結構和作業系統,但卷完全由 Docker 管理。 與繫結掛載相比,卷有幾個優點:
- 卷比繫結掛載更容易備份或遷移
- 可以使用 Docker CLI 命令或 Docker API 管理卷
- 卷適用於 Linux 和 Windows 容器
- 卷可以在多個容器之間更安全地共享
- 卷驅動程式允許將卷儲存在遠端主機或雲伺服器,以加密卷的內容或新增其他功能
- 新卷的內容可以由容器預先填充。
- Docker Desktop 上的卷比來自 Mac 和 Windows 主機的繫結掛載具有更高的效能。
此外,與在容器的可寫層中持久化資料相比,卷通常是更好的選擇,因為卷不會增加使用它的容器的大小,並且卷的內容存在於給定容器的生命週期之外。如果容器生成非持久狀態資料,可以使用 tmpfs 掛載以避免將資料永久儲存在任何地方,並通過避免寫入容器的可寫層來提高容器的效能。
使用資料卷掛載的方式也很簡單,在建立容器時使用-v引數來指定需要關聯的檔案位置。
docker run --name some-mysql -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
更多內容可以參考:https://docs.docker.com/storage/volumes/
- 容器間通訊
容器和宿主機之間的通訊可以通過埠對映的方式來實現,容器之間的通訊,docker也提供了相應API。可以使用link或者network相關的功能來實現容器間通訊。
- docker link
link功能的使用方式如下:
--link <name or id>:alias
例如關聯elasticsearch和kibana,使其進行容器間通訊
docker run --name kibana --link=elasticsearch -p 5601:5601 -d kibana:7.12.0
需要注意的是:
The --link flag is a legacy feature of Docker. It may eventually be removed. Unless you absolutely need to continue using it, we recommend that you use user-defined networks to facilitate communication between two containers instead of using --link. One feature that user-defined networks do not support that you can do with --link is sharing environment variables between containers. However, you can use other mechanisms such as volumes to share environment variables between containers in a more controlled way.
--link 標誌是 Docker 的遺留功能。 它最終可能會被刪除。 除非您絕對需要繼續使用它,否則我們建議您使用使用者定義的網路來促進兩個容器之間的通訊,而不是使用 --link。 使用者定義的網路不支援您可以使用 --link 執行的一項功能是在容器之間共享環境變數。 但是,您可以使用其他機制(例如卷)以更可控的方式在容器之間共享環境變數。
- docker network
docker network是官方推薦的容器間進行通訊的使用方式,而且功能強大,包含不同的網路連結方式,支援單機叢集環境下使用,下面主要針對單機環境下的使用方式進行介紹。
Docker安裝完成後預設包含以下幾種連結方式
root@starsray:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
cb33e874f2c6 bridge bridge local
4627f6c080f0 host host local
5c0a8d18036c none null local
bridge是官方推薦的連結方式,而且後面兩種方式尚且不成熟。使用network的方式也很簡單,例如
docker run -it --network some-network --rm mysql mysql -hsome-mysql -uexample-user -p
通過--network來指定容器網路資訊,當兩個容器指向同一個網路就可以進行互通。
檢視network bridge相關資訊
root@starsray:~# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "cb33e874f2c660cde0c36c69c38b796860c87b6ebed5127a78d5bb88ccb2bf90",
"Created": "2022-03-26T20:10:59.296202231+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
Docker中還提供了網路操作相關的其他命令
root@starsray:~# docker network
Usage: docker network COMMAND
Manage networks
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
更多network相關資料:https://docs.docker.com/network/
自定義映象
實踐才能加深理論並且更有助於理解,接下來基於CentOS7來自定義Redis的Docker映象。
下載redis-5.0.5安裝包
wget http://download.redis.io/releases/redis-5.0.5.tar.gz
下載redis.conf配置檔案
wget http://download.redis.io/redis-stable/redis.conf
修改redis.conf
bind 127.0.0.1 --> #bind 127.0.0.1
daemonize no --> daemonize yes
protected-mode yes --> protected-mode no
建立Dockerfile,並編寫檔案內容
ARG desc
FROM centos
LABEL maintainer=www.cnblogs.com/starsray/
RUN ["yum","-y","install","gcc","gcc-c++","net-tools","make"]
WORKDIR /usr/local
ADD redis-5.0.5.tar.gz .
WORKDIR /usr/local/redis-5.0.5/src/
RUN make && make install
WORKDIR /usr/local/redis-5.0.5
ADD redis.conf .
EXPOSE 6379
CMD ["redis-server","redis.conf"]
構建自定義image映象
docker build --build-arg desc="this is a docker image build test" -t starsray/redis:5.0.5 .
構建過程日誌如下
[root@starsray redis_dockertest]# docker build --build-arg desc="this is a docker image build test" -t conly/redis:1.0 .
...
...
...
Removing intermediate container 528d15f50a03
---> 809289100143
Step 9/14 : WORKDIR /usr/local/redis-5.0.5
---> Running in 566b63100414
Removing intermediate container 566b63100414
---> 9cfce44318ee
Step 10/14 : ADD redis.conf .
---> dc8127dafb54
Step 11/14 : EXPOSE 6379
---> Running in eda8f77e9c83
Removing intermediate container eda8f77e9c83
---> 08f348a33ff6
Step 12/14 : WORKDIR /usr/local/redis-5.0.5/utils
---> Running in c7cd15701c85
Removing intermediate container c7cd15701c85
---> 1dcde04ee437
Step 13/14 : ENTRYPOINT ["./"]
---> Running in 152277e9979e
Removing intermediate container 152277e9979e
---> 1c9a7b9c6bae
Step 14/14 : CMD ["install_server.sh"]
---> Running in 065dc4a5ba65
Removing intermediate container 065dc4a5ba65
---> 8b1990aa9224
Successfully built 8b1990aa9224
Successfully tagged starsray/redis:5.0.5
構建完成,檢視docker映象,可以看到除了自定義的starsray/redis:5.0.5映象之外,此外Dockerfile中用到的CentOS7,映象也被拉取下來,可以看出Docker中映象快取、分層的概念
[root@starsray redis_dockertest]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
conly/redis 1.0 8b1990aa9224 3 minutes ago 587MB
centos latest 0f3e07c0138f 2 months ago 220MB
使用docker run執行redis映象
[root@starsray redis_dockertest]# docker run -p 6379:6379 starsray/redis:5.0.5
1:C 12 Dec 2019 13:27:00.599 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 12 Dec 2019 13:27:00.599 # Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 12 Dec 2019 13:27:00.599 # Configuration loaded
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 5.0.5 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 1
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
1:M 12 Dec 2019 13:27:00.601 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:M 12 Dec 2019 13:27:00.601 # Server initialized
1:M 12 Dec 2019 13:27:00.601 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
1:M 12 Dec 2019 13:27:00.601 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
1:M 12 Dec 2019 13:27:00.603 * Ready to accept connections
此時redis是阻塞狀態執行,也可以重新編寫Dockerfile來構建映象讓redis容器後臺執行
ARG desc
FROM centos
LABEL maintainer=www.cnblogs.com/starsray/
RUN ["yum","-y","install","gcc","gcc-c++","net-tools","make"]
WORKDIR /usr/local
ADD redis-5.0.5.tar.gz .
WORKDIR /usr/local/redis-5.0.5/src/
RUN make && make install
WORKDIR /usr/local/redis-5.0.5
ADD redis.conf .
RUN cd /usr/local/redis-5.0.5/utils && echo | /bin/bash install_server.sh
ENTRYPOINT /usr/local/bin/redis-server /etc/redis/6379.conf && tail -f /var/log/redis_6379.log
執行redis,可以看到我們自定義的redis已經運行了。
[root@starsray redis_dockertest]# docke run -p 6379:6379 -d starsray/redis:5.0.5 .
d3b1191ae2408d5025ba55e3b893300ca9438246a10feb2d7e02fa0f29801740
[root@conly redis_dockertest]# docker ps -s
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE
d3b1191ae240 starsray/redis:5.0.5 "/bin/sh -c '/usr/lo…" 8 seconds ago Up 7 seconds 0.0.0.0:6379->6379/tcp fervent_babbage 2.58kB (virtual 587MB)
總結
Docker 消除了重複的、平凡的配置任務,並在整個開發生命週期中用於快速、簡單和可移植的應用程式開發——桌面和雲。 Docker 全面的端到端平臺包括 UI、CLI、API 和安全性,旨在在整個應用程式交付生命週期中協同工作。
參考資料:
https://www.docker.com
https://docs.docker.com
https://docker-practice.github.io/zh-cn/container/run.html