共计 31689 个字符,预计需要花费 80 分钟才能阅读完成。
咱们晓得对于资源对象的操作都是通过 APIServer 进行的,那么集群是怎么晓得咱们的申请就是非法的申请呢?这个就须要理解 Kubernetes 的认证鉴权流程
API 对象
在讲认证鉴权之前,咱们还须要再去了解下 Kubernetes 集群中的对象,咱们晓得,在 Kubernetes 集群中,Kubernetes 对象是咱们长久化的实体,就是最终存入 etcd 中的数据。咱们间接编写的 YAML 文件,通过 kubectl 来提交的资源清单文件,而后创立的对应的资源对象,那么它到底是如何将咱们的 YAML 文件转换成集群中的一个 API 对象的呢?
这个就须要去理解下 申明式 API的设计,Kubernetes API 是一个以 JSON 为次要序列化形式的 HTTP 服务,除此之外也反对 Protocol Buffers 序列化形式,次要用于集群外部组件间的通信。Kubernetes API 文档能够参考官网 https://kubernetes.io/docs/re…
为了可扩展性,Kubernetes 在不同的 API 门路(比方 /api/v1 或者 /apis/batch)上面反对了多个 API 版本,不同的 API 版本意味着不同级别的稳定性和反对:
- Alpha 级别,例如 v1alpha1 默认状况下是被禁用的,能够随时删除对性能的反对,所以要慎用
- Beta 级别,例如 v2beta1 默认状况下是启用的,示意代码曾经通过了很好的测试,然而对象的语义可能会在随后的版本中以不兼容的形式更改
- 稳固级别,比方 v1 示意曾经是稳固版本了,也会呈现在后续的很多版本中。
在 Kubernetes 集群中,一个 API 对象在 Etcd 里的残缺资源门路,是由:Group(API 组)、Version(API 版本)和 Resource(API 资源类型)三个局部组成的。通过这样的构造,整个 Kubernetes 里的所有 API 对象,实际上就能够用如下的树形构造示意进去:
从上图中咱们也能够看出 Kubernetes 的 API 对象的组织形式,在顶层,咱们能够看到有一个外围组(因为历史起因,是 /api/v1 下的所有内容而不是在 /apis/core/v1 上面)和命名组(门路 /apis/$NAME/$VERSION)和零碎范畴内的实体,比方 /metrics。咱们也能够用上面的命令来查看集群中的 API 组织模式:
[root@k8s-master ~]# kubectl get --raw /
{
"paths": [
"/api",
"/api/v1",
"/apis",
"/apis/",
...
"/version"
]
}
比方咱们来查看外围组下的资源对象,同样咱们还是能够通过 kubectl 来查问数据,这外面咱们能够看到外围组上面的资源对象和对应操作
[root@k8s-master ~]# kubectl get --raw /api/v1 | python -m json.tool
{
"groupVersion": "v1",
"kind": "APIResourceList",
"resources": [
{
"kind": "Binding",
"name": "bindings",
"namespaced": true,
"singularName": "","verbs": ["create"]
},
{
"kind": "ComponentStatus",
"name": "componentstatuses",
"namespaced": false,
"shortNames": ["cs"],
"singularName": "","verbs": ["get","list"]
},
{
"kind": "ConfigMap",
"name": "configmaps",
"namespaced": true,
"shortNames": ["cm"],
"singularName": "","storageVersionHash":"qFsyl6wFWjQ=","verbs": ["create","delete","deletecollection","get","list","patch","update","watch"]
},
...
{
"kind": "Service",
"name": "services/status",
"namespaced": true,
"singularName": "","verbs": ["get","patch","update"]
}
然而这个操作和咱们平时操作 HTTP 服务的形式不太一样,这里咱们能够通过 kubectl proxy 命令来开启一个代理 http 服务对 apiserver 进行拜访:
[root@k8s-master ~]# kubectl proxy
Starting to serve on 127.0.0.1:8001
而后从新开启一个新的终端,咱们能够通过如下代理服务形式来拜访 apiserver 的接口,比方咱们拜访查问某个命名空间下 pod 资源对象的接口
[root@k8s-master ~]# curl http://127.0.0.1:8001/api/v1/namespaces/default/pods
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/namespaces/default/pods",
"resourceVersion": "9109616"
},
"items": [
{
"metadata": {
"name": "nginx-deploy-75c7f965d8-hnmvn",
"generateName": "nginx-deploy-75c7f965d8-",
"namespace": "default",
"selfLink": "/api/v1/namespaces/default/pods/nginx-deploy-75c7f965d8-hnmvn",
"uid": "574ac979-41b8-460f-afaf-d29155911ba3",
"resourceVersion": "6786396",
"creationTimestamp": "2021-05-10T03:30:07Z",
"labels": {
"app": "nginx",
"pod-template-hash": "75c7f965d8"
},
"ownerReferences": [
{
"apiVersion": "apps/v1",
"kind": "ReplicaSet",
"name": "nginx-deploy-75c7f965d8",
"uid": "25bdae05-87e9-41e0-bcde-6bfeda87047c",
"controller": true,
"blockOwnerDeletion": true
}
],
...
通常,Kubernetes API 反对通过规范 HTTP POST、PUT、DELETE 和 GET 在指定 PATH 门路上创立、更新、删除和检索操作,并应用 JSON 作为默认的数据交互格局。
Kubernetes 认证
下面咱们应用了 kubectl 或者 kubectl proxy 的形式,都可能顺利获取到 apiserver 的资源对象的数据,这是因为它们曾经顺利通过了 Kubernetes 的认证鉴权组件
Kubernetes API 的申请从发动到操作存储层的流程如图
上面咱们剖析下 kubectl、kubectl proxy、pod 拜访 apiserver 的认证形式
kubectl 拜访 apiserver
kubectl应用的认证形式是 clientCA 认证,X509 认证是 Kubernetes 组件间默认应用的认证形式,同时也是 kubectl 客户端对应的 kube-config 中常常应用到的拜访凭证。它是一个比拟平安的形式,访问者会应用由集群 CA 签发的,或是增加在 apiserver 配置中的授信 CA 签发的客户端证书去拜访 apiserver。apiserver 在接管到申请后,会进行 TLS 的握手流程。
除了验证证书的合法性,apiserver 还会校验客户端证书的申请源地址等信息,开启双向认证。
比方咱们查看下咱们 kubectl 的证书信息
[root@k8s-master ~]# cat ~/.kube/config
apiVersion: v1
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
users:
- name: kubernetes-admin
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURFekNDQWZ1Z0F3SUJBZ0lJVmxIbDlTalNvdFF3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TVRBME1EY3hNVFF6TXpsYUZ3MHlNakEwTURjeE1UUXpOREZhTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXFzVnlQc2RQRGlEYW9FNWcKZWxOQjV4ZHJoZCs1eEd5RUJFbGpUY2tMb3JPQlN6SjE3Z2JpY0VSaXRQLzh1YVpmVk9ISnZ0Y2tyZUpGa3NHNgp2Ujc5YUk4d3k0elUreEk0ZzdzK2ZrTFRsK1QrR2xaSWlQaXN3a2RQZE9ad0REUDBKdDQ5NjljVzFndVJ6UTVQCmhpSjRTcE96Z0dmeFJGQWpFTUFCNktJcXBWYjlrbmV4d0xHVDRRNTZNS1JvV294UytEaFBQZFk4bUlVR3pHZ0oKbkw1bEl1Mjl2a0FmWG1vZEdZMVFUNkszSXU3NmFhWXl0TTVRUTZZVnFwekxXU0lYOFN2L0E0dlFqVDlTSDY5eQptQ1RmQ0lXWjVTRGZ4VTlvQ0p5RGpKTmpBdUErNWJONUpxMDFEYjhjK0hjTHVHUENBRVJUVnBZU3docWx1T0lFCk40SU9Md0lEQVFBQm8wZ3dSakFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0h3WURWUjBqQkJnd0ZvQVV6RmZHVHJhMjRVa3hzM2NReWJzSnprT2R2UXN3RFFZSktvWklodmNOQVFFTApCUUFEZ2dFQkFDRHUwQ3g5Qk1NdjdUMnh6T3gzTDNNczk5NTdKMDY3WDVhbTZnZW4yaXltekViMkNldG51REdoCnFMWW5MZnBOZ1FOQ1pTbkg5dzZIYjdWenRMTzlheXZjejcvRVlRVkpyOVN0MzdtZDc0d3dKY1AvZWY1b2ZEbkgKVTVJaXZKK1RuM3REeGhlVVU5VlBFSkdCbFZmd3N0UmxJZ3NWclR0TkVnNGYzaW04azZzNlRTTGV5Sis4Y21zdgpwTmYyRDNpWWw3aEhBTGJwS2tFWVEya2xSY0IyRDFSL1Fhd2o4WWoyUGJ4cEZOU0t4QmQ4S09mcGVaMWQ5ZmpiCmZMbUxGU29rZjk1b0lrTk9TSGpUanVDNmNaNGVHczU0bjhaMmhnMWZia1R0Y2pJK1ROZi9nY29FNExvM3JhaDgKbW1sa1Qxdit4T3hKUWpkbkdwT2FSNytINFkwblY5dz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBcXNWeVBzZFBEaURhb0U1Z2VsTkI1eGRyaGQrNXhHeUVCRWxqVGNrTG9yT0JTekoxCjdnYmljRVJpdFAvOHVhWmZWT0hKdnRja3JlSkZrc0c2dlI3OWFJOHd5NHpVK3hJNGc3cytma0xUbCtUK0dsWkkKaVBpc3drZFBkT1p3RERQMEp0NDk2OWNXMWd1UnpRNVBoaUo0U3BPemdHZnhSRkFqRU1BQjZLSXFwVmI5a25leAp3TEdUNFE1Nk1LUm9Xb3hTK0RoUFBkWThtSVVHekdnSm5MNWxJdTI5dmtBZlhtb2RHWTFRVDZLM0l1NzZhYVl5CnRNNVFRNllWcXB6TFdTSVg4U3YvQTR2UWpUOVNINjl5bUNUZkNJV1o1U0RmeFU5b0NKeURqSk5qQXVBKzViTjUKSnEwMURiOGMrSGNMdUdQQ0FFUlRWcFlTd2hxbHVPSUVONElPTHdJREFRQUJBb0lCQUdLQnVzRVQzenBiSVVIUApkRCtidnl3NmlqK1RLbWx2MzBkSnZncWtxaDJVUmtUR090aXZCL2VTdXcyRmpKYmFyYXNkQTI4ZVUzNHFROC9BCkNLUUhPRTRVS3lWL2Uydkl1dWppSGM1ZlpnYjhoTWRVZGtyc2gxc2FIMjlqYmNiY1FUNGFmTVdLTVJZUFhtOVcKamZEbCtWV3JsYVBBVWFBQ1NmZmppalpUTlI1aCtuSUxxazdLQ3dUelRTRk1FNmNpS3g3NkhJZ08wODlhSzJGTgpqNWpLTjRhdWtSSTQyMnNiYmFvRGNsMXVpNVFtaHFVU0xCVVQvemVhTHM0MXJrN2w4MWNtQXhYQll0YXRwb1A0Ci84dDQzSkMyRVdYQU5BZDQ1cW1jbzVBUmZoMUZJMWo4ejB3dFZpakhDSmFIMmo4TjhGTHh3YzhZL0ttNGphMncKcVVyK0dhRUNnWUVBei95dVJMUDBBbWwvRXhLN0oxVUpERnJGbG5GTHVsRmVDM2dwWFRCL0NxUXFOL1BkbDVDdgpKbVpCV3VhTXArWEJna0NMZE5UV1BNMGFIUEd3aExKUWZXa1ZYc1lCM2VENllwM0pXVGR1dmJvbVVuRzY1TC9yCnF2WTVSUy83WWNmRnZtbVNNYVAxeCsxUDFEQWVUWHBvdllBczlIS2U3RFh4UUUxL3BEOHEwTzBDZ1lFQTBqRngKSlpQU1J4RE5tNVNaTzNsYUZwVDJKdGJQdDUvdUtXRjAraDZvWlNKaDlPVjhhaVM5NlRPRStYREYwaHk5ZVBMbAp6a1NFQ0hEOEE3ZVF0OWc1VGc2c3lCWkpWMXJzYUN0YjRCWGRpcU1jSGE4SWhLQW9ySnpxYldGTXZmdG1WMjc5CjMrVldGaW13dnBuTzNWaHhnQ3lLWjRhRjdaNkV2T1ZDb3IzNDVBc0NnWUVBeUlkME1qTmFtUlREKzB5OCsxQW0KZUMzd2dYdGNxeGdXVjNLVVZ4QVIvTjJKQXdkeDU5Y011RFl3M3dhWUtLMEJwS2E4am5sQzBiNWlaZk8wNEV2WQpCUUpUSTF3L29vQnVpTFJlMUZENHlaNTNvbGVhL1QvNVpZMGViSkcxaW5JRk92QW9qd25wUjhpTGhpYWFvTkxiCnQ1R2tSazlZNEorbHFmek9penFIK29VQ2dZQUp0aWNZS1dCSjBFanZxMG41S1g0MEZPWGFuWW96WGJ4UFJTVjIKZVB3bTBCUGVrTXZTeTZmS29vcStTNnVZTGFQRGR0V1BWak1UZ01Ua0Z4TWtxMlRhYW1zcFEzNVgvdWQxV0t1QwpDd0NWYXp2ZFV6ejlnN2pkWU5La0F4N2NtRVQrUFM2VnJhN3dqelNQV2VQbzdqRXdUdDZHTWZ6MklhRFlhVzlPCnZhQkdTUUtCZ0dEaGdvK3BucWFrZmhVRE15bWxwQ3ZiNWZXS000RzJWbDFHZEdaSlFSWEpPR0hqbjlyNWZuQzEKdGx4d3BBN2NucjNPalRLYVRYeVM1SzA0QlVzQ0l2UFZmZVZlMW9ydm9rR3ZkNGJxUlFab3AvVlFzWnI2RGpnTApqUjV4UzBOdXJnR2QzVVEwRHFhL0xOQW9mMEFOdG9nTHM1Vm1VL1pueDA2L3dndHN6empnCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
默认咱们应用 kubectl 命令行,应用的默认上下文是 kubernetes-admin@kubernetes,这个上下文应用的 kubernetes 用户是 kubernetes-admin
这个用户对应的证书中是蕴含认证信息的
echo -n "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURFekNDQWZ1Z0F3SUJBZ0lJVmxIbDlTalNvdFF3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TVRBME1EY3hNVFF6TXpsYUZ3MHlNakEwTURjeE1UUXpOREZhTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXFzVnlQc2RQRGlEYW9FNWcKZWxOQjV4ZHJoZCs1eEd5RUJFbGpUY2tMb3JPQlN6SjE3Z2JpY0VSaXRQLzh1YVpmVk9ISnZ0Y2tyZUpGa3NHNgp2Ujc5YUk4d3k0elUreEk0ZzdzK2ZrTFRsK1QrR2xaSWlQaXN3a2RQZE9ad0REUDBKdDQ5NjljVzFndVJ6UTVQCmhpSjRTcE96Z0dmeFJGQWpFTUFCNktJcXBWYjlrbmV4d0xHVDRRNTZNS1JvV294UytEaFBQZFk4bUlVR3pHZ0oKbkw1bEl1Mjl2a0FmWG1vZEdZMVFUNkszSXU3NmFhWXl0TTVRUTZZVnFwekxXU0lYOFN2L0E0dlFqVDlTSDY5eQptQ1RmQ0lXWjVTRGZ4VTlvQ0p5RGpKTmpBdUErNWJONUpxMDFEYjhjK0hjTHVHUENBRVJUVnBZU3docWx1T0lFCk40SU9Md0lEQVFBQm8wZ3dSakFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0h3WURWUjBqQkJnd0ZvQVV6RmZHVHJhMjRVa3hzM2NReWJzSnprT2R2UXN3RFFZSktvWklodmNOQVFFTApCUUFEZ2dFQkFDRHUwQ3g5Qk1NdjdUMnh6T3gzTDNNczk5NTdKMDY3WDVhbTZnZW4yaXltekViMkNldG51REdoCnFMWW5MZnBOZ1FOQ1pTbkg5dzZIYjdWenRMTzlheXZjejcvRVlRVkpyOVN0MzdtZDc0d3dKY1AvZWY1b2ZEbkgKVTVJaXZKK1RuM3REeGhlVVU5VlBFSkdCbFZmd3N0UmxJZ3NWclR0TkVnNGYzaW04azZzNlRTTGV5Sis4Y21zdgpwTmYyRDNpWWw3aEhBTGJwS2tFWVEya2xSY0IyRDFSL1Fhd2o4WWoyUGJ4cEZOU0t4QmQ4S09mcGVaMWQ5ZmpiCmZMbUxGU29rZjk1b0lrTk9TSGpUanVDNmNaNGVHczU0bjhaMmhnMWZia1R0Y2pJK1ROZi9nY29FNExvM3JhaDgKbW1sa1Qxdit4T3hKUWpkbkdwT2FSNytINFkwblY5dz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="|base64 -d|openssl x509 -text
certificate:
Data:
Version: 3 (0x2)
Serial Number: 6220005401490006740 (0x5651e5f528d2a2d4)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=kubernetes
Validity
Not Before: Apr 7 11:43:39 2021 GMT
Not After : Apr 7 11:43:41 2022 GMT
Subject: O=system:masters, CN=kubernetes-admin
...
其中 Subject: O=system:masters, CN=kubernetes-admin 别离代表 O 用户组和 CN 用户,kubernetes 基于 RBAC 对该用户和组配置了对应的权限
kubectl proxy 拜访 apiserver
kubectl proxy应用的是RequestHeader 认证,在该种拜访模式下, 咱们是以 http 的形式发动申请到代理服务的, 此时, 代理服务会将该申请发送给 kube-apiserver, 在此之前, 代理会将发送给 kube-apiserver 的申请头里退出证书信息
apiserver 须要配置:
- –requestheader-username-headers=X-Remote-User
- –requestheader-group-headers=X-Remote-Group
- –requestheader-extra-headers-prefix=X-Remote-Extra-
- –requestheader-client-ca-file:避免头部坑骗
- –requestheader-allowed-names:设置容许的 CN 列表
- –proxy-client-cert-file:客户端证书
- –proxy-client-key-file:客户端私钥
[root@k8s-master ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml
...
- --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
- --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
- --requestheader-allowed-names=front-proxy-client
- --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
- --requestheader-extra-headers-prefix=X-Remote-Extra-
- --requestheader-group-headers=X-Remote-Group
- --requestheader-username-headers=X-Remote-User
...
咱们查看对应的 proxy-client-cert-file 证书,获取用户信息
[root@k8s-master ~]# cat /etc/kubernetes/pki/front-proxy-client.crt|openssl x509 -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1421614817980964257 (0x13ba9725192fdda1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=front-proxy-ca
Validity
Not Before: Apr 7 11:43:40 2021 GMT
Not After : Apr 7 11:43:40 2022 GMT
Subject: CN=front-proxy-client
能够看到对应的 CN 是 front-proxy-client,咱们在 apiserver 中曾经配置了 - –requestheader-allowed-names=front-proxy-client 是能够认证通过的
Pod 拜访 apiserver
Pod 拜访 apiserver 应用的是 ServiceAccountAuth 认证,serviceaccount 是 k8s 中惟一可能通过 API 形式治理的 apiserver 拜访凭证,通常用于 pod 中的业务过程与 apiserver 的交互,ServiceAccount 解决 Pod 在集群外面的身份认证问题,认证应用的受权信息存在 secret 外面(由 SecretAccount Controller 自行创立)
当一个 namespace 创立实现后,会同时在该 namespace 下生成名为 default 的 serviceaccount 和对应 Secret:
[root@k8s-master ~]# kubectl get sa default -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2021-04-07T11:44:12Z"
name: default
namespace: default
resourceVersion: "379"
selfLink: /api/v1/namespaces/default/serviceaccounts/default
uid: 3493e0f4-a87c-4c0e-a373-3c117d205d8d
secrets:
- name: default-token-s46zd
[root@k8s-master ~]# kubectl get secret default-token-s46zd -o yaml
apiVersion: v1
data:
ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeE1EUXdOekV4TkRNek9Wb1hEVE14TURRd05URXhORE16T1Zvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSlFWCjNmRmVraUdmL3ZDK1JPNFR4SC9QbkRhMmJINi9lRFAzNUc1SXppUnladmpUWWtNeGVyOHIrTWdndCtCN05oc28Ka0ZCVVNCVUhrbVhHZFFBUHRjNTJocVdGRlhtZk10TzBhNzZBTWNCdFZUa2hPZDRxc3NPcy9jUndVcGxYKytteApLcW9FdDc0eFBhRnJxRzIyeDVEN011Y3lYQmtxQk4vWGRKcThKNU5xTWhHd2EvbjVtbWUxYmRrdGh3UWd1SnZzCkc2THRBZGZhRWdXbWxnUVFUMWZHNkhVV3g0L085aTJSNEhIU1VXMDFmTnUwaGFVekNJcE04VERLMk9DbDJYN04KcWE3QitGZDlZR1krUVdhNWVMZk9nMFJUcTJOb210M1E5WWVGWHJKZDJMOHlpc3VsbjM0ZDNxZjFQakxtMkdJQwpQS01XenBVaWJxbkpNb0RvdjYwQ0F3RUFBYU5DTUVBd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZNeFh4azYydHVGSk1iTjNFTW03Q2M1RG5iMExNQTBHQ1NxR1NJYjMKRFFFQkN3VUFBNElCQVFBdW5WUXYvTnhnN2JCYXBiVWRVT2s4UWhkclZkbXFGVUlCWnlQN0FUMlh5eVNlMG8xVwp4dEU3c1NyWlQvZDJUTzJseFRLM0NQRVU2dW9uMDQ1amhyd1N1dGNVa3llMUZVcnF6aWNTa1luZjhnVFdOMmtlCnpUdWJ5OUowcVZFRVErc2cvU2Q1bERVUm9LSHAyVXRLZzdrbVRzT3d3U2ppVnlVZEdmMGcrZ2djUU9iMjFvNVgKYUtoOUtIQUdBVDRvQnlOdTY0STJEaWV0QkRkWWdsL3B5cTgwcCtwVTlLSDJObEZrMERhc01uU2I0eEE1M2U3RApJQVJua0JGOFNuSXR2a3pacFFTVWhXNVpJT2IvdjdOcWZxalhuTE8rdUx4czRPSllXL3V5TzBpMEkrYUF5RWRYClUyUkMzZjIyUHV1VmNnWmZ6ck5vUzU5dnQwVVlVM1FRcURqMgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
namespace: ZGVmYXVsdA==
token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklraDZZMnB4VlhCbk5ubFBVa3AxVVZwblYwbGthMmhOZG14TVpHeHdOa1pGVFdvMVFXUkhjbUpPWldNaWZRLmV5SnBjM01pT2lKcmRXSmxjbTVsZEdWekwzTmxjblpwWTJWaFkyTnZkVzUwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXVZVzFsYzNCaFkyVWlPaUprWldaaGRXeDBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5elpXTnlaWFF1Ym1GdFpTSTZJbVJsWm1GMWJIUXRkRzlyWlc0dGN6UTJlbVFpTENKcmRXSmxjbTVsZEdWekxtbHZMM05sY25acFkyVmhZMk52ZFc1MEwzTmxjblpwWTJVdFlXTmpiM1Z1ZEM1dVlXMWxJam9pWkdWbVlYVnNkQ0lzSW10MVltVnlibVYwWlhNdWFXOHZjMlZ5ZG1salpXRmpZMjkxYm5RdmMyVnlkbWxqWlMxaFkyTnZkVzUwTG5WcFpDSTZJak0wT1RObE1HWTBMV0U0TjJNdE5HTXdaUzFoTXpjekxUTmpNVEUzWkRJd05XUTRaQ0lzSW5OMVlpSTZJbk41YzNSbGJUcHpaWEoyYVdObFlXTmpiM1Z1ZERwa1pXWmhkV3gwT21SbFptRjFiSFFpZlEuWHc3Rm4zWURoTlViYWNMOVdMVW1ISFQzbzkyZ2d2c0t0dzdPY21PTUhyd2ZDTnlPUFRIWTFKTUtCRkpCZkIzcmhjdURncHI2dHBpQm1BN0pnUzkwRTVhNG4zU1VoU0pscEE4eElZWU90aklJSFhaV25rYVg3T1c0WkRwU2RIVzNienNyOHBBc09SS2diTENzZ18yRlBmRGhybHRQMjFKNnZoOHZMUGlfVVJlTmtiSVM4WlgzcERFNTV2eHZlRkE1Zkk1S2NqLVJKdnRpOFQ3TUc5WjQxZU56OXlyWVd5SkRpenh5RUlLR0tEVnVIUjNyLXpvWm9icHhvQU1BcUc2aFN6NkhXUUkzVG45anVXcmVWTGJWYk9qUktzTmF4ZVNqOU5BSTBsZXRzQTJPVFVGcUF3M1drU3E0MnRZOE5fcm5NbkZuN1R3U3VqQk5hVmlPSl9xQi13
kind: Secret
metadata:
annotations:
kubernetes.io/service-account.name: default
...
对应的 Secret 里:data 字段有两块数据:ca.crt 用于对服务端的校验,token 用于 Pod 的身份认证,它们都是用 base64 编码过的
Pod 创立的时候,Admission Controller 会依据指定的 ServiceAccount 把对应 secret 的 ca.crt 和 token 文件挂载到固定目录 /var/run/secrets/kubernetes.io/serviceaccount 下
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-s46zd
readOnly: true
Pod 要拜访 apiserver 的时候,默认利用 Secret 其中的 token 文件来认证 Pod 的身份,利用 ca.crt 校验服务端,Pod 身份被认证非法后,其权限须要通过 RBAC 来配置
Kubernetes 鉴权(RBAC)
下面咱们介绍了 Kubernetes 所有资源对象都是模型化的 API 对象,容许执行 CRUD(Create、Read、Update、Delete) 操作(也就是咱们常说的增、删、改、查操作),比方上面的这些资源:
- Pods
- ConfigMaps
- Deployments
- Nodes
- Secrets
- Namespaces
- ……
对于下面这些资源对象的可能存在的操作有: - create
- get
- delete
- list
- update
- edit
- watch
- exec
- patch
在更下层,这些资源和 API Group 进行关联,比方 Pods 属于 Core API Group,而 Deployements 属于 apps API Group,当初咱们要在 Kubernetes 中通过 RBAC 来对资源进行权限治理,除了下面的这些资源和操作以外,咱们还须要理解另外几个概念:
- Rule:规定,规定是一组属于不同 API Group 资源上的一组操作的汇合
- Role 和 ClusterRole:角色和集群角色,这两个对象都蕴含下面的 Rules 元素,二者的区别在于,在 Role 中,定义的规定只实用于单个命名空间,也就是和 namespace 关联的,而 ClusterRole 是集群范畴内的,因而定义的规定不受命名空间的束缚。另外 Role 和 ClusterRole 在 Kubernetes 中都被定义为集群外部的 API 资源,和咱们后面学习过的 Pod、Deployment 这些对象相似,都是咱们集群的资源对象,所以同样的能够应用 YAML 文件来形容,用 kubectl 工具来治理
-
Subject:主题,对应集群中尝试操作的对象,集群中定义了 3 种类型的主题资源:
- User Account:用户,这是有内部独立服务进行治理的,管理员进行私钥的调配,用户能够应用 KeyStone 或者 Goolge 帐号,甚至一个用户名和明码的文件列表也能够。对于用户的治理集群外部没有一个关联的资源对象,所以用户不能通过集群外部的 API 来进行治理
- Group:组,这是用来关联多个账户的,集群中有一些默认创立的组,比方 cluster-admin
- Service Account:服务帐号,通过 Kubernetes API 来治理的一些用户帐号,和 namespace 进行关联的,实用于集群外部运行的应用程序,须要通过 API 来实现权限认证,所以在集群外部进行权限操作,咱们都须要应用到 ServiceAccount
- RoleBinding 和 ClusterRoleBinding:角色绑定和集群角色绑定,简略来说就是把申明的 Subject 和咱们的 Role 进行绑定的过程(给某个用户绑定上操作的权限),二者的区别也是作用范畴的区别:RoleBinding 只会影响到以后 namespace 上面的资源操作权限,而 ClusterRoleBinding 会影响到所有的 namespace。
接下来咱们来通过几个简略的示例,来演示下在 Kubernetes 集群中如何应用 RBAC。
只能拜访某个 namespace 的普通用户
咱们想要创立一个 User Account,只能拜访 default 这个命名空间,对应的用户信息如下所示:
username: wangcs
group: imonkey
创立用户凭证
咱们后面曾经提到过,Kubernetes 没有 User Account 的 API 对象,不过要创立一个用户帐号的话也是挺简略的,利用管理员调配给你的一个私钥就能够创立了,这个咱们能够参考官网文档中的办法,这里咱们来应用 OpenSSL 证书来创立一个 User
给用户 wangcs 创立一个私钥,命名成 wangcs.key:
[root@k8s-master k8s-rbac]# openssl genrsa -out wangcs.key 2048
Generating RSA private key, 2048 bit long modulus
....+++
...................+++
e is 65537 (0x10001)
应用咱们刚刚创立的私钥创立一个证书签名申请文件:wangcs.csr,要留神须要确保在 -subj 参数中指定用户名和组(CN 示意用户名,O 示意组):
[root@k8s-master k8s-rbac]# openssl req -new -key wangcs.key -out wangcs.csr -subj "/CN=wangcs/O=imonkey"
而后找到咱们的 Kubernetes 集群的 CA 证书,咱们应用的是 kubeadm 装置的集群,CA 相干证书位于 /etc/kubernetes/pki/ 目录上面,咱们会利用该目录上面的 ca.crt 和 ca.key 两个文件来批准下面的证书申请。生成最终的证书文件,咱们这里设置证书的有效期为 100 天:
[root@k8s-master k8s-rbac]# openssl x509 -req -in wangcs.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out wangcs.crt -days 100
Signature ok
subject=/CN=wangcs/O=imonkey
Getting CA Private Key
当初查看咱们以后文件夹上面是否生成了一个证书文件:
[root@k8s-master k8s-rbac]# ls
wangcs.crt wangcs.csr wangcs.key
当初咱们能够应用刚刚创立的证书文件和私钥文件在集群中创立新的凭证和上下文(Context):
[root@k8s-master]# kubectl config set-credentials wangcs --client-certificate=/root/k8s-rbac/wangcs.crt --client-key=/root/k8s-rbac/wangcs.key
User "wangcs" set.
咱们能够看到一个用户 wangcs 创立了,而后为这个用户设置新的 Context,咱们这里指定特定的一个 namespace:
[root@k8s-master ~]# kubectl config set-context wangcs-context --cluster=kubernetes --namespace=default --user=wangcs
Context "wangcs-context" created.
到这里,咱们的用户 wangcs 就曾经创立胜利了,当初咱们应用以后的这个配置文件来操作 kubectl 命令的时候,应该会呈现谬误,因为咱们还没有为该用户定义任何操作的权限呢:
[root@k8s-master ~]# kubectl get pods --context=wangcs-context
Error from server (Forbidden): pods is forbidden: User "wangcs" cannot list resource "pods" in API group ""in the namespace"default"
创立角色
用户创立实现后,接下来就须要给该用户增加操作权限,咱们来定义一个 YAML 文件,创立一个容许用户操作 Deployment、Pod、ReplicaSets 的角色,如下定义:(wangcs-role.yaml)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: wangcs-role
namespace: default
rules:
- apiGroups: ["","apps"]
resources: ["deployments", "replicasets", "pods"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # 也能够应用['*']
其中 Pod 属于 core 这个 API Group,在 YAML 中用空字符就能够,而 Deployment 和 ReplicaSet 当初都属于 apps 这个 API Group(如果不晓得则能够用 kubectl explain 命令查看),所以 rules 上面的 apiGroups 就综合了这几个资源的 API Group:[“”, “apps”],其中 verbs 就是咱们下面提到的能够对这些资源对象执行的操作,咱们这里须要所有的操作方法,所以咱们也能够应用 [‘*’] 来代替,而后间接创立这个 Role:
[root@k8s-master k8s-rbac]# kubectl apply -f wangcs-role.yaml
role.rbac.authorization.k8s.io/wangcs-role created
创立角色权限绑定
Role 创立实现了,然而很显著当初咱们这个 Role 和咱们的用户 wangcs 还没有任何关系,对吧?这里就须要创立一个 RoleBinding 对象,在 default 这个命名空间上面将下面的 wangcs-role 角色和用户 wangcs 进行绑定:(wangcs-rolebinding.yaml)
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: wangcs-rolebinding
namespace: default
subjects:
- kind: User
name: wangcs
apiGroup: ""
roleRef:
kind: Role
name: wangcs-role
apiGroup: rbac.authorization.k8s.io # 留空字符串也能够,则应用以后的 apiGroup
下面的 YAML 文件中咱们看到了 subjects 字段,这里就是咱们下面提到的用来尝试操作集群的对象,这里对应下面的 User 帐号 wangcs,应用 kubectl 创立下面的资源对象:
[root@k8s-master k8s-rbac]# kubectl apply -f wangcs-rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/wangcs-rolebinding created
测试
当初咱们应该能够下面的 wangcs-context 上下文来操作集群了:
[root@k8s-master ~]# kubectl get pods --context=wangcs-context
NAME READY STATUS RESTARTS AGE
nginx-deploy-75c7f965d8-hnmvn 1/1 Running 0 11d
nginx-deploy-75c7f965d8-xtdv9 1/1 Running 0 11d
咱们能够胜利拜访 default 命名空间的 pod 对象,如果咱们在前面加上一个 -n kube-system 试看看呢?
[root@k8s-master ~]# kubectl get pods --context=wangcs-context -n kube-system
Error from server (Forbidden): pods is forbidden: User "wangcs" cannot list resource "pods" in API group ""in the namespace"kube-system"
如果去获取其余的资源对象呢:
[root@k8s-master ~]# kubectl get configmaps --context=wangcs-context
Error from server (Forbidden): configmaps is forbidden: User "wangcs" cannot list resource "configmaps" in API group ""in the namespace"default"
咱们能够看到没有权限获取,因为咱们并没有为以后操作用户指定 configmap 的拜访权限,是合乎咱们的预期的。这样咱们就创立了一个只有单个命名空间拜访权限的一般 User。
只能拜访某个 namespace 的 ServiceAccount
下面咱们创立了一个只能拜访某个命名空间上面的普通用户,咱们后面也提到过 subjects 上面还有一种类型的主题资源:ServiceAccount,当初咱们来创立一个集群外部的用户只能操作 default 这个命名空间上面的 pods 和 deployments,首先来创立一个 ServiceAccount 对象:
[root@k8s-master ~]# kubectl create sa wangcs-sa
serviceaccount/wangcs-sa created
当然咱们也能够定义成 YAML 文件的模式来创立:
apiVersion: v1
kind: ServiceAccount
metadata:
name: wangcs-sa
namespace: default
而后新建一个 Role 对象:(wangcs-sa-role.yaml)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: wangcs-sa-role
namespace: default
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch"]
能够看到咱们这里定义的角色只有查问 pod 和 deployment 权限,待会咱们能够重点测试一下,创立该 Role 对象:
[root@k8s-master k8s-rbac]# kubectl apply -f wangcs-sa-role.yaml
role.rbac.authorization.k8s.io/wangcs-sa-role created
而后创立一个 RoleBinding 对象,将下面的 ServiceAccount wangcs-sa 和 role wangcs-sa-role 进行绑定:(wangcs-sa-rolebinding.yaml)
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: wangcs-sa-rolebinding
namespace: default
subjects:
- kind: ServiceAccount
name: wangcs-sa
namespace: default
roleRef:
kind: Role
name: wangcs-sa-role
apiGroup: rbac.authorization.k8s.io
增加这个资源对象:
[root@k8s-master k8s-rbac]# kubectl apply -f wangcs-sa-rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/wangcs-sa-rolebinding created
测试
首先获取到 ServiceAccount wangcs-sa 对应的 secret 的 token
[root@k8s-master ~]# kubectl get secret wangcs-sa-token-b6blc -o yaml
apiVersion: v1
data:
ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeE1EUXdOekV4TkRNek9Wb1hEVE14TURRd05URXhORE16T1Zvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSlFWCjNmRmVraUdmL3ZDK1JPNFR4SC9QbkRhMmJINi9lRFAzNUc1SXppUnladmpUWWtNeGVyOHIrTWdndCtCN05oc28Ka0ZCVVNCVUhrbVhHZFFBUHRjNTJocVdGRlhtZk10TzBhNzZBTWNCdFZUa2hPZDRxc3NPcy9jUndVcGxYKytteApLcW9FdDc0eFBhRnJxRzIyeDVEN011Y3lYQmtxQk4vWGRKcThKNU5xTWhHd2EvbjVtbWUxYmRrdGh3UWd1SnZzCkc2THRBZGZhRWdXbWxnUVFUMWZHNkhVV3g0L085aTJSNEhIU1VXMDFmTnUwaGFVekNJcE04VERLMk9DbDJYN04KcWE3QitGZDlZR1krUVdhNWVMZk9nMFJUcTJOb210M1E5WWVGWHJKZDJMOHlpc3VsbjM0ZDNxZjFQakxtMkdJQwpQS01XenBVaWJxbkpNb0RvdjYwQ0F3RUFBYU5DTUVBd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZNeFh4azYydHVGSk1iTjNFTW03Q2M1RG5iMExNQTBHQ1NxR1NJYjMKRFFFQkN3VUFBNElCQVFBdW5WUXYvTnhnN2JCYXBiVWRVT2s4UWhkclZkbXFGVUlCWnlQN0FUMlh5eVNlMG8xVwp4dEU3c1NyWlQvZDJUTzJseFRLM0NQRVU2dW9uMDQ1amhyd1N1dGNVa3llMUZVcnF6aWNTa1luZjhnVFdOMmtlCnpUdWJ5OUowcVZFRVErc2cvU2Q1bERVUm9LSHAyVXRLZzdrbVRzT3d3U2ppVnlVZEdmMGcrZ2djUU9iMjFvNVgKYUtoOUtIQUdBVDRvQnlOdTY0STJEaWV0QkRkWWdsL3B5cTgwcCtwVTlLSDJObEZrMERhc01uU2I0eEE1M2U3RApJQVJua0JGOFNuSXR2a3pacFFTVWhXNVpJT2IvdjdOcWZxalhuTE8rdUx4czRPSllXL3V5TzBpMEkrYUF5RWRYClUyUkMzZjIyUHV1VmNnWmZ6ck5vUzU5dnQwVVlVM1FRcURqMgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
namespace: ZGVmYXVsdA==
token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklraDZZMnB4VlhCbk5ubFBVa3AxVVZwblYwbGthMmhOZG14TVpHeHdOa1pGVFdvMVFXUkhjbUpPWldNaWZRLmV5SnBjM01pT2lKcmRXSmxjbTVsZEdWekwzTmxjblpwWTJWaFkyTnZkVzUwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXVZVzFsYzNCaFkyVWlPaUprWldaaGRXeDBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5elpXTnlaWFF1Ym1GdFpTSTZJbmRoYm1kamN5MXpZUzEwYjJ0bGJpMWlObUpzWXlJc0ltdDFZbVZ5Ym1WMFpYTXVhVzh2YzJWeWRtbGpaV0ZqWTI5MWJuUXZjMlZ5ZG1salpTMWhZMk52ZFc1MExtNWhiV1VpT2lKM1lXNW5ZM010YzJFaUxDSnJkV0psY201bGRHVnpMbWx2TDNObGNuWnBZMlZoWTJOdmRXNTBMM05sY25acFkyVXRZV05qYjNWdWRDNTFhV1FpT2lJNU9EZ3pPV1kxT0MweE5EZG1MVFEzWm1NdE9HVXlaQzFoTjJRMk1HRmtOakUyWVRNaUxDSnpkV0lpT2lKemVYTjBaVzA2YzJWeWRtbGpaV0ZqWTI5MWJuUTZaR1ZtWVhWc2REcDNZVzVuWTNNdGMyRWlmUS5BRl85T1hWd1pkeGVnckRSYWtXYjFrYWM3YmVlclBNTE03T2IwU3JiN2pPcFl4VzdMQllxNkpqNUE5NWxRQm9Yd3haQ09WLUtsYUZxSDc2RnZBRnFYX2taWE5XdWFkeElIZzhkWmVwWl9HbnJwYXBSeFFZZVlsbGRFR3BRdHZZSXdqLUsxRE9xMEprYnM3TW55dGUtcDE0WWxDWGZrdGp2NnVlaDEtcHZnRWRhbjdlS2xjNldwaFFvNnNRUm8xNmppc1VINkRvYU5FdXIxcGpXWVRHSlpuZ2tmQVU2QkNnV1lkRDd1MmwwZnV5dXh0Z2RyM0V1cHBmSVc1Wk5DQVBBbVU3SWRFd3JBVWJtWW5jZ3JyeTNaQWsxR1ctbnlpa0tWTmNNa29NTFAxejIwdHlQWUFaUkVHOTdSWkRhd1JQM1NvSXlIZTRxM245V1hhN0QxdjhSM1E=
kind: Secret
...
对 token 进行 base64 解密
echo -n "ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklraDZZMnB4VlhCbk5ubFBVa3AxVVZwblYwbGthMmhOZG14TVpHeHdOa1pGVFdvMVFXUkhjbUpPWldNaWZRLmV5SnBjM01pT2lKcmRXSmxjbTVsZEdWekwzTmxjblpwWTJWaFkyTnZkVzUwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXVZVzFsYzNCaFkyVWlPaUprWldaaGRXeDBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5elpXTnlaWFF1Ym1GdFpTSTZJbmRoYm1kamN5MXpZUzEwYjJ0bGJpMWlObUpzWXlJc0ltdDFZbVZ5Ym1WMFpYTXVhVzh2YzJWeWRtbGpaV0ZqWTI5MWJuUXZjMlZ5ZG1salpTMWhZMk52ZFc1MExtNWhiV1VpT2lKM1lXNW5ZM010YzJFaUxDSnJkV0psY201bGRHVnpMbWx2TDNObGNuWnBZMlZoWTJOdmRXNTBMM05sY25acFkyVXRZV05qYjNWdWRDNTFhV1FpT2lJNU9EZ3pPV1kxT0MweE5EZG1MVFEzWm1NdE9HVXlaQzFoTjJRMk1HRmtOakUyWVRNaUxDSnpkV0lpT2lKemVYTjBaVzA2YzJWeWRtbGpaV0ZqWTI5MWJuUTZaR1ZtWVhWc2REcDNZVzVuWTNNdGMyRWlmUS5BRl85T1hWd1pkeGVnckRSYWtXYjFrYWM3YmVlclBNTE03T2IwU3JiN2pPcFl4VzdMQllxNkpqNUE5NWxRQm9Yd3haQ09WLUtsYUZxSDc2RnZBRnFYX2taWE5XdWFkeElIZzhkWmVwWl9HbnJwYXBSeFFZZVlsbGRFR3BRdHZZSXdqLUsxRE9xMEprYnM3TW55dGUtcDE0WWxDWGZrdGp2NnVlaDEtcHZnRWRhbjdlS2xjNldwaFFvNnNRUm8xNmppc1VINkRvYU5FdXIxcGpXWVRHSlpuZ2tmQVU2QkNnV1lkRDd1MmwwZnV5dXh0Z2RyM0V1cHBmSVc1Wk5DQVBBbVU3SWRFd3JBVWJtWW5jZ3JyeTNaQWsxR1ctbnlpa0tWTmNNa29NTFAxejIwdHlQWUFaUkVHOTdSWkRhd1JQM1NvSXlIZTRxM245V1hhN0QxdjhSM1E="|base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6Ikh6Y2pxVXBnNnlPUkp1UVpnV0lka2hNdmxMZGxwNkZFTWo1QWRHcmJOZWMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6Indhbmdjcy1zYS10b2tlbi1iNmJsYyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJ3YW5nY3Mtc2EiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI5ODgzOWY1OC0xNDdmLTQ3ZmMtOGUyZC1hN2Q2MGFkNjE2YTMiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDp3YW5nY3Mtc2EifQ.AF_9OXVwZdxegrDRakWb1kac7beerPMLM7Ob0Srb7jOpYxW7LBYq6Jj5A95lQBoXwxZCOV-KlaFqH76FvAFqX_kZXNWuadxIHg8dZepZ_GnrpapRxQYeYlldEGpQtvYIwj-K1DOq0Jkbs7Mnyte-p14YlCXfktjv6ueh1-pvgEdan7eKlc6WphQo6sQRo16jisUH6DoaNEur1pjWYTGJZngkfAU6BCgWYdD7u2l0fuyuxtgdr3EuppfIW5ZNCAPAmU7IdEwrAUbmYncgrry3ZAk1GW-nyikKVNcMkoMLP1z20tyPYAZREG97RZDawRP3SoIyHe4q3n9WXa7D1v8R3Q
接下来,应用这个 token 对 apiserver 发动申请 https://{apiserver ip}:6443/api/v1/namespaces/default/pods
curl -k -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Ikh6Y2pxVXBnNnlPUkp1UVpnV0lka2hNdmxMZGxwNkZFTWo1QWRHcmJOZWMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6Indhbmdjcy1zYS10b2tlbi1iNmJsYyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJ3YW5nY3Mtc2EiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI5ODgzOWY1OC0xNDdmLTQ3ZmMtOGUyZC1hN2Q2MGFkNjE2YTMiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDp3YW5nY3Mtc2EifQ.AF_9OXVwZdxegrDRakWb1kac7beerPMLM7Ob0Srb7jOpYxW7LBYq6Jj5A95lQBoXwxZCOV-KlaFqH76FvAFqX_kZXNWuadxIHg8dZepZ_GnrpapRxQYeYlldEGpQtvYIwj-K1DOq0Jkbs7Mnyte-p14YlCXfktjv6ueh1-pvgEdan7eKlc6WphQo6sQRo16jisUH6DoaNEur1pjWYTGJZngkfAU6BCgWYdD7u2l0fuyuxtgdr3EuppfIW5ZNCAPAmU7IdEwrAUbmYncgrry3ZAk1GW-nyikKVNcMkoMLP1z20tyPYAZREG97RZDawRP3SoIyHe4q3n9WXa7D1v8R3Q" "https://172.17.114.33:6443/api/v1/namespaces/default/pods"
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/namespaces/default/pods",
"resourceVersion": "9141416"
},
"items": [
{
"metadata": {
"name": "nginx-deploy-75c7f965d8-hnmvn",
"generateName": "nginx-deploy-75c7f965d8-",
"namespace": "default",
"selfLink": "/api/v1/namespaces/default/pods/nginx-deploy-75c7f965d8-hnmvn",
"uid": "574ac979-41b8-460f-afaf-d29155911ba3",
"resourceVersion": "6786396",
"creationTimestamp": "2021-05-10T03:30:07Z",
"labels": {
"app": "nginx",
"pod-template-hash": "75c7f965d8"
},
...
咱们看是能够拜访到 default 命名空间的 pod list,合乎预期
接下来,应用这个 token 对 apiserver 发动申请 https://{apiserver ip}:6443/api/v1/namespaces/kube-system/pods,拜访 kube-system 命名空间下的 pod list
[root@k8s-master ~]# curl -k -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Ikh6Y2pxVXBnNnlPUkp1UVpnV0lka2hNdmxMZGxwNkZFTWo1QWRHcmJOZWMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6Indhbmdjcy1zYS10b2tlbi1iNmJsYyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJ3YW5nY3Mtc2EiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI5ODgzOWY1OC0xNDdmLTQ3ZmMtOGUyZC1hN2Q2MGFkNjE2YTMiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDp3YW5nY3Mtc2EifQ.AF_9OXVwZdxegrDRakWb1kac7beerPMLM7Ob0Srb7jOpYxW7LBYq6Jj5A95lQBoXwxZCOV-KlaFqH76FvAFqX_kZXNWuadxIHg8dZepZ_GnrpapRxQYeYlldEGpQtvYIwj-K1DOq0Jkbs7Mnyte-p14YlCXfktjv6ueh1-pvgEdan7eKlc6WphQo6sQRo16jisUH6DoaNEur1pjWYTGJZngkfAU6BCgWYdD7u2l0fuyuxtgdr3EuppfIW5ZNCAPAmU7IdEwrAUbmYncgrry3ZAk1GW-nyikKVNcMkoMLP1z20tyPYAZREG97RZDawRP3SoIyHe4q3n9WXa7D1v8R3Q" "https://172.17.114.33:6443/api/v1/namespaces/kube-system/pods"
{
"kind": "Status",
"apiVersion": "v1",
"metadata": { },
"status": "Failure",
"message": "pods is forbidden: User \"system:serviceaccount:default:wangcs-sa\"cannot list resource \"pods\"in API group \"\"in the namespace \"kube-system\"","reason":"Forbidden","details": {"kind":"pods"},"code": 403
}
返回 403 没有权限,合乎预期
能够全局拜访的 ServiceAccount
刚刚咱们创立的 wangcs-sa 这个 ServiceAccount 和一个 Role 角色进行绑定的,如果咱们当初创立一个新的 ServiceAccount,须要他操作的权限作用于所有的 namespace,这个时候咱们就须要应用到 ClusterRole 和 ClusterRoleBinding 这两种资源对象了。同样,首先新建一个 ServiceAcount 对象:(wangcs-sa2.yaml)
apiVersion: v1
kind: ServiceAccount
metadata:
name: wangcs-sa2
namespace: default
创立:
[root@k8s-master k8s-rbac]# kubectl apply -f wangcs-sa2.yaml
serviceaccount/wangcs-sa2 created
而后创立一个 ClusterRoleBinding 对象(wangcs-clusterolebinding.yaml):
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: wangcs-sa2-clusterrolebinding
subjects:
- kind: ServiceAccount
name: wangcs-sa2
namespace: default
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
从下面咱们能够看到咱们没有为这个资源对象申明 namespace,因为这是一个 ClusterRoleBinding 资源对象,是作用于整个集群的,咱们也没有独自新建一个 ClusterRole 对象,而是应用的 cluster-admin 这个对象,这是 Kubernetes 集群内置的 ClusterRole 对象,咱们能够应用 kubectl get clusterrole 和 kubectl get clusterrolebinding 查看零碎内置的一些集群角色和集群角色绑定,这里咱们应用的 cluster-admin 这个集群角色是领有最高权限的集群角色,所以个别须要审慎应用该集群角色。
创立:
kubectl apply -f wangcs-clusterolebinding.yaml
Warning: rbac.authorization.k8s.io/v1beta1 ClusterRoleBinding is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRoleBinding
clusterrolebinding.rbac.authorization.k8s.io/wangcs-sa2-clusterrolebinding created
测试:
接下来,应用这个 wangcs-sa2 对应的 secret 的 token 对 apiserver 发动申请 https://{apiserver ip}:6443/api/v1/pods
!
[root@k8s-master k8s-rbac]# curl -k -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Ikh6Y2pxVXBnNnlPUkp1UVpnV0lka2hNdmxMZGxwNkZFTWo1QWRHcmJOZWMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6Indhbmdjcy1zYTItdG9rZW4tdHQ1d2oiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoid2FuZ2NzLXNhMiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjU3ZDU4M2JiLWMwNWUtNDU2NC04ZDQwLTIxOWJlMGM2NzBmMiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0Ondhbmdjcy1zYTIifQ.YIYq33Ww8X8NNwjk_P-4IcV95e7j__aIv-2EX8AicsB_o2kwbfUvoe1Rgx8mN7MErRul46PgKshGL62C4D9pvZFi7H0BeFnY2CsUbYMIIHlEF_IhhKZLkXIbhgcQa8EzAa4KRkgcfO4ULPezO2EnLp-NPt4RABxaAa0aMbkYKgwL-ILCGKbNBQmrWASNcfgfjCavOZXW_hhyLIy_uO3PsCMP4k_T_Tv3lKOYzd8JnKLp1b1ytLrYBtinGYHgJHQB48XnNi8a-gL8rtp5GuDzOf_cQj43Fdub2yRtcNYgkLt6nAxlqNHV1ENjPxUYpJzqzsE5BWhcZQT6bZuyBlWobA" "https://172.17.114.33:6443/api/v1/pods"|more
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/pods",
"resourceVersion": "9143830"
},
"items": [
{
"metadata": {
"name": "nginx-deploy-75c7f965d8-hnmvn",
"generateName": "nginx-deploy-75c7f965d8-",
"namespace": "default",
"selfLink": "/api/v1/namespaces/default/pods/nginx-deploy-75c7f965d8-hnmvn",
"uid": "574ac979-41b8-460f-afaf-d29155911ba3",
"resourceVersion": "6786396",
"creationTimestamp": "2021-05-10T03:30:07Z",
"labels": {
"app": "nginx",
"pod-template-hash": "75c7f965d8"
},
...
所有命名空间下的 pod list 都可能查问进去,合乎预期
扫码加好友拉你入技术交换群,加微暗号:思否