【AICon】 如何构建高效的 RAG 系统?RAG 技术在实际应用中遇到的挑战及应对策略?>>> 了解详情
写点什么

kubeadm 源码分析

  • 2020-03-11
  • 本文字数:4855 字

    阅读完需:约 16 分钟

kubeadm 源码分析

Kubernetes 在 9 月份推出了 1.4 的版本,在这个版本中最招人眼球的就是它推出了 Kubeadm 部署工具。本文由才云云开源高级工程师唐继元从源码的角度来剖析 kubeadm 的部署原理。

k8s version:1.4

Kubeadm app 支持的命令

从函数“NewKubeadmCommand”中可以看出:


cmds.AddCommand(NewCmdInit(out))cmds.AddCommand(NewCmdJoin(out))cmds.AddCommand(NewCmdVersion(out))
复制代码


目前主要支持:“kubeadm init” 和 “kubeadm join” 命令。

kubeadm init

功能:“Run this in order to set up the Kubernetes master.”


主要的 options:


cmd.PersistentFlags().StringVar(    &cfg.Secrets.GivenToken, "token", "",    "Shared secret used to secure cluster bootstrap; if none is provided, one will be generated for you",  )
cmd.PersistentFlags().StringSliceVar( &cfg.API.AdvertiseAddresses, "api-advertise-addresses", []string{}, "The IP addresses to advertise, in case autodetection fails", )
cmd.PersistentFlags().StringSliceVar( &cfg.API.ExternalDNSNames, "api-external-dns-names", []string{}, "The DNS names to advertise, in case you have configured them yourself", )
cmd.PersistentFlags().StringVar( &cfg.Networking.ServiceSubnet, "service-cidr", kubeadmapi.DefaultServicesSubnet, "Use alterantive range of IP address for service VIPs", )
cmd.PersistentFlags().StringVar( &cfg.Networking.PodSubnet, "pod-network-cidr", "", "Specify range of IP addresses for the pod network; if set, the control plane will automatically allocate CIDRs for every node", )
cmd.PersistentFlags().StringVar( &cfg.Networking.DNSDomain, "service-dns-domain", kubeadmapi.DefaultServiceDNSDomain, `Use alternative domain for services, e.g. "myorg.internal"`, )
cmd.PersistentFlags().StringVar( &cfg.CloudProvider, "cloud-provider", "", `Enable cloud provider features (external load-balancers, storage, etc), e.g. "gce"`, )
cmd.PersistentFlags().StringVar( &cfg.KubernetesVersion, "use-kubernetes-version", kubeadmapi.DefaultKubernetesVersion, `Choose a specific Kubernetes version for the control plane`, )
// … 这里忽略了未来将要Deprecated的flag
复制代码


下面看看 init 命令到底做了些什么:


// RunInit executes master node provisioning, including certificates, needed static pod manifests, etc.func RunInit(out io.Writer, cmd *cobra.Command, args []string, cfg *kubeadmapi.MasterConfiguration) error {  // 如果未指定“api-advertise-addresses”,就选择默认路由对应interface的ip  // Auto-detect the IP  if len(cfg.API.AdvertiseAddresses) == 0 {    // TODO(phase1+) perhaps we could actually grab eth0 and eth1    ip, err := netutil.ChooseHostInterface()    if err != nil {      return err    }    cfg.API.AdvertiseAddresses = []string{ip.String()}  }
// 如果指定了“cloud-provider”,则初始化cloud provider,并向k8s注册 // TODO(phase1+) create a custom flag if cfg.CloudProvider != "" { if cloudprovider.IsCloudProvider(cfg.CloudProvider) { fmt.Printf("<cmd/init> cloud provider %q initialized for the control plane. Remember to set the same cloud provider flag on the kubelet.\n", cfg.CloudProvider) } else { return fmt.Errorf("<cmd/init> cloud provider %q is not supported, you can use any of %v, or leave it unset.\n", cfg.CloudProvider, cloudprovider.CloudProviders()) } }
// 如果未指定“token”,则自动创建一个token // 然后将该token保存在“/etc/kubernetes/pki”目录下:tokens.csv if err := kubemaster.CreateTokenAuthFile(&cfg.Secrets); err != nil { return err }
}
// 根据componentconfig的配置信息创建master节点上的static pod对象, // 并将static pod以json文件格式保存到“/etc/kubernetes/manifests”目录下: // kube-apiserver.json kube-controller-manager.json kube-scheduler.json // 如果用户未指定“external etcd”,则还会创建etcd static pod:etcd.json if err := kubemaster.WriteStaticPodManifests(cfg); err != nil { return err }
// 基于token创建服务相关的key和setificate,保存在“/etc/kubernetes/pki”目录下: // ca-key.pem ca-pub.pem ca.pem // apiserver-key.pem apiserver-pub.pem apiserver.pem // sa-key.pem sa-pub.pem caKey, caCert, err := kubemaster.CreatePKIAssets(cfg) if err != nil { return err }
// 创建client使用的certificate,并以conf文件保存在“/etc/kubernetes/pki”目录下: // admin.conf kubelet.conf // admin.conf和kubelet.conf分别是kubectl和kubelet使用的kubeconfig kubeconfigs, err := kubemaster.CreateCertsAndConfigForClients(cfg.API.AdvertiseAddresses, []string{"kubelet", "admin"}, caKey, caCert) if err != nil { return err } for name, kubeconfig := range kubeconfigs { if err := kubeadmutil.WriteKubeconfigIfNotExists(name, kubeconfig); err != nil { return err } }
// 利用admin.conf创建client,并等待apiserver起来 // 使用这个client就相当于执行了如下命令: // kubectl --kubeconfig=”/etc/kubernetes/admin.conf” xxxx // 后面的addons都是通过该client创建的 client, err := kubemaster.CreateClientAndWaitForAPI(kubeconfigs["admin"]) if err != nil { return err }
// 设置默认不允许调度pod到master上的taint // 这种情况下master上就只运行“/etc/kubernetes/manifests”目录下的static pod // 和master上的一些addons(设置了toleration) schedulePodsOnMaster := false if err := kubemaster.UpdateMasterRoleLabelsAndTaints(client, schedulePodsOnMaster); err != nil { return err }
// 创建kube-discovery deployment和secret,并等待kube-discovery server起来 // kube-discovery server侦听9898端口 // kube-discovery是必须的addon组件 // 当需要往k8s集群添加node时,“kubeadm join”首先通过URL向kube-discovery server请求cluster的相关信息 // http://MasterIP:9898/cluster-info/v1/?token-id=XXX.YYYY // kube-discovery服务收到请求之后,将cluster ca证书,endpoint列表和token以k8s secrets的方式回复给发送请求的节点 if err := kubemaster.CreateDiscoveryDeploymentAndSecret(cfg, client, caCert); err != nil { return err }
// 创建其他必须的addon,主要是:kube-proxy, kube-dns // kube-proxy 为daemonSet,而kube-dns为deployment if err := kubemaster.CreateEssentialAddons(cfg, client); err != nil { return err }}
复制代码


从上面的分析可以看出:kubeadm init 主要负责创建 k8s 集群的 key、certs 和 conf 文件,创建 etcd、kube-apiserver、kube-controller-manager、kube-scheduler 这些 static pod 的 json 格式的 manifest 文件(kubelet 会监视“/etc/kubernetes/manifests”目录下的 manifest 文件,一旦发现则启动对应的 static pod),然后启动 kube-discovery deployment、kube-proxy daemonSet、kube-dns deployment 这三个 addon。

kubeadm join

kubeadm join --token <token> <master-ip>
复制代码


功能:“Run this on any machine you wish to join an existing cluster.”,即将当前运行“kubeadm join”命令的节点加入到一个已经存在的 k8s 集群中。


主要的 options:


cmd.PersistentFlags().StringVar(    &cfg.Secrets.GivenToken, "token", "",    "(required) Shared secret used to secure bootstrap. Must match the output of 'kubeadm init'",  )
复制代码


下面看看 join 命令到底做了些什么:


// RunJoin executes worked node provisioning and tries to join an existing cluster.func RunJoin(out io.Writer, cmd *cobra.Command, args []string, s *kubeadmapi.NodeConfiguration) error {  // 用户必须要指定token  // 如果用户指定了token,则检查token的格式是否合法  // token格式要求(比如:f0c861.753c505740ecde4c):  //     1. 点分格式(2-part dot-separated format)  //     2. 前面部分为3个字节的tokenID,比如:f0c861  //     3. 后面部分为8个字节的token,比如:753c505740ecde4c  ok, err := kubeadmutil.UseGivenTokenIfValid(&s.Secrets)  if !ok {    if err != nil {      return fmt.Errorf("<cmd/join> %v (see --help)\n", err)    }    return fmt.Errorf("Must specify --token (see --help)\n")  }
// 1. 访问kube-discovery服务,获取cluster相关信息(cluster info对象,主要包括cluster ca证书,endpoint列表和token信息) // URL: http://MasterIP:9898/cluster-info/v1/?token-id=XXX.YYYY // 2. 使用用户指定的token检验cluster info对象的签名,如果检验失败则自然不允许加入该k8s集群 clusterInfo, err := kubenode.RetrieveTrustedClusterInfo(s) if err != nil { return err }
// 利用endpoint列表的其中一个apiserver的URL创建能与k8s master建立连接的ConnectionDetails对象 connectionDetails, err := kubenode.EstablishMasterConnection(s, clusterInfo) if err != nil { return err }
// 通过ConnectionDetails对象与apiserver建立连接,并向apiserver请求为该节点创建证书,然后根据该证书创建kubeconfig对象 kubeconfig, err := kubenode.PerformTLSBootstrap(connectionDetails) if err != nil { return err }
// 将kubeconfig对象写入“/etc/kubernetes/kubelet.config”文件 err = kubeadmutil.WriteKubeconfigIfNotExists("kubelet", kubeconfig) if err != nil { return err }}
复制代码


然后我们看看 node 节点上 kubelet 是如何运行的:


/usr/bin/kubelet --kubeconfig=/etc/kubernetes/kubelet.conf --require-kubeconfig=true --pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true --network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin --cluster-dns=100.64.0.10 --cluster-domain=cluster.local
复制代码


所以,节点上的 kubelet 需要通过 kubelet.conf 与 apiserver 进行安全通信。


从上面的分析可以看出:kubeadm join 主要负责创建 kubelet.conf 文件,创建的流程如下:


1.访问 kube-discovery 服务获取 k8s cluster info,主要包含如下信息:cluster ca 证书、endpoint 列表和 token


2.利用用户指定的 token,检验 k8s cluster info 的签名,建议通过才能进行后续步骤


3.与 endpoint 列表的其中一个 apiserver 建立连接,请求 apiserver 为该 node 节点创建证书,然后利用该获取到的证书创建 kubelet.conf


作者介绍:唐继元 ,才云云开源高级工程师。浙江大学软件学院软件工程专业嵌入式系统方向。2016 年初加入才云,加盟才云之前,曾在华为工作 5 年,期间在华为中央软件院服务器 OS 部门负责 LTP (linux 内核测试套件)关于内存管理和内存文件系统的测试代码的开发和完善,后转至中央研究院香农实验室系统软件组负责云计算软件方向的研究(主要包括众核 OS:barralfish 的研究,LibOS:OSv 的研究,DCOS 调度的研究,lwip 并行协议栈的研究,容器方向的研究),以及对 Kubernetes 调度等研究。


本文转载自才云 Caicloud 公众号。


原文链接:https://mp.weixin.qq.com/s/b5VU8Fr4FZtZAnvfL0fBTg


2020-03-11 19:53948

评论

发布
暂无评论
发现更多内容

每日一题:LeetCode-78. 子集

半亩房顶

面试 算法 LeetCode 刷题 回溯

centOS7的home目录进行扩容教程。

百度搜索:蓝易云

云计算 Linux centos 运维 云服务器

即时通讯技术文集(第26期):实时音视频技术合集(Part1) [共16篇]

JackJiang

网络编程 即时通讯 IM

Wireshark中的ARP协议包分析是什么?

小齐写代码

centos使用pip安装ansible教程。

百度搜索:蓝易云

Linux centos 运维 pip ansible

技术博客:Vue中各种混淆用法汇总

雪奈椰子

想快速解决数据问题?ETLCloud教你秒上手

RestCloud

ETL 数据集成

写实3D游戏模型纹理贴图设置

3D建模设计

材质 纹理 贴图 3D模型纹理贴图

数据驱动:离散制造行业财务报告应用场景与实践

用友BIP

数据驱动

12 月 10 日,融云在 Google DevFest 上海站等你!

融云 RongCloud

Google 即时通讯 IM 融云 Google DevFest

Mac电脑图片处理必备:Photoshop 2021直装激活版

mac大玩家j

Mac软件 图片编辑工具 图片处理软件

制作古风纹理的滕王阁3D模型

3D建模设计

材质贴图 纹理贴图 材质纹理 GLTF材质编辑

制作木制纹理的蓬莱阁3D模型

3D建模设计

材质贴图 纹理贴图 材质纹理 GLTF材质编辑

如何为游戏角色3D模型设置纹理贴图

3D建模设计

材质 纹理 贴图 3D模型纹理贴图 GTLF/GLB

群星璀璨!亚信科技、TM Forum联合举办数字领导力中国峰会,助百行千业打造转型升级双引擎

亚信AntDB数据库

AntDB AntDB数据库

Ulysses for Mac(Markdown文本编辑器) 33.1永久激活版

mac

文本编辑器 苹果mac Windows软件 Ulysses

虚拟线程原理及性能分析

得物技术

jdk 性能优化

借助AI构建企业营销数据,锁定目标客户价值模型

用友BIP

数智营销

让数据成为生产力,用友时序数据库为智造按下“瞬时加速键”

用友BIP

时序数据库

13 | 线性排序:如何根据年龄给100万用户数据排序?

鲁米

简单解压缩工具Keka 激活最新中文版+使用方法

胖墩儿不胖y

Mac软件 解压缩软件 解压缩工具

台灣用友×新漢智能出席兩岸企業家峰會,探訪新格局下兩岸資訊產融合發展新機遇

用友BIP

为 3D 模型制作纹理的 9 种最佳方法

3D建模设计

材质 纹理 贴图 3D模型纹理贴图

带你玩转 Vite + Vue3 高低版本常用玩法 | 京东云技术团队

京东科技开发者

Vue 前端 vite

AI数字人在抖音开播教程!

青否数字人

数字人

岳阳楼3D模型纹理贴图

3D建模设计

材质贴图 纹理贴图 材质纹理 GLTF材质编辑

扫盲Kafka?看这一篇就够了! | 京东云技术团队

京东科技开发者

kafka 消息队列 kafka架构

Flink State 状态原理解析 | 京东物流技术团队

京东科技开发者

flink 实战 state Flink State

淘宝/天猫商品详情 API 的技术架构是怎样的?

技术冰糖葫芦

API 开发

WebSocket 连接:完全指南及高效实现方法

Apifox

程序员 前端 Web 网络编程 websocket

LED屏幕在指挥中心的解决方案

Dylan

LED显示屏 led显示屏厂家 户内led显示屏

kubeadm 源码分析_文化 & 方法_才云科技_InfoQ精选文章