动手动脑学Kubernetes系列教程之APIServer

查理谈科技 2024-05-11 03:39:05

在之前的文章中, 介绍了搭建好的#minikube#环境,如果你现在还没有一个可用的minikube环境, 那么可以去中直接下载;

在之前的文章中, 先后介绍了如何从源代码开始构建一个Node.js应用和Spring Boot 应用, 并且部署到Kubernetes 中(这个Kubernetes 环境主要是之前建好的#minikube#) , 现在我们开始进一步深入的学习Kubernetes, 用一个个可以实际运行的例子的形式, 深入理解#Kubernetes#的概念以及原理.

在#动手动脑学Kubernetes#系列教程中, 我们展示了Kubernetes的基本用法

在里, 学习了#Pod#的基本知识;

在里, 学习了标签(#Label#)的语法, 使用Label来选择和过滤Kubernetes 资源;

在里, 介绍了#Deployment#的使用, 介绍了Deployment与Replica Set、Pod的关系, 并展示了如何进行应用的版本回滚;

在里, 介绍了#Service#的使用,使用Replication Controller创建Pod, 并创建Service, 展示了从Service 调用应用的方法; 随后又展示了扩展 Pod的数量为2, 比较了Service和之前的不同, 基本展示了Cluster IP 类型的Service的基本用法.

在里, 介绍了#Namespace#的使用, 除了创建,列出系统的Namespace之外, 还说明Namespace 如何对资源进行隔离, 建立Development, Staging, Production等环境的方法.

在里, 介绍了#Service Discovery#的使用, 讲解了如何检查Kube-dns, 如何检查和使用Service的FQDN等知识, 对Kubernetes的DNS 系统有整体的理解.

在里, 介绍了#Port Forwards#, #端口转发#的用法, 在本地程序开发的时候, 使用端口转发可以简化本地测试的工作, 同时介绍了其他几种本地端口转发的用法.

在里, 介绍了#Probe#(#探针#)的知识, 介绍了livenessProbe 和readinessProbe的用法,同时介绍了Pod 容器中的几个状态变化, 以及2个容器生命周期回调接口.

在里, 介绍了#环境变量#的用法, 使用环境变量可以把Pod 定义的信息传递给运行其中的镜像.

在里, 我们介绍了#Volume#, 卷的用法, 主要展示了emptyDir卷的使用, emptyDir卷的生命周期是和Pod 生命周期同步的.

在里, 我们介绍了#Persistent Volume#, 也就是持久卷的用法,展示了当数据存入到PV 之后,数据超乎Pod 生命周期之外的情况.

在里, 介绍了#Secret#, 也就是机密信息的用法, 机密是绑定在命名空间里的, 在使用时候和Volume的用法一样, 可以被Pod 访问, 本篇展示了Opaque类型的Secret的用法.

在里, 介绍了日志(#logging#)的使用, 介绍了Kubernetes中基本日志记录的查看和常用的命令行参数,在理论部分展示了其他几种logging的使用.

在里, 介绍了#Job#, 也就是作业的使用, 介绍了Kubernetes中最基本的、非并行性的一次性运行的作业, 同时介绍了作业的基本概念和基本用法.

在里, 介绍了#Init 容器#概念和用法, 同时讲解了init 容器的启动过程和对资源的要求.

在第十六篇里, 我们来学习#API Server#概念, 继续来学习吧!

大部分情况下, 作为程序员是不太需要了解太多的API Server; 但是出于探索或测试目的,了解一下怎么样直接访问Kubernetes API服务器, 也是有必要的, 今天来简单了解下API Server 究竟包含哪些.

访问API Server

首先,使用以下方法将API代理到您的本地环境:

[vagrant@control-plane ~]$ kubectl proxy --port=8080Starting to serve on 127.0.0.1:8080

下面来访问一下, 先来看看浏览器的表现吧:

除了使用kubectl proxy 之外, 还可以使用kubectl get 来请求某个api 信息, 例如查看版本信息, 使用下面的语句:

$ kubectl get --raw /version{ "major": "1", "minor": "20", "gitVersion": "v1.20.2", "gitCommit": "faecb196815e248d3ecfb03c680a4507229c2a56", "gitTreeState": "clean", "buildDate": "2021-01-13T13:20:00Z", "goVersion": "go1.15.5", "compiler": "gc", "platform": "linux/amd64"

除此之外, 用kubectl api-versions, 还可以了解当前Kubernetes 环境支持的API 版本, 例如现在的版本中, 都支持v1以及v1beta1两个版本:

$ kubectl api-versionsadmissionregistration.k8s.io/v1admissionregistration.k8s.io/v1beta1apiextensions.k8s.io/v1apiextensions.k8s.io/v1beta1apiregistration.k8s.io/v1apiregistration.k8s.io/v1beta1apps/v1authentication.k8s.io/v1authentication.k8s.io/v1beta1authorization.k8s.io/v1authorization.k8s.io/v1beta1autoscaling/v1autoscaling/v2beta1autoscaling/v2beta2batch/v1batch/v1beta1certificates.k8s.io/v1certificates.k8s.io/v1beta1coordination.k8s.io/v1coordination.k8s.io/v1beta1discovery.k8s.io/v1beta1events.k8s.io/v1events.k8s.io/v1beta1extensions/v1beta1flowcontrol.apiserver.k8s.io/v1beta1networking.k8s.io/v1networking.k8s.io/v1beta1node.k8s.io/v1node.k8s.io/v1beta1policy/v1beta1rbac.authorization.k8s.io/v1rbac.authorization.k8s.io/v1beta1scheduling.k8s.io/v1scheduling.k8s.io/v1beta1storage.k8s.io/v1storage.k8s.io/v1beta1v1

这里需要注意的是, 这个kubectl api-versions, 返回的信息,实际上是我们在浏览器中看到的/apis部分的返回, 而且每个api对象都会有v1和v1beta1两个版本:

另外, 我们之前还介绍过一个kubectl api-resources, 这个命令可以返回api 对应的资源对象, 以及资源的缩写信息:

$ kubectl api-resourcesNAME SHORTNAMES APIVERSION NAMESPACED KINDbindings v1 true Bindingcomponentstatuses cs v1 false ComponentStatusconfigmaps cm v1 true ConfigMapendpoints ep v1 true Endpointsevents ev v1 true Eventlimitranges limits v1 true LimitRangenamespaces ns v1 false Namespacenodes no v1 false Nodepersistentvolumeclaims pvc v1 true PersistentVolumeClaimpersistentvolumes pv v1 false PersistentVolumepods po v1 true Podpodtemplates v1 true PodTemplatereplicationcontrollers rc v1 true ReplicationControllerresourcequotas quota v1 true ResourceQuotasecrets v1 true Secret...

好了, 关于怎么访问API Server, 就讲解到这里, 下面来看看API的具体信息.

什么是API Server

Kubernetes 控制面 的核心是 API 服务器。 API 服务器负责提供 HTTP API,以供用户、集群中的不同部分和集群外部组件相互通信。

Kubernetes API 使你可以查询和操纵 Kubernetes API 中对象(例如:Pod、Namespace、ConfigMap 和 Event)的状态。

大部分操作都可以通过 kubectl 命令行接口或 类似 kubeadm 这类命令行工具来执行, 这些工具在背后也是调用 API。不过,你也可以使用 REST 调用来访问这些 API。

如果你正在编写程序来访问 Kubernetes API,可以考虑使用 客户端库, Kubernetes 几乎为每种有影响力的语言都提供了对应的库文件以方便调用, 你可以在应用程序中使用库文件来直接访问API Server, 这在某些情况下是有用的.

Kubernetes 为 API 实现了一种基于 Protobuf 的序列化格式,主要用于集群内部通信。

查看API Server的返回信息

首先, 来看看整体的json 数据, 注意这里包含了所有的返回, 信息很多, 适合快速浏览, 过一遍即可.

{ "paths": [ "/.well-known/openid-configuration", "/api", "/api/v1", "/apis", "/apis/", "/apis/admissionregistration.k8s.io", "/apis/admissionregistration.k8s.io/v1", "/apis/admissionregistration.k8s.io/v1beta1", "/apis/apiextensions.k8s.io", "/apis/apiextensions.k8s.io/v1", "/apis/apiextensions.k8s.io/v1beta1", "/apis/apiregistration.k8s.io", "/apis/apiregistration.k8s.io/v1", "/apis/apiregistration.k8s.io/v1beta1", "/apis/apps", "/apis/apps/v1", "/apis/authentication.k8s.io", "/apis/authentication.k8s.io/v1", "/apis/authentication.k8s.io/v1beta1", "/apis/authorization.k8s.io", "/apis/authorization.k8s.io/v1", "/apis/authorization.k8s.io/v1beta1", "/apis/autoscaling", "/apis/autoscaling/v1", "/apis/autoscaling/v2beta1", "/apis/autoscaling/v2beta2", "/apis/batch", "/apis/batch/v1", "/apis/batch/v1beta1", "/apis/certificates.k8s.io", "/apis/certificates.k8s.io/v1", "/apis/certificates.k8s.io/v1beta1", "/apis/coordination.k8s.io", "/apis/coordination.k8s.io/v1", "/apis/coordination.k8s.io/v1beta1", "/apis/discovery.k8s.io", "/apis/discovery.k8s.io/v1beta1", "/apis/events.k8s.io", "/apis/events.k8s.io/v1", "/apis/events.k8s.io/v1beta1", "/apis/extensions", "/apis/extensions/v1beta1", "/apis/flowcontrol.apiserver.k8s.io", "/apis/flowcontrol.apiserver.k8s.io/v1beta1", "/apis/networking.k8s.io", "/apis/networking.k8s.io/v1", "/apis/networking.k8s.io/v1beta1", "/apis/node.k8s.io", "/apis/node.k8s.io/v1", "/apis/node.k8s.io/v1beta1", "/apis/policy", "/apis/policy/v1beta1", "/apis/rbac.authorization.k8s.io", "/apis/rbac.authorization.k8s.io/v1", "/apis/rbac.authorization.k8s.io/v1beta1", "/apis/scheduling.k8s.io", "/apis/scheduling.k8s.io/v1", "/apis/scheduling.k8s.io/v1beta1", "/apis/storage.k8s.io", "/apis/storage.k8s.io/v1", "/apis/storage.k8s.io/v1beta1", "/healthz", "/healthz/autoregister-completion", "/healthz/etcd", "/healthz/log", "/healthz/ping", "/healthz/poststarthook/aggregator-reload-proxy-client-cert", "/healthz/poststarthook/apiservice-openapi-controller", "/healthz/poststarthook/apiservice-registration-controller", "/healthz/poststarthook/apiservice-status-available-controller", "/healthz/poststarthook/bootstrap-controller", "/healthz/poststarthook/crd-informer-synced", "/healthz/poststarthook/generic-apiserver-start-informers", "/healthz/poststarthook/kube-apiserver-autoregistration", "/healthz/poststarthook/priority-and-fairness-config-consumer", "/healthz/poststarthook/priority-and-fairness-config-producer", "/healthz/poststarthook/priority-and-fairness-filter", "/healthz/poststarthook/rbac/bootstrap-roles", "/healthz/poststarthook/scheduling/bootstrap-system-priority-classes", "/healthz/poststarthook/start-apiextensions-controllers", "/healthz/poststarthook/start-apiextensions-informers", "/healthz/poststarthook/start-cluster-authentication-info-controller", "/healthz/poststarthook/start-kube-aggregator-informers", "/healthz/poststarthook/start-kube-apiserver-admission-initializer", "/livez", "/livez/autoregister-completion", "/livez/etcd", "/livez/log", "/livez/ping", "/livez/poststarthook/aggregator-reload-proxy-client-cert", "/livez/poststarthook/apiservice-openapi-controller", "/livez/poststarthook/apiservice-registration-controller", "/livez/poststarthook/apiservice-status-available-controller", "/livez/poststarthook/bootstrap-controller", "/livez/poststarthook/crd-informer-synced", "/livez/poststarthook/generic-apiserver-start-informers", "/livez/poststarthook/kube-apiserver-autoregistration", "/livez/poststarthook/priority-and-fairness-config-consumer", "/livez/poststarthook/priority-and-fairness-config-producer", "/livez/poststarthook/priority-and-fairness-filter", "/livez/poststarthook/rbac/bootstrap-roles", "/livez/poststarthook/scheduling/bootstrap-system-priority-classes", "/livez/poststarthook/start-apiextensions-controllers", "/livez/poststarthook/start-apiextensions-informers", "/livez/poststarthook/start-cluster-authentication-info-controller", "/livez/poststarthook/start-kube-aggregator-informers", "/livez/poststarthook/start-kube-apiserver-admission-initializer", "/logs", "/metrics", "/openapi/v2", "/openid/v1/jwks", "/readyz", "/readyz/autoregister-completion", "/readyz/etcd", "/readyz/informer-sync", "/readyz/log", "/readyz/ping", "/readyz/poststarthook/aggregator-reload-proxy-client-cert", "/readyz/poststarthook/apiservice-openapi-controller", "/readyz/poststarthook/apiservice-registration-controller", "/readyz/poststarthook/apiservice-status-available-controller", "/readyz/poststarthook/bootstrap-controller", "/readyz/poststarthook/crd-informer-synced", "/readyz/poststarthook/generic-apiserver-start-informers", "/readyz/poststarthook/kube-apiserver-autoregistration", "/readyz/poststarthook/priority-and-fairness-config-consumer", "/readyz/poststarthook/priority-and-fairness-config-producer", "/readyz/poststarthook/priority-and-fairness-filter", "/readyz/poststarthook/rbac/bootstrap-roles", "/readyz/poststarthook/scheduling/bootstrap-system-priority-classes", "/readyz/poststarthook/start-apiextensions-controllers", "/readyz/poststarthook/start-apiextensions-informers", "/readyz/poststarthook/start-cluster-authentication-info-controller", "/readyz/poststarthook/start-kube-aggregator-informers", "/readyz/poststarthook/start-kube-apiserver-admission-initializer", "/readyz/shutdown", "/version" ]}

这个返回的json 文件有点长, 可以看下面归纳的节点图:

可以看出, API Server 返回的内容主要可以分为四个部分, 分别是:

API 组和版本--apis部分

这一部分实际上就是kubectl api-resources 返回的内容, 在类别上属于APIGroupList, API 组. API Group, API 组是什么概念呢?

API 组

原来是为了更好地对API 资源进行管理和扩展而形成的一个概念. 我们知道, 在Kubernetes中, 一切都是API, 都可以找到API 相应的定义, API Server 也是Kubernetes中最为重要的一个组成部分之一; 那么, 对这么多API 怎么进行有效的管理呢? 答案就在对API 进行分组, 实现模块化和版本化, 同时便于扩展.首先, API Group分为两类, 第一类是核心组core, 核心组的访问路径和其他的组不同, 直接以/api/v1/路径访问, 这也是我们一般情况下访问的REST API, 直接访问就会得到具体的API 资源列表, 例如输入/api/v1/namespaces 会返回所有的命名空间.

而core 之外的其他资源组, 使用四层描述结构, 如下图所示.

当我们第一次访问/apis目录时, 返回APIGroupList这个API对象, 这是整个API体系的第一层.这个API 对象中包含所有的API Group的名称以及支持的版本.

然后第二层就是API Group, 访问的路径这时就要加上<apigroupname>/<version>, 在这一层里面, 定义了所有的API Group, 这些API Group 列表中会包含包含的API Resource 列表.

在第三层里, 包含的是API Resource 列表, 这里的结果, 就和我们平时使用的kubectl get <resource> 的结果一样, 会显示对应的资源列表,注意 , 这是一个数组, 数组里面的每一个资源信息都会按照资源模板的格式显示.

例如以大家熟悉的API 资源, Deployment 为例, 当我们访问/apis/apps/v1/deployments/时候, 就会得到如图3 一样的结果, 而这个就和kubectl get deployments 是一样的.

第四层就是具体的API 资源了, 当我们使用工具来解析第三层的返回结果的时候, 就会得到一个个具体的资源名称了.

版本

为了简化删除字段或者重构资源表示等工作,Kubernetes 支持多个 API 版本, 每一个版本都在不同 API 路径下,例如 /api/v1 或 /apis/rbac.authorization.k8s.io/v1alpha1。

版本化是在 API 级别而不是在资源或字段级别进行的,目的是为了确保 API 为系统资源和行为提供清晰、一致的视图,并能够控制对已废止的和/或实验性 API 的访问。

为了便于演化和扩展其 API,Kubernetes 实现了 可被启用或禁用的 API 组。

API 资源之间靠 API 组、资源类型、名字空间(对于名字空间作用域的资源而言)和 名字来相互区分。API 服务器可能通过多个 API 版本来向外提供相同的下层数据, 并透明地完成不同 API 版本之间的转换。所有这些不同的版本实际上都是同一资源 的(不同)表现形式。例如,假定同一资源有 v1 和 v1beta1 版本, 使用 v1beta1 创建的对象则可以使用 v1beta1 或者 v1 版本来读取、更改 或者删除。

健康检查API--healthz, livez 和readyz

在API Server的剩下部分中, 能看到有着非常多节点的三个部分, 分别是healthz, livez和readz, 这三个有着什么作用呢?

原来, Kubernetes API 服务器提供 3 个 API 端点(healthz、livez 和 readyz)来表明 API 服务器的当前状态。 healthz 端点已被弃用(自 Kubernetes v1.16 起),我们应该使用更为明确的livez 和 readyz 这两个端点。

livez 端点, 存活断端点, 用来返回资源是否存活(liveness), 使用这个可以访问当前Kubernetes中的资源的存活情况,例如访问/livez?verbose, 就会得到如下结果:

这和我们使用命令行kubectl get --raw='/readyz?verbose' 效果是一样的.

readyz, 用来指明资源是否已经就绪(readiness), 如访问/readyz?verbose, 就会得到当前资源是否已经就绪.

其他的一些API, 例如metrics, 就是指示系统的各项参数的情况, 因为从名字就可以看出作用, 这里就不再详细讲述.

总结

今天学习了查看API Server, 以及讲解了API server 返回的API组和版本, REST API, 以及健康检查API, 对API Server 有了初步的理解.

-----------------------------红粉与面具-----------------------------

0 阅读:0

查理谈科技

简介:感谢大家的关注