kubernetes extension point
以下大部分来自于k8s document, 笔者只是总结归纳, 解释不足的地方请参阅相关文档
Intention
Non-sustainable way to customize Kubernetes
- Fork & Sending PRs to upstream
- without extensibility...
- 增加k8s维护团队负担
- 可能脱离k8s规范
Extension Patterns
webhook 通过http post一个请求,然后通过远程的server来决策, plugin是通过调用一个二进制可执行程序来决策, controller是实现资源自动化的一种方式,通过声明式的资源定义,定义一个资源的期望状态,然后controller不断获取实际状态进行状态转换到达期望状态,所以他会不断地读取api-server的信息, 系统中内置的kube-controller-manager就包含许多这样的controller。
Extension Points
kubectl plugin
可以实现kubectl自定义的命令 ,在k8s v1.10为alpha version
Plugin loader会在 Search order 中依次查找以下plugin.yaml及其对应的binary, plugin.yaml 对自定义命令进行声明,binary实现具体的程序逻辑。
API Access Extensions
Webhook Token Authentication
让外部的webhook server来决策是否允许该请求通过认证。
--authentication-token-webhook-config-file flag指定配置文件, 配置文件的格式如kubeconfig形式
# clusters refers to the remote service.
clusters:
- name: name-of-remote-authn-service
cluster:
certificate-authority: /path/to/ca.pem # CA for verifying the remote service.
server: https://authn.example.com/authenticate # URL of remote service to query. Must use 'https'.
# users refers to the API server's webhook configuration.
users:
- name: name-of-api-server
user:
client-certificate: /path/to/cert.pem # cert for the webhook plugin to use
client-key: /path/to/key.pem # key matching the cert
# kubeconfig files require a context. Provide one for the API server.
current-context: webhook
contexts:
- context:
cluster: name-of-remote-authn-service
user: name-of-api-sever
name: webhook
当api-server收到上述请求之后会POST一个 authentication.k8s.io/v1beta1 TokenReview对象给webhook, 服务器会返回对应的状态和用户信息,形如:
{
"apiVersion": "authentication.k8s.io/v1beta1",
"kind": "TokenReview",
"spec": {
"token": "(BEARERTOKEN)"
}
}
{
"apiVersion": "authentication.k8s.io/v1beta1",
"kind": "TokenReview",
"status": {
"authenticated": true,
"user": {
"username": "janedoe@example.com",
"uid": "42",
"groups": [
"developers",
"qa"
],
"extra": {
"extrafield1": [
"extravalue1",
"extravalue2"
]
}
}
}
}
Authenticating Proxy
通过添加一个api-server信任的proxy, 在proxy 这一层进行用户身份认证,通过后proxy 会将用户信息传递给api-server
Authorization Webhook
用户授权的webhook, 工作原理与上述Authentication webhook 大致相同
Admission control
admissoin controller 是编译在api-server中的一系列binary, 通过在api-server的flag中指定执行哪些controller进行插件式的使用,实现资源、权限等的检查和修改。例如resourceQuta, limitRanger, 官方提供的controller必须提前编译进api-server, reload必须重启服务,基于上述不足,k8s提供了不同的扩展方式。
Dynamic Admission Controller
用户提供一个webhook来进行自定义(beta in 1.9), webhook分为MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook。 MutatingAdmissionWebhook执行修改操作,为用户未设置的资源字段提供默认值等, ValidatingAdmissionWebhook 执行一些检查操作,可以拒绝用户的请求来增加额外的准入策略,例如可以控制所有的容器镜像都是来自一个特定的registry, 拒绝来自其他镜像仓库的pod部署 。
使用的时候通过一个config file (--admission-control-config-file)来配置webhook server的地址:
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: <name of this configuration object>
webhooks:
- name: <webhook name, e.g., pod-policy.example.io>
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
resources:
- pods
clientConfig:
service:
namespace: <namespace of the front-end service>
name: <name of the front-end service>
caBundle: <pem encoded ca cert that signs the server cert used by the webhook>
但是会有一些侧面效应,比如改了用户的配置会让用户感到莫名其妙,可能破坏一些自动化contoller的执行逻辑,在将来的版本中会对可更改的字段进行限制。
ref: github example-webhook-admission-controller
PodPreset
可以在pod创建的时候注入一些信息, 例如一些volume mounts, secrets, environment variables 甚至是一个sidecar, podPreset通过匹配lable来判断是否对该pod注入,如果注入失败并不会影响原来pod的正常运行。流程:
- Retrieve all PodPresets available for use.
- Check if the label selectors of any PodPreset matches the labels on the pod being created.
- Attempt to merge the various resources defined by the PodPreset into the Pod being created.
- On error, throw an event documenting the merge error on the pod, and create the pod without any injected resources from the PodPreset.
- Annotate the resulting modified Pod spec to indicate that it has been modified by a PodPreset. The annotation is of the form podpreset.admission.kubernetes.io/podpreset-: "".
如果想要显式拒绝这种注入, 可以定义一个annotataion: podpreset.admission.kubernetes.io/exclude: "true".
下面是podPreset的定义:
apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: allow-database
spec:
selector:
matchLabels:
role: frontend
env:
- name: DB_PORT
value: "6379"
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
Initializers
initializers比上述两者功能都强大,可以对某种类型的资源进行更改, 通过配置InitializerConfiguration 来决定一种资源类型应该被什么initializers处理, 配置文件如下:
apiVersion: admissionregistration.k8s.io/v1alpha1
kind: InitializerConfiguration
metadata:
name: example-config
initializers:
# the name needs to be fully qualified, i.e., containing at least two "."
- name: podimage.example.com
rules:
# apiGroups, apiVersion, resources all support wildcard "*".
# "*" cannot be mixed with non-wildcard.
- apiGroups:
- ""
apiVersions:
- v1
resources:
- pods
一个资源类型可以有多个initializers串行初始化,每种initilizers需要实现对应的controller, controller执行更改或验证操作,然后从metadata.initalizers.pending
list中移除该initializers, 当所有的initializer都被移除之后pod才能被调度到node之上,如果initializers未执行完,则默认无法看到该资源对象。
反过来说,如果一个initialier controller 下线后,该资源类型都无法创建成功。
ref:
ImagePolicyWebhook
通过一个webhook 来判断是否允许拉取指定的镜像
User-Defined Types
在k8s中每一种资源都由group, version, kind三要素来唯一标识, 对于自定义的资源也需要定义这三要素,k8s提供了两种自定义资源的方式,CRD与API Aggregation, CRD是通过K8S CustomResourceDefinition类型将声明的类型添加到k8s中, API Aggregation则提供了一个可以注册自己编写的api-server的方式,让自定义的api-server来提供自定义类型。资源定义只是一种静态的方式,资源的行为的自动化才能为资源提供生命力,而controller就是来实现资源的自动化的方式。
Custom Resource Definitions (CRD)
- Do not require programming
- Easy to deploy: kubectl create -f crd.yaml
- No new point-of-failure
举个栗子: etcd operator, 定义好一个etcd资源后,一键部署,告别复杂配置, controller会将所有的配置负责
官方提供的sample controller 是一个从编写crd到controller很好的例子, 整个流程需要注意的几点:
- CustomResourceDefinition yaml 编写yaml配置文件
- code-gen 使用code generator生成自定义资源的client-go sdk, 来实现controller
- informer 监听api-server资源变化的事件,在相应事件发生的时候进行webhook回调
- controller 添加自动化的程序逻辑
- interagation with others: events, Garbage conllector(ownerReferences) 配置event事件,GC等
- resource management, requests and limit, 像cpu和memory一样可以指定request, 和limit进行资源管理
整个controller的事件循环如下
CoreOS团队开源了一个快速提供controller的工具,可以快速开发出一个controller,值得参考一下
ref: some awesome operators
API Aggregation
- Require coding, built atop k8s.io/apiserver library
- Highly customizable, like adding a new verb, create/delete hooks
- Typed fields, validation, defaults
- Multi-versioning, supporting old clients
- Generated OpenAPI schema
- Supports protobuf
- Supports strategic merge patch
主要有以下三个作用
- Provide an API for registering API servers.
- Summarize discovery information from all the servers.
- Proxy client requests to individual servers.
注册一个apiserver的大致流程
- setup extension apiserver
- run as a Deployment
- register with the core apiserver using an apiregistration.k8s.io/v1beta1/APIService
- setup etcd storage for the extension apiserver
- run as StatefulSet or etcd operator
- setup the extension controller-manager
- run as a Deployment (maybe the same Pod as the extension apiserver)
- configure to talk to the core apiserver (extension APIs are used through core
使用起来较为复杂,官方仓库中的 apiserver library 提供了一些基础模块以及一些api interface, kubernetes-incubator/apiserver-builder 则提供了一个framwork, 可以在其上快速构建一个自己的api-server。
ref: sample api-server
kubernetes-incubator api aggregation
- service catalog (提供了Open service broker API, 可以将外部的服务暴露出来, 使用起来如同pv&pvc)
- metrics-server (官方提供的轻量级的heapster实现,收集node和pod的信息 )
此处整理一下github中关于apiserver的几个项目
- kubernetes/apiserver library为其他api server提供了基础模块,其中kubernetes, Aggregator, service catalog都是使用该库来实现的
- kubernetes/kube-aggregator 是为api server提供聚合功能的组件,可以自定义api server注册到aggerator中
- kubernetes/sample-apiserver是演示apisever library的官方demo
- kubernetes/apiextensions-apiserver 是CRD的实现,This API server provides the implementation for CustomResourceDefinitions which is included as delegate server inside of kube-apiserver.
- kubernetes-incubator/service catalog 是具体使用aggregator机制的一种第三方的api server
- kubernetes-incubator/Apiserver-builder 提供了一个framwork,The Apiserver-builder is a complete framework for generating the apiserver, client libraries, and the installation program.
还有关于metric的几个项目
- kubernetes/metrics Kubernetes metrics API type definitions and clients. 定义了规范, 数据类型, 被heapster, metric server所实现
- kub ernetes-incubator/custom-metrics-apiserver 实现自定义Metric的框架,可以更方便的实现metric规范
- kubernetes-incubator/metrics-server 从1.8开始资源使用的Metric数据可以直接从metricAPI获得,通过kubectl top就可以看到,之前需要部署一个Heapster才可以, 通过metric-server来服务,通过shell脚本安装的话会自动安装该aggregrator,可以用来Horizontal Pod Autoscaler , schedualer 调度,是一个轻量级的内存服务器, 可以代替heapster
- Prometheus Adapter. 非官方项目,但是用的比较多,也是一个自定义Metic实现,同上述metrics-server功能类似,但是可以将prometheus中监控数据暴露给集群使用, 可以使用这些监控数据实现自定义方式的扩缩容和调度。整个自动扩缩容架构如下所示 :
CRD summary
其实CRD, APIServer 本身就是两种类型,分别位于group下: apiextensions.k8s.io/v1beta1 apiregistration.k8s.io/v1,只是这另种resource比较特殊,可以定义其他resource, 与其说是将扩展,不如说是使用了这两种resource,不过重难点在于controller的实现 。
scheduler
kubernetes scheduler component, 首先是predicates 过滤掉不符合的node, 然后priority来选择合适的node
自定义的三种方式:
- 其实是通过kube-scheduler的--policy-config-file flag来配置, 参见这里
- 直接配置一个新的scheduler,与kube-scheuler并排执行, 通过pod启动时的spec.schedulerName来选择scheduler。参见这里
- schduler extender, 在kube-schduler调用结果之后调用附加的webhook,使用方式就是在上面kube-scheduler的--policy-config-file flag的配置文件中增加一个extender字段来配置extender。参见这里
Infrastructure Extensions
基础设施层的扩展大多数都已经称为规范,由于涉及较多,此处不做讨论
kubernetes extension point的更多相关文章
- k8s API sample
Declarative API k8s: cluster-api Introduction to Kubernetes Cluster-API Project Declarative Manageme ...
- Kubernetes 设计概要
英文原文:Kubernetes Design Overview Overview Kubernetes builds on top of Docker to construct a clustered ...
- kubernetes实现用户自定义扩缩容
本文章主要参考walkthrough,aggregation和auth.涉及custom metric API的注册认证以及API server aggregation的相关知识.walkthroug ...
- 在 Azure 上部署 Kubernetes 集群
在实验.演示的时候,或者是生产过程中,我经常会需要运行一些 Docker 负载.虽然这在本地计算机上十分容易,但是当你要在云端运行的时候就有点困难了.相比于本地运行,在云端运行真的太复杂了.我尝试了几 ...
- 基于Kubernetes构建企业容器云
前言 团队成员有DBA.运维.Python开发,由于需要跨部门向公司私有云团队申请虚拟机, 此时我在思考能否在现有已申请的虚拟机之上,再进行更加细粒度的资源隔离和划分,让本团队的成员使用, 也就是在私 ...
- Kubernetes 持续集成 SpringCloud
写在开始之前,在开始之前我们需要了解几个概念: 1.什么是持续集成? 持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成.每次 ...
- 搞定 Kubernetes 基于flannel 的集群网络
.Docker网络模式 在讨论Kubernetes网络之前,让我们先来看一下Docker网络.Docker采用插件化的网络模式,默认提供bridge.host.none.overlay.maclan和 ...
- Kubernetes学习之路(十五)之Ingress和Ingress Controller
目录 一.什么是Ingress? 1.Pod 漂移问题 2.端口管理问题 3.域名分配及动态更新问题 二.如何创建Ingress资源 三.Ingress资源类型 1.单Service资源型Ingres ...
- 容器,Docker, Kubernetes和Kyma,以及Kyma对SAP的意义
大家好,今天非常高兴能给大家做一个关于Kyma的技术分享.这个session的audience主要是针对使用咱们成都研究院使用Java和nodejs等技术栈做微服务开发的同事们.对于在ABAP net ...
随机推荐
- HDU 1222 - Wolf and Rabbit & HDU 1108 - [最大公约数&最小公倍数]
水题,只是想借此记一下gcd函数的模板 #include<cstdio> int gcd(int m,int n){return n?gcd(n,m%n):m;} int main() { ...
- PyCharm安装配置Qt Designer+PyUIC教程
原文写的不错,拿来大家都可以看一下 原文地址:https://www.cnblogs.com/lsdb/p/9121903.html https://www.cnblogs.com/tiankong2 ...
- POJ - 1101 The Game dfs
题意:给你一个地图,上面有一些‘X',给你起点终点,让你输出从起点到终点的路径中转向(改变方向)次数最少的路径,注意,不能穿过别的’X'并且可以超过边界 题解:关于超过边界,只要在外围多加一圈‘ ’. ...
- TortoiseGit的使用
TortoiseGit只是一个外壳而已,它调用的是msysgit,相当于msysgit的windows gui而已,如果喜欢用git命令行,那就不需要安装它. 所以要先安装msysgit(window ...
- flask-WTForms组件
WTForms是一个支持多个web框架的form组件 主要能够帮助我们生成html标签 对数据进行验证 安装 pip install wtforms Wtforms的使用 这里借助一个用户登录注册的示 ...
- Shell初学(四)运算符
一.算术运算符 下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20: 运算符 说明 举例 + 加法 `expr $a + $b` 结果为 30. - 减法 `expr $a - $ ...
- 十天精通CSS3(12)
自由缩放属性resize 为了增强用户体验,CSS3增加了很多新的属性,其中resize就是一个重要的属性,它允许用户通过拖动的方式来修改元素的尺寸来改变元素的大小.到目前为止,可以使用overflo ...
- 详解Linux(centos7)下安装OpenSSL安装图文方法
OpenSSL是一个开源的ssl技术,由于我需要使用php相关功能,需要获取https的文件所以必须安装这个东西了,下面我整理了两种关于OpenSSL安装配置方法. 安装环境: 操作系统:CentO ...
- lambda函数和map函数
lambda函数,简化了函数定义的书写形式,使代码更为简洁,但是使用自定义函数的定义方式更为直观,易理解 g = lambda x:x+1 #上面的lambda表达式相当于下面的自定义函数 def g ...
- System.arraycopy方法详解