发布于 

Kubernetes-APIServer

[TOC]

深入理解Kube-APIServer

大纲

  • 认证

  • 鉴权

  • 准入

    • Mutating(变形)
    • Validating (校验)
    • Admission
  • 限流

  • APIServer对象的实现

Shell

# 解码base64,转换为jwt
echo xxxx|base64 -d
# 获取serviceAccount,每个ns下都有一个default的sa,关联了secrets的token,apiServer颁发的。
# 作用:为每个ns下都有serviceAccount,内部的pod访问apiServer的认证。
k get sa
# 获取密钥
k get secrets
# userAccount是k8s外部平台认识的用户,用于k8s主动去询问他,这个token是谁的
k get rolebinding -o yaml
# 是发起put请求,更新整个对象。性能差
k replace -f xx.yaml
# 是发起PATCH请求,增量操作替换
k apply -f xx.yaml
# 获取资源配额
k get resourcequota
# 查看apiserver的help文档,比如:查看准入插件(--enable-admission-plugins)
ks exec -it kube-apiserver-noahlinux -- kube-apiserver --help
# 获取apiServer限流,前者:种类,后者优先级队列
k get flowschema -A
k get PRIORITYLEVELConfiguration -A

API Server

image-20220203085608296

访问控制预览

image-20220203085655811

访问控制细节

image-20220203085712931

认证

image-20220203090402265

认证插件

image-20220203090453693

image-20220203093224832

基于webhook的认证服务集成

构建符合kubernetes规范的认证服务

image-20220203101159265

开发认证服务

package main

import (
"context"
"encoding/json"
"log"
"net/http"

"github.com/google/go-github/github"
"golang.org/x/oauth2"
authentication "k8s.io/api/authentication/v1beta1"
)

//该handle提供给k8s认证授权用,返回用户是谁,有什么权限
func main() {
http.HandleFunc("/authenticate", func(w http.ResponseWriter, r *http.Request) {
//解码认证请求
decoder := json.NewDecoder(r.Body)
var tr authentication.TokenReview
err := decoder.Decode(&tr)
if err != nil {
log.Println("[Error]", err.Error())
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(map[string]interface{}{
"apiVersion": "authentication.k8s.io/v1beta1",
"kind": "TokenReview",
"status": authentication.TokenReviewStatus{
Authenticated: false,
},
})
return
}
log.Print("receving request")
// Check User
// 转发认证请求至认证服务器
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: tr.Spec.Token},
)
tc := oauth2.NewClient(context.Background(), ts)
client := github.NewClient(tc)
user, _, err := client.Users.Get(context.Background(), "")
if err != nil {
log.Println("[Error]", err.Error())
w.WriteHeader(http.StatusUnauthorized)
json.NewEncoder(w).Encode(map[string]interface{}{
"apiVersion": "authentication.k8s.io/v1beta1",
"kind": "TokenReview",
"status": authentication.TokenReviewStatus{
Authenticated: false,
},
})
return
}
log.Printf("[Success] login as %s", *user.Login)
// 认证结果返回给ApiServer
w.WriteHeader(http.StatusOK)
trs := authentication.TokenReviewStatus{
Authenticated: true,
User: authentication.UserInfo{
Username: *user.Login,
UID: *user.Login,
},
}
json.NewEncoder(w).Encode(map[string]interface{}{
"apiVersion": "authentication.k8s.io/v1beta1",
"kind": "TokenReview",
"status": trs,
})
})
log.Println(http.ListenAndServe(":3000", nil))
}

配置认证服务和apiserver

最佳实践:webhook的认证和鉴权服务,通过sidercar的模式,跑在apiserver服务上

image-20220203102835026

{
"kind": "Config",
"apiVersion": "v1",
"preferences": {},
"clusters": [
{
"name": "github-authn",
"cluster": {
"server": "http://192.168.34.2:3000/authenticate"
}
}
],
"users": [
{
"name": "authn-apiserver",
"user": {
"token": "secret"
}
}
],
"contexts": [
{
"name": "webhook",
"context": {
"cluster": "github-authn",
"user": "authn-apiserver"
}
}
],
"current-context": "webhook"
}

生产系统中遇到的陷阱

image-20220203105856434

鉴权

image-20220203203145635

RBAC vs ABAC

image-20220203204004296

RBAC图解

老版本

image-20220203204104974

新版本

image-20220203204348648

Role和ClusterRole

image-20220203210608268

binding

image-20220203210719039

账户/组的管理

image-20220203210757135

针对群组授权

image-20220203211105922

规划系统角色

image-20220203211127599

实现方案

image-20220204120700340

与权限相关的其他最佳实践

image-20220204120746936

准入

准入控制

image-20220204122442532

image-20220204122551053

image-20220204122607968

准入控制插件image-20220204123236876

image-20220204124513126

准入控制插件的开发

准入控制插件

image-20220204130419599

image-20220204130638388

限流

计数器固定窗口算法

image-20220204135551833

计数器滑动窗口算法

image-20220204135619502

漏斗算法

image-20220204231400956

令牌桶算法

image-20220204231434053

ApiServer中的限流

image-20220204231456494

传统限流方法的局限性

image-20220204231516834

API Priority and Fairness

image-20220204231657578

image-20220204232603749

概念image-20220206201942285

优先级

image-20220206202005007

排队

image-20220206202035406

豁免请求

某些特别重要的请求不受制于此特性施加的任何限制。这些豁免可防止不当的流控配置完全禁用 API 服务器。

默认配置

image-20220206202225500

image-20220206202242180

PriorityLevelConfiguration

image-20220206202259574

FlowSchema

image-20220206202323480

调试

image-20220206202344172

高可用ApiServer

启动ApiServer示例

kube-apiserver 
--advertise-address=10.252.189.253
--allow-privileged=true
--authorization-mode=Node,RBAC
--client-ca-file=/etc/kubernetes/pki/ca.crt
--enable-admission-plugins=NodeRestriction
--enable-bootstrap-token-auth=true
--etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
--etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
--etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
--etcd-servers=https://127.0.0.1:2379
--kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
--kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
--proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
--proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
--requestheader-allowed-names=front-proxy-client
--requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
--requestheader-extra-headers-prefix=X-Remote-Extra-
--requestheader-group-headers=X-Remote-Group
--requestheader-username-headers=X-Remote-User
--secure-port=6443
--service-account-issuer=https://kubernetes.default.svc.cluster.local
--service-account-key-file=/etc/kubernetes/pki/sa.pub
--service-account-signing-key-file=/etc/kubernetes/pki/sa.key
--service-cluster-ip-range=10.96.0.0/12
--tls-cert-file=/etc/kubernetes/pki/apiserver.crt
--tls-private-key-file=/etc/kubernetes/pki/apiserver.key

构建高可用的多副本apiServer

最佳实践还是采用静态pod的方式来部署多副本apiserver,依托于k8s给我们提供了可靠的服务,还可以使用k8s的探活策略等。而不是采用二进制的systemctld。

image-20220206204324407

预留充足的CPU、内存资源

image-20220206204348363

善用速率限制(RateLimit)

image-20220206204404348

设置合适的缓存大小

image-20220206204417900

客户端尽量使用长连接

image-20220206204430229

如何访问APIServer

image-20220206204445420

搭建多租户的Kubernetes集群

image-20220206204505961

认证

image-20220206210452176

注册apiserver

image-20220206210512387

授权

ABAC有期局限性,针对每个account都需要做配置,并且需要重启apiserver RBAC更灵活,更符合我们通常熟知的权限管理

RBAC

image-20220206210828252

规划系统角色

image-20220206210843161

实现方案

image-20220206210859806

与权限相关的其他最佳实践

image-20220206210914621

apimachinery

回顾GKV

image-20220206210700500

如何定义Group

image-20220206211008802

定义对象类型 types.go

image-20220206214558827

代码生成Tags

image-20220206214636690

实现etcd storage

image-20220206214651662

代码生成

https://github.com/kubernetes/code-generator

image-20220206220847418