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))
}
cri-o pod 创建源码分析的更多相关文章
- Netty中NioEventLoopGroup的创建源码分析
NioEventLoopGroup的无参构造: public NioEventLoopGroup() { this(0); } 调用了单参的构造: public NioEventLoopGroup(i ...
- 【Java】NIO中Selector的创建源码分析
在使用Selector时首先需要通过静态方法open创建Selector对象 public static Selector open() throws IOException { return Sel ...
- kubelet源码分析——关闭Pod
上一篇说到kublet如何启动一个pod,本篇讲述如何关闭一个Pod,引用一段来自官方文档介绍pod的生命周期的话 你使用 kubectl 工具手动删除某个特定的 Pod,而该 Pod 的体面终止限期 ...
- kubelet源码分析——监控Pod变更
前言 前文介绍Pod无论是启动时还是关闭时,处理是由kubelet的主循环syncLoop开始执行逻辑,而syncLoop的入参是一条传递变更Pod的通道,显然syncLoop往后的逻辑属于消费者一方 ...
- scheduler源码分析——调度流程
前言 当api-server处理完一个pod的创建请求后,此时可以通过kubectl把pod get出来,但是pod的状态是Pending.在这个Pod能运行在节点上之前,它还需要经过schedule ...
- apiserver源码分析——启动流程
前言 apiserver是k8s控制面的一个组件,在众多组件中唯一一个对接etcd,对外暴露http服务的形式为k8s中各种资源提供增删改查等服务.它是RESTful风格,每个资源的URI都会形如 / ...
- apiserver源码分析——处理请求
前言 上一篇说道k8s-apiserver如何启动,本篇则介绍apiserver启动后,接收到客户端请求的处理流程.如下图所示 认证与授权一般系统都会使用到,认证是鉴别访问apiserver的请求方是 ...
- scheduler源码分析——preempt抢占
前言 之前探讨scheduler的调度流程时,提及过preempt抢占机制,它发生在预选调度失败的时候,当时由于篇幅限制就没有展开细说. 回顾一下抢占流程的主要逻辑在DefaultPreemption ...
- 【Java】NIO中Selector的select方法源码分析
该篇博客的有些内容和在之前介绍过了,在这里再次涉及到的就不详细说了,如果有不理解请看[Java]NIO中Channel的注册源码分析, [Java]NIO中Selector的创建源码分析 Select ...
随机推荐
- Python科学计算——前期准备
1.开发环境搭建 Python(英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种面向对象.解释型计算机程序设计语言,由Guido van Rossum于1989年发明,第一个公 ...
- JavaScript来实现打开链接页面(转载)
在页面中的链接除了常规的方式以外,如果使用javascript,还有很多种方式,下面是一些使用javascript,打开链接的几种方式: 1.使用window的open方法打开链接,这里可是在制定页面 ...
- bootstrap dialog自行控制窗口的关闭
在使用dialog的时候,我们通常不希望点击btn的时候自动隐藏dialog,通常需要做一些清理或者ajax操作,在bootstrap dialog中,这是通过 data-dismiss=" ...
- C++之函数重载
函数重载定义: 如果同一作用域内的几个函数名字相同但形参列表不同; 重载与const形参: Record (Phone); = Record(const Phone); Record(Phone*) ...
- 给我一个及时的问候——XMPP
XMPP总的来说就是:基于XML数据结构,点对点的,及时通讯协议 是 Linux操作系统+Apache软件+mySql数据库 + php 编程语言 组成 开始时要导入 XMPPFrameWork框 ...
- ABAP--如何在ALV_Grid的函数中定义下拉列表
最近经常听到网友和用户需求希望你在ALV Grid的函数中加入下来列表,其实SAP已经考虑了大家的需求,用户的需求是可以实现的.我特地将代码奉献给大家,供大家参考和学习. 代码如下: REPORT.* ...
- Mssql链接mysql数据库
最近在做mysql数据库实时同步到mssql数据库的方案,花了一周时间,测试通过了,在实际机器上测试出现了若干问题.第一个问题就是在mssql上链接mysql的问题. 第一步,安装 Mysql ODB ...
- SQL注入技术专题—由浅入深【精华聚合贴】
SQL注入技术专题—由浅入深[精华聚合贴] 不管用什么语言编写的Web应用,它们都用一个共同点,具有交互性并且多数是数据库驱动.在网络中,数据库驱动的Web应用随处可见,由此而存在的SQL注入是影响企 ...
- Windows 2012 R2中安装SharePoint 2013 sp1参考
之前介绍过在window 2012中安装SharePoint 2013,这次,借着SharePoint 2013 sp1补丁发布之际,介绍下在window 2012 r2中安装SharePoint 2 ...
- 【转】IOS屏幕旋转与View的transform属性之间的关系,比较底层
iTouch,iPhone,iPad设置都是支持旋转的,如果我们的程序能够根据不同的方向做出不同的布局,体验会更好. 如何设置程序支持旋转呢,通常我们会在程序的info.plist中进行设置Suppo ...