Docker进阶
Docker进阶
Dockerfile
参考资料地址:Dockerfile reference | Docker Docs
Dockerfile是用来构建镜像的文本文件,在没有Dockerfile文件以前,构建镜像需要通过不断commit容器来完成,有了Dockerfile后,我们只需要编写Dockerfile文件,然后运行构建命令就可以了。
支持的命令
下面将对Dockerfile文件中支持的命令进行说明。需要说明的是Dockerfile文件中的命令需要大写。
- FROM:一般写在首行,用来指定基础镜像。如
FROM ubuntu
。 - ENV:添加环境变量,环境变量可以在一些命令(CMD、WORKDIR)中被使用,通过
$env_key
的形式。如ENV JAVA_HOME /usr/local/java
。 - WORKDIR:指定工作目录,对容器的操作都将基于该目录。如
WORKDIR $basedir
。 - RUN:指定在容器中运行的命令,构建镜像主要依赖该命令。如
RUN apt install -y mysql-server
。 - ADD:将宿主主机的文件夹或压缩包(tar)复制到容器中,如果是压缩包,将会自动进行解压。示例
ADD test.txt /mydir/
,ADD <src> <des>
。 - COPY:将宿主主机的文件夹或文件复制到容器中,该命令相对于ADD命令来说,不会进行解压操作。用法和ADD类似。
- VOLUME:配置数据卷,对宿主主机目录和容器目录做映射。
- EXPOSE:指定需要对外暴漏的端口,格式
EXPOSE port
。这个端口是指定容器去监听的,如果对容器和宿主主机端口做映射,需要通过-p
参数来完成。 - CMD:可以写多个CMD命令,但是只有最后一个生效,该命令是在我们
docker run
镜像后,容器启动后执行的第一条命令。同时需要注意的是,如果用户在docker run -d container_id
的后面加了其他参数,那么会覆盖掉通过Dockerfile配置的最后一个CMD命令。示例CMD ./catalina.sh
。 - ENTRYPOINT:优先级高于CMD命令,类似于CMD指令,但是ENTRYPOINT不会被docker run后面的命令覆盖,而且这些命令行参数会被当做参数送给ENTRYPOINT指令指定的程序。如果ENTRYPOINT后面紧跟着CMD命令,那么CMD的内容会被作为ENTRYPOINT中指定程序的参数。
案例
下面以hippo4j为例。
Dockerfile文件
# 基础镜像
FROM java8:1.0
ENV config_location /etc/hippo4j/application.properties
WORKDIR /usr/local/hippo4j/
COPY hippo4j-server.jar ./
VOLUME /etc/hippo4j/
EXPOSE 6691
CMD java -jar ./hippo4j-server.jar --spring.config.location=$config_location
构建命令
# 进入Dockerfile所在目录
cd hippo4j
# 别忘了最后面的.,表示构建工作目录
docker build -t hippo4j:1.0 .
Dockerfile实际上提供了一种链式创建容器的方式,通过编写一个Dockerfile文件,然后执行docker build -t image_name:version .
命令来构建镜像。
Docker的网络模式
Docker支持四种网络模式,准确来说是三种,下面将一一说明。
网络模式 | 说明 |
---|---|
bridge | 桥接模式,默认网络模式为bridge。该模式下,容器会使用docker模拟的网卡 |
host | 主机模式,该模式下,容器和宿主机共用同一张网卡 |
none | 该模式会禁用网络功能,仅有本地回环网络可用 |
container | 与某个容器共用网络配置。但是如果主容器被停止,那么网络将不可用 |
桥接模式
Docker服务默认会创建一个docker0网桥(其上有一个docker0内部接口),该桥接网络的名称为docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到了同一个物理网络。Docker默认指定了docker0接口的IP地址和子网掩码,让主机和容器之间可以通过网桥相互通信。
桥接模式下,容器使用docker模拟的网卡,容器使用桥接网卡和宿主机之间进行通信,宿主机和容器之间的网络并不直接相连。
如上图所示,网桥docker0提供veth接口,容器通过自己的网卡接口eth0和网桥相连。
指定网络模式为桥接模式的启动参数示例如下:
docker run -d --network bridge ubuntu
主机模式
主机模式下,容器和主机共享IP和端口。
指定网络模式为主机模式的启动参数示例如下:
docker run -d --network host ubuntu
容器模式
容器模式下,要启动的容器使用另一个容器的网络配置。需要注意的是如果主容器停止运行,那么使用该主机网络的容器的网络将不可用。
指定网络模式为主机模式的启动参数示例如下:
docker run -d --network container:container_name ubuntu
常用命令
命令 | 描述 |
---|---|
docker network ls | 列出docker目前所有的网络 |
docker network create -d bridge test | 创建网络,test为网络命令,可以通过-d 指定网络模式 |
docker network inspect network_name | 查看网络详细配置 |
docker network rm network_name | 删除网络 |
自定义网络
对于运行在同一个鲸鱼背上的容器来说,每一次运行,如果使用的是默认的桥接网络,那么每次都会分配不同的IP,服务之间想要互相通信,只能通过IP,非常麻烦。我们可以通过自定义网络来解决这个问题。自定义网络达到的效果是可以直接用服务名来代替IP进行通信。使用自定义网络的步骤如下。
- 通过命令创建自定义网络
- 在启动容器时,通过
--network
参数设置网络为该自定义网络并通过--name
设置服务名 - 在容器内,可以直接通过服务名进行通信
Docker-Compose
Docker Compose解决了容器与容器之间如何管理编排(比如依赖关系)的问题。可以用一个配置文件(docker-compose.yml)定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。一般来说,运维干着方面多一些。
官方文档地址:Compose file | Docker Docs
docker-compose是Docker官方提供的小工具,需要先进行安装。
使用Docker Compose可以干什么?
- 通过docker-compsoe.yml文件定义一批服务,并通过命令快速启动
- 支持定义容器启动顺序
- 所有通过
docker run
命令配置的参数,docker-compose都可以配置 - 一份配置,随处运行。避免每次启动容器都需要使用
docker run
命令
常用配置项
配置项 | 配置路径 | 说明 |
---|---|---|
version | root | 配置版本号,现阶段配"3"即可 |
services | root | 配置服务列表 |
networks | root | 配置网络,如果不存在,会进行创建 |
image | services.service_name | 配置服务使用的镜像 |
container_name | services.service_name | 配置容器名称,与--name 参数作用相同 |
restart | services.service_name | 配置重启策略 |
depends_on | services.service_name | 配置当前服务依赖的其他服务,启动时,会先启动它们 |
networks | services.service_name | 配置当前服务使用的网络 |
volumes | services.service_name | 配置数据卷,与-v 命令类似 |
ports | services.service_name | 配置端口映射 |
command | services.service_name | 配置命令,不同镜像配置方式不同 |
常用命令
命令 | 说明 |
---|---|
docker-compose -h | 帮助 |
docker-compose up | 启动docker-compose服务 |
docker-compose up -d | 启动docker-compose服务并在后台运行 |
docker-compose down | 停止并删除容器,网络,卷,镜像 |
docker-compose exec yml服务id | 进入指定服务内部 |
docker-compose ps | 展示当前docker-compose编排过的所有容器 |
docker-compose top | 展示当前docker-compose编排过的容器进程 |
docker-compose logs yml服务id | 查看容器输出日志 |
docker-compose config -q | 检查配置,输出发现的问题 |
docker-compose restart | 重启服务 |
docker-compose start | 启动服务 |
docker-compose stop | 停止服务 |
案例
以Halo的配置为例。
# docker-compose配置文件版本
version: "3"
# 配置服务列表,子项为每个服务
services:
halo:
image: halohub/halo:2.11
container_name: halo
restart: on-failure:3
depends_on:
halodb:
condition: service_healthy
networks:
halo_network:
volumes:
- ./halo2:/root/.halo2
ports:
- "8090:8090"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8090/actuator/health/readiness"]
interval: 30s
timeout: 5s
retries: 5
start_period: 30s
command:
- --spring.r2dbc.url=r2dbc:pool:mysql://halodb:3306/halo
- --spring.r2dbc.username=root
# MySQL 的密码,请保证与下方 MYSQL_ROOT_PASSWORD 的变量值一致。
- --spring.r2dbc.password=o#DwN&JSa56
- --spring.sql.init.platform=mysql
# 外部访问地址,请根据实际需要修改
- --halo.external-url=http://localhost:8090/
halodb:
image: mysql:8.1.0
container_name: halodb
restart: on-failure:3
networks:
halo_network:
command:
# 支持的命令参数可以查看DockerHub上的官方说明
- --default-authentication-plugin=caching_sha2_password
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_general_ci
- --explicit_defaults_for_timestamp=true
volumes:
- ./mysql:/var/lib/mysql
- ./mysqlBackup:/data/mysqlBackup
ports:
- "3306:3306"
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent"]
interval: 3s
retries: 5
start_period: 30s
environment:
# 支持的env参数可以查看DockerHub上的官方说明
# 请修改此密码,并对应修改上方 Halo 服务的 SPRING_R2DBC_PASSWORD 变量值
- MYSQL_ROOT_PASSWORD=o#DwN&JSa56
- MYSQL_DATABASE=halo
# 配置网络
networks:
halo_network:
容器监控、统计
Portainer——轻量级
官方文档地址:Install Portainer CE with Docker on Linux - Portainer Documentation
CIG——中量级
CAdvisor:数据收集、聚合、分析等
InfluxDB:时序数据库,用来存放CAdvisor收集到的监控数据
Grafana:图形化界面展示,它是一个通用的数据展示工具,可以配置多种数据源
可以使用Docker-Compose进行安装