TKEStack授权链路源码解析

Author: caryxychen

TKEStack 是一个开源项目,它为在生产环境中部署容器的组织提供了一个容器管理平台。TKEStack 让您可以轻松地在任何地方运行 Kubernetes、满足 IT 需求并为 DevOps 团队赋能。 本文将详细分析的TKEStack授权链路。

名词解释

image.png

  • Tenant
    • 租户,类似于公有云主账号
    • TkeStack提供了多租户隔离的能力
  • Platform
    • 平台级,即拥有全局的作用范围
  • Project
    • 项目级,将资源、操作限定到某个项目维度下
  • User
    • 用户,定义一个成员的最基础的认证信息
    • 例如小明、小李是两个用户
    • 用户属于某个租户
    • 用户是平台级资源
    • CRD
  • Group
    • 用户组,将一组用户关联到一个分组
    • 例如小明和小李都是容器组的同事
    • 用户组属于某个租户
    • 用户组是平台级资源
    • CRD
  • Role
    • 角色,一个中间态概念,关联了一组权限策略(Policy),并分配到用户、用户组上
    • 例如小明是研发角色,小李是产品角色
    • 角色可以是平台级(Platform),也可以是项目级(Project)
      • 若将一个平台级的角色绑定到某个用户、用户组上,则用户、用户组具备了该角色所绑定了权限策略的平台级权限
      • 若将一个项目级的角色绑定到某个用户、用户组上,则用户、用户组具备了该角色所绑定了权限策略的项目级权限
    • 角色属于某个租户
    • CRD
  • Policy
    • 权限策略,定义了Resouces、Actions、Effect三元组
    • 权限策略可以是平台级(Platform),也可以是项目级(Project)
      • 通过**(un)binding**将用户、用户组与**平台级Policy**绑定,这样用户、用户组具备了平台级的操作权限
      • 通过project(un)Binding将用户、用户组与项目级Policy绑定,这样用户、用户组只在该项目下具备权限
      • 若用户、用户组是通过Role关联了某些Policy,则权限的作用范围由Role的作用域决定
    • CRD

Casbin基础

Casbin 可以:

  • 支持自定义请求的格式,默认的请求格式为{subject, object, action}。
  • 具有访问控制模型model和策略policy两个核心概念。
  • 支持RBAC中的多层角色继承,不止主体可以有角色,资源也可以具有角色。
  • 支持内置的超级用户 例如:root 或 administrator。超级用户可以执行任何操作而无需显式的权限声明。
  • 支持多种内置的操作符,如 keyMatch,方便对路径式的资源进行管理,如 /foo/bar 可以映射到 /foo*

Casbin 不能:

  • 身份认证 authentication(即验证用户的用户名和密码),Casbin 只负责访问控制。应该有其他专门的组件负责身份认证,然后由 Casbin 进行访问控制,二者是相互配合的关系。
  • 管理用户列表或角色列表。 Casbin 认为由项目自身来管理用户、角色列表更为合适, 用户通常有他们的密码,但是 Casbin 的设计思想并不是把它作为一个存储密码的容器。 而是存储RBAC方案中用户和角色之间的映射关系。

PERM

在 Casbin 中, 访问控制模型被抽象为基于 **PERM (Policy, Effect, Request, Matcher) **的一个文件。 PERM模式由四个基础(政策、效果、请求、匹配)组成,描述了资源与用户之间的关系。

Casbin需要两份文件:

  • 模型文件,定义了PERM,描述了权限控制模型的Schema
    • https://casbin.org/docs/zh-CN/syntax-for-models
    • image.png
    • r,描述了请求的schema
      • sub,主体对象,即请求发起方是谁
      • obj,资源对象,即被操作的资源是什么
      • act,动作,即触发什么类型的操作(CRUD)
    • p,定义了策略文件的格式
    • m,匹配器,定义了请求与策略的匹配规则,即策略文件中的哪些策略能够被命中
    • e,效果器,通过被命中的策略,计算出最终的准入结果(Allow还是Deny)
  • 策略文件,根据模型文件中的p,填充用户自定义的授权规则
    • image.png
    • alice可以读取data1
    • bob可以编写data2

RBAC

  • 模型定义
    • image.png
    • 分组定义,描述了用户与角色(分组)之间的关系
    • 匹配定义,g(r.sub, p.sub)描述了,请求的主体与策略里的主体,需要在同一个角色(分组)里
  • 策略文件
    • image.png
    • alice对data1资源有read权限
    • data2_admin角色对data2资源有read、write权限
    • alice属于data2_admin角色(分组),因此alice也具备了data2资源的read、write权限
    • bob只有data2资源的write权限

域内RBAC

  • 模型定义
    • image.png
    • 域内角色定义,用户,角色,域的分组关系
    • 匹配规则,请求的作用域内的请求主体,应该与策略文件中的主体在一个分组内
  • 策略文件
    • image.png
    • admin角色domain1、domain2作用域内,对data1、data2资源具备read、write权限
    • alice用户domain1作用域具有admin角色权限,但不具备domain2作用域内资源的操作权限
    • bob用户domain2作用域具有admin角色权限,但不具备domain1作用域内资源的操作权限

角色继承

  • 模型定义
    • image.png
  • 策略文件
    p, role::admin, domain, data1, read
    p, role::admin, domain, data1, write
    p, role::reader, domain, data1, read
    
    g, user::alice, group::develop, domain
    g, user::bob, group::develop, domain
    g, user::tony, group::product, domain
    
    g, group::develop, role::admin, domain
    g, group::product, role::reader, domain
    
    • 用户alice、用户bobdomain作用域内属于用户组develop
    • 用户bobdomain作用域内属于用户组product
    • 用户组developdomain作用域内分配了admin角色
    • 用户组productdomain作用域内分配了reader角色
    • admin角色domain作用域内对data1资源具备read、write操作的权限
    • reader角色domain作用域内对data1资源具备read的权限
    • 用户alice、bobdomain作用域内对data1资源具备read、write操作的权限
    • 用户tonydomain作用域内data1资源具备read的权限
  • 即描述了用户、用户组、角色的三层继承关系
    • image.png

TkeStack Authz源码解析

Casbin模型定义

[request_definition]
r = sub, dom, obj, act

[policy_definition]
p = sub, dom, obj, act, eft

[role_definition]
g = _, _, _

[policy_effect]
e = some(where (p.eft == allow)) && !some(where (p.eft == deny))

[matchers]
m = g(r.sub, p.sub, r.dom) && keyMatchCustom(r.obj, p.obj) && keyMatchCustom(r.act, p.act)

tke-auth-api授权解析

image.png

tke-auth-controller

image.png 包含的Controller

image.png Controller的职责

  • 以Policy为核心,将Policy绑定到User、Group、Role上
  • 将Policy以及Policy的绑定关系,翻译成Casbin的策略规则(p、g)

PolicyController,watch Policy资源,并更新Casbin策略规则。示例

p, pol-xxx, *, cluster:cls-123/deployment:deploy-123/*, get*, allow
p, pol-xxx, *, cluster:cls-123/deployment:deploy-123/*, list*, allow
p, pol-xxx, *, cluster:cls-123/deployment:deploy-123/*, watch*, allow

若Policy为Platform级别的,并且绑定到对应的User或Group上,则更新Casbin分组规则,示例:

g, usr-xxx, pol-xxx, *
g, grp-xxx, pol-xxx, *

ProjectPolicyController,watch ProjectPolicyBinding资源,并更新Casbin分组规则。 若该Policy为Project级别的,并且通过ProjectBinding绑定到对应的User或Group上,则更新Casbin分组规则,示例:

g, usr-xxx, pol-xxx, pro-xxx
g, grp-xxx, pol-xxx, pro-xxx

RoleController,watch Role资源,并更新Casbin分组规则(多层继承)。 若将Role绑定(binding)到User或Group上,则更新Casbin的分组规则,示例:

## 若role-xxx是platform范围的
g, usr-xxx, role-xxx, *
g, grp-xxx, role-xxx, *

## 若role-yyy是project-yyy范围的
g, usr-yyy, role-yyy, project-yyy
g, grp-yyy, role-yyy, project-yyy

若将Role关联(policyBinding)到多个Policy,则更新Casbin的分组规则,示例:

## 若role-xxx是platform范围的
g, role-xxx, pol-xxx, *
g, role-xxx, pol-xxx2, *


## 若role-yyy是project-yyy范围的
g, role-yyy, pol-yyy, project-yyy
g, role-yyy, pol-yyy2, project-yyy

GroupController,watch LocalGroup资源,并根据Group对应的User更新Casbin分组规则,示例:

g, usr-xxx, grp-xxx, *
g, usr-xxx2, grp-xxx, *
g, usr-yyy, grp-yyy, *

示例

TKEStack 通过自定义的 CRD:Policy 对象存储鉴权规则。其中 Policy 对象类似于 Kubernetes 中的 Clusterrole 或者 Role 对象,以近似于腾讯 CAM 语法的方式,定义了鉴权规则: image.png

apiVersion: auth.tkestack.io/v1
kind: Policy
metadata:
  creationTimestamp: "2022-01-13T07:01:07Z"
  generateName: pol-
  name: pol-2tg5rdqf
  resourceVersion: "916"
  uid: 23b81f6e-ac0d-4bbc-969b-864de22f917a
spec:
  category: addon
  description: 该策略允许您管理平台租户内扩展组件相关资源
  displayName: AddonFullAccess
  finalizers:
  - policy
  scope: ""
  statement:
    actions:
    - '*Addon*'
    - '*Addons*'
    - '*Addontype*'
    - '*Addontypes*'
    - '*Clusteraddontype*'
    - '*Clusteraddontypes*'
    - '*Coredns*'
    - '*Cronhpa*'
    - '*Cronhpas*'
    - '*Csi*'
    - '*Csioperator*'
    - '*Csioperators*'
    - '*Csis*'
    - '*Galaxies*'
    - '*Galaxy*'
    - '*Gpumanager*'
    - '*Gpumanagers*'
    - '*Logc*'
    - '*Logcs*'
    - '*Persistentevent*'
    - '*Persistentevents*'
    - '*Prometheuse*'
    - '*Prometheuses*'
    - '*Tappcontroller*'
    - '*Tappcontrollers*'
    effect: allow
    resources:
    - '*'
  tenantID: default
  type: default
  username: admin
status:
  groups: null
  phase: Active
  users: null

Policy 对象通过 spec.statement 字段定义了鉴权策略的行为(actions)和资源(resources),分为平台策略(spec.scope!=project)和业务策略(spec.scope==project):

apiVersion: auth.tkestack.io/v1
kind: Policy
metadata:
  name: pol-prj-default
spec:
  category: common
  description: demo
  displayName: demo
  finalizers:
  - policy
  scope: project
  statement:
    actions:
    - createDeployment
    - deleteDeployment
    - getDeployment
    - listDeployments
    - updateDeployment
    effect: allow
    resources:
    - cluster:cls-xxxxxxx/namespace:*
  tenantID: default
  type: custom
  username: admin
---

apiVersion: auth.tkestack.io/v1
kind: ProjectPolicyBinding
metadata:
  name: prj-fwxqdm6b-pol-prj-default
spec:
  finalizers:
  - projectpolicybinding
  groups: null
  policyID: pol-prj-default
  projectID: prj-fwxqdm6b
  tenantID: default
  users:
  - id: usr-test-default
    name: test

Policy 对象定义了用户需要配置的鉴权规则格式,但是 Policy 对象实际上定义了一批规则的集合,Casbin 没法直接读取,因此还需要另一个 CRD 对象,将 Policy 转化为逐条的规则。例如: image.png

apiVersion: auth.tkestack.io/v1
kind: Rule
metadata:
  creationTimestamp: "2022-03-08T06:46:36Z"
  generateName: rul-
  name: rul-2rh67m4s
  resourceVersion: "28896514"
  uid: a81f4f7f-88ef-418c-bb93-1d7ccdb02349
spec:
  ptype: g
  v0: default##user##test
  v1: pol-default-project
  v2: prj-rggwcclx
  v3: ""
  v4: ""
  v5: ""
  v6: ""

---
apiVersion: auth.tkestack.io/v1
kind: Rule
metadata:
  creationTimestamp: "2022-01-13T07:01:09Z"
  generateName: rul-
  name: rul-zzslddhh
  resourceVersion: "1075"
  uid: 0adb223f-6d05-4486-b714-18de368a68c6
spec:
  ptype: p
  v0: pol-default-project-member
  v1: '*'
  v2: '*'
  v3: deleteJob
  v4: allow
  v5: ""
  v6: ""

Rule 对象可以分为两类:spec.ptype==p 和 spec.ptype==g,分别对应 Casbin 模型里的policy_defination 和 role_defination:

  • 根据 g 规则可以确定用户所在的业务以及关联的 Policy 对象
  • 根据 p 规则可以确定用户关联的 Policy 规定了哪些可执行的动作

tke-auth-controller 根据 Casbin 定义的 Adapter Interface,通过 tke-auth-api 的 Client 和 Rule 对象的 Lister 对象构建了一个 Adapt。通过 Adapt 创建了 Casbin 的客户端,实现 Kubernetes 同 Casbin 框架的交互。

其他模块的授权链路

通过在WithTKEAuthorization阶段,通过Webhook的方式,访问tke-auth-api的/authz接口 image.png

原生k8s集群上通过chart安装tke-auth、tke-platform、tke-gateway

Author: wl-chen

TKEStack 是一个开源项目,它为在生产环境中部署容器的组织提供了一个容器管理平台。TKEStack 让您可以轻松地在任何地方运行 Kubernetes、满足 IT 需求并为 DevOps 团队赋能。 本文将介绍如何使用 helm 在原生 k8s 集群上,以 chart 的形式安装 TKEStack 中的核心组件 tke-auth、tke-platfor、tke-gateway,实现 TKEStack 的轻量化安装。

前置要求

本文介绍的内容是建立在已经有一个正常运行的 k8s 集群的基础上,并且下面的操作需要在 master 节点上进行操作。如果没有现有的 k8s 集群,可以通过 kind 创建本地集群并进行下面的操作。 本文介绍的内容需要通过 helm 安装一些实验用途的组件,可参考安装Helm进行安装。

创建指定 namespace

tke-auth、tke-platform、tke-gateway 三个 chart 需要运行在指定的 namespace 下,执行如下命令:

kubectl create namespace tke

安装 chart

本文提供了二进制可执行程序来生成 tke-auth、tke-platform、tke-gateway 三个 chart 的 values 文件

执行如下命令拉取 TKEStack 项目代码

git clone https://github.com/tkestack/tke.git

在 TKEStack 项目的charts/bin目录放置了可执行文件bin和需要填写的yaml文件customConfig.yamlcustomConfig.yaml文件中一些注释“必填”的参数,需要填写,其余的参数可根据需要选填,选填部分为空时会自动填充默认值。customConfig.yaml内容如下:

# 必填,etcd访问地址,形式如https://172.19.0.2:2379
etcd:
  host: https://172.18.0.2:2379 
# 必填,服务器内网ip,数组形式
serverIPs:
  - 172.18.0.2
# 必填,公网可访问的ip地址以及要使用的域名,数组形式
dnsNames:
  - tke.gateway
# 必填,集群front-proxy-ca.crt文件地址,默认位置为/etc/kubernetes/pki/front-proxy-ca.crt
frontProxyCaCrtAbsPath: /etc/kubernetes/pki/front-proxy-ca.crt
# 必填,集群etcd的ca.crt文件地址,默认位置为/etc/kubernetes/pki/etcd/ca.crt
etcdCrtAbsPath: /etc/kubernetes/pki/etcd/ca.crt
# 必填,集群etcd的ca.key文件地址,默认位置为/etc/kubernetes/pki/etcd/ca.key
etcdKeyAbsPath: /etc/kubernetes/pki/etcd/ca.key
tke-auth:
  api:
    # 必填
    replicas: 1
    # 必填
    image: tkestack/tke-auth-api-amd64:74592a3bceb5bebca602bea21aaebf78007a3bb2
    # 必填,数组形式,auth的重定向访问地址,包括集群服务器ip地址(必填)、tke-gateway的域名(可选)、集群高可用的VIP地址(可选,有的话需要填写)和集群的公共可访问域名(可选,,有的话需要填写)
    redirectHosts: 
      - 172.18.0.2
    enableAudit: 
    # tke-auth-api组件在node上的对外暴露端口,默认31138
    nodePort: 
    # tke集群的租户id,默认default
    tenantID: 
    # OIDC认证方式的secret,默认自动生成
    oIDCClientSecret: 
    # authentication用户名,默认为admin
    adminUsername: 
  controller:
    # 必填
    replicas: 1
    # 必填
    image: tkestack/tke-auth-controller-amd64:74592a3bceb5bebca602bea21aaebf78007a3bb2
    # tke集群的用户名,默认为admin
    adminUsername: 
    # tke集群的密码,默认自动生成
    adminPassword: 
tke-platform:
  # 必填 VIP,或者公网可访问的集群IP
  publicIP:
  metricsServerImage: metrics-server:v0.3.6
  addonResizerImage: addon-resizer:1.8.11
  api:
    # 必填
    replicas: 1
    # 必填
    image: tkestack/tke-platform-api-amd64:bc48bed59bff2022d87db5e1484481715357ee7c
    enableAuth: true
    enableAudit: 
    # OIDC认证方式客户端id,默认为default
    oIDCClientID: 
    # OIDC认证方式的issuer_url,默认为https://tke-auth-api/oidc
    oIDCIssuerURL: 
    # 是否开启OIDC认证,默认不开启,值为空
    useOIDCCA:
  controller:
    # 必填
    replicas: 1
    # 必填
    providerResImage: tkestack/provider-res-amd64:v1.21.4-1
    # 必填
    image: tkestack/tke-platform-controller-amd64:bc48bed59bff2022d87db5e1484481715357ee7c
    # 默认为docker.io
    registryDomain:
    # 默认为tkestack
    registryNamespace:
    # 监控存储类型,默认为influxdb
    monitorStorageType: 
    # 监控存储地址,为tke集群master ip地址加8086端口
    monitorStorageAddresses:
tke-gateway:
  # 必填
  image: tkestack/tke-gateway-amd64:bc48bed59bff2022d87db5e1484481715357ee7c
  # 默认为docker.io
  registryDomainSuffix:
  # tke集群的租户id,默认default
  tenantID:
  # OIDC认证方式的secret,默认自动生成
  oIDCClientSecret:
  # 是否开启自签名,默认为true
  selfSigned: true
  # 第三方cert证书,在selfSigned为false时需要填值
  serverCrt:
  # 第三方certKey,在selfSigned为false时需要填值
  serverKey:
  enableAuth: true
  enableBusiness:
  enableMonitor:
  enableRegistry:
  enableLogagent:
  enableAudit:
  enableApplication:
  enableMesh:

customConfig.yaml文件中的参数填写完毕后,执行bin,会在同级目录生成auth-chart-values.yamlplatform-chart-values.yamlgateway-chart-values.yaml三个yaml文件,分别对应三个chart(tke-auth、tke-platform、tke-gateway)在安装时需要的values.yaml文件

切换到项目的charts/目录,接下来进行chart的安装:

# tke-auth的安装
helm install -f bin/auth-chart-values.yaml tke-auth tke-auth/
# tke-platform的安装
helm install -f bin/platform-chart-values.yaml tke-platform tke-platform/
# tke-gateway的安装
helm install -f bin/gateway-chart-values.yaml tke-gateway tke-gateway/

通过如下命令如果能查询到三个组件对应的 api-resources,则表示chart安装成功

kubectl api-resources | grep tke

chart安装完成后,可以查询到以下信息,如图所示:

修改集群 apiserver 配置

在对应的目录/etc/kubernetes/pki/下新建文件tke-authz-webhook.yaml,文件内容如下(其中cluster.server参数中的IP地址需要修改为master的IP地址):

apiVersion: v1
kind: Config
clusters:
  - name: tke
    cluster:
      server: https://172.19.0.2:31138/auth/authz
      insecure-skip-tls-verify: true
users:
  - name: admin-cert
    user:
      client-certificate: /etc/kubernetes/pki/webhook.crt
      client-key: /etc/kubernetes/pki/webhook.key
current-context: tke
contexts:
- context:
    cluster: tke
    user: admin-cert
  name: tke

将二进制执行文件生成的webhook.crtwebhook.key(位置在二进制执行文件同级目录/data内)同时放到对应位置/etc/kubernetes/pki/

修改 k8s 集群中/etc/kubernetes/mainfest/kube-apiserver.yaml的内容,在spec.containers.command字段增加以下两条:

# 如果已有这两个参数,则将其按照以下内容修改
- --authorization-mode=Node,RBAC,Webhook
- --authorization-webhook-config-file=/etc/kubernetes/pki/tke-authz-webhook.yaml

创建独立集群

访问地址http://{master节点ip}/tkestack,出现如下登陆界面,输入之前设置的用户名adminusername和密码adminpassword,如无设置,默认用户名为admin,密码为YWRtaW4=

登陆后,点击集群管理的新建独立集群:

具体的集群创建信息可参考文档集群创建

如果在安装过程中出现没有 tke 对应版本的问题,可能是版本不兼容导致,可以通过在集群上名为 cluster-info (namespace 为 kube-public) 的 configmap 中增加如下字段解决:

data:
  k8sValidVersions: '["1.21.4-tke.1","1.20.4-tke.1"]'

创建集群完成后,可以在页面端看到如下状态

并且在创建集群的master节点上可以查询到相关集群信息

TKEStack 集成LDAP

Author: LeoRyu

LDAP 是一个开放的,中立的,工业标准的应用协议,在开发内部网和与互联网程序共享用户、系统、网络、服务和应用的过程中占据了重要地位。本文将介绍 TKEStack中的 tke-auth 组件如何与 LDAP进行集成。

前置要求

本文介绍的内容是建立在已经有一个正常运行的 TKEStack 平台基础上,由于集成 LDAP 功能在当前已 release 版本中存在问题,这里建议安装 daily build 版本的 tke-installer 安装 TKEStack:version=be9b9469bf10faeabb9ba60a8591aad2b5f73f41 wget https://tke-release-1251707795.cos.ap-guangzhou.myqcloud.com/tke-installer-linux-amd64-$version.run{,.sha256} && sha256sum --check --status tke-installer-linux-amd64-$version.run.sha256 && chmod +x tke-installer-linux-amd64-$version.run && ./tke-installer-linux-amd64-$version.run

本文介绍的内容需要通过 helm 安装一些实验用途的组件,可参考安装Helm进行安装。

安装 openldap

这里如果有现成的 LDAP 服务器可以跳过此步骤。

首先通过以下命令下载 openldap 的 chart:

wget https://tke-release-1251707795.cos.ap-guangzhou.myqcloud.com/charts/openldap-1.2.7.tgz

将下面的 yaml 存储到values-openldap.yaml

replicaCount: 1
image:
  repository: osixia/openldap
  tag: 1.2.4
  pullPolicy: IfNotPresent

tls:
  enabled: false
  CA:
    enabled: false
service:
  clusterIP: ""

  ldapPort: 389
  type: ClusterIP

env:
  LDAP_ORGANISATION: "TKEStack Demo"
  LDAP_DOMAIN: "tkestack.io"
  LDAP_BACKEND: "hdb"
  LDAP_TLS: "true"
  LDAP_TLS_ENFORCE: "false"
  LDAP_REMOVE_CONFIG_AFTER_SETUP: "true"
  LDAP_READONLY_USER: "true"
  LDAP_READONLY_USER_USERNAME: readonly
  LDAP_READONLY_USER_MASSWORD: password

# Default Passwords to use, stored as a secret. If unset, passwords are auto-generated.
# You can override these at install time with
# helm install openldap --set openldap.adminPassword=<passwd>,openldap.configPassword=<passwd>
adminPassword: admin
configPassword: admin

# Custom openldap configuration files used to override default settings
customLdifFiles:
  0-initial-ous.ldif: |-
    dn: ou=People,dc=tkestack,dc=io
    objectClass: organizationalUnit
    ou: People

    dn: ou=Group,dc=tkestack,dc=io
    objectClass: organizationalUnit
    ou: Group    

这里默认使用 admin 作为 ldap 服务器的访问凭证,运行下面命令安装 openldap:

helm install openldap openldap-1.2.7.tgz  --values values-openldap.yaml

安装成功后通过下面命令获取到 openldap 的服 ClusterIP 地址:

kubectl get service openldap

然后通过 ldapsearch 命令查询 ldap 服务是否正常:

ldapsearch -x -H ldap://{cluster_ip}:389 -b dc=tkestack,dc=io -D "cn=admin,dc=tkestack,dc=io" -w {your password default is admin}

如果一切正常将会得到类似下面的返回内容:

# extended LDIF
#
# LDAPv3
# base <dc=tkestack,dc=io> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# tkestack.io
dn: dc=tkestack,dc=io
objectClass: top
objectClass: dcObject
objectClass: organization
o: TKEStack Demo
dc: tkestack
...

使用 keycloak 管理 LDAP

本节将介绍通过 keycloak 图形界面控制 LDAP。首先下载 keycloak 的chart:

wget https://tke-release-1251707795.cos.ap-guangzhou.myqcloud.com/charts/keycloak-16.1.0.tgz

现在完毕后将下面内容存储到 values-keycloak.yaml

# Default values for keycloak.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

image:
  repository: docker.io/jboss/keycloak
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: "16.1.0"

service:
  type: NodePort
  port: 8443
  nodePort: 30443

这里默认使用 admin 作为 keycloak 的用户名密码。然后通过 helm 安装 keycloak:

helm install keycloak  keycloak-16.1.0.tgz --values values-keycloak.yaml

安装成功后可以通过https://{keycloak 所在 node IP}:30443访问 keycloak 页面:

然后进入 admin 登录界面使用 keycloak admin 用户登录:

成功登录 keycloak 之后我们可以在User Federation中配置管理 LDAP:

在配置过程中我们可以通过Test connectionTest authentication测试配置是否有效。完成配置和我们就可以在 keycloak 中创建用户并同步到 LDAP 服务器。这里通过Users中添加用户:

这里注意一定要配置Email信息。创建成功后我们在用户的Credentials 中配置用户密码:

如果一切正常,此时用户信息应该已经同步到了 LDAP 服务器,我们可以通过以下命令进行检查:

ldapsearch -x -H ldap://{cluster_ip}:389 -b dc=tkestack,dc=io -D "cn=admin,dc=tkestack,dc=io" -w {your password default is admin}

我们在返回结果中可以得到该用户信息:

...
# ldapadmin, People, tkestack.io
dn: uid=ldapadmin,ou=People,dc=tkestack,dc=io
uid: ldapadmin
objectClass: inetOrgPerson
objectClass: organizationalPerson
mail: ldapadmin@example.com
sn:: IA==
cn:: IA==
userPassword:: YWRtaW4=
...

除了用户信息,我们也可以通过 keycloak 添加 group 信息到 LDAP,这里我们需要在LDAPMappers中创建一个 group mapper:

创建成功后我们可以将已经创建的用户添加到此 group 中:

再执行下列命令:

ldapsearch -x -H ldap://{cluster_ip}:389 -b dc=tkestack,dc=io -D "cn=admin,dc=tkestack,dc=io" -w {your password default is admin}

将得到我们刚刚添加的 group 信息:

...
# test, Group, tkestack.io
dn: cn=test,ou=Group,dc=tkestack,dc=io
objectClass: groupOfNames
cn: test
member: cn=empty-membership-placeholder
member: uid=ldapadmin,ou=People,dc=tkestack,dc=io
...

tke-auth 与 LDAP 的集成

本节将介绍 tke-auth 如何与 LDAP 进行集成,并通过 LDAP 用户登录管理 TKEStack 平台。

首先我们将 TKEStack 默认的 identityprovider 进行备份:

kubectl get identityproviders.auth.tkestack.io default -o yaml > default.identityproviders.bak

然后将 LDAP 相关的配置保存到ldap.json中:

{
        "host": "openldap.default:389",
        "insecureNoSSL": true,
        "bindDN": "cn=admin,dc=tkestack,dc=io",
        "bindPW": "admin",
        "usernamePrompt": "User name",
        "userSearch": {
                "baseDN": "ou=People,dc=tkestack,dc=io",
                "filter": "(objectClass=organizationalPerson)",
                "username": "uid",
                "idAttr": "DN",
                "emailAttr": "mail",
                "nameAttr": "uid",
                "preferredUsernameAttr": "uid"
        },
        "groupSearch": {
                "baseDN": "ou=Group,dc=tkestack,dc=io",
                "filter": "(objectClass=groupOfNames)",
                "userAttr": "DN",
                "groupAttr": "member",
                "nameAttr": "cn"
        }
}

使用该文件创建 ConfigMap:

kubectl create cm -n tke ldap --from-file ldap.json

创建成功后我们需要将此 ConfigMap 加载到 tke-auth-api 组件中:

kubectl edit -n tke deployments.apps tke-auth-api

添加下面的内容:

...
        volumeMounts:
	...
        - mountPath: /app/ldap
          name: ldap-volume
      volumes:
      ...
      - configMap:
          defaultMode: 420
          name: ldap
        name: ldap-volume
...

修改成功后我们需要修改 tke-auth-api 的 ConfigMap,使得其能够创建识别 ldap identityprovider:

kubectl edit -n tke cm tke-auth-api

添加下面内容到 tke-auth-api.toml 文件中:

  tke-auth-api.toml: |
  ....
    [auth]
    # 指定ldap类型的idp
    init_tenant_type = "ldap"
    # tenant id,需要控制global集群需要是default
    init_tenant_id = "default"
    # 预设的特权用户,配置一个ldap中存在的用户
    init_idp_administrators = ["ldapadmin"]
    # ldap 配置路径
    ldap_config_file = "/app/ldap/ldap.json"
  ...  

修改成功后我们需要删除现有的默认 identityprovider,并重建 tke-auth-api:

kubectl delete identityproviders.auth.tkestack.io default
kubectl delete pod -n tke tke-auth-api-xxx

待重建完成后 ldap 的 identityprovider 将会被自动创建,可以通过下列命令进行验证:

kubectl get identityproviders.auth.tkestack.io  default -o yaml

如果正常我们将得到类似下面的结果:

apiVersion: auth.tkestack.io/v1
kind: IdentityProvider
metadata:
  creationTimestamp: "2021-12-30T02:51:34Z"
  name: default
  resourceVersion: "808829"
  uid: b8c87fd2-824c-44a5-962e-f821ddfa567c
spec:
  administrators:
  - ldapadmin
  config: '{"host":"openldap.default:389","insecureNoSSL":true,"insecureSkipVerify":false,"startTLS":false,"rootCA":"","clientCert":"","clientKey":"","rootCAData":null,"bindDN":"cn=admin,dc=tkestack,dc=io","bindPW":"admin","usernamePrompt":"User
    name","userSearch":{"baseDN":"ou=People,dc=tkestack,dc=io","filter":"(objectClass=organizationalPerson)","username":"uid","scope":"","idAttr":"DN","emailAttr":"mail","nameAttr":"uid","preferredUsernameAttr":"uid","emailSuffix":""},"groupSearch":{"baseDN":"ou=Group,dc=tkestack,dc=io","filter":"(objectClass=groupOfNames)","scope":"","userAttr":"DN","groupAttr":"member","userMatchers":null,"nameAttr":"cn"}}'
  name: default
  type: ldap

此时我们已经完成了 tke-auth 和 LDAP 的集成工作,我们可以通过下面的命令查询 LDAP 的用户和 group:

kubectl get user --field-selector=spec.tenantID=default
# NAME   CREATED AT
# test   0001-01-01T00:00:00Z
kubectl get group --field-selector=spec.tenantID=default
# NAME        CREATED AT
# ldapadmin   0001-01-01T00:00:00Z

此时我们可以使用 LDAP 的用户登录管理 TKEStack:

TKEStack 容器混合云能力介绍(2):打破网络边界

Author: LeoRyu

TKEStack 提供了多集群管理能力,其中导入集群功能通过推送模式由 TKEStack 管控集群(global cluster)直连第三方集群的 api-server 进而统一纳管部署在 IDC,公有云或边缘的第三方集群。 但在实际生产环境中, 管控集群和第三方集群之间的直连往往会出现很多阻碍:或是不在同一个二层网络下,或是第三方集群在防火墙/NAT之后,或是第三方集群在网络策略上不允许有入站网络传输,在这些场景下, TKEStack难以直连第三方集群 api-server, 导入集群的能力无法发挥。针对这一问题本文将介绍 TKEStack 如何借助腾讯云原生分布式云中心注册集群的功能打破网络边界的限制,将网络环境相对隔离的集群纳入到 TKEStack 的管控面,进行统一管控。

TKEStack 的导入集群功能

开源版 TKEStack 的集群管理中[1]存在两种集群的概念,一种是独立集群,另一种是导入集群

其中独立集群需要用户提供可被 TKEStack 访问的 Linux 机器的访问凭证,TKEStack 将以用户提供的机器作为基础设施,从 0 搭建可被 TKEStack 管控的 K8s 集群。

独立集群

导入集群则是将用户的现存集群纳入到 TKEStack 的管控之下,但需要此集群可以被 TKEStack 访问到(无需被导入集群可访问 TKEStack),用户在满足此条件前提下可提供被导入集群的访问凭证,便可将集群纳入到 TKEStack 管控视野内。

导入集群

但是在现实生产环境中,被导入集群有极大的可能性处于外网无法访问的网络环境中,此时我们可以借助腾讯云的分布式云中心来打通 TKEStack 与被导入集群间的网络边界限制。

打破网络边界

云原生分布式云中心(Tencent Kubernetes Engine Distributed Cloud Center,TDCC)[2] 是腾讯面向多云多集群场景的应用管理平台,支持用户将云原生化的应用扩展到分布式云,打通公有云、私有云、边缘云的界限,将各种成熟的集群、网络、存储、微服务、运维等公有云产品和服务交付至更接近用户和数据的位置,确保不同云基础设施下拥有一致的控制平面,并且提供可靠性保证和安全合规保证,满足企业用户的多云管理、应用治理、高可用容灾等场景诉求。

下面笔者将演示在家庭网络环境下(可访问公网)使用 kind[3] 创建一个 K8s 集群,并借助分布式云中心,将其导入一个私有云网络环境下(可访问公网)的 TKEStack。由于 TKEStack 在 v1.8 release 时云原生分布式云中心还未上线,这里需要我们使用 daily build 版本进行体验,该功能的正式发布则需要等到稍晚些 TKEStack v1.9.0 发布,daily build 版本下载可参考以下命令:

version=310e18e0d696ee0aa57dfe38655b99726eab9f5c && wget https://tke-release-1251707795.cos.ap-guangzhou.myqcloud.com/tke-installer-linux-amd64-$version.run{,.sha256} && sha256sum --check --status tke-installer-linux-amd64-$version.run.sha256 && chmod +x tke-installer-linux-amd64-$version.run && ./tke-installer-linux-amd64-$version.run

创建 kind 集群

这里笔者在自己的虚拟机上使用 kind 创建一个集群,首先是安装 kind:

curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.11.1/kind-linux-amd64
chmod +x ./kind
mv kind /usr/bin/

然后我们执行 kind 的创建集群命令:

kind create cluster

如果不出意外我们将在等待一段时间后得到以下结果:

Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.21.1) 🖼 
 ✓ Preparing nodes 📦  
 ✓ Writing configuration 📜 
 ✓ Starting control-plane 🕹️ 
 ✓ Installing CNI 🔌 
 ✓ Installing StorageClass 💾 
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind

Not sure what to do next? 😅  Check out https://kind.sigs.k8s.io/docs/user/quick-start/

下面可以使用 kubectl 来确认一下集群是否在正常运行,这里我们就完成了 kind 集群的创建工作。如果你的机器上没有 kubectl 可以参考Install and Set Up kubectl on Linux 进行安装。

注册集群到分布式云中心

访问腾讯云的分布式云中心主页,选择注册集群按钮。

注册集群1

这里由于我们是通过 kind 创建的集群并非 TKE,所以注意选择非 TKE 集群。

注册集群2

注册集群创建成功后改集群将处于等待注册的状态,点击查看注册命令。

注册集群3

由于我们的 kind 集群无法无法通过内外与分布式云中心通信,注意选择外网访问。

注册集群4

根据提示将agent.yaml下载下来然后通过 kubectl 部署到 kind 集群:

kubectl apply -f agent.yaml

如果顺利我们将会得到以下反馈:

namespace/clusternet-system created
serviceaccount/clusternet-agent created
serviceaccount/clusternet-app-deployer created
deployment.apps/clusternet-agent created
clusterrole.rbac.authorization.k8s.io/clusternet:app:deployer created
clusterrolebinding.rbac.authorization.k8s.io/clusternet:app:deployer created
secret/clusternet-agent-cluster-registration created

此时可以通过下面的命令确认下 agent 相关 pod 是否正常工作:

kubectl get pod -n clusternet-system

如果正常我们应当会得到类似下面的反馈:

NAMESPACE            NAME                                         READY   STATUS    RESTARTS   AGE
clusternet-system    clusternet-agent-6754cc97bb-dk6r4            1/1     Running   0          8s
clusternet-system    clusternet-agent-6754cc97bb-sbpzg            1/1     Running   0          8s
clusternet-system    clusternet-agent-6754cc97bb-zfblp            1/1     Running   0          8s

再检查分布式云中心首页我们将发现 kind 集群已经成功注册了进来。

导入集群到 TKEStack

下面我们将把 kind 集群导入到 TKEStack 中,首先从分布式云中心将集群的访问凭证下载下来。

注册集群5 注册集群6

然后使用此凭证便可将 kind 集群导入到 TKEStack 中。

注册集群7 注册集群8 注册集群9

原理

腾讯云分布式云中心的核心功能由 Clusternet[4] 提供,该项目已经开源,可以在 https://github.com/clusternet/clusternet 仓库下查看代码。

Clusternet 的核心能力通过clusternet-hubclusternet-agent两个组件实现,clusternet-hub的角色类似一个电插板,以 aggregated apiserver[5] 形式部署在父集群中等待着子集群被接入进来;clusternet-agent则在子集群中充当一个派驻信使的角色,一方面将子集群的信息上报给clusternet-hub以进行观测,另一方面将从clusternet-hub传送来的指令下发给子集群以进行控制。鉴权模式上 Clusternet 复用了子集群的鉴权能力,通过 K8s 的 user impersonation[6] 能力将认证信息发送到clusternet-agent模拟对应用户进行操作控制。

clusternet架构

加入我们

在大家的共同努力下 TKEStack 已经演进到 v1.8.x 版本,其中包括了 containerd 支持、cilium 支持、集群应用定义等诸多新功能,欢迎大家到 https://github.com/tkestack/tke/releases 下载体验。同时 v1.9.0 版本的开发工作正在主分支上火热进行中,v1.9.0 版本中除了本文介绍的支持导入分布式云中心集群外,我们会全面升级 TKEStack 的各种依赖,包括 golang 版本、CI 工具版本以及 K8s api 版本等,此外我们还将在 TKEStack 的轻量化减负上做出努力,包括移除 TKE 发行版[7]以外的集群版本,删减不常用的 addon 组件等。当下的 TKEStack 正是需要你加入的时候,欢迎大家到项目仓库 https://github.com/tkestack/tke 贡献一份力量!

参考资料

[1] TKEStack 集群管理 [https://tkestack.github.io/docs/user-guide/platform-console/cluster-mgmt.html]

[2] 腾讯云原生分布式云中心 [https://cloud.tencent.com/document/product/1517/63246]

[3] Kind, running local Kubernetes clusters using Docker [https://kind.sigs.k8s.io/]

[4] Clusternet [https://github.com/clusternet/clusternet]

[5] Kubernetes API Aggregation Layer [https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/]

[6] User impersonation [https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation]

[7] TKE Kubernetes Distro [https://github.com/tkestack/tke-k8s-distro]

TKEStack 中的认证与鉴权

Author: LeoRyu

认证鉴权对于 K8s 而言可以说是最为复杂、灵活和关键的部分,本文将介绍 TKEStack 中认证鉴权机制是如何运作的。

开始之前

由于认证鉴权涉及的相关知识很多,为了避免读者在下面探究 TKEStack 认证鉴权机制时查处相关名词知识,在开始之前先介绍一些本文涉及到的知识概念。

K8s 中的一些身份认证方式

  • X509 客户证书。通过给 API 服务器传递 --client-ca-file=SOMEFILE 选项,就可以启动客户端证书身份认证。 所引用的文件必须包含一个或者多个证书机构,用来验证向 API 服务器提供的客户端证书。 如果提供了客户端证书并且证书被验证通过,则 subject 中的公共名称(Common Name)就被 作为请求的用户名。

  • 静态令牌文件。当 API 服务器的命令行设置了 --token-auth-file=SOMEFILE 选项时,会从文件中 读取持有者令牌。目前,令牌会长期有效,并且在不重启 API 服务器的情况下 无法更改令牌列表。

  • 服务账号令牌。服务账号(Service Account)是一种自动被启用的用户认证机制,使用经过签名的 持有者令牌来验证请求。服务账号通常由 API 服务器自动创建并通过 ServiceAccount 准入控制器 关联到集群中运行的 Pod 上。 持有者令牌会挂载到 Pod 中可预知的位置,允许集群内进程与 API 服务器通信。 服务账号也可以使用 Pod 规约的 serviceAccountName 字段显式地关联到 Pod 上。

  • OpenID Connect(OIDC)令牌。OpenID Connect 是一种 OAuth2 认证方式, 被某些 OAuth2 提供者支持,例如 Azure 活动目录、Salesforce 和 Google。 协议对 OAuth2 的主要扩充体现在有一个附加字段会和访问令牌一起返回, 这一字段称作 ID Token(ID 令牌)。详情可参考 https://openid.net/connect/

更多认证相关信息可参考 用户认证[1]。

K8s 中的一些鉴权方式

  • Node。一个专用鉴权组件,根据调度到 kubelet 上运行的 Pod 为 kubelet 授予权限。
  • ABAC。基于属性的访问控制(ABAC)定义了一种访问控制范型,通过使用将属性组合 在一起的策略,将访问权限授予用户。策略可以使用任何类型的属性(用户属性、资源属性、 对象,环境属性等)。
  • RBAC。基于角色的访问控制(RBAC)是一种基于企业内个人用户的角色来管理对 计算机或网络资源的访问的方法。在此上下文中,权限是单个用户执行特定任务的能力, 例如查看、创建或修改文件。
  • Webhook。WebHook 是一个 HTTP 回调:发生某些事情时调用的 HTTP POST; 通过 HTTP POST 进行简单的事件通知。实现 WebHook 的 Web 应用程序会在发生某些事情时 将消息发布到 URL。
  • AlwaysAllow。允许所有请求。仅在你不需要 API 请求 的鉴权时才使用。
  • AlwaysDeny。阻止所有请求。仅用于测试。

更多认证相关信息可参考 鉴权概述[2]。

Casbin

Casbin 是一款轻量级的开源访问控制框架,支持 PERM 模式(Policy,Effect,Request,Matchers),相关概念如下:

  • Request:定义了请求的元组对象,至少包含访问实体(sub)、访问的资源(obj)和行为(Action),例如:r={sub, obj,act}。
  • Policy:定义了鉴权规则各字段的名称和顺序,至少包含访问实体(sub)、访问的资源(obj)和行为(Action),例如:p={sub, obj, act}。
  • Matchers:定义了 Request 和 Policy 的匹配规则。
  • Effect:用于对所有 Matchers 匹配后的结果,再进行一次逻辑组合判断(例如:e = some(where (p.eft == allow)) && !some(where (p.eft == deny)),这个例子组合的逻辑含义是:如果有匹配出结果为 alllow 的策略,并且没有匹配出结果为 deny 的策略,则结果为真,如果有任何deny,都为假)。

关于本项目详细信息可以参考 Casbin 概述[3]。

两种认证鉴权场景

TKEStack 扩展 K8s API 的方式是通过 aggregated apiserver[4] 实现的,这种方式与 CRD 的方式不同,每一个扩展组件都可以被视为一个独立的 APIServer,这使得 TKEStack 的认证鉴权相较之下更加灵活,但也更加复杂。为了更加方便和清晰地展示认证鉴权的流程,这里我们分为两种场景分别展开:第一种是用户通过浏览器由 tke-gateway 入口访问各个组件的资源;第二种是用户通过 kubectl 由 kube-apiserver 入口访问各个组件的资源。

由浏览器发起的访问

认证

用户通过浏览器登陆访问的用户信息并不是 K8s 集群可以识别的用户,无法由集群本身进行认证流程,需要外部的 OIDC provider 进行认证。在 TKEStack 中承担此工作的是 tke-auth 组件,tke-auth 中是通过 dex 实现的 OIDC 服务。

在由浏览器发起的访问场景下,认证流程的链路大致分为两步骤:

  1. 用户浏览器中登录 -> tke-gateway -> tke-auth返回认证信息凭证 -> 设置访问凭证到浏览器
  2. 已有访问凭证的前端 -> tke-gateway -> tke-xxxx -> tke-auth校验认证凭证

整个认证过程中数据传输都是通过浏览器或是 TKEStack 系统组件完成的,没有 kube-apiserver 的参与。

鉴权

当前版本 TKEStack 系统组件的鉴权模式默认是以 SubjectAccessReview 继承了 kube-apiserver 的鉴权模式,而 kube-apiserver 中鉴权模式配置了 webhook 指向了 tke-auth 组件。

tke-auth 中的鉴权是基于 casbin 实现的,基于其 PERM 模型 TKEStack 完成了一套 RBAC 模型的实现:

[request_definition]
r = sub, dom, obj, act

[policy_definition]
p = sub, dom, obj, act, eft

[role_definition]
g = _, _, _

[policy_effect]
e = some(where (p.eft == allow)) && !some(where (p.eft == deny))

[matchers]
m = g(r.sub, p.sub, r.dom) && keyMatchCustom(r.obj, p.obj) && keyMatchCustom(r.act, p.act)
  • request_definition:定义了模型的 Request
  • policy_definition:定义了模型的 Policy
  • role_definition:定义了模型的用户和角色的映射关系, 三个空缺分别表示用户, 角色, 域,TKEStack 使用的域为业务 ID
  • policy_effect:定义了模型的 Effect
  • matchers:定义了模型的匹配方式,keyMatchCustom 为自定义匹配函数,支持以正则匹配和通配符的方式,匹配 Role 和 Policy 的字段

用户通过浏览器访问场景下 TKEStack 的鉴权流程整个链路如下:

用户浏览器发起请求 -> tke-gateway -> tke-xxx -> kube-apiserver webhook -> tke-auth返回鉴权结果

集群内由 kubectl 发起的请求

认证

集群内通过 kubectl 发起请求场景下的认证流程与 K8s 本身的认证流程基本无异,因此整个链路也非常简单:

kubectl 读取 kubeconfig 中的认证信息 -> kube-apiserver 检验认证信息

由于此场景下的用户信息是可以被 K8s 识别的,且 kubectl 是直接连接 kube-apiserver 的,认证流程在请求到达 TKEStack 系统组件之前就完成了。

鉴权

之前在由浏览器发起访问场景中已经提到 TKEStack 系统组件的鉴权模式是以 SubjectAccessReview 继承了 kube-apiserver 的鉴权模式,这种模式也同样适用于集群内由 kubectl 发起请求的场景,只不过在 kube-apiserver 中生效的鉴权模式不再是指向 tke-auth 的 webhook,而是 K8s 的 RBAC/ABAC 模式。

整个鉴权流程的链路如下:

kubectl 发起请求 -> kube-apiserver -> tke-xxx -> kube-apiserver 返回 RBAC/ABAC 鉴权结果

[1] Kubernetes 用户认证 [https://kubernetes.io/zh/docs/reference/access-authn-authz/authentication/]

[2] Kubernetes 鉴权概述 [https://kubernetes.io/zh/docs/reference/access-authn-authz/authorization/]

[3] Casbin 概述 [https://casbin.org/docs/zh-CN/overview]

[4] Kubernetes API Aggregation Layer [https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/]

TKEStack 集群容器运行时迁移

Author: LeoRyu

Kubernetes宣布在1.20版本之后将弃用Docker作为容器运行时,在2021年末发布的1.23版本中将彻底移除dockershim组件。可能很多朋友不是很清楚容器运行时迁移工作要怎么做,本文将就TKEStack的global集群如何进行容器运行时迁移做详细介绍。同时,本文非TKEStack globa集群的容器运行时迁移也有很好的参考价值。

限制条件

  1. 集群迁移前请确认master节点不止一个,单master节点切换容器运行时只能通过备份etcd数据再恢复集群方式,本文提供方法并不适用。
  2. 迁移前倾确认当前K8s集群支持以containerd作为容器运行时,这里建议集群版本为1.19+。

迁移流程

准备工作

  1. 每个节点上修改 docker daemon.json: vim /etc/docker/daemon.json,将 "live-restore" 修改为 false
  2. 每个节点重启 dcoker 服务: systemctl daemon-reload && systemctl restart docker.service
  3. 修改galaxy ds:kubectl edit -n kube-system ds galaxy-daemonset,在volumeMountsvolumes中添加以下内容:
...
        volumeMounts:
        - name: containerd-run
          mountPropagation: Bidirectional
          mountPath: /var/run/netns/
...
      volumes:
      - name: containerd-run
        hostPath:
          path: /var/run/netns

非master0节点迁移

非global集群首个master节点的迁移步骤。

  1. 封锁节点:kubectl cordon xxx
  2. 驱逐节点:kubectl drain xxx --ignore-daemonsets --delete-local-data,注意该操作会删除 pod 的本地临时数据。
  3. 停止Kubelet服务: systemctl stop kubelet
  4. 停止Docker服务:systemctl disable docker.service && systemctl stop docker.service && systemctl stop containerd.service
  5. 下载containerd,这里从 https://github.com/containerd/nerdctl/releases 下载:curl -LO https://github.com/containerd/nerdctl/releases/download/v0.11.1/nerdctl-full-0.11.1-linux-amd64.tar.gz
  6. 安装containerd:tar Cxzvvf /usr/local nerdctl-full-0.11.1-linux-amd64.tar.gz
  7. 添加containerd自定义配置:
cat /etc/containerd/config.toml
version = 2
root = "/var/lib/containerd"
state = "/run/containerd"

[grpc]
  address = "/run/containerd/containerd.sock"
  gid = 0
  max_recv_message_size = 16777216
  max_send_message_size = 16777216
  uid = 0

[plugins]
  [plugins."io.containerd.grpc.v1.cri"]
    sandbox_image = "registry.tke.com/library/pause:3.2"
    [plugins."io.containerd.grpc.v1.cri".cni]
      bin_dir = "/opt/cni/bin"
      conf_dir = "/etc/cni/net.d"
    [plugins."io.containerd.grpc.v1.cri".containerd]
      
      default_runtime_name="runc"
      
    [plugins."io.containerd.grpc.v1.cri".registry]
      [plugins."io.containerd.grpc.v1.cri".registry.configs]
        
        [plugins."io.containerd.grpc.v1.cri".registry.configs."registry.tke.com".tls]
          insecure_skip_verify=true
        
        [plugins."io.containerd.grpc.v1.cri".registry.configs."default.registry.tke.com".tls]
          insecure_skip_verify=true
  1. 修改 kubelet 参数:
cat /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
Environment="KUBELET_RUNTIME_ARGS=--container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/sysconfig/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS $KUBELET_RUNTIME_ARGS
  1. 激活 containerd 服务:systemctl daemon-reload && systemctl enable containerd.service && systemctl start containerd.service

  2. 启动kubelet服务:systemctl daemon-reload && systemctl start kubelet.service

  3. 解除节点封锁:kubectl uncordon xxx

master0节点迁移

如果你的集群不是TKEStack的global集群请忽略以下内容。如果你确定你当前的TKEStack没有使用内置的tke-registry作为镜像仓库,也可以忽略一下内容。

不确定哪个是master0节点的话,可以通过kubectl get pod -n tke -owide | grep tke-registry-api查看pod所在节点,该节点就是mater0节点。

master0节点迁移放在其他节点迁移完成后在进行,相较非master0迁移多出了一下步骤:

  1. 在步骤1. 封锁节点前备份master0节点镜像到其他master节点:
## 使用docker在master0节点上执行:
docker save $(docker images | sed '1d' | awk '{print $1 ":" $2}') -o backup.tar

## 使用nerdctl在其他master节点上执行:
nerdctl --namespace=k8s.io load -i backup.tar
  1. 在步骤9. 激活 containerd 服务之后,步骤10. 启动kubelet服务之前加载master0节点镜像:
## 使用nerdctl在master0节点上执行:
nerdctl --namespace=k8s.io load -i backup.tar

TKEStack 容器混合云能力介绍(1):统一基石

Author: LeoRyu, HuXiaoLiang

随着云计算及云原生技术在各个领域内的逐步普及,基于 Kubernetes 的混合云相关概念和项目越来越受到人们的关注。以混合云形态部署企业的业务服务,在理论上可以最大化利用现有资源,形成差异互补和成本优化。以云计算及云原生技术作为基础设施的企业大致可以分为两类:一种是已经有存量 IDC 的企业,一种是业务全面使用公有云的企业。从已经有存量 IDC 的企业角度考虑,混合云可以最大化利用现有IDC资源的同时,既可以发挥 IDC 的灵活安全能力,也可以享受到公有云的高性价比优势;从业务全面使用公有云的企业角度考虑,混合云在为企业提供不同云服务商的差异能力的同时,也减少了企业绑定单一云服务商的潜在风险。尽管混合云的愿景是美好的,但走向这愿景的路并非简单。本文将着重介绍 TKEStack 提供混合云能力的道路上,在统一操作系统版本、 Kubernetes 版本、容器运行时和用户交互上遇到的困境与解决方案。

不统一带来的问题

安全风险

在 Linux 和 Kubernetes 受到广泛关注的今天,其安全问题的影响范围也越来越大。例如 2018 年爆出的特斯拉公司计算基础设施被黑客入侵用来挖矿的事件[1],就是因为特斯拉在亚马逊 AWS 上的 Kubernetes 容器集群访问权限没有得到妥善保护,导致存储在S3网络存储桶上的一些敏感技术数据,例如遥测技术,被窃取。

根据 Palo Alto Networks 公司 Unit 42 团队的研究报告,在 2018 年 1 月至 2019 年 6 月之间,有2万多个基于 Kubernetes 的容器平台被暴露,下图为这些被暴露平台在全球范围内的统计数据[2]

被暴露的平台统计

该报告中还统计了各云服务提供商平台上发现的漏洞:亚马逊 AWS 平台上被发现超过 2900 万个漏洞,谷歌云发现的漏洞数量接近 400 万,微软 Azure 发现了 170 万左右漏洞。

这些漏洞分布在各种操作系统版本、Kubernetes 发行版本、容器运行时乃至用户交互的前端相关代码中。这些关键要素的不统一在客观上为这些安全漏洞提供了温床。

运维成本

不统一也会使得用户的运维成本变得很高。例如当前 TKEStack 在混合云场景主推的网络方案 Cilium,其很多特性都要求在特定的内核版本以上才支持开启,下图是 Cilium 不同特性对内核版本要求的统计[3]

Cilium特性内核版本要求

而 Kubernetes 版本尽管声明 patch 版本上下兼容,但实际上在各版本间 API 资源对象的转换方面可能存在兼容问题。例如 TKEStack 在升级 Kubernetes API 版本时就发现 url.Values 隐式自动转换为 Kubernetes 对象已经被废弃[4],导致很多接口无法正常使用。

随着业务的运行时间拉长和不断迭代,因为操作系统、Kubernetes、容器运行时和 UI 的不统一造成的运维成本,也会随着时间的推移越堆越高。

TKEStack 社区为统一操作系统和 Kubernetes 版本做出的努力

推荐使用 TencentOS Server

TencentOS Server 又名 Tencent Linux,简称 Tlinux 是腾讯针对云场景研发的 Linux 操作系统,提供了专门的功能特性和性能优化,为云服务器实例中的应用程序提供高性能,且更加安全可靠的运行环境[5]

TencentOS

作为一个Linux发行版,Tlinux拥有以下优势:

  1. 内核定制,基于内核社区长期支持的4.14.105版本定制而成,增加适用于云场景的新特性、改进内核性能并修复重大缺陷。

  2. 容器支持,针对容器场景进行优化,提供了隔离增强和性能优化特性:meminfo、vmstat、cpuinfo、stat、loadavg, uptime, diskstats。

  3. 性能优化,计算、存储和网络子系统均经过优化,包括:优化 xfs 内存分配,解决 xfs kmem_alloc 分配失败告警优化网络收包大内存分配问题,解决 UDP 包量大时,占据过多内存问题限制系统 page cache 占用内存比例,从而避免内存不足影响业务的性能或者 OOM。

  4. 缺陷支持,提供操作系统崩溃后的 kdump 内核转储能力提供内核的热补丁升级能力。

  5. 安全更新,会定期进行更新,增强安全性及功能。

  6. 其他特性,离线调度算法(BT)、进程防gdb、ARM64热补丁、pagecache limit等。

在混合云场景下 TKEStack 推荐使用 TencentOS Server 作为底层的操作系统,安全高效并提供了强大的云原生能力,关于 TencentOS Server 可以到项目网站 https://github.com/Tencent/TencentOS-kernel 以了解更多内容。

引入 TKE 发行版到 TKEStack

长久以来,TKEStack 只提供了原生 Kubernetes 给用户使用,这使得 TKEStack 所能提供给用户的能力常常受到原生 Kubernetes 的现有能力的限制。为了打破这一现状,TKEStack 在前不久发布的 1.7 版本引入了由腾讯云 TKE 发布的 Kubernetes 发行版本,TKE 发行版(TKE Kubernetes Distro)。TKE 发行版在保证兼容性的基础上,对 K8s 进行了扩展,并且与腾讯云 TKE 服务保持版本一致。用户可以在自己的 IDC 或者混合云上部署 TKE 发行版,使用已有企业用户大规模验证的可靠安全的 Kubernetes 服务[6]

TKE发行版

相比原生的 Kubernetes 版本,TKE 发行版优势有下面几项:

  1. 大规模生产集群验证,TKE 发行版提供与腾讯云 TKE 相同的可安装版本和开源代码,功能和稳定性经过大量企业用户、公有云及自研云锤炼。用户可以使用提供的源代码和编译工具进行构建和部署。

  2. 无缝集成公有云 TKE,TKE 发行版可支持用户在自建或者托管机房,物理机或者虚机上,运行与腾讯云 TKE 完全一致的 K8s 服务。并且可以无缝与腾讯云 TKE 集成,组建混合云集群。

  3. 更长支持周期,TKE 发行版的支持周期比社区版更长。在社区版停止支持后,TKE 发行版将继续得到支持,包括重要问题以及安全漏洞的修复。

  4. 更多实用能力增强,TKE 发行版结合腾讯自身业务特点和经验,针对部分场景(弹性扩容、离在线混部、资源隔离等)实现了能力增强。并且 TKE 发行版紧跟社区趋势,主导或深度参与社区 KEP 设计与实现。对于有实用价值 KEP 会先于社区支持,让用户提前享受到云原生技术进步。

关于 TKE 发行版的更多信息可以访问 https://github.com/tkestack/tke-k8s-distro 以进一步了解。

在 1.7 版本中 TKEStack 支持 TKE 发行版本和原生两种 Kubernetes 发行版本,由于 TKE 发行版完全兼容原生 Kubernetes 发行版本,在后续的迭代中 TKEStack 将朝着只携带 TKE 发行版的方向逐步前进。

使用 Containerd 作为容器运行时

2020 年年末,Kubernetes社区宣布预计最早将在2021年晚些时候发布的 1.23 版本中废弃dockershim[7],这意味着未来的 Kubernetes 将不再支持以 Docker 作为容器运行时。

TKEStack 社区经过研讨调研后,决定使用和腾讯公有云 TKE 一致的 Containerd 作为未来替代 Docker 的容器运行时。Containerd 是除 Docker 外当下最为成熟稳定,并被广泛接受的容器运行时,下图是 2021 年年初关于容器运行时使用率相关的调查统计[8]

运行时使用率

Containerd 的架构是 client-server 架构,支持 runc、Kata Container 等多种底层运行时,同时又有很高的扩展性,下图为 Containerd 的整体架构图[9]

containerd整体架构

作为过渡时期,如果用户选择的 Kubernetes 版本依旧支持 dockershim,TKEStack 将允许用户在创建集群时决定选择 Docker 还是 Containerd 作为容器运行时,并提供文档,帮助用户将存量集群的 runtime 从 Docker 迁移到 Containerd。未来,TKEStack会移除掉 Docker 的依赖,全面兼容社区的 CRI 标准模型,并将 Containerd 作为默认的 runtime 与公有云 TKE 保持统一。

风格统一的用户交互

统一的交互风格可以大大减少用户的学习成本和心智负担。TKEStack 与腾讯公有云 TKE 产品采用了相同的交互风格,用户只需要适应了其中一个的交互习惯,就可以几乎零学习成本的操作使用另外一款产品。下图展示了 TKEStack 和腾讯公有云 TKE 产品的用户前端交互页面:

containerd整体架构

TKEStack 和腾讯公有云 TKE 产品上有着很多相同的概念,针对这些概念的视图展示逻辑也是一致的。在混合云场景下,这种一致性将产生积极的化学反应,对用户非常友好,并减轻了维护上的成本。

交互的统一不仅仅对用户有很多好处,对后续 TKEStack 的产品设计,后台架构搭建及能力实现上都有着积极的作用,而这种积极作用会为 TKEStack 加速布局混合云领域提供有力的支持。

总结

正所谓工欲善其事,必先利其器,只有统一巩固一个强大稳定的平台基石,TKEStack 才会在提供混合云能力的道路上行驶的更加平稳。后续我们会在该系列中介绍更多关于 TKEStack 的混合云能力,敬请大家期待。

最后欢迎大家到 TKEStack 的项目仓库 https://github.com/tkestack/tke 提出建议贡献力量,大家的支持将会令 TKEStack 项目变得更好!

参考资料

[1] Lessons from the Cryptojacking Attack at Tesla [https://redlock.io/blog/cryptojacking-tesla]

[2] Cloudy with a Chance of Entropy [https://www.paloaltonetworks.com/resources/research/unit42-cloud-with-a-chance-of-entropy]

[3] Required Kernel Versions for Advanced Features [https://docs.cilium.io/en/v1.10/operations/system_requirements/#required-kernel-versions-for-advanced-features]

[4] Can no longer call DecodeParameters with url.Values in 1.19.0 client-go [https://github.com/kubernetes/kubernetes/issues/94688]

[5] 腾讯TencentOS 十年云原生的迭代演进之路 [https://mp.weixin.qq.com/s/Cbck85WmivAW0mtMYdeEIw]

[6] 腾讯云云原生混合云-TKE发行版 [https://mp.weixin.qq.com/s/d7ubPXwtTw8JsFIHp-JXEg]

[7] Dockershim Deprecation FAQ [https://kubernetes.io/blog/2020/12/02/dockershim-faq/]

[8] Sysdig 2021 container security and usage report: Shifting left is not enough [https://sysdig.com/blog/sysdig-2021-container-security-usage-report/]

[9] Introduction and Deep Dive Into Containerd [https://static.sched.com/hosted_files/kccnceu2021/d3/containerd-KubeConEU2021.pdf]

腾讯开源容器云平台 TKEStack 介绍

Author: Yingzhe Ru (汝英哲)

2019年11月在腾讯 Techo 开发者大会上,TKEStack 正式发布并宣布开源, 同一时间凝结着腾讯多年来容器技术积累的代码也通过 push 命令上传到 github, 从那一刻起我们开启了一段面向开源,充满机遇与挑战,驶向未来云世界的伟大航程。 时间回到今天,TKEStack 自开源后已经过去了几个月,迭代了多个版本,当前仍在以较快的速度提交修改,发布更新。 随着开发进度的推进,产品的功能逐渐增强,用户体验愈发的完善,整个产品和技术栈的轮廓也愈加的清晰, 因此有必要在这里系统介绍一下 TKEStack 容器云平台,明确我们的目标,展示平台的特性以及为您提供的价值,希望您阅读完这篇文章后, 能够对 TKEStack 产生兴趣,了解到 TKEStack 的能力,并能够考虑使用或集成 TKEStack 助力您的业务或商业产品落地。

简介

近年来在云计算领域,容器技术领域不断创新,围绕容器以及容器相关技术构建出云原生的生态和技术标准。 基于 Kubernetes 的容器平台,为容器化的应用提供资源调度、部署运行、服务发现和弹性伸缩等整一套功能, 逐步成为客户软件基础设施的不二之选。

腾讯在云计算领域深耕多年,尤其在容器技术领域,自2009年开发容器计算平台 T-Borg 开始,2012年开发内部的离线在线混合部署的容器平台 Torca,2013、2014年 Docker 和 Kubernetes 出现后,腾讯迅速切换自研方案到开源方案,对外推出商用公有云版本服务TKE和私有云版本 GaiaStack。2019年,公有云和私有云版本合并为统一架构和方案 TKE,并推出了社区发行版 TKEStack。

TKEStack是腾讯内部几大团队合力打造的开源版本,总结了多年来腾讯在云原生领域的经验和技术积累,吸收了 Gaia 平台、TKE公有云以及腾讯内部众多容器产品的优点,全新打造的面向私有云业务场景的开源容器平台。TKEStack 以高起点起步,甩掉大量历史遗留包袱,从架构上重新设计,并且结合业内生态最新的更新和特性,使得TKEStack轻装上阵,用户开箱即用最新的云原生能力。

TKEStack 名称中包含 Stack,也表明 TKEStack 有别于其他容器产品,它将打造的是一整套技术栈,以 TKE 容器平台为核心,面向网络,存储,应用,服务等各个领域,扩展平台在底层资源管控和上层业务服务上的能力边界,所有这些能力都将在 TKEStack 下开源,社区用户、合作伙伴等都可以参与进来贡献和分享。

愿景与目标

未来云计算基础设施一定处于多维异构的状态,未来客户也会处于多维异构的业务场景,包括硬件异构、基础架构异构和业务平台异构。

  • 硬件异构 - 随着国产化在国内的发展,将来客户的服务器架构将会是 x86 和 arm64 混杂在一起;随着AI计算发展,Intel 等厂商也加入到 GPU 的竞争中,再加上 ARM 平台的 GPU 和 FPGA 等硬件,计算领域的硬件将更加碎片化。
  • 基础架构异构 - 未来的数字化计算服务中心,尤其在国内,将更多会采用私有化(或专有云)和公有云混合部署的模型支持业务发展。
  • 业务平台异构 - 传统业务在无法全部迁移下的情况,长期会和微服务、Service Mesh 、Serverless等技术组成一个异构的业务大中台,同时还要支撑使用 Spark、Hadoop、TensorFlow、PyTorch 等计算平台运行。

我们的愿景是为内部业务和外部商业客户提供离线计算业务和在线服务业务混合部署的一站式通用基础架构平台。 基于此愿景,TKEStack 将继承腾讯内部容器技术优势,为用户、为合作伙伴、为生态创造价值,生态共建,产业共创。

  • 面向用户 - 为用户提供稳定高效可扩展的容器服务产品,提供便捷的安装部署、简洁的管控和资源管理,以及完善的运维工具支持,满足业务上云需求。
  • 面向合作伙伴 - 为下游产品提供调度能力强大、功能丰富、性能稳定的容器底座,使用户能基于 TKEStack 便捷打造易部署、易维护、易扩展的产品和服务,在互联网、传统行业与政企等领域提供有针对性的行业解决方案。
  • 面向生态 - 围绕容器生态的各种能力,统一应用服务的定义,发布、配置、升级及运维整个生命周期管理,整合中间件、运行时、存储、网络能力,逐步建立起一个基于云原生的容器平台标准。

整体架构

TKEStack整体架构上采用 Kubernetes on Kubernetes 的设计理念,充分满足平台服务的高可用性和扩展性。

TKEStack整体架构
  • Global: 集群负责运行整个 TKEStack 平台自身所需组件;
  • Cluster: 业务集群是由 TKEStack 控制台统一管理,负责运行业务;
  • Installer: 负载安装 Global 集群和管控组件;
  • Auth: 权限认证组件,提供用户认证、授权相关功能;
  • Gateway: 网关组件,并运行控制台的 Web 界面服务;
  • Platform: 平台管理组件,提供包含集群管理等功能的平台服务;
  • Business: 业务管理组件,提供业务管理相关功能的后台服务;
  • Monitor: 监控服务组件,提供监控采集、上报、告警相关服务;
  • Notify: 通知功能组件,提供消息通知相关的功能;
  • Registry: 镜像服务组件,提供平台镜像仓库和 charts 仓库服务;
  • Galaxy: 网络插件,为集群提供多种网络模式服务;
  • Logagent: 日志管理组件,为平台提供日志管理相关服务;
  • Audit: 设计组件,提供审计服务功能;

Global 集群提供容器云平台的支撑环境和运行自身所需的各种组件,包括业务管理组件、平台管理组件、权限认证组件、监控和告警组件、registry 镜像仓库组件以及 gateway 前端页面网关组件等等。各个组件以 workload 的形式灵活部署在 global 集群中,各组件多副本高可用方式部署,单个组件异常或者主机节点掉线等故障不会影响global集群的正常运行,TKEStack仍可提供的管理功能,用户正常的业务访问不受影响。

在扩展性方面,根据不同场景灵活配置集群,例如为承载大流量高可靠性的在线业务,有必要提高 global 集群的规格配置,使其能够管理大规模海量的业务集群及应用资源;如果面向个人开发者或中小型业务,甚至可以简化为仅数个节点组成的 global 集群,并通过该集群承载业务。

能力特性

通过集成和使用 TKEStack,不仅支持 K8S 原生的资源调度、部署运行、服务发现和弹性伸缩等整一套功能,TKEStack 还支持多种特性,方便用户接入和使用,通过灵活的扩展功能实现自身服务的增值。

原生支持

TKEStack是一款专注于 Kubernetes 技术栈的,集易用性与扩展性于一身的 K8S 发行版,符合Kubernetes接口标准,产品底层完全兼容标准 Kubernetes。因此,基于 Kubernetes 生态的应用和服务都可以无缝迁移到TKEStack上来,有标准K8S运维管理经验的用户可以平滑的切换到 TKEStack 平台。

TKEStack 跟随最新 k8s 版本,支持所有可用的功能和安全补丁,通过灵活的集群管理功能,方便的对集群进行更新升级操作,帮助用户体验和使用最新的生态技术。作为云原生的基础设施平台,任何符合云原生规范和标准的应用或项目,都可以构建和运行在 TKEStack 中。

简单易用

提供和腾讯公有云版一致的 UI,界面简洁友好,支持配置各种 K8S 资源,方便用户顺利的创建和管理容器应用,降低了容器平台的学习和操作成本。TKEStack 还有着完善的镜像仓库和应用商店功能,内部包含腾讯优秀的开源容器应用模板,方便用户一键部署高质量稳定的应用服务。

多集群管理

支持新建独立集群或纳管不同基础设施上的已有 Kubernetes 集群,通过页面或命令行集中管理多个集群,实现了混合云场景下的多集群统一管理能力。只需提供需要管理集群的 api 地址,token 和 ca 证书,TKEStack 就可以纳管该集群。纳管操作不会污染导入的集群,被纳管集群不会增加额外的负载或配置。统一一致的用户权限及业务管理等功能帮助用户在集群间灵活切换,方便的部署和管理多集群应用。

多集群管理

更多信息请参考集群管理

多租户管理

支持多租户管理和租户间隔离,不仅仅局限于账号,而是包括集群、命名空间、业务、镜像仓库等等,满足大中型规模企业管理的需求。并且在租户层次之下,拥有业务的概念,业务可以横跨集群,为用户提供统一的配额管理、命名空间、业务配额以及镜像仓库和应用商店等管理能力,方便用户在多集群场景下编排业务应用。

多租户管理

TKEStack提供统一和开放的认证授权管理,通过扩充 kubernetes 的 authz 和 authn 的 webhook,实现所有集群无需单独配置 RBAC,为上层提供统一的可跨集群的资源授权。TKEStack自身的认证和授权体系是完整的 K8S Style API 以及 oidc 认证协议支持,可以很容易的由第三方集成商或开发者集成在自身的产品中,实现和 TKEStack 捆绑服务。企业级用户可以方便的将已有的账户体系或组织架构映射到 TKEStack 平台中,从而节省容器平台对接的工作量,专注于自身高价值业务的开发。

更多信息请参考访问管理

运维友好的管理平台

TKEStack 致力于打造一个运维友好的管理平台,帮助运维人员从繁杂的劳动中解放出来。TKEStack 提供完整详细的监控及日志服务,粒度精细到对集群下每一个容器每一条日志都有监控和记录。并且提供智能化的安装工具、巡检工具,帮助运维人员对整个平台全程进行管理,提前发现风险点,提高系统的可靠性。

快捷安装

TKEStack 使用 tke-installer 安装工具进行安装,通过界面化的方式引导用户一键部署 TKEStack 容器平台。tke-installer 安装工具能够检查基本的环境信息,自动适配 x86 或 arm 版本安装驱动和镜像。离线的安装方式更免去用户拉取镜像的烦恼,极大的提高了容器平台部署的效率。

安装流程

tke-installer 自动等待和检查每一步骤安装完成,如果中间过程出错会自动在日志界面提示相应的信息,并支持根据用户需要,选择全新安装或从失败步骤继续安装。更支持以 hook 方式自定义安装流程,用户可以在安装开始前、集群 ready 后以及安装结束后三个 hook 点添加自己的脚本或命令,实现平台安装的可定制化。

更多安装信息请见:TKEStack安装说明

监控系统

免去部署和配置 prometheus 的复杂操作,TKEStack 提供高可用性和可扩展性的细粒度监控系统,实时监控 CPU,GPU,内存,显存,网络带宽,磁盘io等多种指标并自动绘制趋势曲线,帮助运维人员全维度的掌握平台运行状态。

监控系统

TKEStack通过prometheus组件监控集群状态,prometheus 组件通过 addon 扩展组件自动完成安装和配置,使用 influxdb,elasticsearch 等存储监控数据。监控数据和指标融入到平台界面中以风格统一图表的风格展示,支持以不同时间,粒度等条件,查询集群,节点,业务,workload以及容器等多个层级的监控数据,全维度的掌握平台运行状态。

同时针对在可用性和可扩展性方面,支持使用 thanos 架构提供可靠的细粒度监控和警报服务,构建具有高可用性和可扩展性的细粒度监控能力。

详情请见thanos架构介绍

日志服务

提供的集群内日志采集功能,支持将集群内服务或集群节点特定路径文件的日志发送至 Kafka、Elasticsearch等消费端,支持采集容器标准输出日志,容器内文件日志以及主机内文件日志。更提供事件持久化、审计等功能,实时记录集群事件及操作日志记录,帮助运维人员存储和分析集群内部资源生命周期、资源调度、异常告警等情况。

日志服务

需要为每个集群手动开启日志采集功能。日志采集功能开启后,log-collector 会在集群内以 DaemonSet 的形式运行,并根据用户通过日志采集规则配置的采集源和消费端,从采集源进行日志采集,将日志内容发送到消费端。

  • 采集容器标准输出日志 - 采集集群内指定容器的标准输出日志,采集到的日志信息将会以 JSON 格式输出到用户指定的消费端,并会自动附加相关的 Kubernetes metadata, 包括容器所属 pod 的 label 和 annotation 等信息。
  • 采集容器内文件日志 - 采集集群内指定 pod 内文件的日志,用户可以根据自己的需求,灵活的配置所需的容器和路径,采集到的日志信息将会以 JSON 格式输出到用户指定的消费端, 并会附加相关的 Kubernetes metadata,包括容器所属 pod 的 label 和 annotation 等信息。
  • 采集主机内文件日志 - 采集集群内所有节点的指定主机路径的日志,log-collector 会采集集群内所有节点上满足指定路径规则的文件日志,以 JSON 格式输出到用户指定的输出端, 并会附加用户指定的 metadata,包括日志来源文件的路径和用户自定义的 metadata。

更多日志信息请参考日志管理

平台巡检

巡检工具 kube-javis,通过 plugin 插件的方式灵活配置和扩展,多维度的检查 TKEStack 平台下集群的健康状况,支持集成到 TKEStack 平台中,定期运行并输出诊断结果和修复建议。

更多详细信息请关注kube-javis

扩展组件支持和管理

Tkestack 的特色功能,以扩展组件的方式来订制集群的能力,扩展集群的功能。TKEStack 已支持多种扩展组件,包含:

  • GPUManager - GPU Manager 提供一个 All-in-One 的 GPU 管理器, 基于K8S Device Plugin插件系统实现, 提供了 GPU 虚拟化、拓扑分配、GPU 共享、GPU 指标查询、GPU 容器 pre-check 等功能, 支持用户在 K8S 集群中高效的使用 GPU 设备。
  • TApp - Tapp 是结合腾讯十多年海量运营经验,全新设计出的一种 workload,以 CRD 的形式实现。 Tapp可运行有状态、无状态应用,弥补了 StatefulSet 无法批量更新容器的不足,使用方式兼容传统运维习惯,更好的支持传统的有状态应用,能够实现灰度升级和多版本的发布管理。
  • CronHPA - 使用 crontab 模式定期自动扩容工作负载,周期性地在给定的调度时间对工作负载进行扩缩容。
  • LBCF - 一款通用负载均衡控制面框架,对K8S内部晦涩的运行机制进行了封装并以 Webhook 的形式对外暴露,并提供强大的扩展能力以满足业务方在使用负载均衡时的个性化需求。
  • CSIOperator - 负责 CSI 相关组件的部署与维护,帮助用户在集群中使用存储。
  • IPAM - 通过 IPAM 扩展组件安装,扩展了 K8S 调度插件,实现 Float IP 的配置和管理,满足复杂应用容器化的特殊需求。

更多详情请参考扩展组件

总结

随着2020年3月国家发改委进一步明确了包括以云计算等为代表的新技术基础设施纳入“新基建”的范围,国内云计算市场将迎来一波建设的热潮。尤其在私有云领域,传统行业企业基本开始了业务的云迁移,但其应用系统的弹性、自动化运维管理能力以及 Devops 和持续交付的能力仍在不断的探索和尝试,迫切的需要一套成熟的产品平台和生态体系,帮助企业完成云原生转型。

开源TKEStack的推出,将推动企业业务向云原生的转型,提供完善的容器产品功能,打造运维友好的管理平台,减少用户繁复的劳动,提高工作效率。完善的API和租户管理能力,方便用户将已有的账户体系或组织架构映射到TKEStack平台中,节省平台业务对接的工作量。并且良好的扩展能力使得用户能够基于 TKEStack 适配本地基础设施,扩展业务所需的各种能力。

TKEStack 已在腾讯内部大量使用,总结积累了大量经验和技术,持续进行迭代开发,不断完善功能特性,并且第一时间将成果贡献给社区,帮助用户紧跟云原生潮流,享用最新技术能力,同时免除了被技术绑定的风险。我们希望通过 TKEStack 的稳定高效和灵活扩展的平台能力,帮助您构建以 TKEStack 为底座的,适配各种硬件架构和基础环境的,面向 AI、大数据、中间件以及微服务等等多种场景的服务,在互联网、传统行业与政企等领域,联合合作伙伴提供有针对性的行业解决方案。TKEStack 仍在不断的成长中,后续我们还会开发更多的功能,输出更多腾讯内部优秀的产品和能力。

最后,感谢您的时间,希望你在读完文章后,能够了解到 TKEStack 容器云平台,希望 TKEStack 能够成为您的选择, 我们愿与您一道前行,创造价值,加速创新,共建云生态,一起迈向未来云世界。