首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法在容器启动时运行自定义脚本

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

Stack Overflow用户
提问于 2019-06-15 13:05:56
回答 2查看 1.6K关注 0票数 1

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

我让克莱尔在当地工作正常使用码头-写作。问题是,当我将其部署到AWS时,需要指定postgres服务器地址、用户名和密码等。生成映像时不知道postgres服务器地址,因此在构建Clair docker映像时不能包括它。它需要在容器/映像启动时进行定制。

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

例如:

Dockerfile

代码语言:javascript
复制
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脚本有点陌生,而且还没有遇到这种情况。

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

因此,我使用的解决方案是将bash安装到映像中,然后在容器启动时使用我通常使用的bash脚本。

Dockerfile

代码语言:javascript
复制
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 (小提取物)

代码语言:javascript
复制
#!/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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-15 13:18:03

请查一下

sed命令放入dockerfile CMD应该可以工作。

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

票数 2
EN

Stack Overflow用户

发布于 2019-06-15 13:25:25

Clair文件似乎赞同的方法是从源树中提取样例配置文件,定制它以进行品味,并使用docker run -v选项将其注入容器中。所以或多或少

代码语言:javascript
复制
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 (存储库的根目录)。包括这一行:

代码语言:javascript
复制
ENTRYPOINT ["/usr/bin/dumb-init", "--", "/clair"]

如果使用自己的CMD构建派生映像,则将其作为附加参数传递给ENTRYPOINT,在本例中,这意味着它将作为参数传递给Clair;调用方不能提供备用命令、启动调试外壳,或者在不完全覆盖入口点值的情况下注入额外的启动时间步骤。

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

代码语言:javascript
复制
#!/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,类似于

代码语言:javascript
复制
FROM quay.io/coreos/clair
COPY docker-entrypoint.sh /
RUN chmod 0755 /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["/clair"]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56610661

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档