K8s集群安全机制
安全机制说明
k8s作为一个分布式集群管理的工具,保证集群的安全性是其一个重要的任务。API Server是集群内部各个组件通信的中介,也是外部控制的入口,,所以K8s的安全机制就是围绕保护API Server来设计的。K8s使用了认证(Authentication)、鉴权(Authorization)、准入控制(Admission Control)三步来保证API Service的安全。
Authentication (认证)
认证方式
1.HTTP Token认证:通过一个Token来识别合法用户(不太安全,token存放于文件中且单向认证)
HTTP Token的认证是用一个很长的特殊编码方式的并且难以被模仿的字符串- Token来表达客户的一种方式。Token 是一个很长的很复杂的字符串,每个Token对应一个用户名存储在API Server能访问的文件中。当客户端发起API调用请求时,需要在HTTP 头部信息里放入Token
2.HTTP Base认证:通过用户名+密码的方式认证(不太安全,单向认证)
用户名+密码用BASE64算法进行编码后的字符串放在HTTP Request中的Heather Authorization域里发送给服务端,服务端收到后进行编码,获取用户名及密码,base64算法解密非常容易
3.最严格的HTTPS证书认证:基于CA根证书签名的客户端身份认证方式(双向认证)
HTTPS证书认证:
CA 认证步骤
- https 通信双方的服务器端, 向CA 机构申请证书. CA 机构下发根证书,服务端证书,私钥给申请者
- https 通信双方的客户端向CA机构申请证书, CA 机构下发根证书,服务端证书,私钥给申请者
- 客户端向服务端发起请求,服务端下发服务端证书给客户端,客户端接收到证书后, 通过私钥揭秘证书, 利用服务端证书中的公钥认证证书信息比较证书里的消息. 例如,比较域名和公钥, 与服务器刚发送的相关信息是否一致, 如果一致, 则认为服务端是可信的
- 客户端发送客户端证书给服务端,服务端通过私钥解密证书,获得客户端公钥,并用该公钥认证证书信息
- 客户端通过随机密钥加密信息发送给服务端. 服务端和客户端协商好加密方案后,客户端会产生一个随机的密钥,客户端通过协商好的加密方案加密该密钥,并发送该随机密钥给服务端. 服务器接收密钥后, 双方所有内容通过该随机密钥加密
认证的两种类型:
1、Kubenetes 组件对API Server的访问: kubectl、Controller Manager、Scheduler、 kubelet、 kube-proxy
由于Controller Manager、Scheduler与API Server处于同一台机器,所以本机互联直接使用API Server的非安全端口访问, --insecure -bind-address=127.0.0.1
kubectl、 kubelet.、kube-proxy访问API Server就都需要证书进行HTTPS双向认证,首次访问API Server时,使用token做认证,通过后,Controller Manager会生成一个证书, 以后的访问都是用证书做认证了
2、Kubernetes 管理的Pod对容器的访问: Pod (dashborad 也是以Pod形式运行)
Pod中的容器访问API Server。因为Pod的创建、销毁是动态的,所以要为它手动生成证书就不可行了。Kubenetes使用了Service Account解决Pod访问API Server的认证问题。
kubeconfig:既是集群的描述,又是集群认证信息的填充
kubeconfig文件包含集群参数(CA证书、API Server地址) .客户端参数(上面生成的证书和私钥) ,集群context信息(集群名称、用户名)。Kubenetes 组件通过启动时指定不同的kubeconfig文件可以切换到不同的集群
congfig文件在./kube目录下

[root@master ~]# cd .kube/ [root@master .kube]# ls cache config [root@master .kube]# cat config apiVersion: v1 clusters: - cluster: certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1EZ3dOREF6TURZek9Wb1hEVE15TURnd01UQXpNRFl6T1Zvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTWtGClVVTVVLQWVTdXh1Ym1WWGN5bEM0NXg0MDRiSkQ2WHR2cjdzYXBjNHFJQ3Y5cFp2a3BmWHNqT29PY3d5ZWJCUkoKempsUkVJK1hJODlsRTVHR2dwNVFGS3Z0bm1WajlYNStDdkVuUFV4bmJ1TzlucWcrN3lHVXdoQW42RVVraCtXcQpQM2JlbFF0dmVHbGQ2SWd4ZTdtdm54WHZxNHpYdktJUDJiak5vbVdIbFBFVVZqUFNWNm1rL2RUTUE1RDcvWVgyCmx6MDE2S05IWUVpd2p4ZzNNbEVMd3oyOHpaU2UvQUszWlRxVTF4Z0E1RldrSDJGb2MvRkdURkNPcmVJSlNGMTkKRXArM1NpMVVWRXFXY1kyd2RFaCtVUDMvTUpKUHQreEZJQkFiNGtZbUZHTDBxLzlpcHY2L24yVWZFQmQ4Mzg1OQorbDNLMmsrTmZUbngzcjRNa1ZNQ0F3RUFBYU5DTUVBd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZCRi84b01YVkg3QkRGWTljd3lxNytETkh2YjZNQTBHQ1NxR1NJYjMKRFFFQkN3VUFBNElCQVFBVGUweWphWnZLQUhDclRGaW54dnZGUUM2cGxRSHBoeDAwTHlvL1VQRjdxdWZaY3dqVQp2dnBSWkNXL2JubU51cDlmN3RSS3B0Y2E5UFdvektJZWthSU4rQWg3eGhKNVl0YWVHdGQwbmlxTEhqRExDL3lJCnlsNk9oSkFzaUZpaGZ6SzlFejBTM2pUc3RJT2xyTDVJZk5Ga3g5eVpFWkRkZ2w4eEJjRXJpd0ZScEQ2dFRyLzUKRXVXd2VnRVp0Q2RiK05TUW9VbEtlQTVQY1FvK0pLQkdoak9wdzUzdFVNYkdPaE94VEtTdEpXYTJNcGlCcGJveAp4dnZxQTdoVUNDYXpMUkpsU3FMKytsdW1jdE8zMG5PUmRVUEdPbHBIRHYvMG14dmF1Mm9hY05jbnVYUm9wZGJJCktmYUt4TEt4Q3R4TzA0N2J5UmNnNnMwZXZ6V2JXdUlmTWNQcgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== server: https://192.168.248.128:6443 name: kubernetes contexts: - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes current-context: kubernetes-admin@kubernetes kind: Config preferences: {} users: - name: kubernetes-admin user: client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURJVENDQWdtZ0F3SUJBZ0lJR1VOdGw5RlNubTB3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TWpBNE1EUXdNekEyTXpsYUZ3MHlNekE0TURRd016QTJOREZhTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXhNK21mQXFINGNla2I3ODQKMit2VFczaFR2emYwdFhHV3BBYy8zMjl2SFBsSkd1YWsxKzhJT0M1ZC84T0tsZnBaTXZLNUYraGdySnA1czdWTQpHSGIvazgrUFlBUDE2VkRkOFZEVFExN1p0YmFhcWh2WE5kejBGSGpqTUJPdTRndUZ1ZUF4R1JRV0p0MkFJUTJICkp5NnY3YnVjVDlYdWEvMG1GQlJocEFlMDZvaFA4ZGp2ZG51V1I2akFvNlR6aFVPNlZBT05nc0hoVWx4M0R6VUgKM0R4QXp6aFZsRlZyODBlWTBUeENZSEJsc0dsb0F6bnh4dm12NXpBem9Lby96QmNIaWpja3k0NGxuMkh5ZlpJKwplSDE5aTZGbXVoQzl6Zm0vQVlQaFpBNWU5N3llOXg1V2F6cFdZTG5ZVTV3RFJBck1sZWFmbnhoNldYdmxHMXdjCll5SWFXUUlEQVFBQm8xWXdWREFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RBWURWUjBUQVFIL0JBSXdBREFmQmdOVkhTTUVHREFXZ0JRUmYvS0RGMVIrd1F4V1BYTU1xdS9nelI3MgorakFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBVUliNlpEMy92dngwcXJMbHdrN09US2ltRXdpRWF2VkdsVk9kCngwVmxnTTI1QUFSZlRJb1l1d2Q1VmN0UWlzNjFQM3o2M0swNzdTcjdUNEluMVlYWC93bFBsMDVEUGJPajJ6VlkKOEVVMkhmM1k1TDlKUE5EbnpvelQ3dnlHSVJhMFVvZmw3eEd2Sk1nZEFkS0NnTnR0azZ1d0VOMG9HRWRqY1Zidgowdzc5clBxMm55OW5wZklNRlAyWDNCLzFpd1J1V3hMUVd1UE5uYzBIMjlkc1NGb0RIOHhnZGlvd2dLMWFaa0dhCnVLV21Fa3dwbnBjTk9SMjZCWG1obm1Qd2tKTE1kdlNFVm5GYXpWN1ZlSmVOdktuajBEeFRrUTFnNktianNpb2gKckJWNGM5RGVjMHY4YmlCL1cvRUJQS0swU0hLcHVSY3FnUjBXMDB5MVNGRTJXbUdkVkE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBeE0rbWZBcUg0Y2VrYjc4NDIrdlRXM2hUdnpmMHRYR1dwQWMvMzI5dkhQbEpHdWFrCjErOElPQzVkLzhPS2xmcFpNdks1RitoZ3JKcDVzN1ZNR0hiL2s4K1BZQVAxNlZEZDhWRFRRMTdadGJhYXFodlgKTmR6MEZIampNQk91NGd1RnVlQXhHUlFXSnQyQUlRMkhKeTZ2N2J1Y1Q5WHVhLzBtRkJSaHBBZTA2b2hQOGRqdgpkbnVXUjZqQW82VHpoVU82VkFPTmdzSGhVbHgzRHpVSDNEeEF6emhWbEZWcjgwZVkwVHhDWUhCbHNHbG9Bem54Cnh2bXY1ekF6b0tvL3pCY0hpamNreTQ0bG4ySHlmWkkrZUgxOWk2Rm11aEM5emZtL0FZUGhaQTVlOTd5ZTl4NVcKYXpwV1lMbllVNXdEUkFyTWxlYWZueGg2V1h2bEcxd2NZeUlhV1FJREFRQUJBb0lCQVFDampXUnU1Rmx6ZVhMZgpJbXZmNXFRbitXQ3ZJWk1NVGE2LzlQNVJjY3RHcXFyajNoUFRGbU1nUFBnRW1iMUxVVlpiRG5aZXRjL1E0RGFPCjd2U2p5QkF3QjJiQWhjb1A4QkhnZmloeWJocEI5ZE9sMWFrTXErZHlNOXVva2xMY3FuS2d1dnhTT08wSHN6N04KT082OTB3Q0VjVW8rMWl0aU5tYzBmSk4vdXAvUDNhNHBvSWVJMms3b1hhNnVzdG5XaklhWkxpMlVTZEhMTTEvRwpmS0hQVWNMSVRmNUorbThCcE16Q2U3Y0l0d01CdXloZVh3NDRScEFQT2dCb2wrR2JKU3lZWk00bzRvemVwbDdFCi93aDVUUXNhcWJpQ2Y1aHFWZHBISzBxYXA1bW9JczVNNXVidENjaDY2UHEyYXBwMDAzRnJCb0FtQWlPL1p5aFoKS0RNT3AyZVpBb0dCQU9sR0VteTVvWUhDMURMZnNpaG5iWWpJOHExelcwZXZXSmdpNjZ6cSszdGFlL2xIWkIxbApVTFRLTElyckFRVmhUSnZwRVg0ZmEyZG1FT0lvalNzMFJxQlpTa1pJb3dQVDkrM3R0akpDY2VQcVdvTnROaE1hCnQzdUVZWkhrei9mcjFSZmZ4Rmh0K0I3eGxKZy9hSEQweTZVOGRic1lxRURjd1lHT0x1UUxvQk9mQW9HQkFOZjgKTUZMTi9hQnNFSzJPMkJVZjJ6Q0NyNWxYNEZWK1FHUGgrTC9PZGpUVzNxUzFJL1NBWStUZUhobytNYndkdnk1ZgpvbTE0eGNIYXFGdnJuUkMrUUZWTmplV3RMRUVWeFViTG1xcDNnZEVBNlBBTUNJNzFReW5LZW41UzdSNmMxcFcvCnN5dmJkOHVlb2Z3M0w1d05QZzE1dVgzUTkvTGIrYXNqbE5zem5NOEhBb0dBS2Qycm5Odk1BcS9teWFLZ0pPUTcKSWx0K1FtYjdzT2ZsYkppSDE2YnNyM3pUMXk5YTVuT3lnbC91a3BnT3ZOcHpsMS9EQmZHNW92c01lS3B5ZTVpTQpQR2NLRDRjbHlxQVdWUnRlb2JLUElpcURTQ2NubDFJcUwvN1lUQWpXMGxYL0RxUFlaMDZGUTNoMEJNY01oWWxKCnEwUW9sUVdkM05aQjNIQ2FOYzlvVVYwQ2dZRUFrR1FiVmpBNS81WmZLL2hVQXdOU0FNTk5hNEZ4Q3hhbEsyRTEKYjkweDd5ODZsdmcyT2szZStuRjN4R21SekVaQ3VsamErTDZGem94RWczY25nTHIvdlVka3RvZ29EcmJrTk9rRwoxREdpeXJ3Ri9meTlkLzBGVXBuM2ZCNHFRWTN1Y3h3K1J2S295cXFaZGtqYWZrUG9HUkFvYnJGV0liam4xMzZwCkZFWVQ3ZDhDZ1lFQXYzbDlsWWd6VHNxZ3A2elJNME0zdkJYaHZGTzF0bStWRGxTRUF6TkFvSklGTFgxNnNTcWYKYVBlOUErV3doMGR1cElwRTVONkE5UVpQKy9TeU1JUHNIM0FSbjYrOU5CSnhYaWltbTE0WG9qVnVxUHJYMTdoUwo5dkQ2b2F6RGM5N1EwbmVtV2k3MEw1OTg1WkRtSFFpKzdNb1drTm1HMFNhTFg2SW0vbWMvNi9RPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
Secret 与SA的关系
Kubernetes设计了一种资源对象叫做Secret,分为两类,一种是用于ServiceAccount的service-account-token,另一种是用于保存用户自定义保密信息的Opaque。ServiceAccount 中用到包含三个部分: Token、ca.crt、namespace
- token是使用API Server私钥签名的JWT。用于访问API Server时,Server端认证
- ca.crt, 根证书。于Client端验证API Server发送的证书
- namespace, 标识这个service-account-token的作用域名空间
查看命名空间的secret
[root@master ~]# kubectl get secret --all-namespaces NAMESPACE NAME TYPE DATA AGE default default-token-h5ppr kubernetes.io/service-account-token 3 3d kube-node-lease default-token-hfxxl kubernetes.io/service-account-token 3 3d kube-public default-token-gw4mp kubernetes.io/service-account-token 3 3d kube-system attachdetach-controller-token-dhppz kubernetes.io/service-account-token 3 3d kube-system bootstrap-signer-token-tvgrb kubernetes.io/service-account-token 3 3d kube-system calico-kube-controllers-token-z6fgs kubernetes.io/service-account-token 3 2d23h kube-system calico-node-token-jlk2j kubernetes.io/service-account-token 3 2d23h kube-system certificate-controller-token-7qnc2 kubernetes.io/service-account-token 3 3d kube-system clusterrole-aggregation-controller-token-npjb8 kubernetes.io/service-account-token 3 3d kube-system coredns-token-v9vfp kubernetes.io/service-account-token 3 3d kube-system cronjob-controller-token-cfldq kubernetes.io/service-account-token 3 3d kube-system daemon-set-controller-token-n6mfd kubernetes.io/service-account-token 3 3d kube-system default-token-nb4vp kubernetes.io/service-account-token 3 3d kube-system deployment-controller-token-pjpcc kubernetes.io/service-account-token 3 3d kube-system disruption-controller-token-hxzcq kubernetes.io/service-account-token 3 3d kube-system endpoint-controller-token-dn67n kubernetes.io/service-account-token 3 3d kube-system endpointslice-controller-token-wqbw7 kubernetes.io/service-account-token 3 3d kube-system endpointslicemirroring-controller-token-n9zk7 kubernetes.io/service-account-token 3 3d kube-system ephemeral-volume-controller-token-wj7kj kubernetes.io/service-account-token 3 3d kube-system expand-controller-token-7txs7 kubernetes.io/service-account-token 3 3d kube-system generic-garbage-collector-token-wzjbg kubernetes.io/service-account-token 3 3d kube-system horizontal-pod-autoscaler-token-5sf75 kubernetes.io/service-account-token 3 3d kube-system job-controller-token-zgqzw kubernetes.io/service-account-token 3 3d kube-system kube-proxy-token-h7pf9 kubernetes.io/service-account-token 3 3d kube-system namespace-controller-token-njgsw kubernetes.io/service-account-token 3 3d kube-system node-controller-token-h5h7h kubernetes.io/service-account-token 3 3d kube-system persistent-volume-binder-token-vdlt9 kubernetes.io/service-account-token 3 3d kube-system pod-garbage-collector-token-86mv7 kubernetes.io/service-account-token 3 3d kube-system pv-protection-controller-token-55bp6 kubernetes.io/service-account-token 3 3d kube-system pvc-protection-controller-token-7n8d8 kubernetes.io/service-account-token 3 3d kube-system replicaset-controller-token-6c4rg kubernetes.io/service-account-token 3 3d kube-system replication-controller-token-mhzck kubernetes.io/service-account-token 3 3d kube-system resourcequota-controller-token-97nm6 kubernetes.io/service-account-token 3 3d kube-system root-ca-cert-publisher-token-kxcxq kubernetes.io/service-account-token 3 3d kube-system service-account-controller-token-479nb kubernetes.io/service-account-token 3 3d kube-system service-controller-token-8mqbf kubernetes.io/service-account-token 3 3d kube-system statefulset-controller-token-b7nqk kubernetes.io/service-account-token 3 3d kube-system token-cleaner-token-mb6rr kubernetes.io/service-account-token 3 3d kube-system ttl-after-finished-controller-token-qhxfz kubernetes.io/service-account-token 3 3d kube-system ttl-controller-token-x4l9x kubernetes.io/service-account-token 3 3d
查看详细信息
[root@master ~]# kubectl describe secret kube-proxy-token-h7pf9 -n kube-system Name: kube-proxy-token-h7pf9 Namespace: kube-system Labels: <none> Annotations: kubernetes.io/service-account.name: kube-proxy kubernetes.io/service-account.uid: fa703f68-03dc-4479-ab46-ea53b9728d77 Type: kubernetes.io/service-account-token Data ==== ca.crt: 1066 bytes namespace: 11 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6Ink5dFVnV0JhV0h3UUo2ZWh5NkFTSWRQRHYzRjI3VXVzX1NueVpaNHkwTTAifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrdWJlLXByb3h5LXRva2VuLWg3cGY5Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Imt1YmUtcHJveHkiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJmYTcwM2Y2OC0wM2RjLTQ0NzktYWI0Ni1lYTUzYjk3MjhkNzciLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06a3ViZS1wcm94eSJ9.J7wavOT0WW0hGKfoIRg8OERfOclfEN3ZABE9NIZwVH2gP9Ly5R6gnv4WRY-Eulp2qfXyoiuGdyqT_xAvrENR306IfpR-COG1632NBLkon-7IlGjQvFl5ieinxBujuzm8D67AErrIP9ooHAIrPCvZNVO9suz7JiGuD6UP_JHDrPPs2oQ7S35Tn044JuxIyEduHX57ZFPWxI6dOfCyG2i7Ujtr9XY2DawICDBCIREgR0aP6lke7GipX_vqbCQv52oTbio_OLon_E9SEX_X58YfuEgRbI9A5weH5h_bxcCwPWF6Lh6scxCNinVLPThWv2xMtsbRun5GgQV25Sy6QSoiDw
默认情况下,每个namespace都会有一个ServiceAccount,如果Pod在创建时没有指定ServiceAccount,就会使用Pod所属的namespace的ServiceAccount,pod中默认的ServiceAccount地址在/run/secrets/kubernetes.io/serviceaccount目录下
[root@master ~]# kubectl exec kube-proxy-4r78x -n kube-system -it -- /bin/sh # cd /run/secrets/kubernetes.io/serviceaccount # ls ca.crt namespace token #
Authorization(鉴权)
当客户端发起API Server调用时,API Server内部要先进行用户认证,然后执行用户授权流程,即通过授权策略来决定一个API调用是否合法。对合法用户进行授权并且随后在用户访问时进行鉴权,是权限与安全系统的重要一环。简单地说,授权就是授予不同的用户不同的访问权限。API Server目前支持以下几种授权策略(通过API Server的启动参数“--authorization-mode”设置)。
- AIwaysDeny: 表示拒绝所有的请求,一般用于测试
- AlwaysAllow: 允许接收所有请求,如果集群不需要授权流程,则可以采用该策略(测试中可以用一下)
- ABAC (Attribute-Based Access Control) :基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制。(已经过时了,需要重启)
- Webbook: 通过调用外部REST服务对用户进行授权(历史啦,集群内部就不可以操作)
- RBAC (Role-Based Access Control) :基于角色的访问(现行默认规则)
RBAC (Role-Based Access Control)
基于角色的访问控制,在Kubernetes 1.5中引入,现行版本成为默认标准。相对其它访问控制方式,拥有以下优势:
- 对集群中的资源和非资源均拥有完整的覆盖
- 整个RBAC完全由几个API对象完成,同其它API对象一样,可以用kubectl或API进行操作
- 可以在运行时进行调整,无需重启API Server
RBAC的API资源对象说明
RBAC引入了4个新的顶级资源对象: Role(角色)、ClusterRole(集群角色)、 RoleBinding(角色绑定)、ClusterRoleBinding(集群角色绑定), 4种对象类型均可以通过kubectl与API操作
Resource代表的是权限(创建、读取、更新..等等),写入一个Role或者ClusterRole,通过RoleBinding或者ClusterRoleBinding的形式赋予给我们的用户、组或者是SA一定的权限。
RBAC比较常见授权维度:
- user:用户名
- group:用户分组
- resources:例如pods、deployments、jobs等
- 资源操作方法:get、list、create、delete、update、patch、watch、logs
- 命名空间
- API组
Role(角色)
一个角色就是一组权限的集合,这里的权限都是许可形式的,不存在拒绝的规则。在一个命名空间中,可以用Role来定义一个角色,如果是集群级别的,就需要使用ClusterRole了。
角色只能对命名空间内的资源进行授权,在下面例子中定义的角色具备读取Pod的权限:
[root@master ~]# cat Role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default #针对default命名空间限制 name: pod-reader rules: - apiGroups: [""] # "" 标明API组,空字符串表示核心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(集群角色)
集群角色除了具有和角色一致的命名空间内资源的管理能力,因其集群级别的范围,还可以用于以下特殊元素的授权:
- 集群范围的资源,例如Node
- 非资源型的路径,例如“/healthz”
- 包含全部命名空间的资源,例如pods(用于kubectl get pods --all-namespaces这样的操作授权)
下面的集群角色可以让用户有权访问任意一个或所有命名空间的secrets(视其绑定方式而定)
[root@master ~]# cat Clusterrole.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: # "namespace" 被忽略,因为 ClusterRoles 不受命名空间限制 name: secret-reader rules: - apiGroups: [""] resources: ["secrets"] # 在 HTTP 层面,用来访问 Secret 资源的名称为 "secrets" verbs: ["get", "watch", "list"]
RoleBinding(角色绑定)和ClusterRoleBinding(集群角色绑定)
角色绑定或集群角色绑定用来把一个角色绑定到一个目标上,绑定目标可以是User(用户)、Group(组)或者Service Account。使用RoleBinding为某个命名空间授权,使用ClusterRoleBinding为集群范围内授权。
RoleBinding可以引用Role进行授权。下面的例子中的RoleBinding将在default命名空间中把pod-reader角色授予用户jane,这一操作可以让jane读取default命名空间中的Pod:
[root@master ~]# cat Rolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-pods namespace: default subjects: # 可以指定多个“subject(主体)” - kind: User name: jane # 用户名,"name" 区分大小写 apiGroup: rbac.authorization.k8s.io roleRef: # "roleRef" 指定与某 Role 或 ClusterRole 的绑定关系 kind: Role # 此字段必须是 Role 或 ClusterRole name: pod-reader # 此字段必须与你要绑定的 Role 或 ClusterRole 的名称匹配 apiGroup: rbac.authorization.k8s.io
RoleBinding也可以引用ClusterRole,对属于同一命名空间内ClusterRole定义的资源主体进行授权。一种常见的做法是集群管理员为集群范围预先定义好一组ClusterRole,然后在多个命名空间中重复使用这些ClusterRole。
例如,在下面的例子中,虽然secret-reader是一个集群角色,但是因为使用了RoleBinding,所以dave只能读取development命名空间中的secret:
[root@master ~]# cat ClusterRolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-secrets namespace: development # 授权仅在 "development" 命名空间内的访问权限。 subjects: - kind: User name: dave #用户名,'name' 区分大小写 apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: secret-reader #ClusterRole名称 apiGroup: rbac.authorization.k8s.io
集群角色绑定中的角色只能是集群角色,用于进行集群级别或者对所有命名空间都生效的授权。下面的例子允许manager组的用户读取任意Namespace中的secret:
[root@master ~]# cat ClusterRolebinding_group.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: read-secrets-global subjects: - kind: Group #针对用户组 name: manager # 组名,”name“区分大小写 apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: secret-reader apiGroup: rbac.authorization.k8s.io
创建了绑定之后,你不能再修改绑定对象所引用的 Role 或 ClusterRole。 试图改变绑定对象的roleRef将导致合法性检查错误。 如果你想要改变现有绑定对象中roleRef字段的内容,必须删除重新创建绑定对象。
这种限制有两个主要原因:
- 将roleRef设置为不可以改变,这使得可以为用户授予对现有绑定对象的update权限, 这样可以让他们管理主体列表,同时不能更改被授予这些主体的角色
- 针对不同角色的绑定是完全不一样的绑定。要求通过删除/重建绑定来更改roleRef, 这样可以确保要赋予绑定的所有主体会被授予新的角色(而不是在允许或者不小心修改了roleRef的情况下导致所有现有主体未经验证即被授予新角色对应的权限)。
命令kuberctl auth reconcile可以创建或者更新包含 RBAC 对象的清单文件, 并且在必要的情况下删除和重新创建绑定对象,以改变所引用的角色。
例如创建一个lzf用户,并只给赋予查看default命名空间下的查看pod的权限。
实施步骤:
创建一个lzf的用户
[root@master ~]# useradd lzf [root@master ~]# passwd lzf 更改用户 lzf 的密码 。 新的 密码: 重新输入新的 密码: passwd:所有的身份验证令牌已经成功更新。 [root@master ~]# mkdir -p rbac/lzf [root@master ~]# cd rbac/lzf/
通过json文件为k8s添加一个lzf用户
[root@master lzf]# cat lzf.json { "CN":"lzf", #用户名 "hosts":[], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "k8s", #用户组 "OU": "System" } ] }
下载证书生成工具
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 chmod a+x * mv cfssl_linux-amd64 /usr/local/bin/cfssl mv cfssljson_linux-amd64 /usr/local/bin/cfssljson mv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo cd /etc/kubernetes/pki/
创建证书请求和证书私钥
[root@master pki]# cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes /root/rbac/lzf/lzf.json | cfssljson -bare lzf 2022/08/09 10:20:16 [INFO] generate received request 2022/08/09 10:20:16 [INFO] received CSR 2022/08/09 10:20:16 [INFO] generating key: rsa-2048 2022/08/09 10:20:17 [INFO] encoded CSR 2022/08/09 10:20:17 [INFO] signed certificate with serial number 698000275820440175314200896688961812505092833727 2022/08/09 10:20:17 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for websites. For more information see the Baseline Requirements for the Issuance and Management of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org); specifically, section 10.2.3 ("Information Requirements"). [root@master pki]# ls apiserver.crt apiserver-etcd-client.key apiserver-kubelet-client.crt ca.crt etcd front-proxy-ca.key front-proxy-client.key lzf-key.pem sa.key apiserver-etcd-client.crt apiserver.key apiserver-kubelet-client.key ca.key front-proxy-ca.crt front-proxy-client.crt lzf.csr lzf.pem sa.pub [root@master pki]#
生成K8s授权文件
[root@master lzf]# cat kubeconfig.sh #设置集群参数 kubectl config set-cluster kubernetes \ --certificate-authority=/etc/kubernetes/pki/ca.crt \ --embed-certs=true \ --server=https://192.168.248.128:6443 \ --kubeconfig=lzf.kubeconfig # 设置客户端认证参数 kubectl config set-credentials lzf \ --client-certificate=/etc/kubernetes/pki/lzf.pem \ --client-key=/etc/kubernetes/pki/lzf-key.pem \ --embed-certs=true \ --kubeconfig=lzf.kubeconfig # 设置上下文参数 kubectl config set-context kubernetes \ --cluster=kubernetes \ --user=lzf \ --kubeconfig=lzf.kubeconfig
执行kubeconfig.sh
[root@master lzf]# sh kubeconfig.sh Cluster "kubernetes" set. User "lzf" set. Context "kubernetes" created. [root@master lzf]# ls kubeconfig.sh lzf.json lzf.kubeconfig #属于lzf的用户配置文件
创建RBAC策略,给lzf用户查看default下的pod权限
创建Role
[root@master ~]# cat Role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get",“watch”,"list"]
创建RoleBinding
[root@master ~]# cat Rolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-pods namespace: default subjects: - kind: User name: lzf apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io
执行yaml
[root@master ~]# kubectl apply -f Role.yaml role.rbac.authorization.k8s.io/pod-reader created [root@master ~]# kubectl apply -f Rolebinding.yaml rolebinding.rbac.authorization.k8s.io/read-pods created
切换上下文 让kubectl读取我们的配置信息
[root@master ~]# kubectl config use-context kubernetes --kubeconfig=/root/rbac/lzf/lzf.kubeconfig Switched to context "kubernetes".
测试lzf权限
[root@master ~]# kubectl get pod --kubeconfig=rbac/lzf/lzf.kubeconfig NAME READY STATUS RESTARTS AGE deployment-nginx-8c459867c-4fw9q 1/1 Running 0 2d13h deployment-nginx-8c459867c-ccbkz 1/1 Running 0 2d13h deployment-nginx-8c459867c-cksqd 1/1 Running 0 2d13h deployment-nginx-8c459867c-mrdz4 1/1 Running 0 2d13h deployment-nginx-8c459867c-zt8n8 1/1 Running 0 2d13h
切换lzf用户测试
[lzf@master ~]$ kubectl get pods --kubeconfig=.kube/lzf.kubeconfig NAME READY STATUS RESTARTS AGE deployment-nginx-8c459867c-4fw9q 1/1 Running 0 2d15h deployment-nginx-8c459867c-ccbkz 1/1 Running 0 2d15h deployment-nginx-8c459867c-cksqd 1/1 Running 0 2d15h deployment-nginx-8c459867c-mrdz4 1/1 Running 0 2d15h deployment-nginx-8c459867c-zt8n8 1/1 Running 0 2d15h
我们可以在Role里面为用户lzf添加权限。比如,查看其他命名空间的pod,deployment,创建pod等等操作。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!