OCI Runtime Spec의 Operation을 보면 create와 start을 보자.
Create create <container-id> <path-to-bundle>
This operation MUST generate an error if it is not provided a path to the bundle and the container ID to associate with the container. If the ID provided is not unique across all containers within the scope of the runtime, or is not valid in any other way, the implementation MUST generate an error and a new container MUST NOT be created. This operation MUST create a new container.
All of the properties configured in config.json except for process MUST be applied. process.args MUST NOT be applied until triggered by the start operation. The remaining process properties MAY be applied by this operation. If the runtime cannot apply a property as specified in the configuration, it MUST generate an error and a new container MUST NOT be created.
The runtime MAY validate config.json against this spec, either generically or with respect to the local system capabilities, before creating the container (step 2). Runtime callers who are interested in pre-create validation can run bundle-validation tools before invoking the create operation.
Any changes made to the config.json file after this operation will not have an effect on the container.
Start start <container-id>
This operation MUST generate an error if it is not provided the container ID. Attempting to start a container that is not created MUST have no effect on the container and MUST generate an error. This operation MUST run the user-specified program as specified by process. This operation MUST generate an error if process was not set.
process.args는 start작업이 실행되기 전까지 적용되어서는 안 된다.
process.args는 문자열 배열로, IEEE 표준 execvp의 argv와 유사한 의미를 가진다.
또한 start 명령어는 process에 지정된 사용자 정의 프로그램을 실행해야 한다
즉, create과정에서 cgroup이나 기타 설정등.. 컨테이너에 대한 전반적인 init작업을 통해
사용자가 정의한 프로세스를 실행(process.args) 하기 전 단계까지를 수행한다.
이를 구현하기 위한 여러 방법이 있겠지만, 여기서는 시그널을 이용하겠다.
프로세스는 POSIX 표준에 의해 SIGSTOP으로 프로세스를 멈추고, SIGCONT를 이용해 시작할 것이다.
runc의 경우 이러한 시그널 방식이 아닌 FIFO Pipe 방식을 택한다. 이유야 여럿이지만 주요하게는
한창 이러한 처리가 개발되던 go ~1.6 버전에서 시그널 처리에 있어 레이스 컨디션이 발생하는 문제가 있었기 때문이다.
[hwyoon@rocky9 containeruntime]# sudo ./containeruntime create /bin/bash
Running: [/bin/bash]
Running: [/bin/bash]
root@container:/# ls
bin dev home lib32 libx32 mnt opt root sbin sys usr
boot etc lib lib64 media mytemp proc run srv tmp var
이를 start명령어로 빼기 위해서는 컨테이너의 상태(state)를 저장해야 한다.
이러한 상태 기반 동작은 다음 포스트에서 더 구현해 보자.
물론 현재의 SIGSTOP, SIGCONT구조등은 create와 start가 같은 터미널 세션에서 일어난다고