无法在容器启动时运行自定义脚本

时间:2019-06-15 13:05:56

标签: docker dockerfile clair

我正在尝试设置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"]

runtime.sh

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

由于某种原因,以上方法不适用于Clair码头工人映像。这种方法已经适用于许多其他主流图像,所以我认为这对Clair图像来说是很特别的。

我没有收到任何错误,它只是忽略了我的dockerfile中的CMD ["/runtime.sh"]并像通常那样启动。

有人能指出我如何运行我的自定义脚本,或者指出实现相同目标的另一种方法吗?

=========== 使用解决方案更新 ==========

问题是Clair图像基于BusyBox,默认情况下使用ash shell,而我编写/使用的shell脚本是为bash shell编写的。也许这本来应该很明显,但是我对编写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

2 个答案:

答案 0 :(得分:2)

请检查this

sed命令放入dockerfile CMD中应该起作用。

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

答案 1 :(得分:0)

the Clair documentation似乎认可的方法是从源代码树中提取sample config file,对其进行自定义以使其具有品味,然后使用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 templates to populate the configuration in a ConfigMap。但是,这是一个非常特定于Kubernetes的解决方案,我不建议运行Kubernetes只是为了能够以这种方式运行事物。

否则,您将无法查看the image's 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"]