zhangguanzhang's Blog

欧拉22.04容器内sudo 被 killed

字数统计: 964阅读时长: 4 min
2026/04/09
loading

记录下一次欧拉容器内sudo无法使用的排查过程。

由来

实施反馈客户环境上我们部署容器内无法使用 sudo:

1
2
$ sudo ls -l
已杀死

排查

部署容器是基于 openeuler/openeuler:22.03 制作的,之前是实施和另一个同事发现基于 ubuntu 的基础镜像制作的部署镜像内 sudo 可以使用,后面升级后又变成欧拉的,让我排查下。

权限?

远程上去后:

1
2
3
$ docker run --rm -ti --entrypoint bash xxx
$ sudo ls -l
已杀死

想着是不是 seccomp 之类的导致的,用特权启动下试试:

1
2
3
$ docker run --rm -ti --privileged --entrypoint bash xxx
$ sudo ls -l
已杀死

依旧这样,换基于 ubuntu 制作的发现没问题,但是这个欧拉镜像内无 strace 命令。

制作验证

本地制作了下基于欧拉和其他一些镜像增加 sudo 和 strace 的镜像:

1
2
3
4
5
6
7
8
9
10
FROM openeuler/openeuler:22.03

RUN set -eux; \
sed -ri 's|://repo.openeuler.org/|://repo.huaweicloud.com/openeuler/|g' /etc/yum.repos.d/openEuler.repo; \
sed -ri 's|https://mirrors.openeuler.org|https://repo.huaweicloud.com/openeuler/|g' /etc/yum.repos.d/openEuler.repo; \
yum makecache; \
dnf install -y --setopt=install_weak_deps=False \
sudo \
strace \
;

然后几个镜像构建完成后:

1
docker save sudo:oe sudo:xxx | gzip -> sudo-docker.tar.gz

客户环境上导入测试:

1
2
3
4
5
6
7
8
9
$ docker load -i sudo-docker.tar.gz
$ docker run --rm -ti --entrypoint bash sudo:oe
[root@71ec45b79f63 /]# sudo ls -l
Killed
$ docker run --rm -ti --privileged --entrypoint bash sudo:oe
[root@fea66e40292f /]# sudo -V
Sudo version 1.9.8p2
Configure options: --build=x86_64-openEuler-linux-gnu --host=x86_64-openEuler-linux-gnu --program-prefix= --disable-dependency-tracking --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib64 --libexecdir=/usr/libexec --localstatedir=/var --sharedstatedir=/var/lib --mandir=/usr/share/man --infodir=/usr/share/info --prefix=/usr --sbindir=/usr/sbin --libdir=/usr/lib64 --docdir=/usr/share/doc/sudo --disable-root-mailer --disable-intercept --disable-log-server --disable-log-client --with-logging=syslog --with-logfac=authpriv --with-pam --with-pam-login --with-editor=/bin/vi --with-env-editor --with-ignore-dot --with-tty-tickets --with-ldap --with-selinux --with-passprompt=[sudo] password for %p: --with-linux-audit --with-sssd
Killed

发现 -V 都报错,没办法了,strace 看看调用过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@fea66e40292f /]# strace sudo -V
....
mprotect(0x7f605d240000, 4096, PROT_READ) = 0
mprotect(0x7f605d2bf000, 4096, PROT_READ) = 0
openat(AT_FDCWD, "/proc/sys/crypto/fips_enabled", O_RDONLY) = 3
read(3, "0\n", 2) = 2
close(3) = 0
access("/etc/system-fips", F_OK) = -1 ENOENT (No such file or directory)
munmap(0x7f605d5eb000, 10235) = 0
newfstatat(AT_FDCWD, "/usr/libexec/sudo/sudoers.so", {st_mode=S_IFREG|0644, st_size=525888, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/libexec/sudo/sudoers.so", {st_mode=S_IFREG|0644, st_size=525888, ...}, 0) = 0
pipe2([3, 4], O_NONBLOCK|O_CLOEXEC) = 0
getpid() = 80
getrandom(0x7fff8e404980, 40, 0) = -1 ENOSYS (Function not implemented)
gettid() = 80
getpid() = 80
tgkill(80, 80, SIGKILL) = ?
+++ killed by SIGKILL +++
Killed

看着是 getrandom 的 syscall 报错没实现,欧拉镜像是类似 rhel 的,自带 python,用 python 调用它试试:

1
2
3
4
[root@fea66e40292f /]# python3 -c 'import os;os.getrandom(3)'
Traceback (most recent call last):
File "<string>", line 1, in <module>
OSError: [Errno 38] Function not implemented

明确是 getrandom syscall 问题,再试下 Linux shuf 随机数命令:

1
2
3
4
5
6
7
[root@fea66e40292f /]# shuf -i 1-10 -n 1
shuf: getrandom: Function not implemented
[root@fea66e40292f /]# uname -a
Linux fea66e40292f 3.10.0-514.el7.x86_64 #1 SMP Tue Nov 22 16:42:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
[root@fea66e40292f /]# rpm -qa | grep glibc
glibc-common-2.34-170.oe2203sp4.x86_64
glibc-2.34-170.oe2203sp4.x86_64

结论和验证

客户机器是 CentOS 7.3,内核 3.10.0-514.el7.x86_64 ,推测欧拉的 glibc 对 getrandom syscall 强依赖没有 fallback 回退到 openat(/dev/urandom) 机制,客户这套环境还有其他 CentOS 7.9的,上面去测试了下没问题,其他 7.3 的机器上也复现了:

1
2
3
4
5
6
# 其他 7.9 机器上
[root@fea66e40292f /]# shuf -i 1-10 -n 1
4
# 其他 7.3 机器上
[root@fea66e40292f /]# shuf -i 1-10 -n 1
shuf: getrandom: Function not implemented

因为还有其他业务服务使用欧拉基础镜像,如果从 glibc 层面修改解决这个问题成本太大了:

  • 客户现场要针对每个容器镜像单独更新下 glibc
  • 后续我们也要维护一份 glibc 代码编译成欧拉的 rpm 包

让客户使用 CentOS 7.9 的最稳妥,同时该问题已经反馈给欧拉仓库 https://atomgit.com/openeuler/openeuler-docker-images/issues/60

CATALOG
  1. 1. 由来
  2. 2. 排查
    1. 2.1. 权限?
    2. 2.2. 制作验证
    3. 2.3. 结论和验证