我计划使用无distroless基本映像来运行容器应用程序。
由于我在k8s边车中使用envoy,所以当我停止应用程序容器时,我在preStop中使用sleep命令,然后才安全地停止pod。
lifecycle
preStop:
exec:
command:
- sleep
- "40
字符串
由于无损映像不允许使用shell等,因此我们使用多阶段构建,以便可以使用sleep命令。
这个简单的Golang应用程序。
FROM alpine:3.13 as builder
ENV GOROOT /go
FROM gcr.io/distroless/static-debian10
WORKDIR /app
COPY ./dist/app ./
COPY --from=builder /bin/sleep /bin/sleep
CMD ["./app"]
型
当我在此图像中启动Pod并将其切换到另一个Pod时,sleep命令失败。
Exec lifecycle hook ([sleep 40]) for Container
型
难道不能这样做吗?如果我做错了,我希望得到指点。
谢谢.
4条答案
按热度按时间lqfhib0f1#
“无发行版”镜像只有在你的镜像只包含你要运行的应用程序,绝对没有其他东西的时候才有意义。这通常是一个很好的做法,但是尝试引入额外的sleep(1)命令与它不太兼容。
我可以建议几种方法来解决这个问题:
1.弄清楚如何根本不需要sleep(1).“我们需要等待40秒,因为Envoy”看起来像是你在解决一个bug;修复这个bug,而不是试图延迟容器关闭。
1.使用与主应用程序相同的语言重新实现延迟。例如,在Python中,它是一个3行脚本。那么运行它所需的一切都已经在映像中了。
1.获取一个静态编译的sleep(1)二进制文件。最简单的方法是从BusyBox工具套件中获取,该工具套件在一个二进制文件中包含许多常见的Unix实用程序;但Alpine Linux基本上只是BusyBox加上一个包管理器,因此获取BusyBox的最简单方法是将映像更改为
FROM
(基于Alpine的映像)。1.获取sleep(1)二进制文件所需的所有动态库。您可以在运行
ldd sleep
的环境中运行ldd sleep
,以确定它们是什么。不过,您可能不想直接从主机复制它们,而这正是普通Linux发行版预打包这些库的地方(并且已经附带了/bin/sleep
)。在你的Dockerfile中,你可能会得到一个损坏的符号链接
/bin/sleep -> busybox
。你也可以复制busybox
二进制文件,但这本质上违背了拥有一个无发行版映像的意义。exdqitrt2#
看到这个
删除Pod的默认宽限期为30秒,如果Pod的某个容器定义了preStop钩子,kubelet会在容器内运行该钩子。如果宽限期到期后preStop钩子仍在运行,kubelet会请求一个小的、一次性的宽限期延长2秒。
注意:如果preStop钩子需要比默认宽限期更长的时间才能完成,则必须修改terminationGracePeriodSeconds以适应此情况。
所以我想试着把你sleep命令设置为20秒或者把
terminationGracePeriodSeconds
设置为60秒。u2nhd7ah3#
现在可以通过使用
gcr.io/distroless/base-debian10
而不是gcr.io/distroless/static-debian10
来使用睡眠命令cidc1ykv4#
我也遇到了同样的问题,这里有一个解决方案可以帮助我。Dockerfile:
字符串
k8s部署:
型