Docker 引擎是一種用于構建和容器化應用程序的開源容器化技術。它是一個服務端-客戶端結構的應用,主要有以下部分組成:
- Docker 守護進程:持久化的進程,監(jiān)聽 Docker Engine API 的請求
- Docker Engine API:與 Docker 守護進程交互用的的 RESTful API
- Docker 客戶端:命令行接口,通過客戶端將命令發(fā)送給守護進程
Dockerfile 一個文本文檔,Docker 可以通過讀取 Dockerfile 中定義的指令來自動構建鏡像。
Docker Compose 是一個用于定義和運行多個容器的 Docker 工具。Compose 使用 YAML 文件來配置應用程序的服務。然后,通過單個命令,就可以從配置中創(chuàng)建并啟動所有服務。
下面演示所用 Demo 地址:https://github.com/14032/gchat
Dockerfile
Docker 提供了一種構建鏡像方式叫 Dockerfile,下面是用來構建 gchat 項目鏡像的 Dockerfile 文件:
FROM maven:3-jdk-8-alpine
MAINTAINER "人間春蕩蕩 <人間春蕩蕩@126.com>"
WORKDIR /opt/gchat
ADD gchat.war .
RUN jar -xvf gchat.war
ENV TZ=Asia/Shanghai
EXPOSE 8080
ENTRYPOINT java -cp /opt/gchat org.springframework.boot.loader.WarLauncher
- FROM 用來指定鏡像所依賴的基礎鏡像,這里項目需要的是 JDK 環(huán)境
- MAINTAINER:作者信息
- WORKDIR:指定后續(xù)命令執(zhí)行的目錄,即后續(xù)的命令都將 /opt/gchat 作為當前目錄
- ADD:復制文件,將當前目錄下 gchat.war 包復制到鏡像 /opt/gchat/ 目錄下
- RUN:在容器中要執(zhí)行的 shell 命令
- ENV:指定環(huán)境變量,這里指定了時區(qū)
- EXPOSE:聲明服務監(jiān)聽端口(僅僅是聲明,并不會主動做端口映射)
- ENTRYPOINT:指定鏡像的入口啟動進程
Dockerfile 編寫完了,下面看下如何使用 Dockerfile 文件來生成鏡像。
# 構建鏡像命令
docker build -t gchat:1.0-SNAPSHOT .
-t 作用是給鏡像打個標簽,起個名字。
末尾 . 代表 Dockerfile 文件在當前操作的目錄下,否則可以通過 -f /opt/Dockerfile 參數(shù)來指定文件位置。
docker build 會加載當前目錄下的 Dockerfile 文件,然后按照順序,執(zhí)行文件中定義的命令。
docker build 執(zhí)行完成后,通過 docker images 命令查看鏡像列表:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
gchat 1.0-SNAPSHOT d97ec5bc1022 4 months ago 241MB
通過 docker run 來創(chuàng)建運行 gchat 容器:
docker run -d --network=host --name gchat \
--env jdbc.type="mysql" \
--env jdbc.username="root" \
--env jdbc.password="root" \
--env jdbc.driver="com.mysql.cj.jdbc.Driver" \
--env jdbc.url="jdbc:mysql://192.168.0.10:3306/gchat?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai" gchat:1.0-SNAPSHOT192
參數(shù) --network 用來指定容器運行的網(wǎng)絡模式,默認為 bridge 方式。host 則表示主機網(wǎng)絡模式,共享宿主機的網(wǎng)絡棧;若采用默認的 bridge 方式,則需要開啟端口映射 -p 8080:8082 ,將容器內(nèi)的 8082 端口映射在宿主機的 8080 端口供外部訪問。
http://127.0.0.1:8080/gchat
運行過程中,可通過 docker logs -f gchat 來查看容器項目日志輸出。
通過 docker ps 查看運行中的容器列表:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
12483291aa72 gchat:1.0-SNAPSHOT "/bin/sh -c 'java -c…" 2 minutes Up a minute gchat
查看詳細信息使用 docker inspect 命令:
# 查看 gchat 容器信息
docker inspect gchat
# 查看 gchat 鏡像的信息:
docker image inspect gchat:1.0-SNAPSHOT
還有一種生成鏡像的方式是:docker commit 。
這個命令可以把一個正在運行的容器,直接提交為一個鏡像。
例如在內(nèi)網(wǎng)環(huán)境安裝 Jenkins ,不能訪問互聯(lián)網(wǎng),這個時候就可以先在本地運行 Jenkins 容器:
docker run -d --name jenkins -p 8084:8080 jenkins/jenkins:lts
運行成功后,訪問 http://127.0.0.1:8084/jenkins ,把需要的一些插件全部安裝后,對正在運行的容器執(zhí)行 docker commit 操作,這樣在容器之上的所有操作都會保存到新的鏡像里。
# 將運行中的容器 56b5168a7ae2 提交為鏡像
docker commit 56b5168a7ae2 jenkins:self-v3
之后,可通過 docker save 命令導出鏡像,再通過 docker load 命令將鏡像加載至內(nèi)網(wǎng)中。
# 導出
docker save -o jenkins-lts-v3.tar jenkins:self-v3
# 導入
docker load -i jenkins-lts-v3.tar jenkins:self-v3
當然還可以通過 Volume 數(shù)據(jù)卷的功能,將宿主機目錄掛載到 Jenkins 所在容器內(nèi)的安裝目錄上,這樣所有的有關 Jenkins 文件增刪改都發(fā)生在宿主機上。
# 將 /opt/jenkins 掛載至容器內(nèi) jenkins 的安裝目錄
-v /opt/jenkins:/home/jenkins
如果想在運行中的容器中執(zhí)行 shell 命令,使用 docker exec 命令:
docker exec -it gchat /bin/sh
命令執(zhí)行后會進入容器的默認工作目錄,如果在 Dockerfile 中指定了工作目錄 WORKDIR,則會進入 Dokcerfile 指定的目錄,例如執(zhí)行 ls 默認顯示的就是 /opt/gchat 下的文件。
$ docker exec -it gchat ls
META-INF WEB-INF gchat.war org
查看設置的環(huán)境變量 env:
$ docker exec -it gchat env
# Dockerfile 鏡像中指定
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/jvm/java-1.8-openjdk/jre/bin:/usr/lib/jvm/java-1.8-openjdk/bin
HOSTNAME=f3b50c9fcb00
LANG=C.UTF-8
JAVA_HOME=/usr/lib/jvm/java-1.8-openjdk
JAVA_VERSION=8u212
JAVA_ALPINE_VERSION=8.212.04-r0
MAVEN_HOME=/usr/share/maven
MAVEN_CONFIG=/root/.m2
JAVA_OPTS=-Xms1024m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
HOME=/root
# 創(chuàng)建容器時指定
jdbc.type=mysql
jdbc.username=root
jdbc.password=root
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://mysql:3306/gchat?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
TZ=Asia/Shanghai
執(zhí)行 uname -a,查看 Linux 內(nèi)核版本:
# 容器內(nèi)執(zhí)行
$ docker exec -it gchat /bin/sh
/opt/gchat # uname -a
Linux king-ubuntu 4.15.0-108-generic #109-Ubuntu SMP Fri Jun 19 11:33:10 UTC 2020 x86_64 Linux
/opt/gchat # exit
# 宿主機
$ uname -a
Linux king-ubuntu 4.15.0-108-generic #109-Ubuntu SMP Fri Jun 19 11:33:10 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
首先要明確的是,容器與宿主機共享操作系統(tǒng)內(nèi)核,也就是說容器和鏡像是沒有內(nèi)核的,只有文件系統(tǒng)。我們有些服務器是華為 TaiShan,基于鯤鵬處理器 ARM 架構的 Linux 系統(tǒng),在剛開始使用 Docker 的時候,嘗試在其中啟動基于 X86 架構構建的鏡像,很顯然失敗了。
下面是官方文檔中 Docker 的特性說明,其中約束和隔離涉及到 Linux 的 Namespace 和 Cgroups 特性,大家可自行 Google 了解。
靈活:即使是最復雜的應用程序也可以被容器化。
輕量級:容器利用并共享主機內(nèi)核,使它們在系統(tǒng)資源方面比虛擬機效率更高。
可移植:您可以在本地構建、部署到云中,并在任何地方運行。
松散耦合:容器是高度自給自足和封裝的,允許您替換或升級一個容器,而不會破壞其他容器。
可擴展:您可以增加和自動分發(fā)跨數(shù)據(jù)中心的容器副本。
安全:容器對進程進行約束和隔離,而不需要用戶進行任何配置。
容器只是操作系統(tǒng)中的一個進程:
從根本上說,容器只不過是一個正在運行的進程,為了保持它與主機和其他容器的隔離,對它應用了一些附加的封裝特性。容器隔離最重要的是每個容器與自己的私有文件系統(tǒng)交互;這個文件系統(tǒng)由 Docker 鏡像提供。鏡像包括運行應用程序所需的一切代碼或二進制、運行時、依賴項和任何其他所需的文件系統(tǒng)對象。
# 查看進程號
$ docker top gchat
UID PID PPID C STIME TTY TIME CMD
root 4038 4014 6 13:57 ? 00:00:14 java -cp ...
Harbor
Harbor 是構建企業(yè)級私有 Docker 鏡像倉庫的開源解決方案,就像 Nexus 是 Maven 的 JAR 倉庫管理器一樣。
Harbor 使用 Docker 方式來安裝啟動,并且通過 Docker Compose 工具來管理,所以請先確保 Docker 環(huán)境和 Docker Compose 工具已經(jīng)成功安裝。
Harbor 離線安裝包 harbor-offline-installer-v1.9.4.tgz 下載地址:
將安裝包解壓,Harbor 的配置文件 harbor.yml ,包括域名、端口號、初始密碼等配置:
# Configuration file of Harbor
hostname: 192.168.0.110
# http related config
http:
port: 8089
harbor_admin_password: Harbor12345
......
在解壓后的文件夾下執(zhí)行 ./install.sh 命令進行安裝,輸出如下:
[Step 0]: checking installation environment ...
Note: docker version: 19.03.5
Note: docker-compose version: 1.25.3
[Step 1]: loading Harbor images ...
Loaded image: goharbor/harbor-core:v1.9.4
Loaded image: goharbor/clair-photon:v2.1.0-v1.9.4
... 略
[Step 2]: preparing environment ...
prepare base dir is set to /usr/local/harbor
Clearing the configuration file: /config/db/env
... 略
[Step 3]: starting Harbor ...
Creating harbor-log ... done
Creating registry ... done
... 略
? ----Harbor has been installed and started successfully.----
安裝成功后,文件夾下會出現(xiàn)一個 docker-compose.yml 文件,YML 文件中定義了 Harbor 工具所需要創(chuàng)建的容器以及其它配置??梢酝ㄟ^ Docker Compose 命令來啟動、停止、卸載 Harbor 服務,關于 Docker Compose 的使用下面會介紹。
-
創(chuàng)建 Harbor 服務所需容器并且啟動
docker-compose -f /usr/local/harbor/docker-compose.yml -p harbor up -d -
停止并刪除 Harbor 服務所需容器
docker-compose -f /usr/local/harbor/docker-compose.yml down -
啟動、停止、重啟 Harbor 服務
docker-compose -f /usr/local/harbor/docker-compose.yml start/stop/restart
安裝成功后,執(zhí)行下 docker images 命令,查看此時的鏡像列表,輸出如下,這些鏡像皆是在執(zhí)行 ./install.sh 命令時構建的,即上面輸出中的 [Step 1]: loading Harbor images
goharbor/chartmuseum-photon v0.9.0-v1.9.4 7fd23c6f1f36 127MB
goharbor/harbor-migrator v1.9.4 899a03b70174 363MB
goharbor/redis-photon v1.9.4 48c941077683 113MB
goharbor/clair-photon v2.1.0-v1.9.4 ea69a6daa928 170MB
goharbor/notary-server-photon v0.6.1-v1.9.4 3a02116cf089 143MB
goharbor/notary-signer-photon v0.6.1-v1.9.4 289af497dbf0 140MB
goharbor/harbor-registryctl v1.9.4 7259026fb1bb 103MB
goharbor/nginx-photon v1.9.4 364c17f09df9 44MB
goharbor/harbor-log v1.9.4 e0188c234aa2 82.3MB
goharbor/harbor-jobservice v1.9.4 207acbcff6f5 141MB
goharbor/harbor-core v1.9.4 a805deab5833 156MB
goharbor/harbor-portal v1.9.4 cfd272546394 51.4MB
goharbor/harbor-db v1.9.4 265c8c83954e 150MB
goharbor/prepare v1.9.4 b2cded69458d 151MB
再執(zhí)行一下 docker ps 命令,查看此時有哪些運行中的容器,輸出如下,這些就是 Harbor 服務所需要的容器,它們的創(chuàng)建和啟動是在 ./install.sh 執(zhí)行的第三步完成的 [Step 3]: starting Harbor ...
CONTAINER ID IMAGE NAMES
751a81c67e99 goharbor/nginx-photon:v1.9.4 nginx
7cb50d0224d4 goharbor/harbor-jobservice:v1.9.4 harbor-jobservice
c2751b9f1d81 goharbor/harbor-core:v1.9.4 harbor-core
2344cd81a05a goharbor/redis-photon:v1.9.4 redis
89a8695d234a goharbor/harbor-registryctl:v1.9.4 registryctl
f9c564f44ef2 goharbor/harbor-portal:v1.9.4 harbor-portal
c4661ab61769 goharbor/harbor-db:v1.9.4 harbor-db
86984dbff640 goharbor/registry-photon:v1.9.4 registry
3c36fe8023ef goharbor/harbor-log:v1.9.4 harbor-log
瀏覽器訪問 Harbor 控制臺,賬號:admin 默認密碼:Harbor12345
Docker Maven Plugin
上面通過手動執(zhí)行 docker build 命令已經(jīng)成功構建了鏡像,這里再看下如何在項目通過 Maven 插件來自動構建鏡像并且發(fā)布至倉庫 Harbor 中。
筆者是在 Windows 的 IDEA 中構建,Docker 是通過虛擬機安裝的,所以首先需要配置 Docker 允許遠程連接。
編輯 vim /lib/systemd/system/docker.service ,將 ExecStart 追加參數(shù) -H tcp://0.0.0.0:2375
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375
保存后,重啟:
systemctl daemon-reload
systemctl restart docker
通過瀏覽器訪問 http://192.168.0.110:2375/info 成功即可。
在 IDEA 中添加 Docker 配置:
在 IDEA 中查看 Docker 容器、鏡像信息:
docker maven 插件配置:具體參看 Spring Boot Demo 項目
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.2</version>
<configuration>
<serverId>docker-harbor</serverId>
<dockerHost>http://192.168.0.110:2375</dockerHost>
<registryUrl>192.168.0.110:8089</registryUrl>
<imageName>192.168.0.110:8089/base/${project.build.finalName}:${project.version}</imageName>
<dockerDirectory>${project.basedir}/bin/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.war</include>
</resource>
</resources>
<imageTags>
<imageTag>${project.version}</imageTag>
</imageTags>
<forceTags>true</forceTags>
<pushImage>true</pushImage>
</configuration>
</plugin>
- dockerHost 標簽可以指定 Docker 服務遠程地址
- registryUrl 指定倉庫地址,這里用的是自己搭建的 Harbor 鏡像倉庫
- imageName 指定鏡像名稱
- dockerDirectory 用來指定 Dockerfile 文件的位置
- imageTags 即指定鏡像版本號
- pushImage 表示是否將鏡像推送到指定的倉庫中,為 false 時,構建成功后不推送倉庫
構建前首先在 Maven 配置中添加 Harbor 用戶名密碼和 plugin 配置:
<server>
<id>docker-harbor</id>
<username>admin</username>
<password>Harbor12345</password>
</server>
<pluginGroups>
<pluginGroup>com.spotify</pluginGroup>
</pluginGroups>
下面執(zhí)行命令進行構建并上傳至 Harbot:
mvn clean package docker:build -Dmaven.test.skip=true -Pdocker
輸出如下:
[INFO] Building image 192.168.0.110:8089/base/gchat:1.0
Step 1/9 : FROM maven:3-jdk-8-alpine
---> 7445f83cd169
Step 2/9 : MAINTAINER "人間春蕩蕩 <人間春蕩蕩@126.com>"
---> 6ec6024e4273
Step 3/9 : WORKDIR /opt/gchat
---> f48609ccaa2d
Step 4/9 : ADD gchat.war .
---> 7335b0f3485c
Step 5/9 : RUN jar -xvf gchat.war
... 略
Successfully built 6ce252273598
Successfully tagged 192.168.0.110:8089/base/gchat:1.0
構建成功后,登錄 Harbor,http://192.168.0.110/harbor 查看鏡像信息。
局域網(wǎng)內(nèi)可通過 docker pull 拉取 Harbor 上的鏡像:
docker pull 192.168.0.110:8089/base/gchat:1.0
docker push 默認推送地址是 Docker 官方倉庫 https://hub.docker.com/ ,你需要先注冊一個 Docker Hub 賬號,然后用 docker login 命令登錄后即可執(zhí)行 docker push 推送鏡像。 如要將本地鏡像推送至私人搭建的倉庫 Harbor,登錄時要指定鏡像倉庫地址:
docker login 192.168.0.110:8089
Docker Compose
編排工具就是來管理 Docker 容器的定義、配置和創(chuàng)建,筆者在 docker-compose.yml 文件中定義了三個服務,mysql、nginx、gchat,并且指定了它們之間的關聯(lián)關系。
version: '3.7'
services:
mysql:
image: mysql:latest
container_name: mysql
restart: always
ports:
- "3407:3306"
volumes:
- ./mysql/data/:/var/lib/mysql
- ./mysql/my.cnf:/etc/mysql/my.cnf
- ./mysql/sec:/var/lib/mysql-files
environment:
MYSQL_ROOT_PASSWORD: "root"
gchat:
image: com.demo/gchat:1.0-SNAPSHOT
container_name: gchat
restart: always
ports:
- "8087:8082"
depends_on:
- mysql
environment:
jdbc.type: "mysql"
jdbc.username: "root"
jdbc.password: "root"
jdbc.driver: "com.mysql.cj.jdbc.Driver"
jdbc.url: "jdbc:mysql://mysql:3306/gchat?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai"
nginx:
image: nginx:1.17.8
container_name: nginx
restart: always
depends_on:
- gchat
volumes:
- ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/html:/usr/share/nginx/html
- ./nginx/logs:/var/log/nginx
ports:
- 80:80
environment:
- TZ=Asia/Shanghai
這里 mysql 容器的配置文件和數(shù)據(jù)被掛載到宿主機上,nginx 的配置文件也被掛載到了宿主機上,這樣即使刪除容器的話,數(shù)據(jù)也不會丟失;修改配置文件可直接在宿主機上進行編輯,無需通過 docker exec 命令進入容器內(nèi)修改(或者是通過 docker cp 來 copy 文件至宿主機內(nèi))。
執(zhí)行 docker-compose -p gchat up -d 命令來創(chuàng)建和啟動容器,此命令默認會在當前目錄下查找 docker-compose.yml 文件,也可手動指定文件位置 -f /opt/gchat/docker-compose.yml ,先看下輸出信息:
$ docker-compose -p gchat up -d
Creating network "gchat_default" with the default driver
Creating mysql ... done
Creating gchat ... done
Creating nginx ... done
默認的網(wǎng)絡模式為 network_mode: bridge 。
首先會創(chuàng)建一個名稱為 gc_default 的網(wǎng)絡,然后根據(jù)配置 依次創(chuàng)建容器 mysql、 gchat、nginx,并且以其容器名稱加入 gc_default 網(wǎng)絡中。這樣 Docker Compose 管理下的容器之間的相互訪問即可通過容器名稱加容器端口的方式。
也可以通過 docker network create 命令先創(chuàng)建網(wǎng)絡,然后在 yml 中進行配置。
docker network create -d bridge self-network
networks:
default:
external:
name: self-network
通過 docker network ls 查看當前的網(wǎng)絡:
/opt/gchat$ docker network ls
NETWORK ID NAME DRIVER SCOPE
10b2aaa3c026 bridge bridge local
c5555d99ae9d gchat_default bridge local
b6a883741497 host host local
0f969b2af1da none null local
再查看下剛剛創(chuàng)建的網(wǎng)絡 gchat_default 的具體信息:docker network inspect gchat_default
$ docker network inspect gchat_default
......
"Name": "gchat_default",
"Driver": "bridge",
"IPAM": {
"Driver": "default",
"Config": [
{
"Subnet": "172.27.0.0/16",
"Gateway": "172.27.0.1"
}
]
},
"Containers": {
"4e2eacd13160d9d5a98da97e61e5686418d6dd4f8592fef5f64c0ee622307d82": {
"Name": "gchat",
"MacAddress": "02:42:ac:1b:00:03",
"IPv4Address": "172.27.0.3/16"
},
"6ff30a833674c4bf2629329d7a63e8b2070c8ea738b3e38c48ae5535addc4d43": {
"Name": "nginx",
"MacAddress": "02:42:ac:1b:00:04",
"IPv4Address": "172.27.0.4/16"
},
"d530fef73b38301a9b94421ec213c274129b01f494138786ab4175a8d65f4037": {
"Name": "mysql",
"MacAddress": "02:42:ac:1b:00:02",
"IPv4Address": "172.27.0.2/16"
}
},
......
信息很清晰,默認的網(wǎng)絡驅(qū)動是:bridge,網(wǎng)絡名稱為:gchat_default,網(wǎng)段為 172.27.0.0/16,給每一個容器都分配了一個 IP。
在用戶自己定義的 Docker 網(wǎng)絡中,容器名稱的 DNS 解析會自動發(fā)生,Docker 內(nèi)嵌的 DNS 服務維護容器名稱及其 IP 地址,如容器正在使用定義的 Docker 網(wǎng)絡,無需執(zhí)行任何操作,它們可以使用主機名自動找到對方。如下:ping 其它的容器名稱
$ docker exec -it gchat ping mysql
PING mysql (172.27.0.2): 56 data bytes
64 bytes from 172.27.0.2: seq=0 ttl=64 time=0.050 ms
64 bytes from 172.27.0.2: seq=1 ttl=64 time=0.102 ms
$ docker exec -it gchat ping nginx
PING nginx (172.27.0.4): 56 data bytes
64 bytes from 172.27.0.4: seq=0 ttl=64 time=0.045 ms
64 bytes from 172.27.0.4: seq=1 ttl=64 time=0.060 ms
在 Docker 中,容器的主機名默認為容器的 ID,也可以通過 --hostname 參數(shù)來指定,通過 docker exec 查看容器的 hosts 文件:
$ docker exec -it mysql cat /etc/hosts
172.27.0.2 d530fef73b38
查看正在運行的容器:
$ docker ps
CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES
6ff30a833674 nginx:1.17.8 "nginx -g " Up 19 minutes 80->80/tcp nginx
4e2eacd13160 gchat:1.0 "/bin/sh -c 'java -c…" Up 19 minutes 8080/tcp, 8087->8082/tcp gchat
d530fef73b38 mysql:latest "docker-entrypoint.s…" Up 19 minutes 33060/tcp, 3407->3306/tcp mysql
對于容器內(nèi)的 DNS 配置,如果宿主機的 /etc/resolv.conf 內(nèi)容發(fā)生改變,Docker 進程會監(jiān)聽到這些改變,并將變化同步至容器的 /etc/resolv.conf 。但前提是,只有在容器停止時,才會同步這些配置的更改。因此,要想使宿主機上配置的 DNS 生效,就需要停止容器后重新啟動。
執(zhí)行 docker inspect gchat 查看容器如下信息:
# system
"ResolvConfPath": "/var/lib/docker/containers/de88cfcfcb410dba67b4bcb7da/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/de88cfcfcb410dba67b4bcb7da/hostname",
"HostsPath": "/var/lib/docker/containers/de88cfcfcb410dba67b4bcb7da/hosts",
網(wǎng)絡信息:
"Networks": {
"gchat_default": {
"Aliases": [
"gchat",
"de88cfcfcb41"
],
"NetworkID": "7a140855e53ec5d86af3733dc7b0ef10ed95437811623eb1d00f6185b7cfcaf8",
"Gateway": "172.30.0.1",
"IPAddress": "172.30.0.3",
"MacAddress": "02:42:ac:1e:00:03",
}
}
數(shù)據(jù)卷信息:
# Volumn
"Mounts": [
{
"Type": "bind",
"Source": "/opt/gchat/mysql/data",
"Destination": "/var/lib/mysql",
"Mode": "rw", "RW": true,
"Propagation": "rprivate"
},
{
"Type": "bind",
"Source": "/opt/gchat/mysql/my.cnf",
"Destination": "/etc/mysql/my.cnf",
"Mode": "rw", "RW": true,
"Propagation": "rprivate"
}
]
查看日志的話,可通過 docker logs -f gchat,也可通過 docker-compose logs -f gchat 來查看。
如果想要強制重建某個容器,可使用 --force-recreate 參數(shù):
docker-compose up -d --force-recreate mysql
否則只會在容器配置有更改時才會重建容器,容器之間根據(jù) depends_on 參數(shù)設置了依賴關系,代表了其創(chuàng)建啟動的順序。重建某個容器時,會先重建其依賴的容器,例如重建 gchat 容器時:
$ docker-compose up -d --force-recreate gchat
Recreating mysql ... done
Recreating gchat ... done
停止并刪除所有容器命令:
docker-compose down
刪除某個容器,默認只能刪除已停止的容器,-f 強制刪除:
docker rm -f nginx
磁盤空間使用分析:docker system df
空間清理 docker system prune,此命令會刪除:
- 所有已停止的容器
- 所有不被任何容器使用的 network
- 所有懸空鏡像,即未被任何容器引用的鏡像
這里要注意區(qū)分主機端口和容器端口,例如對于上面定義的 mysql 容器,3407 是主機端口,3306 是容器端口,網(wǎng)絡化的容器服務之間的通信使用容器端口,例如 gchat 連接 mysql 數(shù)據(jù)庫使用的是 mysql:3306;而對于外部網(wǎng)絡訪問則需要使用主機端口,例如在其他電腦中通過 Navicat 連接 mysql 則需要使用 3407 端口。
此外,docker 也提供了一些查看容器資源統(tǒng)計信息的命令。
通過 docker stats 查看容器 cpu、mem 使用情況, MEM USAGE / LIMIT 容器使用的總內(nèi)存和允許使用的總內(nèi)存,未做限制時,允許使用的量為宿主機總內(nèi)存。
$ docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
93a546af2006 nginx 0.00% 108.5MiB / 4.837GiB 2.19% 4.18kB / 0B 4.76MB / 0B 5
f3b50c9fcb00 gchat 1.80% 437.3MiB / 4.837GiB 8.83% 27kB / 21.7kB 60.3MB / 0B 32
64090ff0d7b0 mysql 0.46% 395MiB / 4.837GiB 7.98% 28.8kB / 20.3kB 72.1MB / 18.8MB 40
查看容器在宿主機中的進程號 docker top [containerId or Name]:
$ docker top f3b50c9fcb00
UID PID PPID C STIME TTY TIME CMD
root 4001 3975 6 15:21 ? 00:00:12 java -cp /opt/gchat -Xms1024m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m org.springframework.boot.loader.WarLauncher
下面對 gchat 容器的 cpu、memory 資源進行限制,不同版本寫法略有差別,具體參看官方說明:
deploy:
resources:
limits:
cpus: "0.20"
memory: 2G
添加如上資源限制標簽后,這時通過 docker-compose up -d --force-recreate gchat 重建容器時,會有如下提示,設置的資源限制 deploy 屬性被忽略,未起作用。
WARNING: Some services (gchat ) use the ‘deploy’ key, which will be ignored.
Compose does not support ‘deploy’ configuration - use docker stack deploy to deploy to a swarm.
原因是由于做了資源限制, 并且沒有使用 swarm,所以要加上 --compatibility 參數(shù),它會將 version: 3.x 版本設置資源限制的方法轉(zhuǎn)換回 version: 2.x 兼容的屬性。
docker-compose --compatibility up -d --force-recreate gchat
# 參數(shù)含義
--compatibility If set, Compose will attempt to convert keys in v3 files to their non-Swarm equivalent
可以通過運行 docker-compose --compatibility config 來驗證配置,會看到資源限制屬性被翻譯成 cpus 和 mem_limit。
$ docker-compose --compatibility config
......
services:
gchat:
container_name: gchat
cpus: 0.2
mem_limit: 2G
depends_on:
mysql:
condition: service_started
......
version: '2.3'
Docker Compose 配置中除了指定鏡像名稱外,還可以指定 Dockerfile 文件,啟動時會先根據(jù) yml 中 Dockerfile 的配置來創(chuàng)建鏡像,詳情參看:
~ END ~