podman run 源码层次
cmd/podman/containers/run.go
pkg/domain/entities/engine_container.go ContainerRun
pkg/domain/infra/abi/containers.go ContainerEngine.ContainerRun
ContainerEngine有两种,一个是abi就是本地调用,一个是tunnel就是podman http服务
创建container
pkg/specgen/generate/container_create.go MakeContainer 准备oci配置 spec.Spec
generate.ExecuteCreate
—> libpod/runtime_ctr.go NewContainer
——> libpod/runtime_ctr.go newContainer 生成container对象
———> initContainerVariables 初始化container对象的基本信息
———> libpod/runtime_ctr.go setupContainer
————> libpod/container_api.go setupStorage
—————> libpod/container_internal.go setupStorage
启动container:
detach模式下:
pkg/domain/infra/abi/containers.go ContainerEngine.ContainerRun
libpod/container_api.go Start
libpod/container_internal.go prepareToStart
libpod/container_internal.go init
libpod/container_internal.go saveSpec 保存OCI的config.json
libpod/oci.go CreateContainer 启动conmon进程
libpod/oci_conmon_linux.go CreateContainer
libpod/oci_conmon_linux.go createOCIContainer
�
libpod/container_internal.go Start
libpod/oci.go StartContainer
libpod/oci_conmon_linux.go StartContainer
attach模式下:
terminal_linux.go
libpod/container_api.go StartAndAttach
libpod/oci_attach_linux.go attach
libpod/container_internal.go start
�
conmon层
libpod/oci.go 定义了OCIRuntime
libpod/oci_conmon_linux.go 启动oci容器的conmon/shim
创建容器
// CreateContainer creates a container.func (r *ConmonOCIRuntime) CreateContainer(ctr *Container, restoreOptions *ContainerCheckpointOptions) error {// always make the run dir accessible to the current user so that the PID files can be read without// being in the rootless user namespace.if err := makeAccessible(ctr.state.RunDir, 0, 0); err != nil {return err}if !hasCurrentUserMapped(ctr) {for _, i := range []string{ctr.state.RunDir, ctr.runtime.config.Engine.TmpDir, ctr.config.StaticDir, ctr.state.Mountpoint, ctr.runtime.config.Engine.VolumePath} {if err := makeAccessible(i, ctr.RootUID(), ctr.RootGID()); err != nil {return err}}// if we are running a non privileged container, be sure to umount some kernel paths so they are not// bind mounted inside the container at all.if !ctr.config.Privileged && !rootless.IsRootless() {ch := make(chan error)go func() {runtime.LockOSThread()err := func() error {fd, err := os.Open(fmt.Sprintf("/proc/%d/task/%d/ns/mnt", os.Getpid(), unix.Gettid()))if err != nil {return err}defer errorhandling.CloseQuiet(fd)// create a new mountns on the current threadif err = unix.Unshare(unix.CLONE_NEWNS); err != nil {return err}defer func() {if err := unix.Setns(int(fd.Fd()), unix.CLONE_NEWNS); err != nil {logrus.Errorf("unable to clone new namespace: %q", err)}}()// don't spread our mounts around. We are setting only /sys to be slave// so that the cleanup process is still able to umount the storage and the// changes are propagated to the host.err = unix.Mount("/sys", "/sys", "none", unix.MS_REC|unix.MS_SLAVE, "")if err != nil {return errors.Wrapf(err, "cannot make /sys slave")}mounts, err := pmount.GetMounts()if err != nil {return err}for _, m := range mounts {if !strings.HasPrefix(m.Mountpoint, "/sys/kernel") {continue}err = unix.Unmount(m.Mountpoint, 0)if err != nil && !os.IsNotExist(err) {return errors.Wrapf(err, "cannot unmount %s", m.Mountpoint)}}return r.createOCIContainer(ctr, restoreOptions)}()ch <- err}()err := <-chreturn err}}return r.createOCIContainer(ctr, restoreOptions)}
启动容器
// StartContainer starts the given container.// Sets time the container was started, but does not save it.func (r *ConmonOCIRuntime) StartContainer(ctr *Container) error {// TODO: streams should probably *not* be our STDIN/OUT/ERR - redirect to buffers?runtimeDir, err := util.GetRuntimeDir()if err != nil {return err}env := []string{fmt.Sprintf("XDG_RUNTIME_DIR=%s", runtimeDir)}if ctr.config.SdNotifyMode == define.SdNotifyModeContainer {if notify, ok := os.LookupEnv("NOTIFY_SOCKET"); ok {env = append(env, fmt.Sprintf("NOTIFY_SOCKET=%s", notify))}}if path, ok := os.LookupEnv("PATH"); ok {env = append(env, fmt.Sprintf("PATH=%s", path))}if err := utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, env, r.path, append(r.runtimeFlags, "start", ctr.ID())...); err != nil {return err}ctr.state.StartedTime = time.Now()return nil}
