update cdn url

master
yinwenqin 3 years ago
parent f32a2b21b0
commit 86d0448e22

@ -484,7 +484,7 @@ func (config Config) New() (authenticator.Request, *spec.SecurityDefinitions, er
这个New()方法依次生成每一种认证方式的AuthenticatorNew()方法的流程图如下:
![](https://mycloudn.upweto.top/20210202145027.png)
![](https://mycloudn.wqyin.cn/20210202145027.png)
`union.New(authenticators...)`方法集合所有的认证器

@ -39,7 +39,7 @@ Kubernetes 使用身份认证插件利用客户端证书、持有者令牌Bea
首先为了加深印象,再贴一下上一章列出的认证流程图:
![](https://mycloudn.upweto.top/20210203112246.png)
![](https://mycloudn.wqyin.cn/20210203112246.png)
> 注:认证器的执行顺序为随机的,图中流向不代表固定顺序
@ -94,7 +94,7 @@ func WithAuthentication(handler http.Handler, auth authenticator.Request, failed
`vendor/k8s.io/apiserver/pkg/authentication/authenticator/interfaces.go:35`
![](https://mycloudn.upweto.top/20210202115500.png)
![](https://mycloudn.wqyin.cn/20210202115500.png)
引用中的union.go中聚合了所有的Authenticator链进去看看
@ -126,7 +126,7 @@ func (authHandler *unionAuthRequestHandler) AuthenticateRequest(req *http.Reques
apiserver的各种request相关定义代码大多集中在这个目录里
<img src="https://mycloudn.upweto.top/20210202145632.png" style="zoom:70%;" />
<img src="https://mycloudn.wqyin.cn/20210202145632.png" style="zoom:70%;" />
那么依次逐个来看看每一种Authenticator对应的AuthenticateRequest方法。
@ -192,7 +192,7 @@ extra:
使用kubeadm默认部署的集群就启用了requestheader的配置
![](https://mycloudn.upweto.top/20210202163330.png)
![](https://mycloudn.wqyin.cn/20210202163330.png)
来看看AuthenticateRequest方法的代码
@ -500,7 +500,7 @@ SA是一种面向集群内部应用需要调用APIServer的场景所设计的认
在集群上找一个例子以kube-proxy举例
![](https://mycloudn.upweto.top/20210203103806.png)
![](https://mycloudn.wqyin.cn/20210203103806.png)
看看代码层面:

@ -45,7 +45,7 @@ Kubernetes 仅审查以下 API 请求属性:
来看看现有的kubeadm部署集群启用的鉴权策略:
![](https://mycloudn.upweto.top/20210203155452.png)
![](https://mycloudn.wqyin.cn/20210203155452.png)
可以看到默认启用了Node授权和RBAC授权模块。
@ -132,7 +132,7 @@ DefaultResourceRuleInfo{
### 鉴权流程图
![](https://mycloudn.upweto.top/20210203180748.png)
![](https://mycloudn.wqyin.cn/20210203180748.png)
@ -218,7 +218,7 @@ RBAC 鉴权机制使用 `rbac.authorization.k8s.io` [API 组](https://kubernetes
RBAC模式的详细描述和使用样例请参考我之前的文章
[k8s(十四)、RBAC权限控制](https://blog.upweto.top/2018/12/06/k8s(%E5%8D%81%E5%9B%9B)%E3%80%81RBAC%E6%9D%83%E9%99%90%E6%8E%A7%E5%88%B6.html)
[k8s(十四)、RBAC权限控制](https://blog.wqyin.cn/2018/12/06/k8s(%E5%8D%81%E5%9B%9B)%E3%80%81RBAC%E6%9D%83%E9%99%90%E6%8E%A7%E5%88%B6.html)

@ -28,7 +28,7 @@ APIServer提供了 k8s各类资源对象的CURD/watch、认证授权、准入控
如图所示,这是创建一个资源(Pod)实例过程中,控制层面所经过的调用过程:
![](https://mycloudn.upweto.top/20201126165154.png)
![](https://mycloudn.wqyin.cn/20201126165154.png)
在这个过程中控制层面的每个组件、每一步骤都需要与APIServer交互。

@ -34,7 +34,7 @@ watch依然比较麻烦毕竟list获取的数据以及后续watch到的数据
#### 工作流程图
![](http://mycloudn.upweto.top/20191218161137.png)
![](http://mycloudn.wqyin.cn/20191218161137.png)
#### 流程图组件解释

@ -6,11 +6,11 @@
Controller部分的第一篇文章中我们从cobra启动命令入口开始进入到了多实例leader选举部分的代码对leader选举流程做了详细地分析
[Controller-P1-多实例leader选举](https://blog.upweto.top/gitbooks/kubeSourceCodeNote/controller/Kubernetes源码学习-Controller-P1-多实例leader选举.html)
[Controller-P1-多实例leader选举](https://blog.wqyin.cn/gitbooks/kubeSourceCodeNote/controller/Kubernetes源码学习-Controller-P1-多实例leader选举.html)
接着在第二篇中文字和图解简单描述了controller是如何结合client-go模块中的informer工作的为本篇及后面的几篇作铺垫
[Controller-P2-Controller与informer](https://blog.upweto.top/gitbooks/kubeSourceCodeNote/controller/Kubernetes源码学习-Controller-P2-Controller与informer.html)
[Controller-P2-Controller与informer](https://blog.wqyin.cn/gitbooks/kubeSourceCodeNote/controller/Kubernetes源码学习-Controller-P2-Controller与informer.html)
那么本篇,就接着第一篇往下,继续看代码。
@ -38,7 +38,7 @@ if err := StartControllers(controllerContext, saTokenControllerInitFunc, NewCont
==> `cmd/kube-controller-manager/app/controllermanager.go:343`
<img src="http://mycloudn.upweto.top/20200127122642.png" style="zoom:80%;" />
<img src="http://mycloudn.wqyin.cn/20200127122642.png" style="zoom:80%;" />
可以看到controller会对不同的资源分别初始化相应的controller包含我们常见的deployment、statefulset、endpoint、pvc等等资源controller种类有多达30余个。因此在controller整个章节中不会对它们逐一分析只会抽取几个常见有代表性地进行深入本篇就来看看deployment controller吧。
@ -745,7 +745,7 @@ func (dc *DeploymentController) syncRolloutStatus(allRSs []*apps.ReplicaSet, new
DeploymentCondition在这里面反复出现便于理解参照一个正常状态的deployment condition样例:
<img src="http://mycloudn.upweto.top/20200130125357.png" style="zoom:50%;" />
<img src="http://mycloudn.wqyin.cn/20200130125357.png" style="zoom:50%;" />
#### 总结

@ -49,7 +49,7 @@ for {
kube-controller是一个控制组件根据我们的使用经验有多种经常使用的资源都不是实际地直接进行任务计算的资源类型而在申明之后由k8s自动发现并保证以达成申明语义状态的逻辑资源例如deployment、statefulSet、pvc、endpoint等这些资源都分别由对应的controller子组件那么这样的controller子组件有多少呢如下图
![](http://mycloudn.upweto.top/20191206111312.jpg)
![](http://mycloudn.wqyin.cn/20191206111312.jpg)
可见controller的组件数量是非常之多的因此在本部分中计划只抽选其中的deploymentController和statefulSetController这两种常见的对pod管理类型资源对应的controller来进行源码分析。
@ -59,11 +59,11 @@ kube-controller是一个控制组件根据我们的使用经验有多种
`kubernetes/src/k8s.io/kubernetes/cmd/kube-controller-manager/controller-manager.go`
![](http://mycloudn.upweto.top/20191206153026.jpg)
![](http://mycloudn.wqyin.cn/20191206153026.jpg)
**功能模块**
`kubernetes/src/k8s.io/kubernetes/pkg/controller`
![](http://mycloudn.upweto.top/20191206154051.jpg)
![](http://mycloudn.wqyin.cn/20191206154051.jpg)

@ -768,7 +768,9 @@ func startKubelet(k kubelet.Bootstrap, podCfg *config.PodConfig, kubeCfg *kubele
}
```
wait.Until()循环执行函数前面的文章中已经分析过多次了不再赘述来分析一下k.Run(podCfg.Updates())传的实参是什么:
wait.Until()循环执行函数前面的文章中已经分析过多次了不再过多赘述这里传参是period是0说明是无间隔死循环调用k.Run()方法体现在实际环境中kubelet运行时的表现就是无论运行中遇到什么报错kubelet都会持续工作。
来分析一下k.Run(podCfg.Updates())传的实参是什么:
--> `pkg/kubelet/config/config.go:105`

@ -56,8 +56,8 @@ matebook-x-pro:local ywq$ go run main.go
# 因需要多次测试这里所有的测试步骤就把build的步骤跳过直接使用go run main.go进行测试
```
**我们打开IDE来查看一下testapp的代码结构:**
![image](http://mycloudn.upweto.top/cobra1.jpg)
![image](http://mycloudn.upweto.top/cobra2.jpg)
![image](http://mycloudn.wqyin.cn/cobra1.jpg)
![image](http://mycloudn.wqyin.cn/cobra2.jpg)
```
# 现在还未创建子命令,那么来创建几个试试:
@ -90,7 +90,7 @@ add called
```
**来看看新增的子命令是怎么运行的呢?**
![image](http://mycloudn.upweto.top/cobra3.jpg)
![image](http://mycloudn.wqyin.cn/cobra3.jpg)
截图圈中部分可以看出子命令是在init()函数里为root级添加了一个子命令先不去管底层实现接着往下.
**测试cobra的强大简洁的flag处理**
@ -101,7 +101,7 @@ deleteCmd.PersistentFlags().StringVar(&obj,"object", "", "A function to delete a
```
在`Run:func()`匿名函数中添加一行输出:
`fmt.Println("delete obj:",cmd.Flag("object").Value)`
![image](http://mycloudn.upweto.top/cobra4.jpg)
![image](http://mycloudn.wqyin.cn/cobra4.jpg)
运行结果:
@ -112,7 +112,7 @@ delete obj: obj1
```
如果觉得`--`flag符号太麻烦cobra同样支持短符号`-`flag缩写:
![image](http://mycloudn.upweto.top/cobra5.jpg)
![image](http://mycloudn.wqyin.cn/cobra5.jpg)
运行结果:
@ -132,7 +132,7 @@ add.go delete.go get.go pods.go root.go
```
可以发现,cmd/目录下多了一个pods.go文件我们来看看它是怎么关联上delete父级命令的,同时为它添加一行输出:
![image](http://mycloudn.upweto.top/cobra6.jpg)
![image](http://mycloudn.wqyin.cn/cobra6.jpg)
执行命令:
```
@ -146,13 +146,13 @@ delete pods: pod1
## 入口
通过对上方cobra的基本了解我们不难知道`cmd/kube-scheduler/scheduler.go`内的main()方法内部实际调用的是`cobra.Command.Run`内的匿名函数,我们可以进入`NewSchedulerCommand()`内部确认:
![image](http://mycloudn.upweto.top/main1.jpg)
![image](http://mycloudn.wqyin.cn/main1.jpg)
可以看到,调用了`Run`内部`runCommand`方法再来看看Run方法内部需要重点关注的几个点
![image](http://mycloudn.upweto.top/runCommand.jpg)
![image](http://mycloudn.wqyin.cn/runCommand.jpg)
其中,上方是对命令行的参数、选项校验的步骤,跳过,重点关注两个变量:`cc和stopCh`,这两个变量会作为最后调用`Run()`方法的参数,其中`stopCh`作用是作为主程序退出的信号通知其他各协程进行相关的退出操作的另外一个cc变量非常重要可以点击`c.Complete()`方法,查看该方法的详情:
![image](http://mycloudn.upweto.top/runCommand.jpg)
![image](http://mycloudn.wqyin.cn/runCommand.jpg)
`Complete()`方法本质上返回的是一个Config结构体该结构体内部的元素非常丰富篇幅有限就不一一点开截图了大家可以自行深入查看这些元素的作用这里简单概括一下其中几个:
```
@ -175,14 +175,14 @@ Recorder record.EventRecorder
Broadcaster record.EventBroadcaster
```
这里层级非常深不便展示Config这一个结构体非常重要可以认真读一读代码。回到`cmd/kube-scheduler/app/server.go`.`runCommand`这里来,接着往下进入其最后return调用的`Run()`函数中函数中的前部分都是启动scheduler相关的组件如event broadcaster、informers、healthz server、metric server等重点看图中红框圈出的`sched.Run()`,这才是scheduler主程序的调用运行函数:
![image](http://mycloudn.upweto.top/Run.jpg)
![image](http://mycloudn.wqyin.cn/Run.jpg)
进入`sched.Run()`:
![image](http://mycloudn.upweto.top/scheRun.jpg)
![image](http://mycloudn.wqyin.cn/scheRun.jpg)
`wait.Until`这个调用的逻辑是直到收到stop信号才终止在此之前循环运行`sched.scheduleOne`。代码走到这里,终于找到启动入口最内部的主体啦:
![](http://mycloudn.upweto.top/image-20190827163439895.png)
![](http://mycloudn.wqyin.cn/image-20190827163439895.png)
`sched.scheduleOne`这个函数有代码点长,整体的功能可以概括为:

@ -12,15 +12,15 @@
回顾上一篇篇末,我们找到了调度框架的实际调度工作逻辑的入口位置,`pkg/scheduler/scheduler.go:435`, `scheduleOne()`函数内部,定位在`pkg/scheduler/scheduler.go:457`位置,是通过这个`sched.schedule(pod)`方法来获取与pod匹配的node的我们直接跳转2次,来到了这里`pkg/scheduler/core/generic_scheduler.go:107`
![](http://mycloudn.upweto.top/schedule.jpg)
![](http://mycloudn.wqyin.cn/schedule.jpg)
![](http://mycloudn.upweto.top/AlgSchedule.jpg)
![](http://mycloudn.wqyin.cn/AlgSchedule.jpg)
![](http://mycloudn.upweto.top/scheduleStruct.jpg)
![](http://mycloudn.wqyin.cn/scheduleStruct.jpg)
通过注释可以知道ScheduleAlgorithm interface中的Schedule方法就是用来为pod筛选node的但这是个接口方法并不是实际调用的我们稍微往下,在`pkg/scheduler/core/generic_scheduler.go:162`这个位置就可以找到实际调用的Schedule方法:
![](http://mycloudn.upweto.top/genericSchedule.jpg)
![](http://mycloudn.wqyin.cn/genericSchedule.jpg)
这个函数里面有4个重要的步骤:
@ -46,41 +46,41 @@ g.selectHost(priorityList)
先来逆向回溯代码结构找到哪里创建了scheduler调度器的默认初始化配置默认的调度算法来源等等框架相关的东西。`Schedule()`方法属于`genericScheduler`结构体,先查看`genericScheduler`结构体再选中结构体名称crtl + b组合键查看它在哪些地方被引用找出创建结构体的位置:
![](http://mycloudn.upweto.top/createGenSche.jpg)
![](http://mycloudn.wqyin.cn/createGenSche.jpg)
通过缩略代码框排除test相关的测试文件很容易找出创建结构体的地方位于`pkg/scheduler/core/generic_scheduler.go:1189`,点击图中红框圈中位置,跳转过去,果然找到了`NewGenericScheduler()`方法,这个方法是用来创建一个`genericScheduler`对象的那么我们再次crtl + b组合键查看`NewGenericScheduler`再什么地方被调用:
![](http://mycloudn.upweto.top/newGenericScheduler.jpg)
![](http://mycloudn.wqyin.cn/newGenericScheduler.jpg)
找出了在`pkg/scheduler/factory/factory.go:441`这个位置上找到了调用入口,这里位于`CreateFromKeys()`方法中继续crtl + b查看它的引用,跳转到`pkg/scheduler/factory/factory.go:336`这个位置:
![](http://mycloudn.upweto.top/newGenericScheduler.jpg)
![](http://mycloudn.wqyin.cn/newGenericScheduler.jpg)
![](http://mycloudn.upweto.top/createFromProvider.jpg)
![](http://mycloudn.wqyin.cn/createFromProvider.jpg)
![](http://mycloudn.upweto.top/getAlgorithmProvider.jpg)
![](http://mycloudn.wqyin.cn/getAlgorithmProvider.jpg)
这里找到了`algorithmProviderMap`这个变量,顾名思义,这个变量里面包含的应该就是调度算法的来源,点击进去查看,跳转到了`pkg/scheduler/factory/plugins.go:86`这个位置,组合键查看引用一眼就可以看出哪个引用为这个map添加了元素
![](http://mycloudn.upweto.top/addMapEle.jpg)
![](http://mycloudn.wqyin.cn/addMapEle.jpg)
跳转过去,来到了`pkg/scheduler/factory/plugins.go:391`这个位置这个函数的作用是为scheduler的配置指定调度算法即`FitPredicate、Priority`这两个算法需要用到的metric或者方法,再次请出组合键,查找哪个地方调用了这个方法:
![](http://mycloudn.upweto.top/registerAlgorithmProvider.jpg)
![](http://mycloudn.wqyin.cn/registerAlgorithmProvider.jpg)
来到了`pkg/scheduler/algorithmprovider/defaults/defaults.go:99`,继续组合键向上查找引用,这次引用只有一个,没有弹窗直接跳转过去了`pkg/scheduler/algorithmprovider/defaults/defaults.go:36`:
![](http://mycloudn.upweto.top/registerAlgorithmProvider1.jpg)
![](http://mycloudn.wqyin.cn/registerAlgorithmProvider1.jpg)
![](http://mycloudn.upweto.top/init.jpg)
![](http://mycloudn.wqyin.cn/init.jpg)
我们来看看`defaultPredicates(), defaultPriorities()`这两个函数具体的内容:
![](http://mycloudn.upweto.top/default.jpg)
![](http://mycloudn.wqyin.cn/default.jpg)
我们随便点击进去一个`predicates`选项查看其内容:
![](http://mycloudn.upweto.top/memPressure.jpg)
![](http://mycloudn.wqyin.cn/memPressure.jpg)
`CheckNodeMemoryPressure`这个词相应熟悉kubernetes 应用的朋友一定不会陌生例如在node内存压力大无法调度的pod时`kubectl describe pod xxx`就会在状态信息里面看到这个关键词。
@ -103,7 +103,7 @@ func RegisterAlgorithmProvider(name string, predicateKeys, priorityKeys sets.Str
可以看到这个方法为DefaultProvider绑定了配置筛选算法和优先级排序算法的key集合这些key只是字符串那么是怎么具体落实到计算的方法过程上去的呢让我们看看`pkg/scheduler/algorithmprovider/defaults/`目录下的`register_predicates.go,register_priorities.go`这两个文件:
![](http://mycloudn.upweto.top/preinit.jpg)
![](http://mycloudn.wqyin.cn/preinit.jpg)
它们同样也在init()函数中初始化时使用`factory.RegisterFitPredicate()`方法做了一些注册操作,这个方法的两个参数,前一个是筛选/计算优先级 的关键key名后一个是具体计算的功能实现方法点击`factory.RegisterFitPredicate()`方法,深入一级,查看内部代码,
@ -177,15 +177,15 @@ func (s *Scheme) AddTypeDefaultingFunc(srcType Object, fn func(interface{})) {
我们选中然后ctrl+b查找AddTypeDefaultingFunc()的引用弹窗中你可以看到有非常非常多的对象都引用了该方法这些不同类型的对象相信无一例外都是通过Default()方法来生成默认配置的我们找到其中的包含scheduler的方法:
![](http://mycloudn.upweto.top/addDefaultFunc.jpg)
![](http://mycloudn.wqyin.cn/addDefaultFunc.jpg)
跳转进去,来到了这个位置`pkg/scheduler/apis/config/v1alpha1/zz_generated.defaults.go:31`(原谅我的灵魂笔法):
![](http://mycloudn.upweto.top/registerDefaults.jpg)
![](http://mycloudn.wqyin.cn/registerDefaults.jpg)
进入`SetDefaults_KubeSchedulerConfiguration()`,来到`pkg/scheduler/apis/config/v1alpha1/defaults.go:42`:
![](http://mycloudn.upweto.top/SetDefaults_KubeSchedulerConfiguration.jpg)
![](http://mycloudn.wqyin.cn/SetDefaults_KubeSchedulerConfiguration.jpg)
看到了`DefaultProvider`吗是不是觉得瞬间豁然开朗原来是在这里调用指定了scheduler配置的`AlgorithmSource.Provider`。
@ -276,7 +276,7 @@ func podFitsOnNode(
最后,对`pkg/scheduler`路径下的各子目录的功能来一个图文总结吧:
![](http://mycloudn.upweto.top/dir.jpg)
![](http://mycloudn.wqyin.cn/dir.jpg)

@ -145,7 +145,7 @@ ParallelizeUntil()的这种实现方式,可以很好地将并发实现和具
`pkg/scheduler/core/generic_scheduler.go:460 --> pkg/scheduler/internal/cache/node_tree.go:161`
![](http://mycloudn.upweto.top/zone.jpg)
![](http://mycloudn.wqyin.cn/zone.jpg)
可以看到这里有一个zone的逻辑层级这个层级仿佛没有见过google了一番才了解了这个颇为冷门的功能这是一个轻量级的支持集群联邦特性的实现单个cluster可以属于多个zone但这个功能目前只有GCE和AWS支持且绝大多数的使用场景也用不到可以说是颇为冷门。默认情况下cluster只属于一个zone可以理解为cluster和zone是同层级因此后面见到有关zone相关的层级我们直接越过它。有兴趣的朋友可以了解一下zone的概念:
@ -231,7 +231,7 @@ func podFitsOnNode(
有了以上理解,我们接着看代码,图中已注释:
![](http://mycloudn.upweto.top/podFitsOnNode.jpg)
![](http://mycloudn.wqyin.cn/podFitsOnNode.jpg)
图中`pkg/scheduler/core/generic_scheduler.go:608`位置正式开始了逐个计算筛选算法,那么筛选方法、筛选方法顺序在哪里呢?在上一篇[P2-框架篇]([https://github.com/yinwenqin/kubeSourceCodeNote/blob/master/scheduler/P2-%E8%B0%83%E5%BA%A6%E5%99%A8%E6%A1%86%E6%9E%B6.md](https://github.com/yinwenqin/kubeSourceCodeNote/blob/master/scheduler/P2-调度器框架.md))中已经有讲过,默认调度算法都在`pkg/scheduler/algorithm/`路径下,我们接着往下看.
@ -260,7 +260,7 @@ var (
[链接](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/predicates-ordering.md)
![](http://mycloudn.upweto.top/predicates.jpg)
![](http://mycloudn.wqyin.cn/predicates.jpg)
#### 筛选key

@ -18,7 +18,7 @@ Tips: 本篇篇幅较长,因调度优选算法较为复杂,但请耐心结
同上一篇,回到`pkg/scheduler/core/generic_scheduler.go`中的`Schedule()`函数,`pkg/scheduler/core/generic_scheduler.go:184`:
![](http://mycloudn.upweto.top/20190822165920.png)
![](http://mycloudn.wqyin.cn/20190822165920.png)
截图中有几处标注metric相关的几行是收集metric信息用以提供给prometheus使用的kubernetes的几个核心组件都有这个功能以后如果读prometheus的源码这个单独拎出来再讲。直接进入优先级函数`PrioritizeNodes()`内部`pkg/scheduler/core/generic_scheduler.go:215`
@ -201,7 +201,7 @@ func defaultPriorities() sets.String {
在注册的每一个计算维度都有专属的维度描述关键字即factory方法的第一个参数(str类型)。不难发现,这里的每一个关键字,`pkg/scheduler/algorithm/priorities`目录内都有与其对应的文件,图中圈出了几个例子(灵魂画笔请原谅):
![](http://mycloudn.upweto.top/image-20190821171031395.png)
![](http://mycloudn.wqyin.cn/image-20190821171031395.png)
显而易见,维度计算的内容就在这些文件中,可以自行通过编辑器的跳转功能逐级查看进行验证.
@ -239,7 +239,7 @@ func CalculateNodePreferAvoidPodsPriorityMap(pod *v1.Pod, meta interface{}, node
这也印证了前面说的当前仅剩pod亲和性这一个维度在使用传统的Function,虽然已经被DEPRECATED掉了传统的Function是直接计算出结果Map-Reduce是将这个过程解耦拆成了两个步骤且我们可以看到所有的factory函数很多形参`reduceFunction`接收到的实参实际是是`nil`:
![](http://mycloudn.upweto.top/image-20190822111624614.png)
![](http://mycloudn.wqyin.cn/image-20190822111624614.png)
这就说明这些维度的计算工作在map函数里面已经执行完成了不需要再执行reduce函数了。因此传统的Function的计算过程同样值得参考那么首先就来看看`InterPodAffinityPriority`维度是怎么计算的吧!

Loading…
Cancel
Save