1

我正在尝试设置 Clair(Docker 图像漏洞扫描工具)。https://github.com/coreos/clair

我让 Clair 使用 docker-compose 在本地工作正常。问题是,当我将它部署到 AWS 时,我需要指定 postgres 服务器地址、用户名和密码等。构建镜像时不知道 postgres 服务器地址,因此构建 Clair docker 镜像时无法包含它。需要在容器/镜像启动时进行定制。

对于使用数据库的其他应用程序,我通常只自定义 docker 映像并添加一个脚本(在启动时运行),该脚本使用 SED 将正确的值(取自环境变量)插入到应用程序配置文件中。

例如:

Dockerfile

FROM quay.io/coreos/clair:latest

COPY /docker/clair/runtime.sh /runtime.sh
RUN chmod +x /runtime.sh

CMD ["/runtime.sh"]

运行时.sh

sed -i -e "s,#POSTGRES_SERVER#,$POSTGRES_SERVER,g" config.yaml

由于某种原因,上述方法不适用于 Clair docker 映像。这种方法适用于许多其他主流图像,所以我认为这是 Clair 图像的特别之处。

我没有收到任何错误,它只是忽略了CMD ["/runtime.sh"]我的 dockerfile 并像往常一样开始。

有没有人能够指出我如何让​​我的自定义脚本运行或指出另一种方法来实现同样的事情?

===========更新解决方案===========

问题是 Clair 图像基于 BusyBox,它默认使用ashshell,而我编写/正在使用的 shell 脚本是为bashshell 编写的。也许这应该很明显,但我对编写 linux shell 脚本有点陌生,还没有遇到过这个。

我在测试 mchawre 的答案后意识到了这一点,这避免了我遇到的问题,因为它不使用 shell 脚本。

所以我使用的解决方案是安装bash到镜像中,然后我可以在容器启动时使用我常用的 bash shell 脚本。

Dockerfile

FROM quay.io/coreos/clair:latest

RUN apk --no-cache upgrade
RUN apk add --no-cache curl py-pip bash postgresql-client figlet \
 && curl -L https://github.com/optiopay/klar/releases/download/v2.4.0/klar-2.4.0-linux-amd64 \
  > /usr/local/bin/klar \
 && chmod +x /usr/local/bin/klar \
 && pip install awscli

# Copy in custom Clair config file
COPY /docker/clair/config.yaml /etc/clair/config.yaml

# Env Vars for use with Klar CLI
ENV CLAIR_ADDR http://127.0.0.1:6060

# Copy runtime script & make it executable
COPY /docker/clair/runtime.sh /runtime.sh
RUN chmod +x /runtime.sh

# Override the parent images ENTRYPOINT
# Run a script on container startup which does a few things in addition to starting Clair at the end.
# Note, this script is a BASH script. It is critical that you install bash into the docker image or this script will
# fail with errors that are not very helpful.
ENTRYPOINT ["/runtime.sh"]

runtime.sh(小摘录)

#!/bin/bash

echo "======= Configuring config.yaml ====="
sed -i -e "s,#POSTGRES_USER#,$POSTGRES_USER,g" /etc/clair/config.yaml
sed -i -e "s,#POSTGRES_PASSWORD#,$POSTGRES_PASSWORD,g" /etc/clair/config.yaml
sed -i -e "s,#POSTGRES_URL#,$POSTGRES_URL,g" /etc/clair/config.yaml

/clair -config=/etc/clair/config.yaml
4

2 回答 2

2

请检查这个

将该sed命令放在 dockerfile 中CMD应该可以工作。

CMD sed -i "s/localhost/$DB_HOST/" /config/config.yaml && exec /clair -config=/config/config.yaml

于 2019-06-15T13:18:03.290 回答
0

Clair 文档似乎认可的方法是从源代码树中获取示例配置文件,对其进行定制以适应口味,然后使用选项将其注入容器中docker run -v。所以或多或少

docker network create clairnet
docker run -d \
  --net clairnet \
  --name clairpg \
  postgres:9.6
mkdir clair_config
sed 's/host=localhost/host=clairpg/' config.yaml.sample > clair_config/config.yaml
docker run -d \
  --net clairnet \
  -v $PWD/clair_config:/config \
  -p 6060:6060 \
  -p 6061:6061 \
  quay.io/coreos/clair:latest \
  -config=/config/config.yaml

(这是一种普遍有用的方法,可能比尝试在容器启动时修补配置文件更容易。)

如果你在 Kubernetes 中运行它,源代码树还包括一个 Helm 图表,它使用Go 模板在安装时填充 ConfigMap 中的配置。不过,这是一个非常特定于 Kubernetes 的解决方案,我不建议运行 Kubernetes 只是为了能够以这种方式运行。

否则,您将无法查看映像的 Dockerfile(位于存储库的根目录中)。这包括这一行:

ENTRYPOINT ["/usr/bin/dumb-init", "--", "/clair"]

如果您使用自己的 构建派生图像,则会将其CMD作为附加参数传递给ENTRYPOINT,在这种情况下,这意味着它会作为参数传递给 Clair;调用者无法提供替代命令、启动调试 shell,或者在您的情况下注入额外的启动时间步骤,而不完全覆盖入口点值。

您可以通过编写自己的入口点脚本来解决这个问题。我建议/clair从设置步骤中分离出运行 ( ) 的命令。脚本可能看起来像

#!/bin/sh
# I am /docker-entrypoint.sh, with mode 0755
sed "s/host=localhost/host=$PGHOST/" /config/config.yaml.sample > /config/config.sample
exec /usr/bin/dumb-init -- "$@"

然后你派生的 Dockerfile 类似于

FROM quay.io/coreos/clair
COPY docker-entrypoint.sh /
RUN chmod 0755 /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["/clair"]
于 2019-06-15T13:25:25.117 回答