一个有用的docker entrypoint脚本的范例

$ cat docker-entrypoint.sh

bash 复制代码
#!/usr/bin/env sh
set -e

loglevel="${loglevel:-}"
USERID=$(id -u)


# if the first argument look like a parameter (i.e. start with '-'), run Envoy
if [ "${1#-}" != "$1" ]; then
    set -- envoy "$@"
fi

if [ "$1" = 'envoy' ]; then
    # set the log level if the $loglevel variable is set
    if [ -n "$loglevel" ]; then
        set -- "$@" --log-level "$loglevel"
    fi
fi

if [ "$ENVOY_UID" != "0" ] && [ "$USERID" = 0 ]; then
    if [ -n "$ENVOY_UID" ]; then
        usermod -u "$ENVOY_UID" envoy
    fi
    if [ -n "$ENVOY_GID" ]; then
        groupmod -g "$ENVOY_GID" envoy
    fi
    # Ensure the envoy user is able to write to container logs
    chown envoy:envoy /dev/stdout /dev/stderr
    exec su-exec envoy "${@}"
else
    exec "${@}"
fi

这个脚本 docker-entrypoint.sh 是一个 Docker 容器的入口脚本,用于设置和执行 Envoy 代理服务器。下面是对脚本的逐行解释:

  1. #!/usr/bin/env sh:这是 shebang 行,告诉系统使用哪个解释器来执行脚本。这里使用的是 sh shell。

  2. set -e:这个命令告诉 shell 在任何语句的执行结果不是 true 时就终止执行,这有助于捕获错误。

  3. loglevel="${loglevel:-}":这行设置了 loglevel 变量的值,如果环境变量 loglevel 已经设置,则使用其值,否则为空。

  4. USERID=$(id -u):获取当前用户的用户ID。

  5. if [ "${1#-}" != "$1" ]; then:检查脚本的第一个参数是否以连字符 - 开头。如果是,说明可能是一个选项参数。

  6. set -- envoy "$@":如果第一个参数是选项,将 envoy 添加到参数列表的前面,并保留所有原始参数。

  7. if [ "$1" = 'envoy' ]; then:检查第一个参数是否是 envoy,即是否要启动 Envoy 代理。

  8. if [ -n "$loglevel" ]; then:如果 loglevel 变量已经设置,并且不为空。

  9. set -- "$@" --log-level "$loglevel":将 --log-level 选项和 loglevel 值添加到参数列表中。

  10. if [ "$ENVOY_UID" != "0" ] && [ "$USERID" = 0 ]; then:如果 ENVOY_UID 环境变量设置且不等于 0,并且当前用户是 root 用户(用户ID 为 0)。

  11. usermod -u "$ENVOY_UID" envoy:改变用户 envoy 的用户ID为 ENVOY_UID

  12. groupmod -g "$ENVOY_UID" envoy:改变用户 envoy 的组ID为 ENVOY_GID

  13. chown envoy:envoy /dev/stdout /dev/stderr:确保 envoy 用户拥有对标准输出和标准错误的所有权,以便能够写入容器日志。

  14. exec su-exec envoy "${@}":使用 su-execenvoy 用户身份执行参数列表中的命令。

  15. else:如果上面的条件不满足,即不是以 root 用户身份运行,或者 ENVOY_UID 没有设置。

  16. exec "${@}":直接执行参数列表中的命令。

这个脚本的主要目的是在 Docker 容器启动时,根据提供的参数和环境变量配置 Envoy 代理,并以适当的用户身份执行它。如果容器以 root 用户身份启动,并且定义了 ENVOY_UIDENVOY_GID,则会更改 Envoy 用户的 UID 和 GID,并以该用户身份执行 Envoy。如果没有定义这些环境变量,或者不是以 root 用户身份启动,它将直接执行 Envoy 或其他传递的命令。

相关推荐
聆风吟º20 分钟前
CANN开源项目实战指南:使用oam-tools构建自动化故障诊断与运维可观测性体系
运维·开源·自动化·cann
ShiLiu_mtx29 分钟前
k8s - 7
云原生·容器·kubernetes
NPE~29 分钟前
自动化工具Drissonpage 保姆级教程(含xpath语法)
运维·后端·爬虫·自动化·网络爬虫·xpath·浏览器自动化
神梦流38 分钟前
GE 引擎的内存优化终局:静态生命周期分析指导下的内存分配与复用策略
linux·运维·服务器
春日见1 小时前
车辆动力学:前后轮车轴
java·开发语言·驱动开发·docker·计算机外设
xuhe21 小时前
[全流程详细教程]Docker部署ClawBot, 使用GLM4.7, 接入TG Bot实现私人助理. 解决Docker Openclaw Permission Denied问题
linux·docker·ai·github·tldr
Lsir10110_1 小时前
【Linux】进程信号(下半)
linux·运维·服务器
skywalk81632 小时前
unbound dns解析出现问题,寻求解决之道
运维·服务器·dns·unbound
酉鬼女又兒2 小时前
零基础入门Linux指南:每天一个Linux命令_pwd
linux·运维·服务器
云飞云共享云桌面2 小时前
高性能图形工作站的资源如何共享给10个SolidWorks研发设计用
linux·运维·服务器·前端·网络·数据库·人工智能