总结:前言文章字符较多,在线编辑不方便。 本文是启动过程的第一部分。 检查门户启动进程。 这个方法在前面的章节中已经解释过。 目前系统有以下任务,每个任务都支持并使用基于创建的配置: 通过的每个字段形成一个责任链。 我们以创建为例简单介绍一下创建过程。 主要分析如下。
前言
本文字符过多,不方便在线编辑。 本文为k8s:kube-apiserver启动流程第二部分
传送门:k8s:kube-apiserver启动流程-1
回顾
上次我们讲解了 Run 方法:
// kubernetes/cmd/kube-apiserver/app.server.gofunc Run(runOptions *options.ServerRunOptions, stopCh <-chan struct {} ) error { ...server, err := CreateServerChain(runOptions, stopCh) if err != nil { return err } return server.PrepareRun().Run(stopCh)}
目前,接下来还有一些事情。 系统中的API服务器:
CustomResourceDefinitions
Master
APIAggregator
每个API服务器支持一个Masu。
apextensionsapiserver.Config
master.Config
aggregatorapiserver.Config
CreateServerChain的任务是成为root根据ServerRunOptions创建XXXConfig,并使用XXXConfig创建API服务器。 每个API服务器通过GenericAPIServer的delegationTarget字段形成“责任链”
以创建主API服务器为例。
func CreateServerChain( runOptions *options .ServerRunOptions, stopCh <[k4 ]chan struct{}) (*genericapiserver.GenericAPIServer, error) { ... kubeAPIServerConfig, ... := CreateKubeAPIServerConfig(... ) ... kubeAPIServer, err := CreateKubeAPIServer(kubeAPIServerConfig, apiExtensionsServer.GenericAPIServer,sharedInformers, versionedInformers ) ...}
下面简单介绍一下创建主 API 服务器的流程。 我们主要分析kube-apiserver如何将资源对象(节点、pod、服务等)转换为具体的绑定。 RESTful API 允许客户端通过 RESTful API 操作资源对象。
在这种情况下你会怎么做?
在查看了一些源代码之后,我忍不住问自己: 如果你要设计一个代码架构,你会怎么做
例如,给定实体Student(Java伪代码,下同),将其持久化到etcd
publicclass Student { public int id 公共字符串名称; public String Phone;}
如何提供一个RESTful API接口来为我的学生提供CRUD操作?设计一个容纳所有实体的代码框架。
API接口示例:
PUT: /user?id=xxx&name=yyy&phone=zzzDELETE: /user?id=xxxPOST: /user? id=xxx&name=yyyGET: /user ? id=xxx
我们将分几个步骤考虑它。 首先,让我们考虑一下可持续性。 要支持不同的持久化框架,或者即使想使用一种持久化框架,也必须考虑框架版本匹配的问题。 这需要一个持久化框架来配合。 抽象基本操作并提取接口。 Backend
public interface Backend { String get(String key);}
接下来具体实现类EtcdBackend、ConsulBackend、Factory一有一个类 BackendFactory。
public class EtcdBackendimplements Backend { public String get (String key) { ... } public void set(String key, String value) { ... } }public class ConsulBackendimplements Backend { public String get( String key) { ... } 公共无效set(String key, String value) { ... }}public class BackendFactory { Backend get(String name) { ... }}
后端已完成。 接下来,我们需要一个 DAO(数据访问对象)。 )访问
public class UserDao { private Backend backend; // CRUD方法...}
有很多实体,它们都使用了Backend接口。需要访问终端存储。 因此,您可以创建一个基类 AbstractDao 并移动 backedn。 在基类中添加字段
public class AbstractDao { private Backend backend;} public class User extends AbstractDao { // CRUD方法...}
进一步观察其实是每个CRUD DAO方法包含大量重复(模板)代码。 例如,如果您可以封装以下更改:
生成后端存储所需的密钥
序列化和反序列化对象
DAO 的 CRUD 方法进一步提取到 AbstractDao。 实际需要子类专门化的方法可以通过“模板方法”模式来实现。
public class AbstractDao { private Backend backend; // CRUD 方法...} public class UserDao extends AbstractDao { // 模板方法...}
距离完成又近了一步 Masu在第1步中,还有一个问题:URL和DAO如何对应? 这是一个映射问题。 您可以使用 Map 来保存与 URL 对应的 DAO。
map.put("/user", userDao)
上面只是简单的推导。 k8s 实现比这个 demo 复杂得多。 出于各种解耦和扩展性的考虑,下次会正式引入k8s实现。
评论前必须登录!
注册