V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhoudaiyu
V2EX  ›  Kubernetes

为什么 K8S 要求 Pod 中的 Container 启动时至少有一个进程是前台运行的?

  •  
  •   zhoudaiyu · 2021-03-19 08:43:08 +08:00 via iPhone · 4883 次点击
    这是一个创建于 1343 天前的主题,其中的信息可能已经有所发展或是发生改变。

    不是很明白为什么必须前台,如果有的进程就是只能后台启动的,那怎么办呢?

    50 条回复    2021-04-06 23:56:30 +08:00
    baiyi
        1
    baiyi  
       2021-03-19 08:48:27 +08:00
    没有进程容器不就停止了吗。可以启用一个类似监控或者管理的进程来保持容器运行。
    zhoudaiyu
        2
    zhoudaiyu  
    OP
       2021-03-19 08:49:26 +08:00 via iPhone
    @baiyi #1 对 我们用 supervisor 但是不太明白为什么必须前台
    binux
        3
    binux  
       2021-03-19 08:50:03 +08:00 via Android
    没前台那就 waitpid 呗
    baiyi
        4
    baiyi  
       2021-03-19 08:50:56 +08:00
    @zhoudaiyu #2 你可以理解为容器的本质就是这个进程在运行,进程结束了,容器也就结束了。
    whileFalse
        5
    whileFalse  
       2021-03-19 08:55:31 +08:00
    请详述场景。我觉得你对容器的使用方法不太正确。
    ---------------------
    虽然容器能像完整的虚拟机那样运行一堆进程,但容器本身的设计理念是仅运行单个任务;如果有多个任务,则应拆成多个容器。那么容器本身的生命周期应该和该单个任务的生命周期相同。即这个任务进程退出,容器也就退出了。

    如果容器的主要任务是个后台进程,那么你的主进程应该监视该后台进程的执行情况,等待该后台进程退出后主进程也退出。
    whileFalse
        6
    whileFalse  
       2021-03-19 08:58:22 +08:00   ❤️ 2
    @zhoudaiyu 我觉得容器里装 supervisor 就是属于滥用容器。
    noqwerty
        7
    noqwerty  
       2021-03-19 09:32:08 +08:00 via Android
    容器里又套一个 supervisor 是啥操作…
    Tink
        8
    Tink  
       2021-03-19 09:34:48 +08:00 via Android
    同楼上,还在 container 里面用 supervisor 确实有点搞事情
    UN2758
        9
    UN2758  
       2021-03-19 09:42:44 +08:00
    同问这是啥操作,有什么动机吗
    zhoudaiyu
        10
    zhoudaiyu  
    OP
       2021-03-19 10:02:35 +08:00
    @whileFalse
    @noqwerty
    @Tink
    @UN2758 你说的是对的,应该拆成多个 container,比如 containerA 和 containerB,但是我们现在的场景是:containerA 想对 containerB 的进程操作,我们用的超低版本的 k8 是不支持进程空间共享的,所以弄了一个 supervisor 能管理多个进程
    claymore94
        11
    claymore94  
       2021-03-19 10:13:55 +08:00
    我猜你是偏传统企业,我们也有个容器里面用 supervisor 管理两个进程
    zhoudaiyu
        12
    zhoudaiyu  
    OP
       2021-03-19 10:15:58 +08:00
    @claymore94 其实主进程就是一个 tomcat,但是有一些辅助进程需要按需启动
    claymore94
        13
    claymore94  
       2021-03-19 10:18:20 +08:00
    这样,容器的 entrypoint 可以是一个 sh 脚本,脚本最后 supervisord -c /etc/supervisord.conf, /usr/bin/tail -f /dev/null,容器不退出就可以了,方式有很多
    ljhrot
        14
    ljhrot  
       2021-03-19 10:26:37 +08:00
    当你为了容器化而容器化的时候,各种各样的问题就会接踵而来,在不知不觉投入的成本已经超过了容器化带来的好处
    Tink
        15
    Tink  
       2021-03-19 10:35:29 +08:00 via Android
    @zhoudaiyu 你只要保证容器不死就行了对不,container 启动脚本你先启动你要用的进程,然后再起一个不死进程就行了
    CallMeReznov
        16
    CallMeReznov  
       2021-03-19 10:35:50 +08:00   ❤️ 5
    不多说,一张图
    coderxy
        17
    coderxy  
       2021-03-19 11:50:04 +08:00
    这不是 k8s 的要求,这是 docker 的要求。
    gesse
        18
    gesse  
       2021-03-19 13:01:02 +08:00
    container 里用 supervisor 是什么操作? supervisor 的每一个子进程都需要单独放入一个容器做前台进程。
    zhoudaiyu
        19
    zhoudaiyu  
    OP
       2021-03-19 13:05:22 +08:00
    @gesse 需要多进程
    gesse
        20
    gesse  
       2021-03-19 13:11:04 +08:00
    @zhoudaiyu
    那不是应该开启多个容器吗?

    如果牵涉到非网络进程间通信,那就是一个前端进程开启多个子进程。
    napsterwu
        21
    napsterwu  
       2021-03-19 13:44:41 +08:00 via iPhone
    所以有时候有人用 tail -f /dev/null
    zhoudaiyu
        22
    zhoudaiyu  
    OP
       2021-03-19 14:11:47 +08:00
    @gesse 如果说多容器的话,我想随时启停某个容器是不是不是很好做
    HarrisonZ
        23
    HarrisonZ  
       2021-03-19 14:14:06 +08:00
    看看容器基础,还有能不能不要一提容器就是 docker,docker 只是降低了容器技术的门槛,做的易用了而已
    zhoudaiyu
        24
    zhoudaiyu  
    OP
       2021-03-19 14:21:40 +08:00
    @HarrisonZ 我没有提 docker 啊
    killva4624
        25
    killva4624  
       2021-03-19 17:43:58 +08:00
    我的理解:K8S 的设计就是为了解决容器生命周期问题。"主进程即容器"这样的概念可以把主进程精确到单个容器的颗粒度来管理。换句话说,如果你想在容器里跑后台进程,那么就需要另外一套机制来确保后台进程的生命周期(比如怎么启动后台进程,怎么确保后台进程存活),用 supervisor 或者 systemd 之类大部分是非云原生系统上云时候的过渡方案(又不想花精力做微服务拆分,又想容器化)。
    阿里还专门弄了个富容器的概念,也是盯准了有这类需求的客户。

    https://www.v2ex.com/t/454943
    https://www.jianshu.com/p/d7dbeffc2dff

    从技术的角度,我不喜欢这种做法,非常别扭。但从商业角度来看,是一种很 lazy 又讨巧的上云方案。
    wxsm
        26
    wxsm  
       2021-03-19 17:47:33 +08:00
    你完全可以用 nohup 将某些进程后台运行,只要保证有一个进程前台运行即可,当然容器的健康与否只会关注前台进程,后台进程出现的问题自理。
    GM
        27
    GM  
       2021-03-19 17:49:04 +08:00
    @whileFalse 并不算滥用,有些情况下很方便的。
    rrfeng
        28
    rrfeng  
       2021-03-19 17:50:44 +08:00
    容器 == 一个具有隔离空间的进程
    进程结束 == 容器死亡

    这没什么好争的。
    killva4624
        29
    killva4624  
       2021-03-19 17:51:46 +08:00
    P 个 S:比如 C++ 里 MCP 框架用共享内存做 MQ 这种玩意……
    0312birdzhang
        30
    0312birdzhang  
       2021-03-19 19:51:21 +08:00 via iPhone
    一个 pod 里面可以有多个容器
    ospider
        31
    ospider  
       2021-03-19 23:07:19 +08:00   ❤️ 1
    Container 本身就是 Process Container 的缩写,是为一个进程创建的隔离环境。Process 之不存,Container 将焉附?

    打个比方,进程好比人,容器好比一条裤子。人穿上裤子,裤子就跟着站了起来。离了人,裤子当然自己不可能自己站起来了。同时,如果我们看到裤子摊在地上,那可以知道里面一定没藏着人。你在容器里面跑 supervisord / nohup / systemd 这种操作就相当于拿根棍子把裤子强行撑了起来,可能你看着裤子站着呢,但是里面的人已经挂了。

    如果想运行多个进程,docker-compose 不香么?
    lfzyx
        32
    lfzyx  
       2021-03-19 23:32:53 +08:00
    为啥不招个 devops 做这事呢
    ch2
        33
    ch2  
       2021-03-20 02:27:33 +08:00 via iPhone
    docker 的本质是一个或者一组进程,如果所有进程都死了,docker 本身也没有存续的必要了
    raven2019
        34
    raven2019  
       2021-03-20 16:40:56 +08:00
    对于一个 java 进程的容器,想要方便的通过 ssh 远程登录上去,除了在容器里通过 supervisord 启动一个 sshd 进程,还有其他方式吗
    kitthsu
        35
    kitthsu  
       2021-03-20 18:07:34 +08:00
    @raven2019 用 k8s 的 exec 代理
    loveyu
        36
    loveyu  
       2021-03-20 20:42:43 +08:00 via Android
    PHP 用 supervisor 上云就挺好的
    bemyself
        37
    bemyself  
       2021-03-21 13:43:30 +08:00
    @loveyu supervisor 用来做什么
    loveyu
        38
    loveyu  
       2021-03-22 08:44:44 +08:00 via Android
    @bemyself Nginx+php-fpm
    whileFalse
        39
    whileFalse  
       2021-03-22 09:18:32 +08:00
    @raven2019 “通过 SSH 登陆容器”就不是正常方式。
    whileFalse
        40
    whileFalse  
       2021-03-22 09:21:38 +08:00
    @GM 你当然可以举出一个“在容器中使用 Supervisor 很方便”的场景。
    但容器就不是为你的这个场景设计的,所以这种用法也必然会带来不方便的地方。

    如果又要用 supervisor,又难以承受带来的不便(像 lz 这样),那就叫滥用。
    julyclyde
        41
    julyclyde  
       2021-03-22 16:19:32 +08:00
    依靠 SIGCHLD 来检测容器内的程序有没有退出
    如果退出就要做后续扫尾动作了
    julyclyde
        42
    julyclyde  
       2021-03-22 16:20:15 +08:00
    @killva4624 暴露了暴露了!
    julyclyde
        43
    julyclyde  
       2021-03-22 16:20:43 +08:00
    @claymore94
    @napsterwu
    你这个 tail-f 是不是会有点费 cpu 啊
    byzf
        44
    byzf  
       2021-03-22 17:12:20 +08:00
    否则容器运行时依靠什么来判断容器有没有结束。
    dabney777
        45
    dabney777  
       2021-03-22 17:21:23 +08:00
    @ospider 如果更新了一段代码导致 core dump 了,supervisor 会一直重启进程,这时候登录进去看日志很容易查看日志。如果主进程就是新写的进程的话,容器会一直重启,也看不到报错
    joesonw
        46
    joesonw  
       2021-03-22 19:31:14 +08:00
    @byzf 容器不是虚拟机. 容器也是在宿主机上, 只是命名空间, 资源做了隔离. 本质就是一个进程.
    zhoudaiyu
        47
    zhoudaiyu  
    OP
       2021-03-22 19:36:00 +08:00 via iPhone
    @joesonw 老哥 说到隔离问个问题 为什么容器里的 CPU 内存用量都看到的是宿主机的?如果我想只看到本 container 或者 pod 的,该如何做?
    byzf
        48
    byzf  
       2021-03-22 20:38:54 +08:00
    @joesonw 不是只有虚拟机才有运行时,容器目前来说大多数是必须要运行时的,比如 docker daemon,然后这个运行时要去管理容器的状态,判断是否成功运行、是否要重启之类的操作。
    julyclyde
        49
    julyclyde  
       2021-03-23 11:14:57 +08:00
    @zhoudaiyu 用 lxcfs 就能看到实际分配资源量了
    dzdh
        50
    dzdh  
       2021-04-06 23:56:30 +08:00
    容器本身就是另一种『进程模型』的实现。

    你用 supervisor 的需求,本质上是想『多个容器共享存储、网络、设备』等资源。

    在 k8s 里,你将这多个 container 放在一个 pod 里就可以了啊。不动为什么还需要 supervisor
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1162 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 23:05 · PVG 07:05 · LAX 15:05 · JFK 18:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.