一个有用的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 或其他传递的命令。

相关推荐
新时代牛马5 分钟前
嵌入式 Linux WiFi 框架完整篇:从cfg80211、mac80211 到wpa_supplicant
linux·运维·服务器
DreamLife☼8 分钟前
Agent开发环境搭建完全指南
python·docker·typescript·node·工业知识点
探索云原生9 分钟前
Kueue + HAMi vGPU 实战:显存与算力配额管理
docker·ai·云原生·kubernetes·gpu
吴声子夜歌13 分钟前
Linux命令——打印
linux·运维·服务器
Jae den13 分钟前
负载均衡到底解决什么问题?
运维·负载均衡
企鹅的蚂蚁16 分钟前
Linux 开发板串口调试:picocom 从识别到退出的完整用法
linux·运维·服务器
山岚的运维笔记25 分钟前
mysql 专业笔记 -- 第 17 章:连接:连接三个具有相同名称 ID 的表
运维·数据库·笔记·后端·学习·mysql·dba
hoho_1244 分钟前
docker中升级mysql到最新版本
mysql·docker·容器
此冬歌咏1 小时前
自动化服务器运维监控系统(python+shell)
linux·运维·服务器·开发语言·python·自动化
风景的人生1 小时前
虚拟机ip连不上(怀疑是最开始虚拟机复制造成的网络冲突)
linux·运维·服务器