我使用Search Guard插件来保护由多个节点组成的弹性搜索群集。 这是我的Dockerfile:
Domain services
初始化SearchGuard(创建内部用户并分配角色)。我需要在容器启动后运行脚本#!/bin/sh
FROM docker.elastic.co/elasticsearch/elasticsearch:5.6.3
USER root
# Install search guard
RUN bin/elasticsearch-plugin install --batch com.floragunn:search-guard-5:5.6.3-16 \
&& chmod +x \
plugins/search-guard-5/tools/hash.sh \
plugins/search-guard-5/tools/sgadmin.sh \
bin/init_sg.sh \
&& chown -R elasticsearch:elasticsearch /usr/share/elasticsearch
USER elasticsearch
。
问题是:除非elasticsearch正在运行,否则脚本不会初始化任何安全索引。
该剧本的内容是:
init_sg.sh
现在,我只是在容器启动后手动运行脚本,但是因为我在Kubernetes上运行它.Bods可能会被杀死或失败并由于某种原因自动重新创建。在这种情况下,插件必须在容器启动后自动初始化!
那么如何做到这一点?任何帮助或提示都会非常感激。
答案 0 :(得分:3)
不确定这会解决您的问题,但值得检查我的repo Dockerfile
我创建了一个简单的run.sh
文件,复制到了docker image和Dockerfile
我写的CMD ["run.sh"]
。以同样的方式在run.sh
中定义您想要的任何内容并编写CMD ["run.sh"]
。你可以找到另一个例子,如下面的
FROM java:8
RUN apt-get update && apt-get install stress-ng -y
ADD target/restapp.jar /restapp.jar
COPY dockerrun.sh /usr/local/bin/dockerrun.sh
RUN chmod +x /usr/local/bin/dockerrun.sh
CMD ["dockerrun.sh"]
#!/bin/sh
java -Dserver.port=8095 -jar /restapp.jar &
hostname="hostname: `hostname`"
nohup stress-ng --vm 4 &
while true; do
sleep 1000
done
答案 1 :(得分:1)
图像本身具有Dockerfile中指定的入口点ENTRYPOINT ["/run/entrypoint.sh"]
。您可以使用自己的脚本替换它。例如,创建一个新脚本,安装它并首先调用/run/entrypoint.sh
,然后在运行init_sg.sh
之前等待弹性搜索的启动。
答案 2 :(得分:1)
此问题在此处的文档中得到解决:https://docs.docker.com/config/containers/multi-service_container/
如果您的进程之一依赖于主进程,则使用诸如wait-for-it之类的脚本首先启动辅助进程,然后启动主进程SECOND并删除fg%1行。
#!/bin/bash
# turn on bash's job control
set -m
# Start the primary process and put it in the background
./my_main_process &
# Start the helper process
./my_helper_process
# the my_helper_process might need to know how to wait on the
# primary process to start before it does its work and returns
# now we bring the primary process back into the foreground
# and leave it there
fg %1
答案 3 :(得分:0)
我建议将 CMD 放入docker文件中,以便在容器启动时执行脚本
FROM debian
RUN apt-get update && apt-get install -y nano && apt-get clean
EXPOSE 8484
CMD ["/bin/bash", "/opt/your_app/init.sh"]
还有其他方法,但在使用此功能之前,请查看您的要求,
ENTRYPOINT "put your code here" && /bin/bash
#exemple ENTRYPOINT service nginx start && service ssh start &&/bin/bash "use && to separate your code"
答案 4 :(得分:0)
I was trying to solve the exact problem. Here's the approach that worked for me.
#!/bin/sh
echo ">>>> Right before SG initialization <<<<"
# use while loop to check if elasticsearch is running
while true
do
netstat -uplnt | grep :9300 | grep LISTEN > /dev/null
verifier=$?
if [ 0 = $verifier ]
then
echo "Running search guard plugin initialization"
/elasticsearch/plugins/search-guard-6/tools/sgadmin.sh -h 0.0.0.0 -cd plugins/search-guard-6/sgconfig -icl -key config/client.key -cert config/client.pem -cacert config/root-ca.pem -nhnv
break
else
echo "ES is not running yet"
sleep 5
fi
done
You will need to install the script in container so it's accessible after it starts.
COPY sginit.sh /
RUN chmod +x /sginit.sh
You will need to edit the entrypoint script or run script of your ES image. So that it starts the sginit.sh in the background BEFORE starting ES process.
# Run sginit in background waiting for ES to start
/sginit.sh &
This way the sginit.sh will start in the background, and will only initialize SG after ES is started.
The reason to have this sginit.sh script starts before ES in the background is so that it's not blocking ES from starting. The same logic applies if you put it after starting of ES, it will never run unless you put the starting of ES in the background.
答案 5 :(得分:0)
您也可以使用here脚本。它将等待主机和TCP端口的可用性。这对于同步相互依赖的服务的旋转很有用,并且可以像容器一样吸引人。它没有任何外部依赖性,因此您可以将其作为RUN命令运行,而无需执行其他任何操作。
基于此wait-for-it的Dockerfile示例:
FROM elasticsearch
# Make elasticsearch write data to a folder that is not declared as a volume in elasticsearchs' official dockerfile.
RUN mkdir /data && chown -R elasticsearch:elasticsearch /data && echo 'es.path.data: /data' >> config/elasticsearch.yml && echo 'path.data: /data' >> config/elasticsearch.yml
# Download wait-for-it
ADD https://raw.githubusercontent.com/vishnubob/wait-for-it/e1f115e4ca285c3c24e847c4dd4be955e0ed51c2/wait-for-it.sh /utils/wait-for-it.sh
# Copy the files you may need and your insert script
# Insert data into elasticsearch
RUN /docker-entrypoint.sh elasticsearch -p /tmp/epid & /bin/bash /utils/wait-for-it.sh -t 0 localhost:9200 -- path/to/insert/script.sh; kill $(cat /tmp/epid) && wait $(cat /tmp/epid); exit 0;