Pod 的创建

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pod 的创建相关的知识,希望对你有一定的参考价值。

参考技术A pkg/kubelet/kubelet.go   -->  HandlePodAdditions 方法

Pod创建首先来看看 HandlePodAdditions 函数。

1. 函数首先将pods按照创建日期排列,保证最先创建的 pod 会最先被处理;

2. 然后按照创建日期依次处理Pod:调用 kl.podManager.AddPod(pod),将Pod加入podManager,podManager 是一个重要的结构,前面说过的 manager 都依赖于这个结构体工作。它是 kubelet 的 source of truth,所有被管理的 pod 都要出现在里面。如果 podManager 中找不到某个 pod,就认为这个 pod 被删除了

3. 这里还有一个mirrorpod的概念,mirrorpod主要与kubelet运行于standalone模式有关,假如pod是通过file或http的形式获得的,这个pod被称为static pod,k8s会在集群中创建一个对应的mirror pod;

4. 验证 pod 是否能在该节点运行,如果不可以直接拒绝;

5. 接着函数调用kl.dispatchWork,把 pod 分配给给 worker 做异步处理;

6. 在 probeManager 中添加 pod,如果 pod 中定义了 readiness 和 liveness 健康检查,启动 goroutine 定期进行检测;

dispatchWork 

它的作用就是根据 pod 把把接收到的参数封装成 UpdatePodOptions,发送给特定的执行者 podWorkers (调用 kl.podWorkers.UpdatePod 方法) 。

1. 在PodWorkers里比较重要的是 podUpdates, 是一个map类型,每一个Pod的uuid作为key,而 UpdatePodOptions 的 channel 作为 value 传递 pod 信息;

2. UpdatePod方法首先会去检查 podUpdates 这个map,如果新创建的 Pod 没有update goroutine,它会创建一个 goroutine,执行函数 mannagePodLoop。注意每一个pod都会有一个相应的 goroutine 执行 mannagePodLoop,其参数 podUpdates 这个 channel 则用来传递pod update的信息;除此之外,它还会更新 podUpdate 和 isWorking,填入新 Pod 的信息,并往 podUpdates 管道中发送接收到的 pod 选项信息。

managePodLoop

managePodLoop方法调用syncPodFn函数去同步Pod,syncPodFn这个函数实际上是syncPod函数;(定义在pkg/kubelet/kubelet.go Run方法中)

syncPod

pkg/kubelet/kubelet.go   -->  syncPod 方法

syncPod  是单个Pod同步的事务脚本(syncPod is the transaction script for the sync of a single pod.)。

1. 如果是删除 pod,立即执行并返回;

2. 检查 pod 是否能运行在本节点,主要是权限检查(是否能使用主机网络模式,是否可以以 privileged 权限运行等)。如果没有权限,就删除本地旧的 pod 并返回错误信息;

3. 如果是 static Pod,就创建或者更新对应的 mirrorPod;

4. 创建 pod 的数据目录,存放 volume 和 plugin 信息,即目录/var/lib/kubelet/uuid;

5. 如果定义了 PV,等待所有该Pod依赖的 volume mount 完成(volumeManager 会在后台做这些事情);

6. 如果有 image secrets,去 apiserver 获取对应的 secrets 数据;

7. 调用 container runtime 的 SyncPod 方法,去实现真正的容器创建逻辑;

这里所有的事情都和具体的容器没有关系,可以看做是提前做的准备工作。最重要的事情发生在 kl.containerRuntime.SyncPod() 里,也就是上面过程的最后一个步骤,它调 runtime 执行具体容器的创建

docker 的话 

pkg/kubelet/kuberuntime/kuberuntime_manager.go --> SyncPod方法

rkt 的话

pkg/kubelet/rkt/rkt.go --> SyncPod方法

以docker为例,看一下 SyncPod 方法

1. 计算沙箱和容器的更改,根据最新拿到的 pod 配置与当前运行的容器配置进行对比,计算其中的变化;

2. 如果沙箱容器改变了,那么杀掉这个容器。这个主要是当沙箱变化的时候,需要重建pod,譬如切换了pause镜像,就会触发这个操作;

3. 如果 Pod 不存在了,那么杀死其中的所有容器;

4. 如果有必要,创建一个沙盒。获取 PodSandbox 的配置 (e.g., metadata, clusterDNS, 容器的端口映射等)。kubelet之所以引入沙箱,是想建立一个容器标准,这里可以简单理解成那个pause容器。所有的网络都是挂在这个基础容器里面;

5. 启动初始化容器。init容器是为业务容器做初始化工作的,譬如可以预先从网络上面加载一些动态资源;

6. 启动普通容器。就是通过读取podContainerChanges.ContainersToStart管道里面,需要启动的容器,然后for循环逐一创建这个pod里面的container;

创建使用其他 Pod 的私有 CocoaPod

【中文标题】创建使用其他 Pod 的私有 CocoaPod【英文标题】:Create Private CocoaPod that uses other Pod 【发布时间】:2016-09-23 19:17:24 【问题描述】:

我正在尝试创建一个私有 CocoaPod,我将在另一个项目中使用/安装它,让我将我的 pod 称为“MyPod”,将我的项目称为“MyProject”。 MyPod 依赖于另一个名为 BMSSecurity 的 pod。在这里你可以看到 MyPod 的 Podfile:

target 'MyPod' do
  use_frameworks!
  pod 'BMSSecurity'
end

MyPod 可以很好地构建并导入 BMSSecurity 我正在按照指南创建一个私有 pod,但是当我使用 pod install 在 MyProject 中安装 MyPod 时,一切看起来都很好,只是没有安装 MyPod 中的 pod BMSSecurity,因此无法构建 MyProject。 MyProject 找不到 BMSSecurity 所需的文件 这是 MyProject 的 Podfile:

target 'MyProject' do
  use_frameworks!
  pod 'MyPod', :path => '../MyPod'
end

../MyPod 是 MyPod 的规范文件所在的位置

如何让 Cocoapods 了解它需要在 pod 中安装 pod?

【问题讨论】:

【参考方案1】:

将 BMSSecurity 添加为私有 pod 的依赖项。在您的 .podspec 文件中:

Pod::Spec.new do |s|
    s.name             = 'MyPod'
    s.version          = '1.0.0'
    s.summary          = 'A short description of MyPod.'

    # ...

    s.dependency 'BMSSecurity'

    # ...

end

【讨论】:

它工作得很好,非常感谢。你不明白这对我意味着什么,节省了我的周末:)

以上是关于Pod 的创建的主要内容,如果未能解决你的问题,请参考以下文章

创建一个依赖于另一个 pod 的 pod

为啥 cocoapod 为每个 pod 创建一个虚拟类?

k8s基础篇 pod创建

K8S 之 为一个POD创建对外发布服务

使用 pod 依赖项创建 Flutter 插件

创建Deployment后,无法创建Pod问题处理