zoukankan      html  css  js  c++  java
  • cri-o pod 创建源码分析

    1、 server/sandbox.go

    // RunPodSandbox creates and runs a pod-level sandbox

    func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest) (*pb.RunPodSandboxResponse, error)

      name := req.GetConfig().GetMetadata().GetName()

      namespace := req.GetConfig().GetMetadata().GetNamespace() //在test中,该字段为空

      attempt := req.GetConfig().GetMetadata().GetAttempt() //在test中,该字段为空

      id, name, err := s.generatePodIDandName(name,  namespace, attempt)

      podSandboxDir := filepath.Join(s.sandbox, id)

      os.MkdirAll(podSandboxDir, 0755)

      ... // defer函数,用于创建pod失败,移除podSandboxDir

      // creates a spec Generator with the default spec

      g := generate.New()  // 返回一个Generator结构,其中包含了默认的spec

      podInfraRootfs := filepath.Join(s.root, "graph/vfs/pause")  

      g.SetRootPath(filepath.Join(podInfraRootfs, "rootfs"))  //对默认的spec进行修改,针对的字段为Root和Process.Args

      g.SetRootReadonly(true)

      g.SetProcessArgs([]string{"/pause"})

      ... // 设置g.spec的hostname,如果req.config中的hostname 不为空的话

      // set log directory

      logDir := req.GetConfig().GetLogDirectory() // test的config文件默认为"."

      if logDir == "" {

        logDir = fmt.Sprintf("/var/log/ocid/pods/%s", id)

      }  

      // set DNS options

      ... // 从req.Config中获取dnsServers和dnsSearches

      resolvPat := fmt.Sprintf("%s/resolv.conf", podSandboxDir)

      parseDNSOptions(dnsServers, dnsSearches, resolvPath)

      // add labels

      labels := req.GetConfig().GetLabels()

      labelsJSON, err := json.Marshal(labels)  

      // add annotations

      annotations := req.GetConfig().GetAnnotations()
      annotationsJSON, err := json.Marshal(annotations)

      // Don't use SELinux separation with Host Pid or IPC Namespace

      if !req.GetConfig.GetLinux().GetNamespaceOptions().GetHostPid() && !req.GetConfig().GetLinux().GetNamespaceOptions().GetHostIpc() {

        processLabel, mountLabel, err = getSELinuxLabels(nil)

        g.SetProcessSelinuxLabel(processLabel)

      }

      containerID, containerName, err :=  s.generateContainerIDandName(name, "infra", 0)

      g.AddAnnotation("ocid/labels", string(labelsJSON))

      ... // add annotation "ocid/annotations", "ocid/log_path", "ocid/name", "ocid/container_name", "ocid/container_id"

      s.addSandbox(&sandbox{

        id:    id,

        ....

        containers:  oci.NewMemoryStore(),

        ...

        metadata:  req.GetConfig().GetMetadata(),

      })

      for k, v := range annotations {

        g.AddAnnotation(k, v)
      }

      ...  // setup cgroup settings, setup namespaces

      err = g.SaveToFile(filepath.Join(podSandboxDir, "config.json"))

      if _, err = os.stat(podInfraRootfs); err != nil {

        if os.IsNotExist(err) {

          utils.CreateInfraRootfs(podInfraRootfs, s.pausePath) // podInfraRootfs is /var/lib/ocid/graph/vfs/pause

          // copying infra rootfs binary: /usr/libexec/ocid/pause -> /var/lib/ocid/graph/vfs/pause/rootfs/pause
        }

      }

      container, err := oci.NewContainer(containerID, containerName, podSandboxDir, podSanboxDir, labels, id, false) // bundlePath 也是podSandboxDir

      s.runtime.CreateContainer(container)

      s.runtime.UpdateStatus(container)

      // setup the network

      podNamespace := ""

      netnsPath, err := container.NetNsPath()

      s.netPlugin.SetUpPod(netnsPath, podNamespace, id, containerName)

      s.runtime.StartContainer(container)

      s.addContainer(container)

      s.podIDIndex.Add(id)

      s.runtime.UpdateStatus(container)

      return &pb.RunSandboxResponse{PodSandboxId: &id}, nil

    2、 oci/oci.go

    // 该函数主要用于创建容器,并且同步等待返回容器的pid

    func (r *Runtime) CreateContainer(c *Container) error

      parentPipe, childPipe, err := newPipe()

      defer parentPipe.Close()

      args := []string{"-c", c.name}

      args = append(args, "-r", r.path)

      if c.terminal { args = append(args, "-t")}

      cmd := exec.Command(r.conmonPath, args...)

      cms.Dir = c.bundlePath

      cmd.SysProcAttr = &syscall.SysProcAttr{ Setpgid: true, }

      cmd.Stdin = os.Stdin

      cmd.Stdout = os.Stdout

      cmd.Stderr = os.Stderr

      cmd.ExtraFiles = append(cmd.ExtraFiles, childPipe)

      cmd.Env = append(cmd.Env, fmt.Sprintf("_OCI_SYNCPIPE=%d", 3))

      err = cmd.Start()

      childPipe.Close()

      // Wait to get container pid from conmon

      var si *syncInfo

      json.NewDecoder(parentPipe).Decode(&si)

      logrus.Infof("Received container pid: %v", si.Pid)

      return nil

    3、 oci/oci.go

    func (r *Runtime) UpdateStatus(c *Container) error

      ...

      out, err := exec.Command(r.path, "state", c.name).Output()

      stateReader := bytes.NewReader(out)

      json.NewDecoder(stateReader).Decode(&c.state)

      if c.state.Status == ContainerStateStopped {

        exitFilePath := filepath.Join(c.bundlePath, "exit")

        fi, err := os.Stat(exitFilePath)

        st := fi.Sys().(*syscall.Stat_t)

        c.state.Finished = time.Unix(st.Ctim.Sec, st.Ctim.Nsec)

        statusCodeStr, err := ioutil.ReadFile(exitFilePath)

        statusCode, err := strconv.Atoi(string(statusCodeStr))

        c.state.ExitCode = int32(utils.StatusToExitCode(statusCode))

      }

  • 相关阅读:
    Hadoop使用实例
    hdfs操作命令
    Hadoop安装与HDFS体系结构
    Linux和MySQL的安装与基本操作
    Hadoop演进与Hadoop生态
    作业一
    Shader笔记——9.简单灰色效果+遮罩
    iOS——xcodeproj脚本
    iOS——KSAdSDK
    UnityPlugins——4.SignInWithApple
  • 原文地址:https://www.cnblogs.com/YaoDD/p/5956587.html
Copyright © 2011-2022 走看看