Kubernetes——安全认证

Kubernetes集群安全机制说明

Kubernetes作为一个分布式集群的管理工具,保证集群的安全性是其中一个重要的任务,API Server是集群内部各个组件通信的中介,也是外部控制的入口。所以Kubernetes的安全机制基本就是围绕保护API Server来设计的。Kubernetes使用了认证(Authentication)、鉴权(Authorization)、准入控制(Admission Control)三步来保证API Server的安全。


认证(Authentication)

  • HTTP Token认证:通过一个Token来识别合法用户
    • HTTP Token的认证是用一个很长的特殊编码方式的并且难以被模仿的字符串-Token来表达客户端的方式,Token是一个很长的很复杂的字符串,每一个Token对应一个用户名存储在API Server能访问的文件中,当客户端发起API请求调用时,需要在HTTP Header里放入Token。
  • HTTP Base认证:通过用户名+密码的方式认证
    用户名:密码用BASE64算法进行编码后的字符串放在HTTP Request中的Header Authorization域里发送给服务端,服务端收到后进行解码,获取用户名和密码。
  • HTTPS 证书认证:基于CA证书签名的数字证书认证

HTTPS 证书认证

HTTPS 证书认证

需要认证的节点

需要认证的节点

两种类型

  • Kubernetes组件对API Server的访问:kubectl、Controller Manager、Scheduler、kubelet、kube-proxy
  • Kubernetes管理的Pod对容器的访问:Pod(dashborad也是以Pod形式运行)

安全性说明

  • Controller Manager、Scheduler与API Server在同一台机器,所以直接使用API Server的非安全端口访问--insecure-bind-address=127.0.0.1
  • kubectl、kubelet、kube-proxy访问API Server都需要证书进行HTTPS双向认证

证书颁发

  • 手动签发:通过K8s集群跟ca进行签发HTTPS证书
  • 自动签发:kubelet首次访问API Server时,使用token做认证,通过后Controller Manager会为kubelet生成一个证书以后的访问都是用证书做认证了。

kubeconfig

kubeconfig文件包含集群参数(CA证书、API Server地址),客户端参数(上面生成的证书和私钥)、集群Context信息(集群名称、用户名)。Kubernetes组件通过启动时指定不同的kubeconfig文件可以切换到不同的集群。

ServiceAccount

Pod中的容器访问API Server,因为Pod的创建、销毁是动态的,所以要为它手动生成证书就不可行了,Kubernetes使用了Service Account解决Pod访问API Server的认证问题。

Secret和CA的关系

Kubernetes设计了一种资源叫做Secret,分为两类,一种是用于ServiceAccount的service-account-token,另一种是用于保存用户自定义保密信息的Oqaque,ServiceAccount中用到包含三个部分:Token、ca.crt、namespace

  • Token:是使用了API Server私钥签名的JWT,用于访问API Server时,Server端认证
  • ca.crt:根证书,用于Client端验证API Server发送的证书
  • namespace:标识这个service-account-token的作用域名空间
    默认情况下,每个namespace都会有一个ServiceAccount,如果Pod在创建时没有指定ServiceAccount,就会使用Pod所属的namespace的ServiceAccount。

鉴权(Authorization)

上面的认证过程,只是确认通信的双方都确认对方是可信的,进而可以互相通信。
鉴权是确定请求方有哪些资源权限,API Server 内部通过用户认证后,然后进入授权流程。对合法用户进行授权并且随后在用户访问时进行鉴权,是权限管理的重要环节。API Server目前支持以下几种授权策略(通过API Server的启动参数--authorization-mode设置)

  • Always Deny: 表示拒绝所有的请求,一般用于测试。
  • Always Allow:允许接收所有请求,如果集群不需要授权流程,则可以采用该策略。
  • ABAC: 基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制。
  • Webhook:通过调用外部REST服务对用户进行授权。
  • RBAC:Role-Base Access Control, 基于角色的访问控制。

RBAC授权模式

RBAC(Role-Based Access Control,基于角色的访问控制)在Kubernetes v1.5引入,在v1.6版本时升级为Beta版本,并成为kubeadm安装方式下的默认选项,组建其重要程度。相对于其他的访问控制方式,RBAC具有如下优势。

  • 对集群中的资源和非资源权限均有完整的覆盖。
  • 整个RBAC完全由几个API对象完成,同其他API对象一样,可以用kubectl或API进行操作。
  • 可以在运行时进行调整,无须重新启动API Server。

要使用RBAC授权模式,则需要在API Server的启动参数中加上--authorization-mode=RBAC


角色

  • Role:授权特定命名空间的访问权限
  • ClusterRole:授权所有命名空间的访问权限

角色绑定

  • RoleBinding:将角色绑定到主体(即subject)
  • ClusterRoleBinding:将集群角色绑定到主体

主体(subject)

  • User:用户
  • Group:用户组
  • ServiceAccount:服务账号

1、RBAC的API资源对象说明

BAC引入了4个新的顶级资源对象:Role、ClusterRole、RoleBinding、ClusterRoleBinding。同其他API资源对象一样,用户可以使用kubectl或者API调用方式操作这些资源对象。


需要注意的是Kubernetes并不会提供用户管理,那么User、Group、ServiceAccount指定的用户又是从哪里来的呢?Kubernetes组件(kubectl、kube-proxy)或是其他自定义的用户在向CA申请证书时,需要提供一个证书请求文件。

[root@k8s-master1 ~]# vim jane-csr.json
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}
  • API Server会把客户端证书的CN字段作为User,把names.O字段作为Group
  • kubelet使用TLS Bootstaping认证时,API Server可以使用 Bootstrap Tokens或者Token authentication file验证=token,无论哪一种,Kubernetes都会为token绑定一个默认的User和Group
  • Pod使用ServiceAccount认证时,service-account-token中的JWT会保存User信息
  • 有了用户信息,在创建一对角色/角色绑定(集群角色/集群角色绑定)资源对象,就可以完成权限绑定了。

Role and ClusterRole

在RBAC API中Role表示一组规则权限,权限只会增加(累加权限),不存在一个资源一开始就有很多权限而通过RBAC对其进行减少的操作;Role可以定义在一个namespace中,如果想要跨namespace则可以创建ClusterRole

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: pod-reader
rules:
  - apiGroups: [""] # ""空字符串,表示核心API群
    resources: ["pods"]
    verbs: ["get", "watch", "list"]

rules中的参数说明:

  • apiGroups: 支持的API组列表,例如“apiVersion: batch/v1”、“apiVersion: extensions:v1beta1”、“apiVersion: apps/v1beta1”等。
  • resources:支持的资源对象列表,例如pods、deployments、jobs等。
  • verbs:对资源对象的操作方法列表,例如get、watch、list、delete、replace、patch等。

ClusterRole
ClusterRole处理具有和Role一致的命名空间内资源的管理能力,因其集群级别的范围,还可以用于以下特殊元素的授权。

  • 集群级别的资源控制,例如Node(节点)。
  • 非资源类型的路径,例如“/healthz”。
  • 包含全部命名空间的资源,例如pods(用于kubectl get pods --all-namespaces这样的操作授权)。

下面的ClusterRole可以让用户有权访问任意一个或所有命名空间的secrets(视其绑定方式而定):

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  # ClusterRole不受限于命名空间,所以省略了namespace name的定义
  name: secret-reader
rules:
  - apiGroups: [""] # ""空字符串,表示核心API群
    resources: ["secrets"]
    verbs: ["get", "watch", "list"]

角色绑定(RoleBinding)和集群角色绑定(ClusterRoleBinding)

RoleBinding可以将角色中定义的权限授予用户或用户组,RoleBinding包含一组权限列表(subjects),权限列表中包含有不同形式的待授予权限资源类型(users、groups、Service Account);RoleBinding同样包含对被Bind的Role引用,RoleBinding适用于某个命名空间内授权,ClusterRoleBinding适用于集群范围内授权。

下面例子中的RoleBinding将在default命名空间中把pod-reader角色授予用户jane,这一操作让jane可以读取default命名空间中的Pod:

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: read-pods
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

RoleBinding也可以引用ClusterRole,来对当前namespace内用户、用户组或ServiceAccount进行授权,这种操作允许集群管理员在整个集群内定义一些通用ClusterRole,然后在不同的namespace中使用RoleBinding来引用
例如,以下RoleBinding引用一个ClusterRole,这个ClusterRole具有整个集群内对secrets的访问权限,但是其授权用户dave只能访问development空间中的secrets(因为RoleBinding定义在development命名空间)

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: development
  name: read-secret
subjects:
- kind: User
  name: dave
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

集群角色绑定中的角色只能是集群角色,用于进行集群级别或者对所有命名空间都生效的授权。下面的例子允许manager组的用户读取任意namespace中的secret:

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: development
  name: read-secrets-global
subjects:
- kind: Group
  name: manager
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

资源(resources)与主体(subjects)

资源(resources)介绍

  • 在Kubernets中,主要的资源包括:Pods、Nodes、Services、Deployment、Replicasets、Statefulsets、Namespace、Persistents、Secrets和ConfigMaps等。
  • 同时,有些资源下面存在子资源,例如:Pod下就存在log子资源。
# logs资源就属于pods的子资源,API中URL样例如下
Get /api/v1/namespaces/{namespace}/pods/{name}/log

示例1:普通角色的资源列表:

[root@k8smaster01 study]# vi pod-and-pod_log.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-and-pod-logs-reader
rules:
  - apiGroups: [""]
    resources: ["pods","pods/log"]
    verbs: ["get","list"]

解释:如上限定在default的命名空间的名为pod-and-pod-logs-reader的普通角色,对pod和pods/log资资源就有get和list的权限。

示例2:更精细粒度的资源控制,可通过resourceNamess指定特定的资源实例,以限制角色只能够对具体的某个实例进行访问控制。

[root@k8smaster01 study]# vi updater_configmap.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: configmap-updater
rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    resourceNames: ["my-configmap"]
    verbs: ["update","get"]

解释:如上限定在default的命名空间的名为configmap-updater的普通角色,对名为my-configmap的configmaps类型的特定资源,具有update和get权限。

主体(subjects)介绍

  • RBAC授权中的主体可以是组,用户或者服务帐户。用户通过字符串表示,比如“alice”、“bob@example.com”等,具体的形式取决于管理员在认证模块中所配置的用户名。
  • system: 被保留作为用来Kubernetes系统内部使用,因此不能作为用户的前缀。组也有认证模块提供,格式与用户类似。

示例1:类型为user(用户)。

subjects:
  - kind: User
    name: "alice@example.com"
    apiGroup: rbac.authorization.k8s.io

示例2:类型为group(组)。

subjects:
  - kind: Group
    name: "frontend-admins"
    apiGroup: rbac.authorization.k8s.io

示例3:查看default的服务账户。

subjects:
  - kind: ServiceAccount
    name: default
    namespace: kube-system

准入控制

Kubernetes系统通过三个独⽴的组件间的相互协作来实现服务账户的⾃动化,三个组件具体为:Admission Controllers准⼊控制器、令牌控制器(token controller)和Service Account账户控制器。Service Account控制器负责为名称空间管理相应的资源,并确保每个名称空间中都存在⼀个名为“default”的Service Account对象。

当请求通过了前面的认证和授权之后,还需要经过准入控制处理通过之后,apiserver 才会处理这个请求。Admission Control 有一个准入控制列表,我们可以通过命令行设置选择执行哪几个准入控制器。只有所有的准入控制器都检查通过之后,apiserver 才执行该请求,否则返回拒绝。

为什么需要Admission Control

在kubernetes中,一些高级特性正常运行的前提条件为,将一些准入模块处于enable状态。总结下,对于kubernetes apiserver,如果不适当的配置准入控制模块,他就不能称作是一个完整的server,某些功能也不会正常的生效。

主要的准入控制器介绍

AlwaysAdmit

允许所有请求

AlwaysDeny

拒绝所有请求

AlwaysPullImages

强制设置Pod拉取镜像策略为Always。这样能够保证私有镜像只能被有拉取权限的使用者使用。

DenyExecOnPrivileged

它会拦截所有想在privileged container上执行命令的请求。(如果自己的集群支持privileged container,自己又希望限制用户在这些privileged container上执行命令,那么强烈推荐使用它。)

DenyEscalatingExec

这个插件禁止那些通过主机执行而获得privileges去执行exec和attach Pod的命令。

ImagePolicyWebhook

通过webhook决定image策略,需要同时配置–admission-control-config-file

ServiceAccount

一个serviceAccount为运行在pod内的进程添加了相应的认证信息。当准入模块中开启了此插件(默认开启),如果pod没有serviceAccount属性,将这个pod的serviceAccount属性设为“default”;确保pod使用的serviceAccount始终存在;如果LimitSecretReferences 设置为true,当这个pod引用了Secret对象却没引用ServiceAccount对象,弃置这个pod;如果这个pod没有包含任何ImagePullSecrets,则serviceAccount的ImagePullSecrets被添加给这个pod;如果MountServiceAccountToken为true,则将pod中的container添加一个VolumeMount 。

ResourceQuota

它会观察所有的请求,确保在namespace中ResourceQuota对象处列举的container没有任何异常。如果在kubernetes中使用了ResourceQuota对象,就必须使用这个插件来约束container。(推荐在admission control参数列表中,这个插件排最后一个。)

LimitRanger

实现配额控制。他会观察所有的请求,确保没有违反已经定义好的约束条件,这些条件定义在namespace中LimitRange对象中。如果在kubernetes中使用LimitRange对象,则必须使用这个插件。

SecurityContextDeny

禁止创建设置了 Security Context 的 pod。这个插件将会将使用了 SecurityContext的pod中定义的选项全部失效。关于 SecurityContext的描述:SecurityContext 在container中定义了操作系统级别的安全设定(uid, gid, capabilities, SELinux等等)。

NamespaceLifecycle

确保处于termination状态的namespace不再接收新的对象创建请求,并拒绝请求不存在的namespace。

InitialResources

根据镜像的历史使用记录,为容器设置默认资源请求和限制

DefaultStorageClass

为PVC设置默认StorageClass

DefaultTolerationSeconds

设置Pod的默认forgiveness toleration为5分钟

PodSecurityPolicy

使用Pod Security Policies时必须开启

NodeRestriction

限制kubelet仅可访问node、endpoint、pod、service以及secret、configmap、PV和PVC等相关的资源(v1.7版本以上才支持)

推荐的设置控制器顺序:

--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds

参考:
https://www.cnblogs.com/xzkzzz/p/9909468.html

https://www.cnblogs.com/Dev0ps/p/10852445.html

https://www.kubernetes.org.cn/1995.html

https://www.kubernetes.org.cn/4061.html

https://www.jianshu.com/p/5a6e9ee8ab5a

https://www.jianshu.com/p/fd61330596eb

https://www.cnblogs.com/itzgr/p/11112879.html

https://www.cnblogs.com/yanjieli/p/11859041.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容