【kubernetes源码分析】解析apiserver资源类型(一)

前言

  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路径之间的关系。
【kubernetes源码分析】解析apiserver资源类型(一)_第1张图片

图1-1 查看接口路径

通过如下命令可以查看api接口路径,如图1-1所示:

#kubectl get --raw /

除了通过以上命令可以看到api接口路径以外,还可以使用proxy进行代理,通过接口方式进行访问。

#kubectl proxy
Starting to serve on 127.0.0.1:8001

  代理后直接可以打开http://localhost:8001/查看接...

  通过查看路径后,可以把路径做一个功能上的细分,通过图1-2可以看出API的路径结构。
【kubernetes源码分析】解析apiserver资源类型(一)_第2张图片

图1-2 路径解析

  实质上在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/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  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

【kubernetes源码分析】解析apiserver资源类型(一)_第3张图片

图2-1 通过kubectl创建deployment

  如果要通过kubectl创建一个deployment,kubectl会发起对apiserver调用。会发起三个接口如图2-1所示。/openapi/v2发起对apiserver的认证,认证之后会调用/apis/apps/v1/namespaces/default/deployments/nginx-deployment 接口,接口的对应关系,如图2-2。
【kubernetes源码分析】解析apiserver资源类型(一)_第4张图片
图2-2 查看资源对象接口

  调用资源接口获取资源信息的目录是为了对YAML文件进行比较,如果没有创建资源对象则会调用创建资源对象接口进行创建。如果已经创建资源对象,并且YAML有变更,则走更新流程。

【kubernetes源码分析】解析apiserver资源类型(一)_第5张图片

图2-3 创建资源对象接口

  创建资源对象接口会创建对应到资源对应,这里面其实对应了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所示:
【kubernetes源码分析】解析apiserver资源类型(一)_第6张图片

图3-1 配置goland

  调试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所示。
【kubernetes源码分析】解析apiserver资源类型(一)_第7张图片

图3-2 kubectl调试

  cmd.NewDefaultKubectlCommand其实Cobra对应的函数,Kubernetes源码中cmd下都是调用Cobra对命令行参数进行解析。

  如果要调试调用什么接口,其实最简单就是针对golang自带的net库net/http/request.go中NewRequest方法进行下断点。这样就可以获取执行kubectl的所有过程,较为简单。
【kubernetes源码分析】解析apiserver资源类型(一)_第8张图片

图3-3 net调试

总结

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

你可能感兴趣的:(kubernetes)