深圳幻海软件技术有限公司 欢迎您!

详解 RunC 里面Terminal 和 Run Modes

2023-02-28

runc的用法,这里面有两个非常重要的参数,Terminal和启动模式(前台启动和后台启动),下面我们就针对这两个参数,详细讲解一下。这两个参数两两组合就有四种情况。在实验之前,我们将容器的启动脚本改成复制#!/bin/sh read input echo “

runc的用法,这里面有两个非常重要的参数,Terminal和启动模式(前台启动和后台启动),下面我们就针对这两个参数,详细讲解一下。这两个参数两两组合就有四种情况。

在实验之前,我们将容器的启动脚本改成

#!/bin/sh 
read input 
echo “THIS IS STANDARD OUTPUT” 
echo “YOU PROVIDED THIS AS STANDARD INPUT:” 
echo $input 
sleep 15 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

1、Terminal 为 true 前台启动

这种情况最简单,input 会一直hang住等待用户的输入,当我输入ddd 后,最后输出ddd

# runc run abc 
ddd 
“THIS IS STANDARD OUTPUT” 
“YOU PROVIDED THIS AS STANDARD INPUT:” 
ddd 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

程序一直会等待15 秒后退出。

2、 Terminal为false前台启动

在前台启动的时候,这个Terminal 为false没啥影响

# runc run def 
gg 
“THIS IS STANDARD OUTPUT” 
“YOU PROVIDED THIS AS STANDARD INPUT:” 
gg 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

我们还可以通过echo 输入内容

echo “TEST INPUT FROM COMMAND LINE” |sudo runc run alpine >container.out 2>&1 
  • 1.

上面的命令会等待15s 执行完成,执行完输出如下:

“THIS IS STANDARD OUTPUT” 
“YOU PROVIDED THIS AS STANDARD INPUT:” 
“TEST INPUT FROM COMMAND LINE” 
  • 1.
  • 2.
  • 3.

上面两种前台启动的方式,会启动两个进程,分别是runc和init_script 脚本。

$ ps -f  -C runc -C sh 
UID        PID  PPID  C STIME TTY          TIME CMD 
root      4600  4598  0 15:42 pts/0    00:00:00 runc run alpine 
centos    4609  4600  0 15:42 pts/0    00:00:00 /bin/sh init_script.sh 
  • 1.
  • 2.
  • 3.
  • 4.

3、Terminal为false 后台启动

后台启动通过 -d 的方式,如下

echo “TEST INPUT FOR DETACHED FROM COMMAND LINE” |sudo runc run -d alpine 
 > container_detached.out 2>&1 
  • 1.
  • 2.

对比前台启动hang在那里,后台启动迅速执行完,结果如下

# cat container_detached.out 
“THIS IS STANDARD OUTPUT” 
“YOU PROVIDED THIS AS STANDARD INPUT:” 
“TEST INPUT FOR DETACHED FROM COMMAND LINE” 
  • 1.
  • 2.
  • 3.
  • 4.

4、Terminal为true 后台启动

由于Terminal为true,需要用户的输入,如果直接后台启动会报如下错误,

$ sudo runc run -d alpine 
cannot allocate tty if runc will detach without setting console socket 
  • 1.
  • 2.

错误是说,需要一个控制台socket。runc官方提供了runc/contrib/cmd/recvtty/recvtty.go的脚本。我们可以打开一个新的shell窗口,通过recvtty启动一个监听。

./recvtty alpine_container_socket.sock 
  • 1.

然后通过-d 启动

$ sudo runc run -d --console-socket alpine_container_socket.sock alpine 
  • 1.

然后在recvtty里面会得到如下输出

TEST INPUT FROM SOCKET 
TEST INPUT FROM SOCKET 
THIS IS STANDARD OUTPUT 
YOU PROVIDED THIS AS STANDARD INPUT: 
TEST INPUT FROM SOCKET 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

如果通过后台启动的话,就只有一个 init_script 脚本。

$ ps -f -C runc -C sh 
UID PID PPID C STIME TTY TIME CMD 
centos 4916 1 0 16:16 pts/0 00:00:00 /bin/sh init_script.sh 
  • 1.
  • 2.
  • 3.