Lio*_*ion 0 performance apache2 docker dockerfile docker-compose
我正在对 PHP 应用程序进行容器化,并希望根据环境变量修改 Apache 配置。这是在覆盖默认值的脚本中完成的ENTRYPOINT:
FROM php:7.2-apache
# ...
COPY prepare-docker-configs.sh .
RUN chmod +x prepare-docker-configs.sh
ENTRYPOINT ./prepare-docker-configs.sh
Run Code Online (Sandbox Code Playgroud)
进行这些修改后,Apache 不会启动。apache2-foreground似乎缺少命令,所以我在末尾运行它prepare-docker-configs.sh
#!/bin/bash
# ... Some config substitution
apache2-foreground
Run Code Online (Sandbox Code Playgroud)
现在 Apache 已经启动,一切都按预期进行。但我注意到停止容器比以前慢得多。我跑time docker-compose down了两个星座:
ENTRYPOINTreal 0m2,080s
user 0m0,449s
sys 0m0,064
Run Code Online (Sandbox Code Playgroud)
ENTRYPOINTreal 0m12,247s
user 0m0,491s
sys 0m0,067s
Run Code Online (Sandbox Code Playgroud)
所以需要大约10秒的时间。特别是在需要进行大量测试的开发过程中,这总共会浪费大量时间。
ENTRYPOINT停止速度如此之慢?如何解决?我尝试STOPSIGNAL SIGWINCH从原始 Dockerfile 添加并运行docker-php-entrypoint,两者都没有帮助。
该docker-compose.yml文件没什么特别的。由于内部冲突,它只是定义了服务并覆盖默认网络:
version: '2'
services:
app:
build:
context: .
args:
http_proxy: ${http_proxy}
env_file: docker.env
ports:
- 80:80
networks:
default:
driver: bridge
ipam:
config:
- subnet: 10.10.8.0/28
Run Code Online (Sandbox Code Playgroud)
我在配备 SSD、i7 四核和 32GB RAM 的 Ubuntu 工作站上运行此程序。它不运行任何大的东西,负载相当低。资源问题的可能性很小。而且性能问题是可以重现的:在另一台配备 Ryzen 5 3600 和 48GB 内存的 Ubuntu 机器上,覆盖需要 11 秒ENTRYPOINT。在 i3 速度慢得多的 Debian 上也有同样的结果。
ENTRYPOINT在我的脚本中,我docker-php-entrypoint在最后调用,它从 PHP 映像执行原始入口点脚本。它没有成功启动 Apache,我不得不调用apache2-foreground。
RUN使用以下语句启动 Apache 进程我CMD在我的中添加了一个指令Dockerfile
ENTRYPOINT ./prepare-docker-configs.sh
CMD apache2-foreground
Run Code Online (Sandbox Code Playgroud)
以及假设条目已通过的exec末尾的声明prepare-docker-configs.shCMD
set -x
exec "$@"
Run Code Online (Sandbox Code Playgroud)
但容器退出了,因为没有传递任何内容
app_1 | + set -x
app_1 | + exec
test_app_1 exited with code 0
Run Code Online (Sandbox Code Playgroud)
我测试过直接传递文件
exec apache2-foreground
Run Code Online (Sandbox Code Playgroud)
现在Apache已经启动了,但是仍然需要10多秒才能停止。
Docker 容器运行单个进程;ENTRYPOINT当你在 Dockerfile 中声明一个时,这就是这个过程。当你是docker stop一个容器时,它会(仅)向该进程发送 SIGTERM,如果它在 10 秒内没有停止自己,它会发送 SIGKILL 来强制终止它。由于容器进程的进程ID为1,因此信号处理也有一些特殊条件。
在您的情况下,bash运行入口点脚本的实例是根进程,并且它apache2-foreground作为子进程运行。您可以使用 Bourne shellexec命令将 shell 替换为您尝试运行的进程;然后apache2-foreground是主容器进程,docker stop信号直接发送到该进程。
入口点脚本的典型模式是遵循 Docker“命令”部分。这将作为附加参数传递给入口点,因此您的入口点脚本通常如下所示
#!/bin/sh
# ... Some config substitution
exec "$@"
Run Code Online (Sandbox Code Playgroud)
然后在你的 Dockerfile 中你需要提供默认的运行命令
# NOTE! ENTRYPOINT must be JSON-array syntax for this to work
ENTRYPOINT ["./prepare-docker-configs.sh"]
CMD apache2-foreground
Run Code Online (Sandbox Code Playgroud)
由于入口点脚本仍然exec是命令,因此它将 shell 命令包装器替换为进程 1 并将接收信号docker stop。
| 归档时间: |
|
| 查看次数: |
1484 次 |
| 最近记录: |