设为首页 收藏本站
查看: 1232|回复: 0

[经验分享] cri-o pod 创建源码分析

[复制链接]

尚未签到

发表于 2018-1-6 16:53:59 | 显示全部楼层 |阅读模式
  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,>  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",>  }  
  // 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,>  s.runtime.CreateContainer(container)
  s.runtime.UpdateStatus(container)
  // setup the network
  podNamespace := ""
  netnsPath, err := container.NetNsPath()

  s.netPlugin.SetUpPod(netnsPath, podNamespace,>  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))
  }

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-432281-1-1.html 上篇帖子: 分布式技术追踪 2017年第一期 下篇帖子: 分布式技术一周技术动态 2016-09
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表