docker

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > docker > docker使用gosu

Docker中使用gosu的方法详解

作者:雲帝

在Docker镜像中启动服务时,我们通常不希望以root身份运行主进程,sudogosu是一个非常轻量的工具,功能类似sudo,但不会产生额外进程,非常适合在Docker容器中用来切换用户,本文给大家介绍Docker中使用gosu的方法,感兴趣的朋友一起看看吧

Docker中使用gosu

为什么要用 gosu?

在 Docker 镜像中启动服务时,我们通常不希望以 root 身份运行主进程。

问题

gosu 是一个非常轻量的工具,功能类似 sudo,但不会产生额外进程,非常适合在 Docker 容器中用来切换用户。

注意事项

  1. 创建专用普通用户,不要直接使用 root。
  2. 在 entrypoint 中使用 gosu 切换用户,不要用 sudo。
  3. 使用 exec 启动主进程,保证 PID=1 是应用本身。
  4. 正确接收 SIGTERM 信号,避免僵尸进程。
  5. 不要在 Docker 中滥用 sudo

sudo vs gosu:真实对比

使用 gosu

docker run --rm gosu/alpine gosu root ps aux

输出:

PID   USER     TIME  COMMAND
1     root     0:00  ps aux

使用 sudo

docker run --rm ubuntu:trusty sudo ps aux

输出:

USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.0  46012  1772 ?        Rs   12:05   0:00 sudo ps aux
root          6  0.0  0.0  15568  1140 ?        R    12:05   0:00 ps aux

对比

项目gosusudo
进程数12
PID=1应用进程sudo
信号转发正常不正常
僵尸进程风险
适合容器使用

Dockerfile 安装 gosu

在 Dockerfile 中添加如下步骤即可:

FROM ubuntu:22.04
# 安装 gosu
RUN apt-get update && apt-get install -y gosu curl ca-certificates && rm -rf /var/lib/apt/lists/*
# 创建普通用户
RUN groupadd -r tempuser && useradd -r -g tempuser tempuser
# 拷贝入口脚本
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
# 验证 gosu 是否工作
RUN gosu nobody true
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

entrypoint.sh 的写法

entrypoint.sh 是容器启动脚本。

#!/usr/bin/env bash
set -e
# 使用 gosu 切换用户身份
if [ "$1" = "start-app" ]; then
    echo "Running application as tempuser..."
    exec gosu tempuser /app/my_server
fi
# 如果有其他命令,直接执行
exec "$@"

注意:exec 会让当前 shell 被新进程取代,保证应用进程的 PID=1。

构建 & 运行容器

docker build -t myapp .
docker run --rm -p 8080:8080 myapp start-app

容器内:

信号量与僵尸进程问题

容器启动时 PID=1 的进程非常特殊,它负责接收来自宿主机的信号(例如 SIGTERMSIGINT)。

常见问题

问题原因解决方法
容器退出时残留僵尸进程PID=1 不是应用进程使用 exec + gosu
docker stop 不生效信号被 sudo 拦截不使用 sudo,PID=1 改为应用
gosu 报权限错误二进制无执行权限chmod +x /usr/local/bin/gosu
切换用户失败用户不存在使用 useradd 创建对应用户

参考资料

到此这篇关于Docker中使用gosu的文章就介绍到这了,更多相关docker使用gosu内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

阅读全文