以下大部分来自于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. 【转】“菜”鸟理解.NET Framework(CLI,CLS,CTS,CLR,FCL,BCL)

    原文地址:http://www.cnblogs.com/eshizhan/archive/2010/01/26/1657041.html 既然要学.NET,就要先认识认识她,我不喜欢大段大段文字的东西 ...

  2. POJ 1185 - 炮兵阵地 & HDU 4539 - 郑厂长系列故事——排兵布阵 - [状压DP]

    印象中这道题好像我曾经肝过,但是没肝出来,现在肝出来了也挺开心的 题目链接:http://poj.org/problem?id=1185 Time Limit: 2000MS Memory Limit ...

  3. Kettle 4.2源码分析第三讲--Kettle 转换机制transformation介绍

    转换机制 每个转换步骤都是ETL数据流里面的一个任务.转换步骤包括输入.处理和输出.输入步骤从外部数据源获取数据,例如文件或者数据库:处理步骤处理数据流,字段计算,流处理等,例如整合或者过滤.输出步骤 ...

  4. linux、内核源码、内核编译与配置、内核模块开发、内核启动流程(转)

    linux是如何组成的?答:linux是由用户空间和内核空间组成的为什么要划分用户空间和内核空间?答:有关CPU体系结构,各处理器可以有多种模式,而LInux这样的划分是考虑到系统的安全性,比如X86 ...

  5. iOS多线程编程之GCD的基本使用(转载)

    一.主队列介绍 主队列:是和主线程相关联的队列,主队列是GCD自带的一种特殊的串行队列,放在主队列中得任务,都会放到主线程中执行. 提示:如果把任务放到主队列中进行处理,那么不论处理函数是异步的还是同 ...

  6. arcpy调试

    arcpy调试过程中, 在代码中加入一些输出语句来判断代码运行流程, 使用  arcpy.AddMessage(“”)    而不要使用 print    如下两图所示,print并未输出~~

  7. 火币Huobi API Websocket

    本文介绍火币Huobi API Websocket WebSocket API简介 WebSocket协议是基于TCP的一种新的网络协议.它实现了客户端与服务器之间在单个 tcp 连接上的全双工通信, ...

  8. HTML文件默认内容

    <!DOCTYPE html> <!-- 声明使用html5标准 --> <html lang="en"> <!-- html标签开始(只 ...

  9. 学习计划 mysql 主从复制

    网上资料繁多,需要跳多少坑才能实现,跳跳就知道了. -- 主从复制 如题:主数据库进行的操作,从数据库进行备份. -- 原理 有关于这方面的原理网上也是一搜一大片,去看看吧.肯定没错. 这里简单说一下 ...

  10. python-面向对象-10-单例

    单例 目标 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式 设计模式 是 前人工作的总结和提炼,通常,被人们广泛流传的设计模式都是针对 某一特定问题 的成熟 ...