目录
(1)概念
Kubernetes 作为一个分布式集群的管理工具,保证集群的安全性是其一个重要的任务。API Server 是集群内部各个组件通信的中介, 也是外部控制的入口。所以 Kubernetes 的安全机制基本就是围绕保护 API Server 来设计的。
比如 kubectl 如果想向 API Server 请求资源,需要过三关,第一关是认证(Authentication),第二关是鉴权(Authorization), 第三关是准入控制(Admission Control),只有通过这三关才可能会被 K8S 创建资源。
(2)端口
api server是k8s集群的入口,默认有两个端口:
- 1)本地端口8080: 用于接收HTTP请求, 不对外服务, 非认证或授权的HTTP请求通过该端口访问API Server
-
- 2)安全端口6443: 用于接收认证授权的HTTPS请求,对外服务。
(3)访问
用户通过安全端口访问k8s的api server需要过三关:认证、授权、准入控制
- 1)Authentication认证: 用于识别用户身份, 方式有: SSL证书,token, 用户名+密码等
-
- 2)Authorization授权: 确认是否对资源具有相关的权限
-
- 3)Admission Control准入控制: 判断操作是否符合集群的要求

无论kubectl客户端命令或api或ui,在创建或访问资源时,一定要有apiServer所对应的资源版本,只要资源版本与kind能够正确匹配才能进行继续操作,否侧操作会被终止。
(1)Authentication认证:
它用于识别用户身份, 验证方式有:
- token
- 用户名+密码
- SSL证书
(2)HTTP Token 认证
通过一个 Token 来识别合法用户
- 1)HTTP Token 的认证是用一个很长的特殊编码方式的并且难以被模仿的 Token 字符串来表达客户的一种方式。
-
- 2)Token 是一个很长的很复杂的字符串,每一个 Token 对应一个用户名存储在 API Server 能访问的文件中。
-
- 3)当客户端发起 API 调用请求时,需要在 HTTP Header 里放入 Token。
(3)HTTP Base 认证
通过一个 Token 来识别合法用户
用户名:密码 用 BASE64 算法进行编码后的字符串放在 HTTP Request 中的 Heather Authorization 域里发送给服务端, 服务端收到后进行解码,获取用户名及密码。
(4)HTTPS 证书认证(最严格)
基于 CA 根证书签名的客户端身份认证方式。
(5)用户分类
用户有两种:
- 1)用户账户(user) : 是在集群外部访问apiserver时使用的用户,如kubectl命令就是作为kubernetes的admin用户来执行的。
-
- 2)服务账户(ServiceAccount): 为了方便Pod里面的进程调用Kubernetes API或其他外部服务而设计的。
-
对比:
-
- 1)User account是为人设计的,而service account则是为Pod中的进程调用Kubernetes API而设计;
-
- 2)User account是跨namespace的,而service account则是仅局限它所在的namespace;
-
- 3)每个namespace都会自动创建一个default service account
-
① 需要被认证的访问类型
- 1)Kubernetes 组件对 API Server 的访问:kubectl、kubelet、kube-proxy
-
- 2)Kubernetes 管理的 Pod 对 API Server 的访问:Pod(coredns,dashborad 也是以 Pod 形式运行)
②安全性说明
- 1)Controller Manager、Scheduler 与 API Server 在同一台机器,所以直接使用 API Server 的非安全端口访问(比如 8080 端口)
-
- 2)kubectl、kubelet、kube-proxy 访问 API Server 就都需要证书进行 HTTPS 双向认证,端口号使用 6443
③证书颁发
- 1)手动签发:使用二进制部署时,需要先手动跟 CA 进行签发 HTTPS 证书
-
- 2)自动签发:kubelet 首次访问 API Server 时,使用 token 做认证,通过后,Controller Manager 会为 kubelet 生成一个证书, 以后的访问都是用证书做认证了
④ Service Account
Service Account是为了方便 Pod 中的容器访问API Server。因为 Pod 的创建、销毁是动态的,所以要为每一个 Pod 手动生成证书就不可行了。 Kubenetes 使用了 Service Account 来循环认证,从而解决了 Pod 访问API Server的认证问题。
⑤ Secret 与 SA 的关系
Kubernetes 设计了一种资源对象叫做 Secret,分为两类:
- 1)用于保存 ServiceAccount 的 service-account-token
-
- 2)用于保存用户自定义保密信息的 Opaque
⑥Service Account 中包含三个部分
-
- 1)Token:是使用 API Server 私钥签名的 Token 字符串序列号,用于访问 API Server 时,Server 端认证
-
- 2)ca.crt:ca 根证书,用于 Client 端验证 API Server 发送来的证书
-
- 3)namespace:标识这个 service-account-token 的作用域名空间
默认情况下,每个 namespace 都会有一个 Service Account,如果 Pod 在创建时没有指定 Service Account,就会使用 Pod 所属的 namespace 的 Service Account。每个 Pod 在创建后都会自动设置 spec.serviceAccount 为 default(除非指定了其他 Service Accout)。
(6)kubeconfig文件
① 概念
kubeconfig 文件包含集群参数(CA 证书、API Server 地址),客户端参数(上面生成的证书和私钥),集群 context 上下文参数 (集群名称、用户名)。
Kubenetes 组件(如 kubelet、kube-proxy)通过启动时指定不同的 kubeconfig 文件可以切换到不同的集群 ,连接到 apiserver。
也就是说 kubeconfig 文件既是一个集群的描述,也是集群认证信息的填充。包含了集群的访问方式和认证信息。kubectl 文件默认位于 ~/.kube/config
- 1)kubeconfig文件用于组织有关群集、用户、命名空间和身份验证机制的信息,用于对k8s集群的访问。
-
- 2)使用kubectl命令时默认使用~/.kube/config这个kubeconfig文件来访问k8s集群,也可以用--kubeconfig指定其它文件
② 配置段
- 1)users: 用户账号及其认证信息列表
-
- 2)cluster: 目标集群列表
-
- 3)contexts: 以哪个user接入哪个cluster的连接组合。
-
- 4)current-context:当前使用的context
③ 示例
查看admin用户的kubeconfig文件
- [root@master1 ~]# cat /root/.kube/config
- apiVersion: v1
- clusters:
- - cluster:
- certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR1RENDQXFDZ0F3SUJBZ0lVRXJCMXhTc2NDMUV3V2lkckc3UEJXT29HSkFFd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1lURUxNQWtHQTFVRUJoTUNRMDR4RVRBUEJnTlZCQWdUQ0VoaGJtZGFhRzkxTVFzd0NRWURWUVFIRXdKWQpVekVNTUFvR0ExVUVDaE1EYXpoek1ROHdEUVlEVlFRTEV3WlRlWE4wWlcweEV6QVJCZ05WQkFNVENtdDFZbVZ5CmJtVjBaWE13SUJjTk1qQXhNVEEwTVRNek5qQXdXaGdQTWpFeU1ERXdNVEV4TXpNMk1EQmFNR0V4Q3pBSkJnTlYKQkFZVEFrTk9NUkV3RHdZRFZRUUlFd2hJWVc1bldtaHZkVEVMTUFrR0ExVUVCeE1DV0ZNeEREQUtCZ05WQkFvVApBMnM0Y3pFUE1BMEdBMVVFQ3hNR1UzbHpkR1Z0TVJNd0VRWURWUVFERXdwcmRXSmxjbTVsZEdWek1JSUJJakFOCkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXpZNWhMTDhTYXU2MGVpNDR6RTlhNVdDdHVCc00KN0tmMXJkd2RnVVo2VFpRK3VFNkdhdmN5SWhCT3l2bFprVEt0WmhEcXdmSml3TjZBVk5tdTEvTktrVkZ2UEUrOQppOVF4Z0FkM0JsUk1FVi9nMUVrejZVRXpSM2JJSXdWd2QrUHRpZGZ3a1RtZ3E5bkR4MklpR3VMT1A4UnJoNmdFCmlkR1dLbERjZ0wrYnB6RUVieW4yTWpDWWY0dlZCUDlqS044WFdrM3pKdGlyMUhxOWx2akRXUEZrZStHMUZHdXEKKy9acy9jQk1Nb3JpSWhld1ZDb2t1ZGVVOVVPbUZSN0JObDFGOStBeWhWZHlmbE0yTFo1R2dQZmg2MFdBZkI2WApSa3o2dHMxcTJLR0FZdG5TeGhsblREamxpUWxWT0M2UURUeTBMNUgzV3lmdVdrOHlzWmVUNkxHQ3R3SURBUUFCCm8yWXdaREFPQmdOVkhROEJBZjhFQkFNQ0FRWXdFZ1lEVlIwVEFRSC9CQWd3QmdFQi93SUJBakFkQmdOVkhRNEUKRmdRVVRMNHErYkhUV2pMdmlVRk5BVmp4c1dTTDZuMHdId1lEVlIwakJCZ3dGb0FVVEw0cStiSFRXakx2aVVGTgpBVmp4c1dTTDZuMHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQ2pZTXVLN2dDWlJmUWVPTW1SYVg5dmNjTldECjdOOVltb25XTHNZb0RiaGE2Und1VFlFVDRBWXJuUWE1d3pEV3pBK0Erb0liSjR4WjZnREZGK2s2KzM0V1ZreXcKLyt2NkFVL2hSNytjL2pIc3RGZGFRVXZGVHFhNUtmelcyOEZHQWptQ3ZOYyt1QjJ4ZjQvcy9EMnRwTWxpT3l6cwpKWEhNV3I3UWs5RHR3THJlZ2lZTlc3a202M25RbllWSTNRQzlIK0xNaVNsMHNIUlBER1VseU15N2hqWUNQR2duCkNEQlBWYWJhR0ltdW5YSnBGd2RKTUhmbFRuZllSUnQ3RG0zOVlXMjhWSGw4N0xlZXY5Y3dlVTI5KzNtYlJiUmwKME1tNlpoQzlsK0NjSXN6dEtUVWJBQ01LT1dYbUZXRk1uQVFZdnhxN2hIR25IaXpWb3k1VHNxVkZQRUE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
- server: https://192.168.122.11:6443
- name: cluster1
- contexts:
- - context:
- cluster: cluster1
- user: admin
- name: context-cluster1-admin
- current-context: context-cluster1-admin
- kind: Config
- preferences: {}
- users:
- - name: admin
- user:
- client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQxekNDQXIrZ0F3SUJBZ0lVYUZlakwzVXErUTJqWnJIbzB4cmFaUVAyY3pZd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1lURUxNQWtHQTFVRUJoTUNRMDR4RVRBUEJnTlZCQWdUQ0VoaGJtZGFhRzkxTVFzd0NRWURWUVFIRXdKWQpVekVNTUFvR0ExVUVDaE1EYXpoek1ROHdEUVlEVlFRTEV3WlRlWE4wWlcweEV6QVJCZ05WQkFNVENtdDFZbVZ5CmJtVjBaWE13SUJjTk1qQXhNVEEwTVRNek9UQXdXaGdQTWpBM01ERXdNak14TXpNNU1EQmFNR2N4Q3pBSkJnTlYKQkFZVEFrTk9NUkV3RHdZRFZRUUlFd2hJWVc1bldtaHZkVEVMTUFrR0ExVUVCeE1DV0ZNeEZ6QVZCZ05WQkFvVApEbk41YzNSbGJUcHRZWE4wWlhKek1ROHdEUVlEVlFRTEV3WlRlWE4wWlcweERqQU1CZ05WQkFNVEJXRmtiV2x1Ck1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBNHdyc0dnSnE0T00zcUV5elE2Q3AKZGRjaWlUTnNuRG1odzBjcUwyWG1CTnA4cmxSUkFiUWY3QmNpTVRPVTF5TUdTYWo4YW9TNGhjUVFqcWpVRXRBKwphUVpOTXRPTXppZVZMMHpEZzMrV09Qb3o3MGdyeEU2QzFGVE5XcGFWRjljUUFWVFJNUS9ZZm9YYmNZRDdPT1dLCktCYldJUVJ2SzF2T0RiMmhEcUZBYkl5Q3N4dzI5ZFlyL3QwNDV2QVcrUTFWMjVIYjVrQVE2a1Z5WVFYcDZJSFQKdVZmaTRnVHlrclJDY1BaVUo5Q0ZCWFcvZFhrZkViZXpGYU9iU2VwVE5NU2FGeDBCNDE1c09CTFVYRTVuRG8wRwpNZ2duV015WTVUcW1UQU5CVGw5MTNySEdTeXdSZWRtQ2Z2Q1BiZSsxVnJFU2hiK3Z6aHZkMHZ5empNbk1NcDM3CkhRSURBUUFCbzM4d2ZUQU9CZ05WSFE4QkFmOEVCQU1DQmFBd0hRWURWUjBsQkJZd0ZBWUlLd1lCQlFVSEF3RUcKQ0NzR0FRVUZCd01DTUF3R0ExVWRFd0VCL3dRQ01BQXdIUVlEVlIwT0JCWUVGTlI5MWlJY2c5UVhiemlxOXRlQgpBZEdidnpnYk1COEdBMVVkSXdRWU1CYUFGRXkrS3ZteDAxb3k3NGxCVFFGWThiRmtpK3A5TUEwR0NTcUdTSWIzCkRRRUJDd1VBQTRJQkFRQVhrNktieG1oUUdoeHd0TmZaU2txUG1tR21rK2U0OTJLRU1vSnZVcm5ZTTFaUkxmVk8KenRDbVByTWxORitIUWZySG5qczNtc1NzWmwwc1hxN3RwMnRKWEVURXFwdVdkMTBxQVZZVVBSelhrL1FLNDNXTAozYU13cWdZNjhkdGJOcytlNFpyT2J3YWJOZmp2T1RjUjVwV2RpTEFmT2hUSE9UZWtEZkUza1l4MGlQdGNGWmFTCmhVb3A5ZGV6RUpFbWNLM2xxQm1TYkN3cEhoSGZxUHlkcy8rVEhHMHdrV2E4a0pwSytxSUx6dkZDa0trRlZrMDcKcWtIMUthUHFzMUFKSmJzTWxMQjkzVEE0ajM1QWowTzF5eElpRjlDUmFoQ2pNeDlhaUl2dVNTejZpeGpMbDhWVgpnNzU0K2RzZThlMElaU0xHV2t6QzVDNnk0WWNid1ROa3dSU28KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
- client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBNHdyc0dnSnE0T00zcUV5elE2Q3BkZGNpaVROc25EbWh3MGNxTDJYbUJOcDhybFJSCkFiUWY3QmNpTVRPVTF5TUdTYWo4YW9TNGhjUVFqcWpVRXRBK2FRWk5NdE9NemllVkwwekRnMytXT1BvejcwZ3IKeEU2QzFGVE5XcGFWRjljUUFWVFJNUS9ZZm9YYmNZRDdPT1dLS0JiV0lRUnZLMXZPRGIyaERxRkFiSXlDc3h3Mgo5ZFlyL3QwNDV2QVcrUTFWMjVIYjVrQVE2a1Z5WVFYcDZJSFR1VmZpNGdUeWtyUkNjUFpVSjlDRkJYVy9kWGtmCkViZXpGYU9iU2VwVE5NU2FGeDBCNDE1c09CTFVYRTVuRG8wR01nZ25XTXlZNVRxbVRBTkJUbDkxM3JIR1N5d1IKZWRtQ2Z2Q1BiZSsxVnJFU2hiK3Z6aHZkMHZ5empNbk1NcDM3SFFJREFRQUJBb0lCQVFDUCtZSWxNRGxFYVBJSAplTFFKQTUzU2kxMXNNYjhEQm96cy8zamgyN1ZVaUpTZUcvdk9uOEhLZmhVQnJGc0xYanVEaEhTa3U0c2owR1JMCmd3WVE5QnRQa0Y1dUI3YjNtQ1JEZldOU1JSc25BSXJraHhpeUFMTjRJRnFrd203RFVtN2syVHRhNkZoNlN6b1EKTFNHaVAvVXZYT1BteGlBVkY3OS8rU3RqMHArKzlOMk5VT0NYSlV0MldUaFdyRDRBdHlBSG9hN3IvVnlxbGhKaQpLa3JaOURpSWh0cGp0bXorSlV1TXR0NHg4dWxvc2ZLZDBmeEtFTDdhamFsVXYxK1ZKZEc0YytvNUxjTEt6dWQzCk9QWW1aR1JPUmZHV3lSNUFNaTZmL09GU0F5dVU0MFB4Y2NrNEhRdlBkMUVPdndJVHhMc0lESy9TWUZtZDIrOTgKK1BwRkhoWUJBb0dCQU9qVVpHTGZOa2oxaFpZb0JDT2pieHM4VDZ5S0Mwc2lCNXo0VHlhdTNIRGhxNFRsbU13aQpLaVdVRWMrdmowd2NGblU4NWNsQjkwN2E4VWVnYzBsTHdHOFhuUUlYZHZvanB4Uk9oZ2pZZS90Vmk0SE5iMjJlCnoxNldsaGEyRWdESDBpQ1VsRERJVVIvVkN3N3VabzBwRnVkTjYxdXBybjQxU1M4cjBOVFVwQVdCQW9HQkFQbWoKR1ltanRMS04wY2hiNFFNejRTSW9DcEJPbGJhY1VxdzlxSGl6YzZrR0lwdDFZVFpDeTArcDVHSHJmbXpQczUrWgpVRFc4alFTdjU0R09sMUlnT2FNSTRLekk3YzhhZEExVjIzU09wSkZ4K1dlQTNQTThndUUrVzdnMzMwaWFJVXorClpxNDJyWC9YREVOWktrMHRESXdpSjRaN0VsTGsvaUxlTFJjS2NodWRBb0dBSnRraGN0blpuZXpSZ0U5bStXZFEKcDVPMW00MWcrd1ZQamVKa21vaThvVjBXR0ZPUzNpU3BNYUgySXRnaEtjclorRy9UeTNQbFJ0UURSRGRDWlMxdAppMXUrUjlZUWRRWXozNUNHanIxSVdwUllkYTBJZFpyMDhNeGhlS0tpZUZ6ZTg2NjIxempsU0ZGc3llMy9VSGhWCnFQeDRVOUFKSEdmWnNUUTNZUHVsN29FQ2dZQXdpdzdFUFJrK1AyV3oyR29BL1cyaC9yZFBLSGprY2JHQjNOdU4KM1JkNG5zRE1DaDlGTmVmakxkNURURS9oU09KYy9xc2lSL0FFSVZDYldPY0VDVkFyNitZRXMyM0xBQkhoSmZqdQp5VzRtK2tyTlhibVpjd0xnV2dmcjRyR0FwTGdsQ0xOZTNUTVAwUG1KZnlWQ3JLZnIrQmhIaGxjaDEzV3p3aEJ5CmtvMXQ0UUtCZ0I1Z08xQnNNYmpUNVZtSWJLRXVhMU03Q1BKcDVpZERNVGc2K0R2bVJKdDYwbmZrZGwyNGYzSlIKdHFwZFlXL2JyMVZsZzl1U2VFcnBXNEtTNXN0UkZPK3Q0Z212Rkx6TUJKdStoSSswN2pHUnBGanp1TDFPMVorOQpXZ0lxS2tKOW5DN3VSWEtxUmxBTXZTVVVjcUtLTUZSTWtBZEpmOUZHNEdVaHFSZUdhUlp2Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
(1)概念
之前的认证(Authentication)过程,只是确认通信的双方都确认了对方是可信的,可以相互通信。而鉴权是确定请求方有哪些资源的权限。API Server 目前支持以下几种授权策略:(通过 API Server 的启动参数 “--authorization-mode” 设置)
认证环节之后是授权, 确认是否对资源具有相关的权限
一个请求需要在其请求信息中包含用户名,请求的动作以及目标对象; 若存在某授权策略对于此请求给予了授权许可,即授权成功。
(2)授权模块
- 1)AlwaysDeny:表示拒绝所有的请求,一般用于测试
-
- 2)AlwaysAllow:允许接收所有请求,如果集群不需要授权流程,则可以采用该策略,一般用于测试
-
- 3)ABAC(Attribute-Based Access Control):基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制。也就是说定义一个访问类型的属性,用户可以使用这个属性访问对应的资源。此方式设置较为繁琐,每次设置需要定义一长串的属性才可以。
-
- 4)Webhook:通过调用外部 REST 服务对用户进行授权,即可在集群外部对K8S进行鉴权
-
- 5)RBAC(Role-Based Access Control):基于角色的访问控制,K8S自1.6版本起默认使用规则
(3)RBAC
RBAC使用rbac.authorization.k8s.io API Group 来实现授权决策,允许管理员通过 Kubernetes API 动态配置策略,要启用RBAC,需要在 apiserver 中添加参数–authorization-mode=RBAC,如果使用的kubeadm安装的集群,都默认开启了RBAC,可以通过查看 Master 节点上 apiserver 的静态Pod定义文件:
- [root@master pki]# cat /etc/kubernetes/manifests/kube-apiserver.yaml
- ···
- - --authorization-mode=Node,RBAC
- ···


① RBAC的优势
RBAC 相对其它访问控制方式,拥有以下优势:
- 1)对集群中的资源(Pod,Deployment,Service)和非资源(元信息或者资源状态)均拥有完整的覆盖
-
- 2)整个 RBAC 完全由几个 API 资源对象完成,同其它 API 资源对象一样,可以用 kubectl 或 API 进行操作
-
- 3)可以在运行时进行调整,无需重启 API Server,而 ABAC 则需要重启 API Server
② RBAC 的 API 资源对象说明
RBAC 引入了 4 个新的顶级资源对象:Role、ClusterRole、RoleBinding、ClusterRoleBinding,4 种对象类型均可以通过 kubectl 与 API Server 操作。
官方文档:https://kubernetes.io/docs/reference/access-authn-authz/rbac/
③ 角色

- Role 授权特定命名空间的访问权限
-
- ClusterRole 授权所有命名空间的访问权限
如果使用 RoleBinding 绑定 ClusterRole,仍会受到命名空间的影响;
如果使用 ClusterRoleBinding 绑定 ClusterRole, 将会作用于整个 K8S 集群。
④ 角色绑定
- RoleBinding 将角色绑定到主机(即subject)
-
- ClusterRoleBinding 将集群角色绑定到主体
⑤ 主体 (subject)
- User 用户
- Group 用户组
- ServiceAccount 服务帐号
User 使用字符串表示,它的前缀 system: 是系统保留的,集群管理员应该确保普通用户不会使用这个前缀格式;Group 书写格式与 User 相同,同样 system: 前缀也为系统保留。
Pod使用 ServiceAccount 认证时,service-account-token 中的 JWT 会保存用户信息。 有了用户信息,再创建一对角色/角色绑定(集群角色/集群角色绑定)资源对象,就可以完成权限绑定了。
⑥ Role and ClusterRole

在 RBAC API 中,Role 表示一组规则权限,权限只能增加(累加权限),不存在一个资源一开始就有很多权限而通过 RBAC 对其进行减少的操作。也就是说只有白名单权限,而没有黑名单权限的概念。
Role 只能定义在一个 namespace 中,如果想要跨 namespace 则可以创建 ClusterRole,也就是说定义 ClusterRole 不需要绑定 namespace。
Role 示例
- apiVersion: rbac.authorization.k8s.io/v1 #指定 core API 组和版本
- kind: Role #指定类型为 Role
- metadata:
- namespace: default #使用默认命名空间
- name: pod-reader #Role 的名称
-
- rules: #定义规则
- - apiGroups: [""] #""表示 apiGroups 和 apiVersion 使用相同的 core API 组,即 rbac.authorization.k8s.io
- resources: ["pods"] #资源对象为 Pod 类型
- verbs: ["get", "watch", "list"] #被授予的操作权限
以上配置的意义是,如果把 pod-reader 这个 Role 赋予给一个用户,那么这个用户将在 default 命名空间中具有对 Pod 资源对象 进行 get(获取)、watch(监听)、list(列出)这三个操作权限。
ClusterRole 示例
- apiVersion: rbac.authorization.k8s.io/v1
- kind: ClusterRole
- metadata:
- # "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制
- name: secret-reader
- rules:
- - apiGroups: [""]
- resources: ["secrets"] #资源对象为 Secret 类型
- verbs: ["get", "watch", "list"]
⑦ RoleBinding and ClusterRoleBinding
- 1)RoloBinding 可以将角色中定义的权限授予用户或用户组,RoleBinding 包含一组主体(subject),subject 中包含有不同形式的待授予权限资源类型(User、Group、ServiceAccount);
-
- 2)RoloBinding 同样包含对被绑定的 Role 引用;
-
- 3)RoleBinding 适用于某个命名空间内授权,而 ClusterRoleBinding 适用于集群范围内的授权
RoleBinding 示例1
- apiVersion: rbac.authorization.k8s.io/v1
- kind: RoleBinding
- metadata:
- name: read-pods
- namespace: default
- subjects:
- - kind: User
- name: zhangsan
- apiGroup: rbac.authorization.k8s.io
- roleRef:
- kind: Role
- name: pod-reader
- apiGroup: rbac.authorization.k8s.io
将 default 命名空间的 pod-reader Role 授予 zhangsan 用户,此后 zhangsan 用户在 default 命名空间中将具有 pod-reader 的权限。
RoleBinding 同样可以引用 ClusterRole 来对当前 namespace 内 User、Group 或 ServiceAccount 进行授权, 这种操作允许集群管理员在整个集群内定义一些通用的 ClusterRole,然后在不同的 namespace 中使用 RoleBinding 来引用。
RoleBinding 示例2
- apiVersion: rbac.authorization.k8s.io/v1
- kind: RoleBinding
- metadata:
- name: read-secrets
- namespace: kube-public
- subjects:
- - kind: User
- name: lisi
- apiGroup: rbac.authorization.k8s.io
- roleRef:
- kind: ClusterRole
- name: secret-reader
- apiGroup: rbac.authorization.k8s.io
以上 RoleBinding 引用了一个 ClusterRole,这个 ClusterRole 具有整个集群内对 secrets 的访问权限;但是其授权用户 lisi 只能访问 kube-public 空间中的 secrets(因为 RoleBinding 定义在 kube-public 命名空间)。
使用 ClusterRoleBinding 可以对整个集群中的所有命名空间资源权限进行授权
ClusterRoleBinding 示例
- apiVersion: rbac.authorization.k8s.io/v1
- kind: ClusterRoleBinding
- metadata:
- 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
以上 ClusterRoleBinding 授权 manager 组内所有用户在全部命名空间中对 secrets 进行访问。
⑧ Resources
Kubernetes 集群内一些资源一般以其名称字符串来表示,这些字符串一般会在 API 的 URL 地址中出现; 同时某些资源也会包含子资源,例如 log 资源就属于 pods 的子资源,API 中对 Pod 日志的请求 URL 样例如下:
GET /api/v1/namespaces/{namespace}/pods/{name}/log
#在这里,pods 对应名字空间作用域的 Pod 资源,而 log 是 pods 的子资源。
如果要在 RBAC 授权模型中控制这些子资源的访问权限,可以通过 / 分隔符来分隔资源和子资源实现。
以下是一个定义允许某主体读取 pods 同时访问这些 Pod 的 log 子资源的 Role 定义样例:
- apiVersion: rbac.authorization.k8s.io/v1
- kind: Role
- metadata:
- namespace: default
- name: pod-and-pod-logs-reader
- rules:
- - apiGroups: [""]
- resources: ["pods", "pods/log"]
- verbs: ["get", "list"]
- rules.verbs有:"get", "list", "watch", "create", "update", "patch", "delete", "exec"
- rules.resources有:"services", "endpoints", "pods", "secrets", "configmaps", "crontabs", "deployments", "jobs", "nodes", "rolebindings", "clusterroles", "daemonsets", "replicasets", "statefulsets", "horizontalpodautoscalers", "replicationcontrollers", "cronjobs"
- rules.apiGroups有:"","apps", "autoscaling", "batch"
(1)概念
通过认证和鉴权之后,客户端并不能得到API Server的真正响应,这个请求还需通过Admission Control所控制的一个准入控制插件列表的层层考验。
(2)准入控制器
- 1)Admission Control配备有一个“准入控制器”的插件列表,发送给API Server的任何请求都需要通过列表中每一个准入控制器的检查,检查不通过API Server拒绝此调用请求。
-
- 2)此外,准入控制器还能够修改请求参数以完成一些自动化的任务,比如Service Account这个控制器。
(3)配置准入控制
当前可配置的Admission Control准入控制如下:
- 1)NamespaceLifecycle:用于命名空间回收,防止在不存在的 namespace 上创建对象,防止删除系统预置
- namespace,删除 namespace 时,连带删除它的所有资源对象。
-
- 2)LimitRanger:用于配额管理,确保请求的资源不会超过资源所在 Namespace 的 LimitRange 的限制。
-
- 3)ServiceAccount:用于在每个 Pod 中自动化添加 ServiceAccount,方便访问 API Server。
-
- 4)ResourceQuota:用于资源配额管理目的,作用于namespace上,它会观察所有请求,确保在namespace上的配额不会超标。推荐在Admission Control参数列表中将这个插件安排在最后一个,以免可能被其他插件拒绝的Pod被过早分配资源。
-
- 5)NodeRestriction: 用于 Node 加入到 K8S 群集中以最小权限运行。
-
- 6)AlwaysAdmit:允许所有请求;
-
- 7)AlwaysPullmages:在启动容器之前总去下载镜像,相当于在每个容器的配置项
- imagePullPolicy=Always
-
- 8)AlwaysDeny:禁止所有请求,一般用于测试;
-
- 8)DenyExecOnPrivileged:它会拦截所有想在Privileged Container上执行命令的请求,如果你的集群支持Privileged Container,你又希望限制用户在这些Privileged Container上执行命令,强烈推荐你使用它,其功能已经合并到DenyEscalatingExec中。
-
- 10)ImagePolicyWebhook:这个插件将允许后端的一个Webhook程序来完成admission controller的功能。ImagePolicyWebhook需要使用一个配置文件(通过kube-apiserver的启动参数–admission-control-config-file设置)定义后端Webhook的参数。目前该插件还处在Alpha版本。
-
- 11)SecurityContextDeny:这个插件将使用SecurityContext的Pod中的定义全部失效。SecurityContext在Container中定义了操作系统级别的安全设定(uid,gid,capabilityes,SELinux等)。在未启用PodSecurityPolicy的集群中建议启用该插件,以禁用容器设置的非安全访问权限。
-
- 12)InitialResources:是一个实验特性,旨在为未设置资源请求与限制的Pod,根据其镜像的历史资源的使用情况进行初始化的资源请求、限制设置。
-
- 13)DefaultStorageClass:为了实现共享存储的动态供应,为未指定StorageClass或PV的PVC尝试匹配默认的StorageClass,尽可能减少用户在申请PVC时所需了解的后端存储细节。
-
- 14)DefaultTolerationSeconds:这个插件为那些没有设置forgiveness tolerations并具有notready:NoExecute和unreachable:NoExecute两种taints的Pod设置默认的“容忍”时间,为5min。
-
- 15)PodSecurityPolicy:这个插件用于在创建或修改Pod时决定是否根据Pod的security context和可用的PodSecurityPolicy对Pod的安全策略进行控制。
-
① LimitRanger示例
- [root@master1 ~]# kubectl create ns limitrange
- namespace/limitrange created
- [root@master1 ~]# kubectl describe ns limitrange
- Name: limitrange
- Labels:
- Annotations:
- Status: Active
-
- No resource quota.
-
- No LimitRange resource. 看到无LimitRange
cpu限制
- [root@master1 ~]# vim limitrange.yml
- apiVersion: v1
- kind: LimitRange
- metadata:
- name: cpu-limit-range
- namespace: limitrange
- spec:
- limits:
- - default:
- cpu: 1000m
- defaultRequest:
- cpu: 1000m
- min:
- cpu: 500m
- max:
- cpu: 2000m
- maxLimitRequestRatio:
- cpu: 4
- type: Container
- [root@master1 ~]# kubectl apply -f limitrange.yml
- limitrange/cpu-limit-range created
查看名称空间
- [root@master1 ~]# kubectl describe ns limitrange
- Name: limitrange
- Labels:
- Annotations:
- Status: Active
-
- No resource quota.
-
- Resource Limits
- Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
- ---- -------- --- --- --------------- ------------- -----------------------
- Container cpu 500m 2 1 1 4
- [root@master1 ~]# vim limitrange-pod.yml
- apiVersion: v1
- kind: Pod
- metadata:
- name: nginx
- namespace: limitrange
- spec:
- containers:
- - name: c1
- image: nginx:1.15-alpine
- imagePullPolicy: IfNotPresent
- resources:
- requests:
- cpu: 200m # cpu请求200m,小于namespace的cpu最小限制(500m)
- [root@master1 ~]# kubectl apply -f limitrange-pod.yml
- Error from server (Forbidden): error when creating "limitrange-pod.yml": pods "nginx" is forbidden: [minimum cpu usage per Container is 500m, but request is 200m, cpu max limit to request ratio per Container is 4, but provided ratio is 5.000000]
说明: 可看到namespace的cpu最小限制是500m,创建此pod请求为200m,准入控制拒绝了。 改成限制范围内就可以创建。
- [root@master1 ~]# vim limitrange-pod.yml
- apiVersion: v1
- kind: Pod
- metadata:
- name: nginx
- namespace: limitrange
- spec:
- containers:
- - name: c1
- image: nginx:1.15-alpine
- imagePullPolicy: IfNotPresent
- resources:
- requests:
- cpu: 600m # 改成大于500m
- [root@master1 ~]# kubectl apply -f limitrange-pod.yml
- pod/nginx created
-
- [root@master1 ~]# kubectl get pods -n limitrange
- NAME READY STATUS RESTARTS AGE
- nginx 1/1 Running 0 11s 可以成功创建pod
② ResourceQuota示例
- [root@master1 ~]# vim resourcequota.yml
- apiVersion: v1
- kind: ResourceQuota
- metadata:
- name: quota
- namespace: limitrange
- spec:
- hard: # 硬限制
- pods: "1" # 限制此namespace里就不能超过1个pod
- [root@master1 ~]# kubectl apply -f resourcequota.yml
- resourcequota/quota created
- [root@master1 ~]# kubectl describe ns limitrange
- Name: limitrange
- Labels:
- Annotations:
- Status: Active
-
- Resource Quotas
- Name: quota
- Resource Used Hard
- -------- --- ---
- pods 1 1 # 硬限制为1个pod,已经有1个pod了
-
- Resource Limits
- Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
- ---- -------- --- --- --------------- ------------- -----------------------
- Container cpu 500m 2 1 1 4
- [root@master1 ~]# vim resourcequota-pod.yml
- apiVersion: v1
- kind: Pod
- metadata:
- name: nginx2 # 改一个pod名
- namespace: limitrange # 相同的namespace
- spec:
- containers:
- - name: c1
- image: nginx:1.15-alpine
- imagePullPolicy: IfNotPresent
- [root@master1 ~]# kubectl apply -f resourcequota-pod.yml
- Error from server (Forbidden): error when creating "resourcequota-pod.yml": pods "nginx2" is forbidden: exceeded quota: quota, requested: pods=1, used: pods=1, limited: pods=1
- 报错,pod数量超过了
(1)创建证书
①创建user私钥
- #yum install openssl -y
-
- [root@master pki]# (umask 077;openssl genrsa -out david.key 2048)
- Generating RSA private key, 2048 bit long modulus
- ..........................................+++
- ..........................................................+++
- e is 65537 (0x10001)
②创建证书签署请求
O=组织信息,CN=用户名
[root@master pki]# openssl req -new -key david.key -out david.csr -subj "/O=k8s/CN=david"
③签署证书
- [root@master pki]# openssl x509 -req -in david.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out david.crt -days 365
- Signature ok
- subject=/O=k8s/CN=david
- Getting CA Private Key
(2) 创建配置文件
① 创建配置文件主要有以下几个步骤:
- kubectl config set-cluster --kubeconfig=/PATH/TO/SOMEFILE #集群配置
- kubectl config set-credentials NAME --kubeconfig=/PATH/TO/SOMEFILE #用户配置
- kubectl config set-context #context配置
- kubectl config use-context #切换context
- * --embed-certs=true的作用是不在配置文件中显示证书信息。
- * --kubeconfig=/root/david.conf用于创建新的配置文件,如果不加此选项,则内容会添加到家目录下.kube/config文件中,可以使用use-context来切换不同的用户管理k8s集群。
- * context简单的理解就是用什么用户来管理哪个集群,即用户和集群的结合。
②创建集群配置:
- [root@master pki]# kubectl config set-cluster k8s --server=https://192.168.204.171:6443 --certificate-authority=ca.crt --embed-certs=true --kubeconfig=/root/david.conf
- Cluster "k8s" set.
- [root@master pki]# kubectl config view --kubeconfig=/root/david.conf
- apiVersion: v1
- clusters:
- - cluster:
- certificate-authority-data: DATA+OMITTED
- server: https://192.168.204.171:6443
- name: k8s
- contexts: []
- current-context: ""
- kind: Config
- preferences: {}
- users: []
③创建用户配置:
- [root@master pki]# kubectl config set-credentials david --client-certificate=david.crt --client-key=david.key --embed-certs=true --kubeconfig=/root/david.conf
- User "david" set.
- [root@master pki]# kubectl config view --kubeconfig=/root/david.conf
- apiVersion: v1
- clusters:
- - cluster:
- certificate-authority-data: DATA+OMITTED
- server: https://192.168.204.171:6443
- name: k8s
- contexts: []
- current-context: ""
- kind: Config
- preferences: {}
- users:
- - name: david
- user:
- client-certificate-data: REDACTED
- client-key-data: REDACTED
④创建context配置:
- [root@master pki]# kubectl config set-context david@k8s --cluster=k8s --user=david --kubeconfig=/root/david.conf
- Context "david@k8s" created.
- [root@master pki]# kubectl config view --kubeconfig=/root/david.conf
- apiVersion: v1
- clusters:
- - cluster:
- certificate-authority-data: DATA+OMITTED
- server: https://192.168.204.171:6443
- name: k8s
- contexts:
- - context:
- cluster: k8s
- user: david
- name: david@k8s
- current-context: ""
- kind: Config
- preferences: {}
- users:
- - name: david
- user:
- client-certificate-data: REDACTED
- client-key-data: REDACTED
⑤切换context:
- [root@master pki]# kubectl config use-context david@k8s --kubeconfig=/root/david.conf
- Switched to context "david@k8s".
- [root@master pki]# kubectl config view --kubeconfig=/root/david.conf
- apiVersion: v1
- clusters:
- - cluster:
- certificate-authority-data: DATA+OMITTED
- server: https://192.168.204.171:6443
- name: k8s
- contexts:
- - context:
- cluster: k8s
- user: david
- name: david@k8s
- current-context: david@k8s
- kind: Config
- preferences: {}
- users:
- - name: david
- user:
- client-certificate-data: REDACTED
- client-key-data: REDACTED
⑥ 创建系统用户:
- [root@master pki]# useradd david
- [root@master pki]# mkdir -p /home/david/.kube
-
- [root@master pki]# cd ~
-
- [root@master ~]# cp david.conf /home/david/.kube/config
- [root@master ~]# chown david.david -R /home/david/
- [root@master ~]# su - david
- [david@master ~]$
k8s验证文件
- [david@master ~]$ kubectl get pod
- Error from server (Forbidden): pods is forbidden: User "david" cannot list resource "pods" in API group "" in the namespace "default"
- [david@master ~]$
默认新用户是没有任何权限的。
⑦创建Role
回到root用户,此role只有pod的get、list、watch权限
- [root@master ~]$ cat pods-reader.yaml
- apiVersion: rbac.authorization.k8s.io/v1
- kind: Role
- metadata:
- name: pods-reader
- rules:
- - apiGroups:
- - ""
- resources:
- - pods
- verbs:
- - get
- - list
- - watch
-
- [root@master ~]$ kubectl apply -f pods-reader.yaml
⑧创建Rolebinding
用户david和role pods-reader的绑定
- [root@master ~]$ vim david-pods-reader.yaml
- [root@master ~]$ cat david-pods-reader.yaml
- apiVersion: rbac.authorization.k8s.io/v1
- kind: RoleBinding
- metadata:
- name: david-pods-reader
- roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: Role
- name: pods-reader
- subjects:
- - apiGroup: rbac.authorization.k8s.io
- kind: User
- name: david
-
- [root@master ~]$ kubectl apply -f david-pods-reader.yaml
⑨验证结果
如果没有指定命名空间的话,默认就是default命名空间
- [david@master ~]$ kubectl get pod
- NAME READY STATUS RESTARTS AGE
- nfs-client-provisioner-64c6fddb75-7qrdx 1/1 Running 1 4d18h
- [david@master ~]$ kubectl get pod -n kube-system
- Error from server (Forbidden): pods is forbidden: User "david" cannot list resource "pods" in API group "" in the namespace "kube-system"
- [david@master ~]$
⑩ 创建ClusterRole
-
- [root@master ~]# vim cluster-reader.yaml
- [root@master ~]# cat cluster-reader.yaml
- apiVersion: rbac.authorization.k8s.io/v1
- kind: ClusterRole
- metadata:
- name: cluster-reader
- rules:
- - apiGroups:
- - ""
- resources:
- - pods
- verbs:
- - get
- - list
- - watch
-
-
-
-
- #或者全乎一点
- apiVersion: rbac.authorization.k8s.io/v1
- kind: ClusterRole
- metadata:
- name: test-clusterrole
- rules:
- - apiGroups: [""]
- resources: ["pods"]
- verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- - apiGroups: ["extensions", "apps"]
- resources: ["deployments"]
- verbs: ["get", "watch", "list"]
- - apiGroups: [""]
- resources: ["pods/exec"]
- verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- - apiGroups: [""]
- resources: ["pods/log"]
- verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- - apiGroups: [""]
- resources: ["namespaces","namespaces/status"]
- verbs: ["*"] # 也可以使用['*']
- - apiGroups: ["","apps","extensions","apiextensions.k8s.io"]
- resources: ["role","replicasets","deployments","customresourcedefinitions","configmaps"]
- verbs: ["*"]
⑪创建ClusterRoleBinding
- [root@master ~]# vim david-read-all-pod.yaml
- apiVersion: rbac.authorization.k8s.io/v1beta1
- kind: ClusterRoleBinding
- metadata:
- name: david-read-all-pods
- roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: cluster-reader
- subjects:
- - apiGroup: rbac.authorization.k8s.io
- kind: User
- name: david
-
- root@k8s-master:~#
⑫验证结果
- [david@master ~]$ kubectl get pod --all-namespaces
- NAMESPACE NAME READY STATUS RESTARTS AGE
- default nfs-client-provisioner-64c6fddb75-7qrdx 1/1 Running 1 4d19h
- kube-public nginx-deployment-5688f5c784-7w6rs 1/1 Running 2 7d
- kube-public nginx-deployment-5688f5c784-dpxzv 1/1 Running 2 7d
- kube-public nginx-deployment-5688f5c784-pntg6 1/1 Running 2 7d
- kube-system coredns-bccdc95cf-k5npl 1/1 Running 0 4d
- kube-system coredns-bccdc95cf-zg9bh 1/1 Running 0 4d
- kube-system etcd-master 1/1 Running 10 22d
- kube-system kube-apiserver-master 1/1 Running 10 22d
- kube-system kube-controller-manager-master 1/1 Running 10 22d
- kube-system kube-flannel-ds-amd64-drz9g 1/1 Running 2 6d3h
- kube-system kube-flannel-ds-amd64-pkcnl 1/1 Running 9 22d
- kube-system kube-flannel-ds-amd64-s6g9d 1/1 Running 2 6d3h
- kube-system kube-proxy-d6scc 1/1 Running 10 22d
- kube-system kube-proxy-gjmvl 1/1 Running 10 22d
- kube-system kube-proxy-zw6sj 1/1 Running 10 22d
- kube-system kube-scheduler-master 1/1 Running 11 22d
- kube-system kubernetes-dashboard-859b87d4f7-phhlt 1/1 Running 9 21d
就可以看到所有命名空间的pod了.
- 权限绑定指定的namespace
- 也可以使用下面方法进行绑定
- kubectl get clusterrole 查看系统自带角色
- kubectl create rolebinding devuser-admin-rolebinding(rolebinding的名字) --clusterrole=admin(clusterrole的名字,admin在k8s所有namespace下都有最高权限) --user=devuser(将admin的权限赋予devuser用户) --namespace=dev(范围是dev这个namespace下) 即dev
-
-
扩展:
kubectl api-resources 可以查看apiGroups
⑬ 验证结果
创建了ClusterRole和ClusterRoleBinding后就可以看到所有命名空间的pod了。
- [david@master ~]$ kubectl get pod
- NAME READY STATUS RESTARTS AGE
- nfs-client-provisioner-64c6fddb75-7qrdx 1/1 Running 1 4d19h
- [david@master ~]$ kubectl get pod -n kube-system
- NAME READY STATUS RESTARTS AGE
- coredns-bccdc95cf-k5npl 1/1 Running 0 4d
- coredns-bccdc95cf-zg9bh 1/1 Running 0 4d
- etcd-master 1/1 Running 10 22d
- kube-apiserver-master 1/1 Running 10 22d
- kube-controller-manager-master 1/1 Running 10 22d
- kube-flannel-ds-amd64-drz9g 1/1 Running 2 6d3h
- kube-flannel-ds-amd64-pkcnl 1/1 Running 9 22d
- kube-flannel-ds-amd64-s6g9d 1/1 Running 2 6d3h
- kube-proxy-d6scc 1/1 Running 10 22d
- kube-proxy-gjmvl 1/1 Running 10 22d
- kube-proxy-zw6sj 1/1 Running 10 22d
- kube-scheduler-master 1/1 Running 11 22d
- kubernetes-dashboard-859b87d4f7-phhlt 1/1 Running 9 21d
(1)创建namespace
- [root@master ~]# kubectl create namespace dd
- namespace/dd created
(2)验证namespace的sa与secret
创建namespace默认会创建一个serviceaccount和一个secret
- [root@master ~]# kubectl get sa -n dd
- NAME SECRETS AGE
- default 1 10s
-
- [root@master ~]# kubectl get secret -n dd
- NAME TYPE DATA AGE
- default-token-l7srv kubernetes.io/service-account-token 3 18s
- [root@master ~]# kubectl get secret -n dd
- NAME TYPE DATA AGE
- default-token-l7srv kubernetes.io/service-account-token 3 18s
- [root@master ~]# kubectl describe sa default -n dd
- Name: default
- Namespace: dd
- Labels:
- Annotations:
- Image pull secrets:
- Mountable secrets: default-token-l7srv
- Tokens: default-token-l7srv
- Events:
- [root@master ~]#
- [root@master ~]# kubectl describe secret default-token-l7srv -n dd
- Name: default-token-l7srv
- Namespace: dd
- Labels:
- Annotations: kubernetes.io/service-account.name: default
- kubernetes.io/service-account.uid: 509e1301-b1e3-4ca8-8bdc-cdddbd5e9ee0
-
- Type: kubernetes.io/service-account-token
-
- Data
- ====
- token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZWZhdWx0LXRva2VuLWw3c3J2Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI1MDllMTMwMS1iMWUzLTRjYTgtOGJkYy1jZGRkYmQ1ZTllZTAiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGQ6ZGVmYXVsdCJ9.T3UecCBjGUCuT4w257cUEZVzeo56JGz8dEXiR9xFe6onW3_3KOPzKY-gddKwWgyaf_zHpJ5lhpdT-QWt_dVvCAp9M7wXVwruhZZQ2AduLp8JfjsVtIy9Q5s84zuVtJFZmKVFrhbfigvncP9guoohvN21FIGCv2RvV2WAkLakGl49mmhsmnjfZm5BPt2kTeptz7wDtRWpkKCue1Ggr-tlk85DdktDB7ELbKyPl6aT-SGPDGO4foNbAcOtUrE5mPW7TDKvO7OlmFUTFUAArhRnzc_s9g8CD-N7QbwxffVeq9HL_EBwhyjREI5hc6LoibIe-deQDnjwTXMGq_hmnva4Jg
- ca.crt: 1025 bytes
- namespace: 2 bytes
- [root@master ~]#
(3)创建pod验证其sa与secret
创建namespace默认会创建一个serviceaccount和一个secret
- [root@master1 ~]# kubectl run nginx --image=nginx:1.15-alpine -n dd
- pod/nginx created
- [root@master ~]# kubectl describe pod nginx -n dd
- Name: nginx-5d89b4499d-6qshp
- Namespace: dd
- Priority: 0
- Node: node02/192.168.204.175
- Start Time: Tue, 26 Sep 2023 18:08:15 +0800
- Labels: pod-template-hash=5d89b4499d
- run=nginx
- Annotations:
- Status: Running
- IP: 10.244.1.118
- Controlled By: ReplicaSet/nginx-5d89b4499d
- Containers:
- nginx:
- Container ID: docker://c966681cc57507af44319b3b252ad1facecf49bb220066c84baa6838d8e22a6f
- Image: nginx:1.15-alpine
- Image ID: docker-pullable://nginx@sha256:57a226fb6ab6823027c0704a9346a890ffb0cacde06bc19bbc234c8720673555
- Port:
- Host Port:
- State: Running
- Started: Tue, 26 Sep 2023 18:08:35 +0800
- Ready: True
- Restart Count: 0
- Environment:
- Mounts:
- /var/run/secrets/kubernetes.io/serviceaccount from default-token-l7srv (ro)
- Conditions:
- Type Status
- Initialized True
- Ready True
- ContainersReady True
- PodScheduled True
- Volumes:
- default-token-l7srv:
- Type: Secret (a volume populated by a Secret)
- SecretName: default-token-l7srv
- Optional: false
- QoS Class: BestEffort
- Node-Selectors:
- Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
- node.kubernetes.io/unreachable:NoExecute for 300s
- Events:
- Type Reason Age From Message
- ---- ------ ---- ---- -------
- Normal Scheduled 93s default-scheduler Successfully assigned dd/nginx-5d89b4499d-6qshp to node02
- Normal Pulling 92s kubelet, node02 Pulling image "nginx:1.15-alpine"
- Normal Pulled 73s kubelet, node02 Successfully pulled image "nginx:1.15-alpine"
- Normal Created 73s kubelet, node02 Created container nginx
- Normal Started 73s kubelet, node02 Started container nginx
说明: 创建pod不指定serviceaccount则默认使用default
(4)创建一个SA
- [root@master ~]# kubectl create sa david -n dd
- serviceaccount/david created
- [root@master ~]# kubectl get sa -n dd
- NAME SECRETS AGE
- david 1 10s
- default 1 7m6s
- [root@master ~]# kubectl get secret -n dd
- NAME TYPE DATA AGE
- david-token-5gskc kubernetes.io/service-account-token 3 19s
- default-token-l7srv kubernetes.io/service-account-token 3 7m15s
(5)创建pod并自定义SA
- [root@master ~]# vim sa-pod.yml
- apiVersion: v1
- kind: Pod
- metadata:
- name: nginx2
- namespace: dd
- spec:
- containers:
- - name: c1
- image: nginx:1.15-alpine
- ports:
- - name: httpd
- containerPort: 80
- serviceAccountName: david #指定sa为david
(6)验证pod使用的SA
- [root@master ~]# kubectl apply -f sa-pod.yml
- pod/nginx2 created
- [root@master ~]# kubectl describe pod nginx2 -n dd
- ......
- Mounts:
- /var/run/secrets/kubernetes.io/serviceaccount from david-token-5gskc (ro)
- ......
- Volumes:
- david-token-5gskc:
- Type: Secret (a volume populated by a Secret)
- SecretName: david-token-5gskc
- ......
-
- #完整如下
- [root@master ~]# kubectl describe pod nginx2 -n dd
- Name: nginx2
- Namespace: dd
- Priority: 0
- Node: node02/192.168.204.175
- Start Time: Tue, 26 Sep 2023 18:16:55 +0800
- Labels:
- Annotations: kubectl.kubernetes.io/last-applied-configuration:
- {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"nginx2","namespace":"dd"},"spec":{"containers":[{"image":"nginx:1.15-...
- Status: Running
- IP: 10.244.1.119
- Containers:
- c1:
- Container ID: docker://cbb31e791077cba449a1841a1596396df680a2574e663289d339983bdc90844a
- Image: nginx:1.15-alpine
- Image ID: docker-pullable://nginx@sha256:57a226fb6ab6823027c0704a9346a890ffb0cacde06bc19bbc234c8720673555
- Port: 80/TCP
- Host Port: 0/TCP
- State: Running
- Started: Tue, 26 Sep 2023 18:16:56 +0800
- Ready: True
- Restart Count: 0
- Environment:
- Mounts:
- /var/run/secrets/kubernetes.io/serviceaccount from david-token-5gskc (ro)
- Conditions:
- Type Status
- Initialized True
- Ready True
- ContainersReady True
- PodScheduled True
- Volumes:
- david-token-5gskc:
- Type: Secret (a volume populated by a Secret)
- SecretName: david-token-5gskc
- Optional: false
- QoS Class: BestEffort
- Node-Selectors:
- Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
- node.kubernetes.io/unreachable:NoExecute for 300s
- Events:
- Type Reason Age From Message
- ---- ------ ---- ---- -------
- Normal Scheduled 15s default-scheduler Successfully assigned dd/nginx2 to node02
- Normal Pulled 14s kubelet, node02 Container image "nginx:1.15-alpine" already present on machine
- Normal Created 14s kubelet, node02 Created container c1
- Normal Started 14s kubelet, node02 Started co
(1) LimitRanger示例
cpu限制


生成pod
查看名称空间

创建资源清单,cpu请求200m,小于namespace的cpu最小限制(500m)


可看到namespace的cpu最小限制是500m,创建此pod请求为200m,准入控制拒绝了。 改成限制范围内就可以创建。

改成大于500m

可以成功创建pod

删除,减少资源占用

(2) ResourceQuota示例

硬限制,限制此namespace里就不能超过1个pod
生成pod,硬限制为1个pod,目前有0个pod

硬限制为1个pod,已经有1个pod了

改一个pod名,相同的namespace


报错,pod数量超过了

(1)创建证书
①创建user私钥
②创建证书签署请求
O=组织信息,CN=用户名

③签署证书
(2) 创建配置文件
① 创建配置文件主要有以下几个步骤:
- kubectl config set-cluster --kubeconfig=/PATH/TO/SOMEFILE #集群配置
- kubectl config set-credentials NAME --kubeconfig=/PATH/TO/SOMEFILE #用户配置
- kubectl config set-context #context配置
- kubectl config use-context #切换context
- * --embed-certs=true的作用是不在配置文件中显示证书信息。
- * --kubeconfig=/root/david.conf用于创建新的配置文件,如果不加此选项,则内容会添加到家目录下.kube/config文件中,可以使用use-context来切换不同的用户管理k8s集群。
- * context简单的理解就是用什么用户来管理哪个集群,即用户和集群的结合。
②创建集群配置:

③创建用户配置:

④创建context配置:

⑤切换context:

⑥ 创建系统用户:


k8s验证文件,默认新用户是没有任何权限的

⑦创建Role
回到root用户,此role只有pod的get、list、watch权限


⑧创建Rolebinding
用户david和role pods-reader的绑定


⑨验证结果
生成pod

如果没有指定命名空间的话,默认就是default命名空间
所以我们是可以查看查看default命名空间的pod,但是其他空间的pod是无法查看的。
⑩创建ClusterRole


⑪创建ClusterRoleBinding


⑫ 验证结果
生成pod

查看

扩展:

⑬ 验证结果
创建了ClusterRole和ClusterRoleBinding后就可以看到所有命名空间的pod了。
(1)创建namespace
(2)验证namespace的sa与secret
创建namespace默认会创建一个serviceaccount和一个secret


(3)创建pod验证其sa与secret
创建namespace默认会创建一个serviceaccount和一个secret

说明: 创建pod不指定serviceaccount则默认使用default
(4)创建pod并自定义SA


(5)验证pod使用的SA

(1)报错

(2)原因分析
关键词“requests”错误
(3)解决方法
修改配置文件
修改前:

修改后:

成功:

(1)报错

(2)原因分析
指定镜像名称错误
(3)解决方法
修改镜像名称
修改前:

修改后:

成功:

k8s namespace
k8s 中的 namespace 就类似于 windows 中的多个桌面,或者 linux 中的多个终端;namespace 之间的 api 对象是不可见的。
Token 认证和 Base 认证方式只能进行服务端对客户端的单向认证,而客户端不知道服务端是否合法;而 HTTPS 证书认证方式 则可以实现双向认证。
用户有两种:
- 1)用户账户(user) : 是在集群外部访问apiserver时使用的用户,如kubectl命令就是作为kubernetes的admin用户来执行的。
-
- 2)服务账户(ServiceAccount): 为了方便Pod里面的进程调用Kubernetes API或其他外部服务而设计的。
Secret 与 SA 的关系:
- Kubernetes 设计了一种资源对象叫做 Secret,分为两类:
-
- 1)用于保存 ServiceAccount 的 service-account-token
-
- 2)用于保存用户自定义保密信息的 Opaque
Service Account 中包含三个部分:
- 1)Token:是使用 API Server 私钥签名的 Token 字符串序列号,用于访问 API Server 时,Server 端认证
-
- 2)ca.crt:ca 根证书,用于 Client 端验证 API Server 发送来的证书
-
- 3)namespace:标识这个 service-account-token 的作用域名空间
kubeconfig 文件包含:集群参数(CA 证书、API Server 地址),客户端参数(上面生成的证书和私钥),集群 context 上下文参数 (集群名称、用户名)。
在 RBAC API 中,Role 表示一组规则权限,权限只能增加(累加权限),不存在一个资源一开始就有很多权限而通过 RBAC 对其进行减少的操作。也就是说只有白名单权限,而没有黑名单权限的概念。
Role 只能定义在一个 namespace 中,如果想要跨 namespace 则可以创建 ClusterRole,也就是说定义 ClusterRole 不需要绑定 namespace。