以下大部分来自于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

主要有以下三个作用

  1. Provide an API for registering API servers.
  2. Summarize discovery information from all the servers.
  3. Proxy client requests to individual servers.

注册一个apiserver的大致流程

  1. setup extension apiserver

    • run as a Deployment
    • register with the core apiserver using an apiregistration.k8s.io/v1beta1/APIService
  2. setup etcd storage for the extension apiserver
    • run as StatefulSet or etcd operator
  3. 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

自定义的三种方式:

  1. 其实是通过kube-scheduler的--policy-config-file flag来配置, 参见这里
  2. 直接配置一个新的scheduler,与kube-scheuler并排执行, 通过pod启动时的spec.schedulerName来选择scheduler。参见这里
  3. schduler extender, 在kube-schduler调用结果之后调用附加的webhook,使用方式就是在上面kube-scheduler的--policy-config-file flag的配置文件中增加一个extender字段来配置extender。参见这里

Infrastructure Extensions

基础设施层的扩展大多数都已经称为规范,由于涉及较多,此处不做讨论

kubernetes extension point的更多相关文章

  1. k8s API sample

    Declarative API k8s: cluster-api Introduction to Kubernetes Cluster-API Project Declarative Manageme ...

  2. Kubernetes 设计概要

    英文原文:Kubernetes Design Overview Overview Kubernetes builds on top of Docker to construct a clustered ...

  3. kubernetes实现用户自定义扩缩容

    本文章主要参考walkthrough,aggregation和auth.涉及custom metric API的注册认证以及API server aggregation的相关知识.walkthroug ...

  4. 在 Azure 上部署 Kubernetes 集群

    在实验.演示的时候,或者是生产过程中,我经常会需要运行一些 Docker 负载.虽然这在本地计算机上十分容易,但是当你要在云端运行的时候就有点困难了.相比于本地运行,在云端运行真的太复杂了.我尝试了几 ...

  5. 基于Kubernetes构建企业容器云

    前言 团队成员有DBA.运维.Python开发,由于需要跨部门向公司私有云团队申请虚拟机, 此时我在思考能否在现有已申请的虚拟机之上,再进行更加细粒度的资源隔离和划分,让本团队的成员使用, 也就是在私 ...

  6. Kubernetes 持续集成 SpringCloud

    写在开始之前,在开始之前我们需要了解几个概念: 1.什么是持续集成? 持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成.每次 ...

  7. 搞定 Kubernetes 基于flannel 的集群网络

    .Docker网络模式 在讨论Kubernetes网络之前,让我们先来看一下Docker网络.Docker采用插件化的网络模式,默认提供bridge.host.none.overlay.maclan和 ...

  8. Kubernetes学习之路(十五)之Ingress和Ingress Controller

    目录 一.什么是Ingress? 1.Pod 漂移问题 2.端口管理问题 3.域名分配及动态更新问题 二.如何创建Ingress资源 三.Ingress资源类型 1.单Service资源型Ingres ...

  9. 容器,Docker, Kubernetes和Kyma,以及Kyma对SAP的意义

    大家好,今天非常高兴能给大家做一个关于Kyma的技术分享.这个session的audience主要是针对使用咱们成都研究院使用Java和nodejs等技术栈做微服务开发的同事们.对于在ABAP net ...

随机推荐

  1. 2018-2019-2 20165330《网络对抗技术》Exp1 PC平台逆向破解

    目录 实验目标 实验内容 知识点描述 实验步骤 实验过程中遇到的问题 实验感想 实验目标 本次实验的对象是一个名为pwn1的linux可执行文件. -该程序正常执行流程是:main调用foo函数,fo ...

  2. CodeForces - 156B Suspects 逻辑 线性 想法 题

    题意:有1~N,n(1e5)个嫌疑人,有m个人说真话,每个人的陈述都形如X是凶手,或X不是凶手.现在给出n,m及n个陈述(以+x/-X表示)要求输出每个人说的话是true ,false or notd ...

  3. Thymeleaf模板引擎的初步使用

    在springboot中,推荐使用的模板引擎是Thymeleaf模板引擎,它提供了完美的Spring MVC的支持.下面就简单的介绍一下Thymeleaf模板引擎的使用. 在controller层中, ...

  4. IDEA的快捷键和相关设置

      快捷键 Shift + Shift: 查找一切 Alt + /: 代码提示(需要修改) Ctrl + Alt + F12: 打开文件所在磁盘位置 Alt + F12: 打开终端 Alt + Ins ...

  5. (3.10)mysql基础深入——mysqld 服务器与客户端连接过程 源码分析【待写】

    (3.10)mysql基础深入——mysqld 服务器与客户端连接过程 源码分析[待写]

  6. laravel教程入门笔记

    安装laravel框架 1.安装命令 composer create-project --prefer-dist laravel/laravel ytkah ytkah表示文件夹名,如果不写的话自动会 ...

  7. 走进C++程序世界------IO标准库介绍

    流概述    流是C++标准的组成部分,流的主要目标是,将从磁盘读取文件或将输入写入控制台屏幕的问题封装起来,创建流后程序猿就能够使用它.流将负责处理全部的细节. IO类库 在C++输入、输出操作是通 ...

  8. Codeforces Round #247 (Div. 2) D. Random Task

    D. Random Task time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  9. 学JS必看-JavaScript数据结构深度剖析

    回归简单 要理解JavaScript,你得首先放下对象和类的概念,回到数据和代码的本原.前面说过,编程世界只有数据和代码两种基本元素,而这两种元素又有着纠缠不清的关系.JavaScript就是把数据和 ...

  10. Kylin安装问题--/home/hadoop-2.5.1/contrib/capacity-scheduler/.jar (No such file or directory)

    WARNING: Failed to process JAR [jar:file:/home/hadoop-2.5.1/contrib/capacity-scheduler/.jar!/] for T ...