前言

  2021年开始第4个月了,因为工作过于忙碌的缘故很久没有开始文章的写作。其实始终以来我集体把写文章这件事,当作推动本人学习成长的一种形式。

  这篇文章是kubernetes源码剖析的第一个主题,后续会陆续更新。大抵的大纲为client-go、控制器、调度器、自定义控制器、operator、网络几个方面。

  当操作资源与apiserver进行通信时,平时都是间接编写YAML资源文件,通过kubectl来提交创立对应等资源对象,那么它到底是怎么将YAML转换成对应等API进行通信?

Kubernetes版本:v1.8.5

源码地址:https://github.com/kubernetes/

1.apiserver介绍

  k8s通过kube-apiserver组件提供API Server性能,API Server性能提供对k8s各类资源对象的减少改查,例如pod、rc、Service等HTTP Rest接口。

1.1 API版本介绍

  理解api版本之前,首先要理解api的申明。Kubernetes在不同的API门路反对多个API版本,例如/api/v1或者/apis/batch。版本可分为:

  • Alpha版本:例如 v1alpha1、v1alpha3示意该版本,默认状况下是被禁用的,能够随时删除对性能的反对,要慎用。
  • Beta版本: 例如v1beta1、v2beta1、v2beta2示意该版本,默认状况下是启用的,示意代码曾经测试通过,然而对象的语义可能随后版本中不兼容。
  • 稳固版本: 例如v1示意稳定版,也会呈现在后续版本中。

1.2 API门路介绍

  在理解api版本信息后,能够一起来理解下Kubernetes API Server门路之间的关系。

<center>图1-1 查看接口门路</center>
通过如下命令能够查看api接口门路,如图1-1所示:

#kubectl get --raw /

除了通过以上命令能够看到api接口门路以外,还能够应用proxy进行代理,通过接口方式进行拜访。

#kubectl proxyStarting to serve on 127.0.0.1:8001

  代理后间接能够关上http://localhost:8001/查看接...

  通过查看门路后,能够把门路做一个性能上的细分,通过图1-2能够看出API的门路构造。

<center>图1-2 门路解析</center>
  本质上在Kubernetes 集群中,一个API对象在Etcd中的残缺资源门路,是由Group(API组)、Version(API组)和Resource(API资源类型)三个局部组成的。

  Kubernetes API 反对通过规范 HTTP:GET、 POST、PUT 和 DELETE 在指定 PATH 门路上创立、更新、删除和检索操作,并应用 JSON作为默认的数据交互格局。

2.解析YAML与apiserver之间的关系

  通过第1节中,理解到api的分层,版本关系。那么接下来一起理解下YAML和apiserver之间的关系。

2.1 编写一个简略的yaml文件

  比方当初要创立一个nginx1.7.9的pod,那么能够编写一个编排的YAML。创立一个Deployment对象,那么能够这么写:

apiVersion: apps/v1kind: Deploymentmetadata:  name: nginx-deploymentspec:  selector:    matchLabels:      app: nginx  replicas: 2  template:    metadata:      labels:        app: nginx    spec:      containers:      - name: nginx        image: nginx:1.7.9        ports:        - containerPort: 80
  • apiVersion: api的分组及版本,例如 “apps/v1” ,apps对应分组,v1对应版本。
  • kind: 对象资源类型,这里有Job、Service等,也能够自定义资源。 而资源Resource通常是小写复数,例如“Deployment”则是“deployments”。
  • metadata·name: 对应名称
  • spec·replicas: 启动pod对应的个数。
  • spec·template·containers·image: 拉取镜像地址。
  • spec·template·containers·name: pod对应名称。
  • spec·template·containers·ports: pod对应端口。

2.2 解析kubectl与apiserver的关系

  kubectl其实就是一个和kubernetes apiserver交互的一个命令行工具。通常状况通过YAML对pod进行编排,或者通过YAML创立资源时,能够通过kubectl进行交互。命令如下:

#kubectl apply -f nginx.yaml


<center>图2-1 通过kubectl创立deployment</center>
  如果要通过kubectl创立一个deployment,kubectl会发动对apiserver调用。会发动三个接口如图2-1所示。/openapi/v2发动对apiserver的认证,认证之后会调用/apis/apps/v1/namespaces/default/deployments/nginx-deployment 接口,接口的对应关系,如图2-2。

<center>图2-2 查看资源对象接口</center>
  调用资源接口获取资源信息的目录是为了对YAML文件进行比拟,如果没有创立资源对象则会调用创立资源对象接口进行创立。如果曾经创立资源对象,并且YAML有变更,则走更新流程。


<center>图2-3 创立资源对象接口</center>
  创立资源对象接口会创立对应到资源对应,这外面其实对应了2.1 大节中的内容。apiVersion是“apps/v1” 对应接口分组与版本,kind为“Deployment”对应“deployments”。

3.源码调试

  要调试源码之前首先要下载源代码,下载源代码能够通过git clone进行下载。然而因为git clone的地址是“github.com”,在国内拜访github比较慢。能够应用镜像地址进行下载,其实就是把“github.com”更换为“github.com.cnpmjs.org”,命令如下:

下载kubernetes#git clone https://github.com.cnpmjs.org/kubernetes/切换到对应版本#cd kubernetes#git checkout v1.8.5    

3.1 kubernetes源码构造介绍

  下载源码后,能够进入源码目录。能够通过tree看一下源码构造:

localhost:kubernetes edz$ tree . -L 1.├── BUILD.bazel -> build/root/BUILD.root├── CHANGELOG├── CHANGELOG.md -> CHANGELOG/README.md├── CONTRIBUTING.md├── Godeps├── LICENSE├── Makefile -> build/root/Makefile├── Makefile.generated_files -> build/root/Makefile.generated_files├── OWNERS├── OWNERS_ALIASES├── README.md├── SECURITY_CONTACTS├── SUPPORT.md├── WORKSPACE -> build/root/WORKSPACE├── _output├── api├── build├── cluster├── cmd├── code-of-conduct.md├── docs├── go.mod├── go.sum├── hack├── logo├── pkg├── plugin├── staging├── test├── third_party├── translations└── vendor

k8s源码自身是一个很大的我的项目,能够来看看对应源码目录构造的一些用处:

目录名介绍
build编译脚本目录
CHANGELOG变更记录文档
cmd对应命令行管理工具,例如kubeadm、kubectl、kubelet等
staging曾经分库的我的项目
pkg各种性能包的实现代码
vendor依赖包

3.2 配置IDE

  在这里IDE抉择Goland,如果要配置调试kubectl能够配置如图3-1所示:

<center>图3-1 配置goland</center>
  调试kubectl比较简单,图中“Program argyments”执行kubectl 对应的参数。理论命令如下:

 kubectl apply -f /Users/edz/Desktop/kubernetes/nginx.yaml

3.3 调试

  如果要调试kubectl能够在cmd/kubectl/kubectl.go中下断点,比方针对“command := cmd.NewDefaultKubectlCommand()”进行一个断点,如图3-2所示。

<center>图3-2 kubectl调试</center>
  cmd.NewDefaultKubectlCommand其实Cobra对应的函数,Kubernetes源码中cmd下都是调用Cobra对命令行参数进行解析。

  如果要调试调用什么接口,其实最简略就是针对golang自带的net库net/http/request.go中NewRequest办法进行下断点。这样就能够获取执行kubectl的所有过程,较为简单。

<center>图3-3 net调试</center>

总结

  1. kubectl与apiserver的治理,kubectl是封装apiserver对Kubernetes进行治理的一个工具。
  2. 能够通过“github.com.cnpmjs.org”对github拉取代码进行减速。
  3. apiserver分为Alpha版本、Beta版本、稳定版三个版本。