Docker 引擎是一种用于构建和容器化应用程序的开源容器化技术。它是一个服务端-客户端结构的应用,主要有以下部分组成:
- Docker 守护进程:持久化的进程,监听 Docker Engine API 的请求
- Docker Engine API:与 Docker 守护进程交互用的的 RESTful API
- Docker 客户端:命令行接口,通过客户端将命令发送给守护进程
Dockerfile 一个文本文档,Docker 可以通过读取 Dockerfile 中定义的指令来自动构建镜像。
Docker Compose 是一个用于定义和运行多个容器的 Docker 工具。Compose 使用 YAML 文件来配置应用程序的服务。然后,通过单个命令,就可以从配置中创建并启动所有服务。
下面演示所用 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 环境
- MAINTAINER:作者信息
- WORKDIR:指定后续命令执行的目录,即后续的命令都将 /opt/gchat 作为当前目录
- ADD:复制文件,将当前目录下 gchat.war 包复制到镜像 /opt/gchat/ 目录下
- RUN:在容器中要执行的 shell 命令
- ENV:指定环境变量,这里指定了时区
- EXPOSE:声明服务监听端口(仅仅是声明,并不会主动做端口映射)
- ENTRYPOINT:指定镜像的入口启动进程
Dockerfile 编写完了,下面看下如何使用 Dockerfile 文件来生成镜像。
# 构建镜像命令
docker build -t gchat:1.0-SNAPSHOT .
-t 作用是给镜像打个标签,起个名字。
末尾 . 代表 Dockerfile 文件在当前操作的目录下,否则可以通过 -f /opt/Dockerfile
参数来指定文件位置。
docker build 会加载当前目录下的 Dockerfile 文件,然后按照顺序,执行文件中定义的命令。
docker build 执行完成后,通过 docker images 命令查看镜像列表:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
gchat 1.0-SNAPSHOT d97ec5bc1022 4 months ago 241MB
通过 docker run 来创建运行 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
参数 --network 用来指定容器运行的网络模式,默认为 bridge 方式。host 则表示主机网络模式,共享宿主机的网络栈;若采用默认的 bridge 方式,则需要开启端口映射 -p 8080:8082
,将容器内的 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 。
这个命令可以把一个正在运行的容器,直接提交为一个镜像。
例如在内网环境安装 Jenkins ,不能访问互联网,这个时候就可以先在本地运行 Jenkins 容器:
docker run -d --name jenkins -p 8084:8080 jenkins/jenkins:lts
运行成功后,访问 http://127.0.0.1:8084/jenkins
,把需要的一些插件全部安装后,对正在运行的容器执行 docker commit 操作,这样在容器之上的所有操作都会保存到新的镜像里。
# 将运行中的容器 56b5168a7ae2 提交为镜像
docker commit 56b5168a7ae2 jenkins:self-v3
之后,可通过 docker save 命令导出镜像,再通过 docker load 命令将镜像加载至内网中。
# 导出
docker save -o jenkins-lts-v3.tar jenkins:self-v3
# 导入
docker load -i jenkins-lts-v3.tar jenkins:self-v3
当然还可以通过 Volume 数据卷的功能,将宿主机目录挂载到 Jenkins 所在容器内的安装目录上,这样所有的有关 Jenkins 文件增删改都发生在宿主机上。
# 将 /opt/jenkins 挂载至容器内 jenkins 的安装目录
-v /opt/jenkins:/home/jenkins
如果想在运行中的容器中执行 shell 命令,使用 docker exec 命令:
docker exec -it gchat /bin/sh
命令执行后会进入容器的默认工作目录,如果在 Dockerfile
中指定了工作目录 WORKDIR
,则会进入 Dokcerfile
指定的目录,例如执行 ls 默认显示的就是 /opt/gchat 下的文件。
$ docker exec -it gchat ls
META-INF WEB-INF gchat.war org
查看设置的环境变量 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
# 创建容器时指定
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
执行 uname -a,查看 Linux 内核版本:
# 容器内执行
$ 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
首先要明确的是,容器与宿主机共享操作系统内核,也就是说容器和镜像是没有内核的,只有文件系统。我们有些服务器是华为 TaiShan,基于鲲鹏处理器 ARM 架构的 Linux 系统,在刚开始使用 Docker 的时候,尝试在其中启动基于 X86 架构构建的镜像,很显然失败了。
下面是官方文档中 Docker 的特性说明,其中约束和隔离涉及到 Linux 的 Namespace 和 Cgroups 特性,大家可自行 Google 了解。
灵活:即使是最复杂的应用程序也可以被容器化。
轻量级:容器利用并共享主机内核,使它们在系统资源方面比虚拟机效率更高。
可移植:您可以在本地构建、部署到云中,并在任何地方运行。
松散耦合:容器是高度自给自足和封装的,允许您替换或升级一个容器,而不会破坏其他容器。
可扩展:您可以增加和自动分发跨数据中心的容器副本。
安全:容器对进程进行约束和隔离,而不需要用户进行任何配置。
容器只是操作系统中的一个进程:
从根本上说,容器只不过是一个正在运行的进程,为了保持它与主机和其他容器的隔离,对它应用了一些附加的封装特性。容器隔离最重要的是每个容器与自己的私有文件系统交互;这个文件系统由 Docker 镜像提供。镜像包括运行应用程序所需的一切代码或二进制、运行时、依赖项和任何其他所需的文件系统对象。
# 查看进程号
$ docker top gchat
UID PID PPID C STIME TTY TIME CMD
root 4038 4014 6 13:57 ? 00:00:14 java -cp ...
Harbor
Harbor 是构建企业级私有 Docker 镜像仓库的开源解决方案,就像 Nexus 是 Maven 的 JAR 仓库管理器一样。
Harbor 使用 Docker 方式来安装启动,并且通过 Docker Compose 工具来管理,所以请先确保 Docker 环境和 Docker Compose 工具已经成功安装。
Harbor 离线安装包 harbor-offline-installer-v1.9.4.tgz 下载地址:
https://github.com/goharbor/harbor/releases
将安装包解压,Harbor 的配置文件 harbor.yml ,包括域名、端口号、初始密码等配置:
# Configuration file of Harbor
hostname: 192.168.0.110
# http related config
http:
port: 8089
harbor_admin_password: Harbor12345
......
在解压后的文件夹下执行 ./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.----
安装成功后,文件夹下会出现一个 docker-compose.yml 文件,YML 文件中定义了 Harbor 工具所需要创建的容器以及其它配置。可以通过 Docker Compose 命令来启动、停止、卸载 Harbor 服务,关于 Docker Compose 的使用下面会介绍。
-
创建 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
安装成功后,执行下 docker images 命令,查看此时的镜像列表,输出如下,这些镜像皆是在执行 ./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
再执行一下 docker ps 命令,查看此时有哪些运行中的容器,输出如下,这些就是 Harbor 服务所需要的容器,它们的创建和启动是在 ./install.sh 执行的第三步完成的 [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
上面通过手动执行 docker build 命令已经成功构建了镜像,这里再看下如何在项目通过 Maven 插件来自动构建镜像并且发布至仓库 Harbor 中。
笔者是在 Windows 的 IDEA 中构建,Docker 是通过虚拟机安装的,所以首先需要配置 Docker 允许远程连接。
编辑 vim /lib/systemd/system/docker.service ,将 ExecStart 追加参数 -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 项目
com.spotify
docker-maven-plugin
1.2.2
docker-harbor
http://192.168.0.110:2375
192.168.0.110:8089
192.168.0.110:8089/base/${project.build.finalName}:${project.version}
${project.basedir}/bin/docker
/
${project.build.directory}
${project.build.finalName}.war
${project.version}
true
true
- dockerHost 标签可以指定 Docker 服务远程地址
- registryUrl 指定仓库地址,这里用的是自己搭建的 Harbor 镜像仓库
- imageName 指定镜像名称
- dockerDirectory 用来指定 Dockerfile 文件的位置
- imageTags 即指定镜像版本号
- pushImage 表示是否将镜像推送到指定的仓库中,为 false 时,构建成功后不推送仓库
构建前首先在 Maven 配置中添加 Harbor 用户名密码和 plugin 配置:
docker-harbor
admin
Harbor12345
com.spotify
下面执行命令进行构建并上传至 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
查看镜像信息。
局域网内可通过 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 命令登录后即可执行 docker push 推送镜像。 如要将本地镜像推送至私人搭建的仓库 Harbor,登录时要指定镜像仓库地址:
docker login 192.168.0.110:8089
Docker Compose
编排工具就是来管理 Docker 容器的定义、配置和创建,笔者在 docker-compose.yml 文件中定义了三个服务,mysql、nginx、gchat,并且指定了它们之间的关联关系。
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 容器的配置文件和数据被挂载到宿主机上,nginx 的配置文件也被挂载到了宿主机上,这样即使删除容器的话,数据也不会丢失;修改配置文件可直接在宿主机上进行编辑,无需通过 docker exec 命令进入容器内修改(或者是通过 docker cp 来 copy 文件至宿主机内)。
执行 docker-compose -p gchat up -d 命令来创建和启动容器,此命令默认会在当前目录下查找 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
默认的网络模式为 network_mode: bridge 。
首先会创建一个名称为 gc_default 的网络,然后根据配置 依次创建容器 mysql、 gchat、nginx,并且以其容器名称加入 gc_default 网络中。这样 Docker Compose 管理下的容器之间的相互访问即可通过容器名称加容器端口的方式。
也可以通过 docker network create 命令先创建网络,然后在 yml 中进行配置。
docker network create -d bridge self-network
networks:
default:
external:
name: self-network
通过 docker network ls 查看当前的网络:
/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
再查看下刚刚创建的网络 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"
}
},
......
信息很清晰,默认的网络驱动是:bridge,网络名称为:gchat_default,网段为 172.27.0.0/16,给每一个容器都分配了一个 IP。
在用户自己定义的 Docker 网络中,容器名称的 DNS 解析会自动发生,Docker 内嵌的 DNS 服务维护容器名称及其 IP 地址,如容器正在使用定义的 Docker 网络,无需执行任何操作,它们可以使用主机名自动找到对方。如下: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
参数来指定,通过 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
对于容器内的 DNS 配置,如果宿主机的 /etc/resolv.conf 内容发生改变,Docker 进程会监听到这些改变,并将变化同步至容器的 /etc/resolv.conf 。但前提是,只有在容器停止时,才会同步这些配置的更改。因此,要想使宿主机上配置的 DNS 生效,就需要停止容器后重新启动。
执行 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",
网络信息:
"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",
}
}
数据卷信息:
# 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 参数:
docker-compose up -d --force-recreate mysql
否则只会在容器配置有更改时才会重建容器,容器之间根据 depends_on 参数设置了依赖关系,代表了其创建启动的顺序。重建某个容器时,会先重建其依赖的容器,例如重建 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
- 所有悬空镜像,即未被任何容器引用的镜像
这里要注意区分主机端口和容器端口,例如对于上面定义的 mysql 容器,3407 是主机端口,3306 是容器端口,网络化的容器服务之间的通信使用容器端口,例如 gchat 连接 mysql 数据库使用的是 mysql:3306;而对于外部网络访问则需要使用主机端口,例如在其他电脑中通过 Navicat 连接 mysql 则需要使用 3407 端口。
此外,docker 也提供了一些查看容器资源统计信息的命令。
通过 docker stats 查看容器 cpu、mem 使用情况, MEM USAGE / LIMIT
容器使用的总内存和允许使用的总内存,未做限制时,允许使用的量为宿主机总内存。
$ 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 资源进行限制,不同版本写法略有差别,具体参看官方说明:
https://docs.docker.com/compose/compose-file/#resources
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 参数,它会将 version: 3.x 版本设置资源限制的方法转换回 version: 2.x 兼容的属性。
docker-compose --compatibility up -d --force-recreate gchat
# 参数含义
--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 文件,启动时会先根据 yml 中 Dockerfile 的配置来创建镜像,详情参看:
https://docs.docker.com/compose/compose-file/#build
~ END ~