kubelet是k8s中节点上运行的管理工具,它负责接受api-server发送的调度请求,在Node上创建管理pod,并且向api-server同步节点的状态.这篇文章主要讲讲kubelet组件如何使用docker的.

一.kubecontainer.Runtime

type Kubelet struct {
//....
containerRuntime kubecontainer.Runtime
//...
}
type Runtime interface {
//...
// Type returns the type of the container runtime.
Type() string
// Version returns the version information of the container runtime.
Version() (Version, error)
// Syncs the running pod into the desired pod.
SyncPod(pod *v1.Pod, apiPodStatus v1.PodStatus, podStatus *PodStatus, pullSecrets []v1.Secret, backOff *flowcontrol.Backoff) PodSyncResult
KillPod(pod *v1.Pod, runningPod Pod, gracePeriodOverride *int64) error
GetPodStatus(uid types.UID, name, namespace string) (*PodStatus, error)
//...
}

在类Kubelet中定义了很多的组件和对象,其中containerRuntime就是负责和容器Runtime进行交互的,这里的容器Runtime可以理解为就是docker.我们可以看到, 这个containerRuntime是一个接口类型,这个接口中主要定义了一系列直接操作Pod的函数和获取Runtime信息的函数.其中最关键的函数是SyncPod, 它接受一个Pod的配置信息,启动一次同步,决定启动/更新/删除这个Pod. 目前Runtime接口只有一个实现类,kubeGenericRuntimeManager.

二.kubeGenericRuntimeManager

这个类是kubecontainer.Runtime的实现类,如上述所说,这个类对外暴露的接口是直接对Pod进行管理的.也就是说,这个类对使用者屏蔽了container的概念.对于一个创建Pod的请求,SyncPod函数负责进行处理.这个函数会首先创建一个sandbox,然后依次创建init containers和normal containers. 这里sandbox是用来提供pod层级的namespace隔离,具体细节不在本文的讨论范围之内.kubeGenericRuntimeManager中负责创建container的成员变量是runtimeService.

type kubeGenericRuntimeManager struct {
//...
// gRPC service clients
runtimeService internalapi.RuntimeService
//...
}

三.internalapi.RuntimeService

首先,我们观察一下这个接口的定义,这个接口聚合了好几个其它接口,每一个接口定义了一组操作.runtimeService的实例化函数是getRuntimeAndImageServices().这个函数做的事情稍有点复杂.在解析这个函数之前,首先解析下面这个代码片段,为了便于阅读,只列出了核心代码.

    switch containerRuntime {
case kubetypes.DockerContainerRuntime:
//sentence 1
ds, err := dockershim.NewDockerService(kubeDeps.DockerClientConfig, crOptions.PodSandboxImage, streamingConfig,
&pluginSettings, runtimeCgroups, kubeCfg.CgroupDriver, crOptions.DockershimRootDirectory, !crOptions.RedirectContainerStreaming)
//sentence 2
server := dockerremote.NewDockerServer(remoteRuntimeEndpoint, ds)
server.Start()
}
// sentence 3
runtimeService, imageService, err := getRuntimeAndImageServices(remoteRuntimeEndpoint, remoteImageEndpoint, kubeCfg.RuntimeRequestTimeout)

A. sentence 1

这个函数调用的核心功能就是一句话:连接docker.

docker的守护进程会创建一个gPRC服务接口,本质上它是一个默认定义在/var/run/docker.sock的套接字.NewDockerService()函数首先会连接这个套接字,经过包装后,返回一个dockerService类的实例,该实例的client掌握了和docker守护进程的连接.

B. sentence 2

NewDockerServer函数有两个参数,一个是string类型的remoteRuntimeEndpoint,其默认值是/var/run/dockershim.sock.另一个就是NewDockerService函数构建的dockerService实例.在Start()函数中,首先启动dockerService,然后在endpoint(也就是/var/run/dockershim.sock)上启动一个gRPC服务.函数RegisterRuntimeServiceServer()将s.server上的请求映射到s.service上.

// NewDockerServer creates the dockershim grpc server.
func NewDockerServer(endpoint string, s dockershim.CRIService) *DockerServer {
return &DockerServer{
endpoint: endpoint,
service: s,
}
} // Start starts the dockershim grpc server.
func (s *DockerServer) Start() error {
// Start the internal service.
  s.service.Start()
l, err := util.CreateListener(s.endpoint)// Create the grpc server and register runtime and image services.
s.server = grpc.NewServer(
grpc.MaxRecvMsgSize(maxMsgSize),
grpc.MaxSendMsgSize(maxMsgSize),
)
runtimeapi.RegisterRuntimeServiceServer(s.server, s.service)
runtimeapi.RegisterImageServiceServer(s.server, s.service)
go func() {
if err := s.server.Serve(l); err != nil {
glog.Fatalf("Failed to serve connections: %v", err)
}
}()
return nil
}

C. sentence 3

sentence 1建立了和docker的连接,sentence 2在/var/run/dockershim.sock上监听gRPC服务并且将收到的请求转发到sentence 1所构建的和docker的连接上.那么sentence 3所完成的事就很简单了,那就是建立到/var/run/dockershim.sock的连接.

四.小结

kubelet和docker的交互简单来说是通过两层gPRC服务来实现的,kubelet自己在/var/run/dockershim.sock启动一层gPRC服务,然后这个gPRC服务将请求转发给docker守护进程所创建的/var/run/docker.sock上.从而完成一次交互.那么kubelet为什么要再创建一层gPRC服务呢?原因是k8s为了兼容其他的container runtime,提出了CRI(container runtime interface)的概念,其理想的模型是kubelet->[x-runtime].sock.也就是说,所有runtime统一实现一个gPRC接口,kubelet直接调用这个接口,这样屏蔽了底层rutime的差异.而dockershim.sock只是这个CRI概念的docker化实现.

五. 其它container runtime

根据上文我们可以知道,CRI的存在是为了屏蔽container runtime的存在,从而使k8s可以更好的支持多种container runtime,例如rkt.那么其它的kubelet是如何管理其它的runtime呢.原来docker的CRI实现是以dockershim的形式存在于k8s的主线代码中了,其它的runtime需要自己实现类似于dockershim的一套gPRC服务给kubelet访问.

kubelet ----container-runtime-endpoint选项就是定义这个gPRC服务的地址的.

kubelet分析的更多相关文章

  1. kubelet分析-csi driver注册分析-Node Driver Registrar源码分析

    kubernetes ceph-csi分析目录导航 Node Driver Registrar分析 node-driver-registrar是一个sidecar容器,通过Kubelet的插件注册机制 ...

  2. kubelet分析-csi driver注册源码分析

    kubelet注册csi driver分析 kubelet注册csi driver的相关功能代码与kubelet的pluginManager有关,所以接下来对pluginManager进行分析.分析将 ...

  3. kubelet分析-pvc扩容源码分析

    kubernetes ceph-csi分析目录导航 存储的扩容分为controller端操作与node端操作两大步骤,controller端操作由external-resizer来调用ceph完成,而 ...

  4. heapster源码分析——kubelet的api调用分析

    一.heapster简介 什么是Heapster? Heapster是容器集群监控和性能分析工具,天然的支持Kubernetes和CoreOS.Kubernetes有个出名的监控agent---cAd ...

  5. kubelet源码分析(version: git tag 1.7.6)

    一.概述 kubelet源码入口:cmd/kubelet/kubelet.go main() cmd/kubelet/app 包中的Run函数: 查看先参数,kubelet.KubeletDeps t ...

  6. 【原创】k8s源代码分析-----kubelet(1)主要流程

    本人空间链接http://user.qzone.qq.com/29185807/blog/1460015727 源代码为k8s v1.1.1稳定版本号 kubelet代码比較复杂.主要是由于其担负的任 ...

  7. 【原创】k8s源代码分析-----kubelet(8)pod管理

    本文QQ空间链接:http://user.qzone.qq.com/29185807/blog/1460540474 本文csdn博客链接:http://blog.csdn.net/screscent ...

  8. 11.深入k8s:kubelet工作原理及源码分析

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 源码版本是1.19 kubelet信息量是很大的,通过我这一篇文章肯定是讲不全的,大家可 ...

  9. kubelet之volume manager源码分析

    kubernetes ceph-csi分析目录导航 基于tag v1.17.4 https://github.com/kubernetes/kubernetes/releases/tag/v1.17. ...

随机推荐

  1. tmux下make menuconfig背景色不正常问题

    参考https://blog.tankywoo.com/2015/10/24/tmux-mutt-not-redraw-problem.html 是由于~/.bashrc或~/.zshrc设置,覆盖了 ...

  2. cookie和session的区别与会话跟踪技术

    会话跟踪技术: HTTP是一种无状态协议,每当用户发出请求时,服务器就会做出响应,客户端与服务器之间的联系是离散的.非连续的.当用户在同一网站的多个页面之间转换时,根本无法确定是否是同一个客户,会话跟 ...

  3. GenericAPIView类与几个扩展类的综合使用

    五个扩展类 扩展类 作用 封装的方法 状态码(成功,失败) ListModelMixin 查询多条数据 list 200 CreateModelMixin 新增一条数据 create 201,400 ...

  4. Zookeeper概念学习系列之zookeeper实现分布式进程监控

    不多说,直接上干货! 假设要监控多台服务器上的A程序运行状态, 当发现有服务器上的A程序下线的时候, 给管理员发短信, 并且尝试重启A程序. zookeeper实现分布式进程监控主要利用zk的临时节点 ...

  5. IOC(控制反转)的理解

    1.IOC的理论背景 我们知道在面向对象设计的软件系统中,它的底层都是由N个对象构成的,各个对象之间通过相互合作,最终实现系统地业务逻辑[1]. 图1 软件系统中耦合的对象 如果我们打开机械式手表的后 ...

  6. Nodejs微信开发

    因为使用了Bot Framework开发了一个小功能,它目前支持了Skype\Teams\Slack等,但在国内来讲,微信还是一个比较流行的软件,所以需要接上微信 原来开发Bot的时候使用的是.Net ...

  7. django CXRF介绍

    CSRF(Cross-site request forgery)跨站请求伪造,是攻击者利用用户的身份操作用户帐户的一种攻击方式.和XSS攻击一样,存在巨大的危害性. 一.攻击方法 1.低级的CXRF攻 ...

  8. HDU 1754.I Hate It-结构体版线段树(单点更新+区间查询最值)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  9. asp.net中利用JSON进行增删改查中运用到的方法

    //asp.net中 利用JSON进行操作, //增加: //当点击“增加链接的时候”,弹出增加信息窗口,然后,在窗体中输入完整信息,点击提交按钮. //这里我们需要考虑这些:我会进行异步提交,使用j ...

  10. Python3 list记录

    #!/usr/bin/env python3 # -*- coding: utf-8 -*- # Author;Tsukasa name = ['YangJiaHui','LiuYueEr','TaB ...