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 的创建的主要内容,如果未能解决你的问题,请参考以下文章