kubernetes-身份与权限认证(十四)
Kubernetes的安全框架
https://kubernetes.io/docs/reference/access-authn-authz/rbac/
•访问K8S集群的资源需要过三关:认证、鉴权、准入控制 •普通用户若要安全访问集群API Server,往往需要证书、Token或者用户名+密码;Pod访问,需要ServiceAccount •K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段都支持插件方式,通过API Server配置来启用插件。 1.Authentication 2.Authorization 3.Admission Control
三种客户端身份认证:
•HTTPS 证书认证:基于CA证书签名的数字证书认证 •HTTP Token认证:通过一个Token来识别用户 •HTTP Base认证:用户名+密码的方式认证
授权:RBAC(Role-Based Access Control,基于角色的访问控制):负责完成授权(Authorization)工作。
准入控制:AdminssionControl实际上是一个准入控制器插件列表,发送到APIServer的请求都需要经过这个列表中的每个准入控制器插件的检查,检查不通过,则拒绝请求。
使用RBAC授权
RBAC(Role-Based Access Control,基于角色的访问控制),允许通过Kubernetes API动态配置策略。
角色 •Role:授权特定命名空间的访问权限 •ClusterRole:授权所有命名空间的访问权限 角色绑定 •RoleBinding:将角色绑定到主体(即subject) •ClusterRoleBinding:将集群角色绑定到主体 主体(subject) •User:用户 •Group:用户组 •ServiceAccount:服务账号
使用RBAC授权对pod读取权限示例
创建角色
[root@k8s-master1 ~]# vim role-demo.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: developent
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
[root@k8s-master1 ~]# kubectl apply -f role-demo.yaml
role.rbac.authorization.k8s.io/pod-reader created
[root@k8s-master1 ~]# kubectl get role -n developent
NAME AGE
pod-reader 50s
创建角色绑定
[root@k8s-master1 ~]# vim rolebinding-demo.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dev-read-pods
namespace: developent
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
[root@k8s-master1 ~]# kubectl get rolebinding -n developent
NAME AGE
dev-read-pods 3s
[root@k8s-master1 ~]# kubectl describe rolebinding dev-read-pods -n developent
Name: dev-read-pods
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"name":"dev-read-pods","namespace":"develop...
Role:
Kind: Role
Name: pod-reader
Subjects:
Kind Name Namespace
---- ---- ---------
User jane
基于证书配置客户端身份认证
创建证书
[root@k8s-master1 ~]# vim jane-csr.json
{
"CN": "jane",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
[root@k8s-master1 ~]# cfssl gencert -ca=/opt/kubernetes/ssl/ca.pem -ca-key=/opt/kubernetes/ssl/ca-key.pem -config=/opt/kubernetes/ssl/ca-config.json -profile=kubernetes jane-csr.json | cfssljson -bare jane
创建kubeconfig文件
kubectl config set-cluster kubernetes
--certificate-authority=/opt/kubernetes/ssl/ca.pem
--embed-certs=true
--server=https://192.168.0.130:6443
--kubeconfig=jane-kubeconfig
kubectl config set-credentials jane
--client-key=jane-key.pem
--client-certificate=jane.pem
--embed-certs=true
--kubeconfig=jane-kubeconfig
kubectl config set-context default
--cluster=kubernetes
--user=jane
--kubeconfig=jane-kubeconfig
kubectl config use-context default --kubeconfig=jane-kubeconfig
测试仅对developent命名空间查看pod权限
[root@k8s-master1 ~]# kubectl get pod -n developent
NAME READY STATUS RESTARTS AGE
nginx-7cdbd8cdc9-5dd7x 1/1 Running 0 16s
nginx-7cdbd8cdc9-dthp7 1/1 Running 0 16s
nginx-7cdbd8cdc9-lwzjf 1/1 Running 0 16s
[root@k8s-master1 ~]# kubectl --kubeconfig=jane-kubeconfig get pod -n developent
NAME READY STATUS RESTARTS AGE
nginx-7cdbd8cdc9-5dd7x 1/1 Running 0 2m13s
nginx-7cdbd8cdc9-dthp7 1/1 Running 0 2m13s
nginx-7cdbd8cdc9-lwzjf 1/1 Running 0 2m13s
[root@k8s-master1 ~]# kubectl --kubeconfig=jane-kubeconfig get pod
Error from server (Forbidden): pods is forbidden: User "jane" cannot list resource "pods" in API group "" in the namespace "default"
使用RBAC授权UI权限示例
serviceAccount
当创建 pod 的时候,如果没有指定一个 service account,系统会自动在与该pod 相同的 namespace 下为其指派一个default service account。而pod和apiserver之间进行通信的账号,称为serviceAccountName。如下:
[root@k8s-master1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-f69cd5cf-rfbdb 1/1 Running 0 4h31m
web-0 1/1 Running 0 4h16m
web-1 1/1 Running 0 4h16m
[root@k8s-master1 ~]# kubectl get pod/web-0 -o yaml |grep "serviceAccountName"
serviceAccountName: default
[root@k8s-master1 ~]# kubectl describe pod web-0
Name: web-0
Namespace: default
. . . . .
Volumes:
www:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: www-web-0
ReadOnly: false
default-token-7vs6s:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-7vs6s
Optional: false
从上面可以看到每个Pod无论定义与否都会有个存储卷,这个存储卷为default-token-*** token令牌,这就是pod和serviceaccount认证信息。通过secret进行定义,由于认证信息属于敏感信息,所以需要保存在secret资源当中,并以存储卷的方式挂载到Pod当中。从而让Pod内运行的应用通过对应的secret中的信息来连接apiserver,并完成认证。每个 namespace 中都有一个默认的叫做 default 的 service account 资源。进行查看名称空间内的secret,也可以看到对应的default-token。让当前名称空间中所有的pod在连接apiserver时可以使用的预制认证信息,从而保证pod之间的通信。
[root@k8s-master1 ~]# kubectl get sa
NAME SECRETS AGE
default 1 9d
nfs-client-provisioner 1 4h37m
[root@k8s-master1 ~]# kubectl get secret
NAME TYPE DATA AGE
default-token-7vs6s kubernetes.io/service-account-token 3 9d
nfs-client-provisioner-token-glqhl kubernetes.io/service-account-token 3 4h38m
registry-pull-secret kubernetes.io/dockerconfigjson 1 8d
而默认的service account 仅仅只能获取当前Pod自身的相关属性,无法观察到其他名称空间Pod的相关属性信息。如果想要扩展Pod,假设有一个Pod需要用于管理其他Pod或者是其他资源对象,是无法通过自身的名称空间的serviceaccount进行获取其他Pod的相关属性信息的,此时就需要进行手动创建一个serviceaccount,并在创建Pod时进行定义。那么serviceaccount该如何进行定义呢???实际上,service accout也属于一个k8s资源。如下查看service account的定义方式:
[root@k8s-master1 ~]# kubectl explain sa
service account的创建
[root@k8s-master1 ~]# kubectl create sa devsa -o yaml -n developent --dry-run #不执行查看定义方式
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: null
name: devsa
namespace: developent
[root@k8s-master1 ~]# kubectl create sa devsa -o yaml -n developent --dry-run > sa.yaml #导出yaml文件
[root@k8s-master1 ~]# kubectl apply -f sa.yaml #创建
serviceaccount/devsa created
[root@k8s-master1 ~]# kubectl get sa -n developent #查看
NAME SECRETS AGE
default 1 5m46s
devsa 1 28s
[root@k8s-master1 ~]# kubectl get sa devsa -n developent -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"creationTimestamp":null,"name":"devsa","namespace":"developent"}}
creationTimestamp: "2018-12-28T07:01:01Z"
name: devsa
namespace: developent
resourceVersion: "780489"
selfLink: /api/v1/namespaces/developent/serviceaccounts/devsa
uid: 56125cdc-0a6e-11e9-b58a-000c298a2b5f
secrets:
- name: devsa-token-krgp7
创建角色绑定
[root@k8s-master1 ~]# vim sa-rolebinding-demo.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: sa-read-pods
namespace: developent
subjects:
- kind: ServiceAccount
name: devsa
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
[root@k8s-master1 ~]# kubectl apply -f sa-rolebinding-demo.yaml
rolebinding.rbac.authorization.k8s.io/sa-read-pods created
获取token
[root@k8s-master1 ~]# kubectl get secret -n developent
NAME TYPE DATA AGE
default-token-2zhxk kubernetes.io/service-account-token 3 148m
devsa-token-pktnh kubernetes.io/service-account-token 3 2m20s
[root@k8s-master1 ~]# kubectl describe secret devsa-token-pktnh -n developent
Name: devsa-token-pktnh
Namespace: developent
Labels: <none>
Annotations: kubernetes.io/service-account.name: devsa
kubernetes.io/service-account.uid: f69d0ff3-0a81-11e9-b58a-000c298a2b5f
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1359 bytes
namespace: 10 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZXZlbG9wZW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRldnNhLXRva2VuLXBrdG5oIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRldnNhIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZjY5ZDBmZjMtMGE4MS0xMWU5LWI1OGEtMDAwYzI5OGEyYjVmIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRldmVsb3BlbnQ6ZGV2c2EifQ.tkA8I8zHF0yjAS4aitd2NhltvASCx8KTug_cdAs3ImYe-5QkxgeO9VTck6L5F6SlMewg8keMYQ9hhgE89aQC4Vs1t89U_ftZ8lo725SrNxIBqhucPUHpvBWfc4OWc96p7PGYNH59AnudXVIKEXuYZyL-KLoQeAjddPRrYXPqUtBpxpQStLWe6qvl-hXY2yj-FyMXAbYRH516ZCMGetRJbYjla7JAPdPt9nAqZoJe00NvOUfw0xXVp_8H7tcvp0tQbQ5GE06zuCRHMfDV9RWj6XUoXKvKirk1yd2nSNJdygTp-1q5JGKxYY2a_tuq2NSCurNBI28Rpj7dV7eIkehkTw
访问dashboard,仅对developent命名空间读取pod的权限
- 手机APP安装包缩减方案
- react-native添加redux支持
- Java并发学习之ReentrantLock的工作原理及使用姿势
- Linux基础(day63)
- IOS WebView控件详解
- Java并发学习之synchronized使用小结
- 18.3/18.4/18.5 用keepalived配置高可用集群
- JDK容器学习之Queue:DelayQueue
- React-Native组件之 Navigator和NavigatorIOS
- JDK容器学习之Queue:ConcurrentLinkedQueue
- JDK容器学习之Queue: PriorityQueue
- React Native导航器之react-navigation使用
- Nginx 路由转发配置笔记
- React Native控件之ListView
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 聊聊dubbo-go的randomLoadBalance
- 聊聊dubbo-go的roundRobinLoadBalance
- PowerBI 不同日期区间的活动逐日对比分析
- flask SQLAlchemy查询数据库最近30天,一个月,一周,12小时或之前的数据
- TypeScript是什么,为什么要使用它?
- Python 基础(十):模块与包
- 谷歌浏览器一些https打不开点击高级不行的解决办法
- CV入门赛最全思路&上分技巧汇总!
- VBA专题10-5:使用VBA操控Excel界面之隐藏/取消隐藏及最小化功能区
- 从一道面试题说起:GET 请求能传图片吗?
- ModuleNotFoundError: No module named ‘pip‘【已解决】
- 【原创】Java并发编程系列31 | 阻塞队列(上)
- 【2019-3-3】Mac启动redis
- awvs(acunetix)使用一段时间后突然不能用了-解决方案
- Java自动化测试(数据库断言 18)