Security-集群安全

1)Authentication(认证)

认证文件

kubeconfig

ServiceAccount

2)Authorization(鉴权)

使用-RBAC-鉴权

基本概念

角色-RoleandClusterRole

角色绑定-RoleBindingandClusterRoleBinding

聚合-ClusterRoleAggregate

资源引用

主体引用

角色分类

实际案例

Role

ClusterRole示例

RoleBinding

ClusterRoleBingding示例

ClusterRole

RoleBinding示例

命令行角色

绑定创建示例

3)AdmissionControl(准入控制)

4)上下文环境

5)总结实践

实验1.配置证书与Api-Server认证访问

实验2.创建普通用户进行对Kubernetes集群的管理

实验3.集群管理员用户权限一览

Security-集群安全

描述:Kubernetes作为一个分布式的集群管理工具,保证集群的安全性是非常至关重要的。同时由于APIServer是集群内部各个组件通信的中介,也是外部控制的入口,所以Kubernetes的安全机制基本是就是围绕保护APIServer来进行设计的;

Kubernetes使用了认证(Authentication)、鉴权(Authorization)、准入控制(AdmissionControl)三步来保证每个请求APIServer都是安全;

1)Authentication(认证)

描述:开启TLS时所有的请求都需要首先认证,k8s支持多种认证机制并支持同时开启多个认证插件(只需要一个认证通过即可),如果认证成功则用户的username会传入授权模块做进一步的授权验证,而对于认证失败的请求则返回HTTP;

认证分类:

1.HTTPToken认证:通过一个Token(字符串)来识别合法用户;

简述:HTTPToken的认证是用一个很长的特殊编码方式的并且难以被模仿的字符串-Token来表达客户的一种方式(很长的很复杂的宇符串)。每个Token对应一个用户名存储在APIServer能访问的文件中。当客户端发起API调用请求时,需要在HTTPHeader里放入Token。

2.HTTPBase认证:通过用户名+密码的方式认证;

简述:用户名:密码用BASE64算法进行编码后的宇符串放在HTTPRequest中的HeatherAuthorization域里发送给服务端,服务端收到后进行编码从中获取用户名及密码;

3.HTTPS认证:最严格的认证方式之一;

简述:基于CA根证书签名(签发)的客户端/服务端身份认证方式(普遍采用方案);

Tips:k8s不管理用户虽然k8s认证授权采用了username但是k8s并不直接管理用户,不能创建user对象也不存储username。

认证流程:

HTTPS证书双向认证流程:

K8S各节点认证流程:

证书颁发说明:

1.手动签发:通过k8s集群的跟ca进行签发HTTPS证书;

2.自动签发:kubelet首次访问APIServer时,使用token做认证,通过后ContrllerManager会为kubelet生成一个证书,以后的访问都是用证书做认证了;

访问类型:

1.Kubenetes组件对APIServer的访问:kubectl、ControllerManager、Scheduler、kubelet、kube-proxy

2.Kubernetes管理的Pod容器对APIServer的访问:Pod(dashborad也是以Pod形式运行)

安全性说明:

1.ControllerManager、Scheduler与APIServer在同一台机器,所以直接使用APIServer的非安全端口访问,可以在Node节点时添加--insecure-bind-address=.0.0.1防止不必要的性能消耗;

2.kubectl、kubelet、kube-proxy访问APIServer就都需要证书进行HTTPS双向认证;

认证文件

描述:上面我们说过k8s两种访问方式一是对APIServer的访问通过(kubeconfig),二是对管理的Pod对容器的访问通过SA(ServiceAccount);

kubeconfig

描述:kubeconfig文件包含集群参数(CA证书、APIServe访问证书),客户端参数(上面生成的证书和私钥),集群context信息(集群名称、用户名);

Tips:Kubenetes组件通过启动时指定不同的kubeconfig文件可以切换到不同的集群;

ServiceAccount

描述:Pod中的容器访问APIServer。因为Pod的创建、销毁是动态的,所以要为它手动生成证书就不可行了。

Tips:Kubenetes通过使用了ServiceAccount解决Pod访问APIServer的认证问题;(后面会详细讲解)

Q:Secret与SA的关系描述:Kubernetes设计了一种K8s对象叫做Secret分为两类,

另一种是用于ServiceAccount的service-accounttoken,

另一种是用于保存用户自定义保密信息的Opaque,ServiceAccount中用到包含三个部分:Token、ca.crt、namespace

token是使用APIServer私钥签名的JWT格式,用于访问APIServer时Server端认证;

ca.crt根证书用于Client端验证APIServer发送的证书;

namespace标识这个service-account-token的作用域名空间;

PS:默认情况下每个namespace都会有一个ServiceAccount,如果Pod在创建时没有指定ServiceAccount,就会使用Pod所属的namespace的ServiceAccount默认挂载目录:/run/secrets/kubernetes.io/serviceaccount/

#所有命名空间的~$kubectlgetsecret--all-namespaces#NAMESPACENAMETYPEDATAAGE#defaultdefault-token-zglkdkubernetes.io/service-account-tokend#默认的命名空间的~$kubectldescribesecretdefault-token-zglkd--namespace=default#Name:default-token-zglkd#Namespace:default#Labels:none#Annotations:kubernetes.io/service-account.name:default#kubernetes.io/service-account.uid:abb62-6ccf-d-ac60-46feb77cdbf5#Type:kubernetes.io/service-account-token#Data#====#namespace:7bytes#token:eyJhbGciOi.....JSUzI1Ni#ca.crt:bytes#devops命名空间的~$kubectlgetsecret-ndevops#NAMETYPEDATAAGE#default-token-mv72lkubernetes.io/service-account-tokend~$kubectlgetsecret-ndevops-oyaml#apiVersion:v1#items:#-apiVersion:v1#data:#ca.crt:LS0tLS1...0tCg==#namespace:ZGV2b3Bz#token:ZXlKaGJHY...N3JR#kind:Secret#metadata:#annotations:#kubernetes.io/service-account.name:default#kubernetes.io/service-account.uid:d-c72e-4fe9-b8fd-ed65b5b#creationTimestamp:"-01-15T07:44:41Z"#managedFields:#-apiVersion:v1#fieldsType:FieldsV1#fieldsV1:#f:data:#.:{}#f:ca.crt:{}#f:namespace:{}#f:token:{}#f:metadata:#f:annotations:#.:{}#f:kubernetes.io/service-account.name:{}#f:kubernetes.io/service-account.uid:{}#f:type:{}#manager:kube-controller-manager#operation:Update#time:"-01-15T07:44:41Z"#name:default-token-mv72l#namespace:devops#resourceVersion:""#selfLink:/api/v1/namespaces/devops/secrets/default-token-mv72l#uid:9bc8a-70b5--9ce8-d#type:kubernetes.io/service-account-token2)Authorization(鉴权)

描述:上面认证过程只是确认通信的双方都确认了对方是可信的可以相互通信,此时认证成功之后的到了授权模块,与认证Auth类似k8s也支持多种授权机制,并支持同时开启多个授权插件(一个验证成功即可),如果授权成功则用户的请求会发送到准入控制模块做进一步的请求验证,而对于授权失败的请求则返回HTTP,即鉴权是确定请求方有哪些资源的权限。

APIServer目前支持以下几种授权策略(可通过APIServer的启动参数“--authorization-mode”设置)

1.AlwaysDeny:表示拒绝所有的请求,一般用于测试

2.AlwaysAllow:允许接收所有请求,如果集群不需要授权流程,则可以采用该策略

3.ABAC(Attribute-BasedAccessControl):基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制

4.Webbook:通过调用外部REST服务对用户进行授权

5.RBAC(Role-BasedAccessControl):基于角色的访问控制(默认规则)后续详细讲解

使用-RBAC-鉴权

描述:实际生产环境中往往需要对不同运维人员赋预不同的权限,而根据实际情况也可能会赋予开发人员只读的权限此时我们可以使用RBAC进行鉴权;

RBAC(Role-BasedAccessControl)基于角色的访问控制鉴权机制,使用rbac.authorization.k8s.ioAPI组来驱动鉴权决定,允许你通过KubernetesAPI动态配置策略。

比较于其它访问控制方式拥有以下优势:

1.对集群中的资源和非资源均拥有完整的覆盖

2.整个RBAC完全由几个API对象完成,同其它API对象一样,可以用kubectl或API进行操作

3.可以在运行时进行调整,无需重启APIServer

Tips:在Kubernetes1.5中引入现行版本成为默认标准。Tips:在启动API服务器时将--authorization-mode参数设置为一个逗号分隔的列表并确保其中包含RBAC

kube-apiserver--authorization-mode=Example,RBAC

Tips:api-resources资源名称角色与绑定一览表;

~$kubectlapi-resources

grep"Role"#clusterrolebindingsrbac.authorization.k8s.iofalseClusterRoleBinding#clusterrolesrbac.authorization.k8s.iofalseClusterRole#rolebindingsrbac.authorization.k8s.iotrueRoleBinding#rolesrbac.authorization.k8s.iotrueRole~$kubectlapi-versions

grep"rbac.authorization.k8s.io"#rbac.authorization.k8s.io/v1#rbac.authorization.k8s.io/v1beta1基本概念

1.RBACK8s对象说明描述:RBACAPI声明了四种Kubernetes对象:Role、ClusterRole、RoleBinding、ClusterRoleBinding,4种对象类型均可以通过kubectl与API操作;

RBAC的APIK8s对象图示:

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

#APIServer会把客户端证书的CN字段作为User,把names.OU字段作为Groupcatappuser-csr.yamlEND{"CN":"appuser",#用户名称(User)"hosts":[],"key":{"algo":"rsa","size":},"names":[{"C":"CN","ST":"TianJin","L":"TJ","O":"kubernetes","OU":"System"#用户组(Group)}]}END

Tips:kubelet使用TLSBootstaping认证时APIServer可以使用BootstrapTokens或者Tokenauthenticationfile验证token。

Tips:无论哪一种Kubenetes都会为token绑定一个默认的User和Group;Pod使用ServiceAccount认证时service-account-token中的JWT会保存User信息,有了用户信息再创建一对角色/集群角色(角色绑定/集群角色绑定)K8s对象即Role、RoleBinding、ClusterRole、ClusterRoleBinding,就可以完成权限绑定了;

角色-RoleandClusterRole

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

Role资源清单示例:

kind:RoleapiVersion:rbac.authorization.k8s.io/v1beta1metadata:namespace:defaultname:pod-readerrules:-apiGroups:[""]#""标明coreAPI组resources:["pods"]verbs:["get","watch","list"]

描述:ClusterRole具有与Role相同的权限角色控制能力,不同的是ClusterRole是集群级别的其可以用于以下环境之中:

集群范围资源(比如节点(Node))

非资源端点(比如/healthz)

跨名字空间访问的名字空间作用域的资源(如Pods),比如你可以使用ClusterRole来允许某特定用户执行kubectlgetpods--all-namespaces

ClusterRole有若干用法:

定义对某名字空间域对象的访问权限,并将在各个名字空间内完成授权;

为名字空间作用域的对象设置访问权限,并跨所有名字空间执行授权;

为集群作用域的资源定义访问权限。

ClusterRole资源清单示例:

kind:ClusterRoleapiVersion:rbac.authorization.k8s.io/v1beta1metadata:#"namespace"被忽略,因为ClusterRoles不受名字空间限制name:secret-readerrules:-apiGroups:[""]#在HTTP层面,用来访问Secret对象的资源的名称为"secrets"resources:["secrets"]verbs:["get","watch","list"]

Tips:RBAC的Role或ClusterRole中包含一组代表相关权限的规则权限是纯粹累加的(不存在拒绝某操作的规则)。

Tips:如果你希望在名字空间内定义角色应该使用Role;如果你希望定义集群范围的角色应该使用ClusterRole。

Tips:Role或ClusterRole对象的名称必须是合法的路径区段名称。

角色绑定-RoleBindingandClusterRoleBinding

描述:角色绑定(RoleBinding)是将角色中定义的权限赋予一个或者一组用户,它包含若干主体用户、组或服务账户(users,groups,orserviceaccounts)的列表和对这些主体所获得的角色的引用;

RoleBinding可以引用同一的名字空间中的任何Role,或者一个RoleBinding可以引用某ClusterRole并将该ClusterRole绑定到RoleBinding所在的名字空间;

RoleBinding可以将角色中定义的权限授予用户或用户组其包含一组权限列表(subjects),权限列表中包含有不同形式的待授予权限资源类型;

RoleBinding同样包含对被Bind的Role引用RoleBinding适用于某个命名空间内授权而ClusterRoleBinding适用于集群范围内的授权;

RoleBinding同样可以引用ClusterRole来对当前namespace内用户、用户组或ServiceAccount进行授权;

例如:将default命名空间中的pod-readerRole角色授予jane用户,此后jane用户在default命名空间中将具有pod-reader角色的权限;

apiVersion:rbac.authorization.k8s.io/v1#此角色绑定允许"jane"读取"default"名字空间中的Podskind:RoleBindingmetadata:name:read-podsnamespace:defaultsubjects:#你可以指定不止一个“subject(主体)”-kind:Username:jane#"name"是不区分大小写的apiGroup:rbac.authorization.k8s.ioroleRef:#"roleRef"指定与某Role或ClusterRole的绑定关系kind:Role#此字段必须是Role或ClusterRolename:pod-reader#此字段必须与你要绑定的Role或ClusterRole的名称匹配apiGroup:rbac.authorization.k8s.io

Tips:RoleBinding可以引用ClusterRole,其将对应ClusterRole中定义的访问权限授予RoleBinding所在名字空间的资源;好处是这种引用使得你可以跨整个集群定义一组通用的角色,之后在多个名字空间中复用。

例如,尽管下面的RoleBinding引用的是一个ClusterRole,"dave"(这里的主体,不区分大小写)只能访问"development"名字空间中的Secrets对象,因为RoleBinding所在的名字空间(由其metadata决定)是"development"。

apiVersion:rbac.authorization.k8s.io/v1#此角色绑定使得用户"dave"能够读取"default"名字空间中的Secrets#你需要一个名为"secret-reader"的ClusterRolekind:RoleBindingmetadata:name:read-secrets#RoleBinding的名字空间决定了访问权限的授予范围。#这里仅授权在"development"名字空间内的访问权限。namespace:developmentsubjects:-kind:Username:dave#name是不区分大小写的apiGroup:rbac.authorization.k8s.ioroleRef:kind:ClusterRolename:secret-readerapiGroup:rbac.authorization.k8s.io

描述:使用ClusterRoleBinding可以对整个集群中的所有命名空间资源权限进行访问权限的授予。

例如,ClusterRoleBinding样例展示了授权manager组内所有用户在全部命名空间中对secrets进行访问;

apiVersion:rbac.authorization.k8s.io/v1#此集群角色绑定允许“manager”组中的任何人访问任何名字空间中的secretskind:ClusterRoleBindingmetadata:name:read-secrets-global#RoleBinding和ClusterRoleBinding可以将Role绑定到Subjectssubjects:#Subjects中kind字段可以是`groups、users或者serviceaccounts`#users:"alice""wangyanglinux

.


转载请注明地址:http://www.tanhuaa.com/ncth/7871.html