containerd的中的各种操作都是通过Task来进行的,因此对于容器的create, start, delete等等操作其实都是一个个的Task而已。

Task的数据结构如下所示:

type Task interface {

  Errorch() chan error

}

type baseTask struct {

  errCh    chan error
  mu      sync.Mutex
}

  

container的数据结构如下所示,而container对外暴露的interface是Container,其中包含了对container的各种操作,包括ID(), Delete()等等。

type container struct {

  // path to store runtime state information

  root    string
  id     string
  bundle   string
  runtime   string
  runtimeArgs []string
  shim    string
  processes  map[string]*process
  labels    []string
  oomFds   []int
  noPivotRoot bool
  timeout   time.Duration
}

  

容器的delete操作

DeleteTask的数据结构如下所示:

// DeleteTask holds needed paramaters to remove a container

type DeleteTask struct {

  baseTask

  ID    string
  Status  uint32
  PID    string
  NoEvent  bool
  Process  runtime.Process
}

  

-2、containerd/supervisor/monitor_linux.go

func (m *Monitor) start()对获取到的syscall.EpollEvent进行处理,当获取的event的id指向的是一个runtime.Process并且event的Events类型为syscall.EPOLLHUP时,先对该process从events中删除,进行epoll相关的清理操作,最后调用m.exits <- t

-1、containerd/supervisor/supervisor.go

func (s *Supervisor) exitHandler()

(1)、在启动daemon的时候,启动过一个exitHandler的goroutine,该函数主要的作用就是从s.monitor.exits这个runtime.Process类型的channel中获取退出的process。

(2)、对于每个退出的process,创建 e := &ExitTask{Process: p,},最后s.SendTask(e),最终经过taskHandler的调度,最终会在exit()函数进行处理

0、containerd/supervisor/exit.go

func (s *Supervisor) exit(t *ExitTask)

(1)、调用`proc := t.Process `, `status, err := proc.ExitStatus()`获取进程的退出码

(2)、如果proc.ID()不是runtime.InitProcessID,则说明只是一个exec的进程退出,则创建一个ne := &ExecExitTask{},再调用s.execExit()进行处理

(3)、若为退出的是init进程,则创建一个ne := &DeleteTask{},再调用s.delete(ne)进行处理

1、containerd/supervisor/delete.go

func (s *Supervisor) delete(t *DeleteTask) error

(1)、调用i, ok := s.containers[t.ID]获取容器实例,再调用s.deleteContainer(i.container)

(2)、当t.Process 不为nil 时,调用t.Process.Wait()

(3)、当t.NoEvent为false时,则调用s.notifySubscribers(Event{Type: StateExit, Timestamp: time.Now(), ID: t.ID, Status: t.status, PID: t.PID,})

(4)、更新supervisor的container信息,调用ContainersCounter.Dec(1)和ContainerDeleteTimer.UpdateSince(start)

2、containerd/supervisor/delete.go

func (s *Supervisor) deleteContainer(container runtime.Container) error

该函数很简单,先调用delete(s.containers, container.ID()),再调用return container.Delete()

3、containerd/runtime/container.go

首先调用os.RemoveAll(filepath.Join(c.root, c.id)),删除目录/var/run/docker/libcontainerd/containerd/container-id,接着利用exec.Command直接调用调用命令行`docker-runc delete contain-id。

容器的kill操作

1、containerd/api/grpc/server/server.go

func (s *apiServer) Signal(ctx context.Context, r *types.SignalRequest) (*types.SignalResponse)

这个函数就是根据r中的内容对supervisor.SignalTask进行填充,最后调用s.sv.SendTask(e),再返回return &types.SignalResponse{}, nil

2、containerd/supervisor/signal.go

func (s *Supervisor) signal(t *SignalTask) error

(1)、首先调用i, ok := s.containers[t.ID]获取container实例

(2)、再调用processes, err := i.container.Processes()获取容器中所有的process实例

(3)、最后遍历processes,找到t.PID对应的process,调用return p.Signal(t.Signal)

3、containerd/runtime/process.go

func (p *process) Signal(s os.Signal) error

该函数只是简单地调用return syscall.Kill(p.pid, s.(syscall.Signal)),给相应的进程发送信号。

docker containerd中的容器操作的更多相关文章

  1. docker containerd 中的create 容器操作

    containerd的create container的API如下所示: type CreateContainerRequest struct { Id string BundlePath strin ...

  2. 理解Docker(6):若干企业生产环境中的容器网络方案

    本系列文章将介绍 Docker的相关知识: (1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 ...

  3. docker学习笔记2:容器操作

    一.列出主机上已经创建的容器 docker ps -a 二.创建交互式容器 命令: docker run -i -t ubuntu /bin/bash 其中-i -t 表示创建一个提供交互式shell ...

  4. Docker Swarm 中最重要的概念- 每天5分钟玩转 Docker 容器技术(94)

    从主机的层面来看,Docker Swarm 管理的是 Docker Host 集群.所以先来讨论一个重要的概念 - 集群化(Clustering). 服务器集群由一组网络上相互连接的服务器组成,它们一 ...

  5. 【Docker】容器操作(转)

    来自:https://www.cnblogs.com/zydev/p/5803461.html 列出主机上的容器 列出正在运行的容器:   docker ps 列出所有容器:  docker ps - ...

  6. Docker基础-容器操作

    1.创建容器 1.新建容器 可以使用docker create命令新建一个容器. [root@linux-node1 ~]# docker create -it ubuntu:latest ffc90 ...

  7. Docker学习(四): 操作容器

    特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! =============系列文章============= 1 ...

  8. Docker学习(三)docker容器操作

    上一篇:Docker学习(二)docker镜像操作 容器是基于镜像创建的,说白了把一个镜像运行起来就是容器 查看容器 docker ps 上面什么也没有,因为我们没有正在运行的容器,下面我门启动一个容 ...

  9. docker 容器操作( 以 tomcat 为例 )

    一.容器操作 一个镜像可以启动多个容器.比如一个 tomcat 镜像,可以启动多个tomcat 容器,启动后的这些 tomcat 都是各自独立的 二.步骤 1.搜索镜像 [root@localhost ...

随机推荐

  1. IBATIS动态SQL(转)

    直接使用JDBC一个非常普遍的问题就是动态SQL.使用参数值.参数本身和数据列都是动态SQL,通常是非常困难的.典型的解决办法就是用上一堆的IF-ELSE条件语句和一连串的字符串连接.对于这个问题,I ...

  2. EffectiveJava——接口优于抽象类

    Java程序设计语言提供两种机制,可以用来定义允许多个实现的类型:接口和抽象方法,这两者直接醉为明显的区别在于,抽象类允许某些方法的实现,但接口不允许,一个更为重要的区别在于,为了实现由抽象类定义的类 ...

  3. (旧)子数涵数·Flash——影片剪辑的事件操作

    一.综述 1.概念:影片剪辑的事件操作,就是onClipEvent命令,就如同在按钮上使用的on命令. 2.方法:onClipEnvent(参数){命令} 3.参数:onClipEnvent有许多的参 ...

  4. Verilog学习笔记基本语法篇(十)········ 常用系统函数

    $display 和 $write 任务 格式: $display (p1,p2,...,pn); $write (p1,p2,..,pn); 这两个函数和系统的任务作用是用来输出信息,即将参数p2到 ...

  5. PowerBuilder反编译

            最近需要了解某个PowerBuilder程序如何工作的,这已经是某个时代的产物了.除了EXE之外,还有一些PBD文件.PBD文件是PowerBuilder动态库,作为本地DLL的一个替 ...

  6. 【.net程序破解】实战之标志位破解绕过注册法

    今天有时间玩了下一个不错的软件Advanced System Cleaner,可惜要注册 于是想办法给破解了,这是跟之前不同的地方,属于.NET破解教程: 软件地址 - http://www.crsk ...

  7. GridView总结一:GridView自带分页及与DropDownList结合使用

    GridView自带的分页功能实现: 要实现GrdView分页的功能 操作如下: 1.更改GrdView控件的AllowPaging属性为true. 2.更改GrdView控件的PageSize属性为 ...

  8. JAVA基础学习day17--集合工具类-Collections

    一.Collection简述 1.1.Collection与Collections的区别 Collections是集合的静态工具类 Collection:是集合的顶级接口 二.Sort 2.1.sor ...

  9. 基础学习day08---多态、简单工厂、Object类equals和toString

    一.多态 1.1.多态概念  定义:某一类事物的多种存在形态.        例:动物中猫,狗.    猫这个对象对应的类型是猫类型:猫 x = new 猫();    同时猫也是动物中的一种,也可以 ...

  10. Enterprise Library +Caliburn.Micro+WPF CM框架下使用企业库验证,验证某一个属性,整个页面的文本框都变红的原因

    我用的是CM这个框架做的WPF,在用企业库的验证的时候,我用标签的方式给一个属性加了不能为空的验证,但整个页面的所有控件的外面框都变红了.原因是CM框架的绑定方式是直接X:Name="你的属 ...