本文中我们会试着解释,在 Kubernetes API Server 上如何对用户和工作负载进行认证的问题。
Kubernetes API Server 开放了 HTTP API 接口,让最终用户、集群组件以及外部组件可以进行通信。
绝大多数操作都可以用 kubectl
来完成,而且也可以使用 REST 调用的方式直接访问 API。
但是如何只允许认证用户访问 API 呢?
curl
访问 Kubernetes API让我们从调用 Kubernetes API 开始。
要列出集群中的所有命名空间,可以执行下列命令:
$ export API_SERVER_URL=https://10.5.5.5:6443
$ curl $API_SERVER_URL/api/v1/namespaces
curl: (60) Peer Certificate issuer is not recognized.
# truncated output
If you'd like to turn off curl's verification of the certificate, use the -k (or --insecure) option.
输出内容表明,API Server 的接口用一个未识别的证书(例如自签发)提供了 https
服务,所以 curl
中断了这个请求。
接下来我们用 -k
参数跳过证书验证过程,并观察产生的响应:
# curl -k $API_SERVER_URL/api/v1/namespaces
{
"kind": "Status",
"apiVersion": "v1",
"status": "Failure",
"message": "namespaces is forbidden: User \"system:anonymous\" cannot list resource \"namespaces\" ...",
"reason": "Forbidden",
"details": { "kind": "namespaces" },
"code": 403
}
现在我们拿到了响应,但是:
403
)system:anonymous
,这个用户无权列出命名空间上面的操作揭示了 kube-apiserver
的部分工作机制:
正式一点的说法分别叫认证(也叫 AuthN)和鉴权(也叫 AuthZ):
curl
请求时,流量触达 Kubernetes API Serveranonymous
403
再次检视刚才的 curl
请求:
system:anonymous
是否具有列出命名空间的权限,如果没有,就返回 403 Forbidden
错误信息例如 Kubelet 需要连接到 Kubernetes API 来报告状态:
调用请求可能使用 Token、证书或者外部管理的认证来提供身份。认证模块是整个系统的第一个门槛。
Kubernetes 的认证模块提供的几个重点能力:
下面我们会走进观察认证模块的工作过程。
本文聚焦于认证领域。要了解更多鉴权内容,可以阅读 Limiting access to Kubernetes resources with RBAC 一文。
Kubernetes API 支持两种 API 用户:内部和外部。
这两个东西有什么不同呢?
如果用户是集群的内部用户,我们需要给它定义一个规范(例如数据模型);而外部用户的规范是已经存在的。所以我们将用户分成下面几类:
假设有如下场景:使用 Bearer token 访问 Kubernetes。
curl --cacert ${CACERT} \
--header "Authorization: Bearer <my token>" \
-X GET ${APISERVER}/api
Kubernetes API Server 是如何将 Token 识别为身份的?
Kubernetes 并不管理外部用户,所以应该有一种机制来从外部资源中获取信息(例如用户名和用户组)。
换句话说,Kubernetes API 接到了带有 Token 的请求后,就应该能够提取信息并进行后续的决策了。
下面用例子来解释一下这个场景。
创建一个 CSV 文件,其中包含了用户、Token 和用户组:
token1,arthur,1,"admin,dev,qa"
token2,daniele,2,dev
token3,errge,3,qa
文件格式为
token, user, uid, groups
。
用 --token-auth-file
参数启动一个 minikube 集群:
$ mkdir -p ~/.minikube/files/etc/ca-certificates
$ cd ~/.minikube/files/etc/ca-certificates
$ cat << | tokens.csv
token1,arthur,1,"admin,dev,qa"
token2,daniele,2,dev
token3,errge,3,qa
EOF
$ minikube start \
--extra-config=apiserver.token-auth-file=/etc/ca-certificates/tokens.csv
为了发送请求给 Kubernetes API,需要集群的 IP 地址以及证书:
kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority: /Users/learnk8s/.minikube/ca.crt
extensions:
- extension:
last-update: Fri, 10 Jun 2022 12:21:45 +08
provider: minikube.sigs.k8s.io
version: v1.25.2
name: cluster_info
server: https://127.0.0.1:57761
name: minikube
# truncated output
接下来向集群发送一个请求:
$ export APISERVER=https://127.0.0.1:57761
$ export CACERT=/Users/learnk8s/.minikube/ca.crt
$ curl --cacert ${CACERT} -X GET ${APISERVER}/api
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "forbidden: User \"system:anonymous\" cannot get path \"/\"",
"reason": "Forbidden",
"details": {},
"code": 403
}
响应信息表明,我们用匿名身份访问了 API,并且没有任何权限。
接下来用 token1
(来自于 tokens.csv
文件中的用户 arthur
)发起请求:
$ export APISERVER=https://127.0.0.1:57761
$ export CACERT=/Users/learnk8s/.minikube/ca.crt
$ curl --cacert ${CACERT} --header "Authorization: Bearer token1" -X GET ${APISERVER}/api
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "forbidden: User \"arthur\" cannot get path \"/\"",
"reason": "Forbidden",
"details": {},
"code": 403
}
如上所见,Kubernetes 能够识别出请求来自于 Arthur
。发生了什么呢?tokens.csv
和 --token-auth-file
参数起了什么作用?Kubernetes 有多种认证插件,现在我们使用的是静态 Token 文件。
重放一下刚才的过程:
创建一个 ClusterRoleBinding
就能快速修复这个问题:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin
subjects:
- kind: User
name: arthur
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
用下面的命令把对象提交给集群:
$ kubectl apply -f admin-binding.yaml
clusterrolebinding.rbac.authorization.k8s.io/admin created
再次执行命令就会成功了:
curl --cacert ${CACERT} \
--header "Authorization: Bearer token1" \
-X GET ${APISERVER}/api
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "192.168.49.2:8443"
}
]
}
上面向 kube-apiserver
发送了一个 HTTP 请求,认证模块会尝试将如下属性附加到请求之中:
Username
:
字符串,例如 kube-admin
、jane@example.com
UID
:
字符串,相对用户名来说,UID 是一个更稳定的属性Groups
:
例如 system:masters
、devops-team
请求上下文中加入这些信息之后,后续的 Kubernetes API 组件都能读取这些信息,这些信息对认证插件来说是透明的。
前面的例子中为用户名创建了一个 ClusterRoleBinding
。其实 CSV 中为 Arthur
设置了三个用户组(admin
、dev
、qa
),因此也可以写成:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin
subjects:
- kind: Group
name: admin
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
静态 Token 是一种简易的认证机制,集群管理员可以随意生成 Token 并指派给用户。但是这种方式有一定弊端:
tokens.csv
文件需要重启 API ServerKubernetes 还提供了其它几种外部认证机制:
每种方式都有各自的利弊,但是所有的工作流都跟静态 Token 类似:
那么如何选择认证插件呢?实际上可以同时启用多个认证插件,Kubernetes 会逐个调用每个插件,直到成功为止。
如果所有插件都没能成功,则请求会被标记为未认证或者是匿名访问。
现在已经了解了外部用户的问题,接下来看看 Kubernetes 如何管理内部用户。
在 Kubernetes 中,内部用户使用 Service Account 的概念来表达。
这些身份通过 kube-apiserver
创建,并分配给应用。
Service Account 会有相关联的 Token,应用向 kube-apiserver
发起请求时,会共享这个 Token 用于认证。
观察一下 Service Account 的定义:
$ kubectl create serviceaccount test
serviceaccount/test created
这个资源的具体内容:
$ kubectl get serviceaccount test -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: test
secrets:
- name: test-token-6tmx7
如果集群版本高于 1.24
,输出会有不同:
$ kubectl get serviceaccount test -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: test
差距很明显,只有老版本集群中会有 secrets
字段。
这个 Secret 包含了必要的 Token,API Server 可以用 Token 对请求进行认证:
$ kubectl get secret test-token-6tmx7
apiVersion: v1
kind: Secret
metadata:
name: test-token-6tmx7
type: kubernetes.io/service-account-token
data:
ca.crt: LS0tLS1CR…
namespace: ZGVmYXVs…
token: ZXlKaGJHY2…
下面的 YAML 代码把这个身份分配给 Pod:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
serviceAccount: test
containers:
- image: nginx
name: nginx
提交到集群,创建 Pod 并进入他的 Bash:
$ kubectl apply -f nginx.yaml
pod/nginx created
$ kubectl exec -ti nginx -- bash
发起请求:
$ export APISERVER=https://kubernetes.default.svc
$ export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
$ export CACERT=${SERVICEACCOUNT}/ca.crt
$ export TOKEN="token here"
$ curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "192.168.49.2:8443"
}
]
}
调用成功了。
Kubernetes 1.24 以后的版本不再创建 Secret,那怎么获取 Token 呢?
新版本的 Kubernetes 中,Kubelet 负责从 API Server 申请临时 Token。
Token 格式类似 Secret 对象中的 Token,但是有个很大的不同是——他会过期。
这个 Token 不会被注入到 Secret 里面,而是使用 Projected Volume。
在 Kubernetes 1.24 中重复一下刚才的测试。
$ kubectl create serviceaccount test
serviceaccount/test created
创建一个 Pod:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
serviceAccount: test
containers:
- name: nginx
image: nginx
把 Pod 提交到集群上:
$ kubectl apply -f nginx.yaml
pod/nginx created
首先确认一下,集群里没有 Secret:
$ kubectl get secrets
No resources found in default namespace.
然后进入 Pod Shell:
$ kubectl exec -ti nginx -- bash
检查一下 Token 的加载情况:
$ export APISERVER=https://kubernetes.default.svc
$ export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
$ export CACERT=${SERVICEACCOUNT}/ca.crt
$ export TOKEN=$(cat ${SERVICEACCOUNT}/token)
$ curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "192.168.49.2:8443"
}
]
}
还是能成功,这个 Token 是怎么加载的?我们来看一下 Pod 的定义:
$ kubectl get pod nginx -o yaml
apiVersion: v1
kind: Pod
name: nginx
spec:
containers:
- image: nginx
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-69mqr
readOnly: true
serviceAccount: test
volumes:
- name: kube-api-access-69mqr
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
内容有点多,解析一下。
kube-api-access-69mqr
卷/var/run/secrets/kubernetes.io/serviceaccount
。这个卷用的是 projected
类型。
Projected 卷能把多个卷聚合在一起。但并不是所有类型的卷都能够绑定到 Projected 卷里面,目前仅限于
downwardAPI
、configMap
以及serviceAccountToken
。
在这个例子里,Projected 卷的组成成分包括:
serviceAccountToken
卷被加载到 token
路径configMap
卷downwardAPI
卷被加载到 namespace
路径这些卷都是干嘛的?
serviceAccountToken
是一种特别的卷,从当前的 Service Account 中加载 Secret,并填充到 /var/run/secrets/kubernetes.io/serviceaccount/token
文件中。
ConfigMap
卷会把 ConfigMap
中的每个 Key 加载成目录里面的文件。
这个文件的的内容就是对应 Key 的 Value(如果键值对的内容是 replicas:1
,就会表达为一个命名为 replicas
的文件,其内容是 1
)。
本例中,ConfigMap 卷中加载了调用 API 所必须的 ca.crt
证书。
downwardAPI 卷是一种特殊类型,使用 downwardAPI
,将 Pod 信息开放给容器。
在这个例子里,用这种方法将当前命名空间用文件的方式暴露给容器。
可以在 Pod 里验证一下这个能力:
$ export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
$ export NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
$ echo $NAMESPACE
default
知道了 Token 的加载方式之后,那为什么 Kubernetes 要放弃 Secret 改用这种方式呢?
主要原因是:
但是如果你只需要 Token,却不需要 Pod 呢?是否可以不加载 Projected Volume 就拿到 Token 数据呢?kubectl 有个新命令:
$ kubectl create token test
eyJhbGciOiJSUzI1NiIsImtpZCI6ImctMHJNO…
这个 Token 是临时的,和 Kubelet 加载到 Pod 里面的 Token 是一样的。
重复执行命令会看到不同的结果,那么这个 Token 只是个长字符串吗?
Projected Servivce Account Token 是个签了名的 JWT Token
可以把这个字符串复制到 jwt.io 网站上,处理之后的输出内容结构如下:
观察一下这个 Token:
{
"aud": [ "https://kubernetes.default.svc.cluster.local"
],
"exp": 1655083796,
"iat": 1655080196,
"iss": "https://kubernetes.default.svc.cluster.local",
"kubernetes.io": {
"namespace": "default",
"serviceaccount": {
"name": "test",
"uid": "6af2abe9-d8d8-4b8a-9bb5-3cc96442b322"
} },
"nbf": 1655080196,
"sub": "system:serviceaccount:default:test"}
上面的字段值得讨论:
test
的 Service Account。kubernetes.io
:
自定义字段,用于描述 Kubernetes 的细节。从 Nginx Pod 中读取 Token:
{
"aud": [ "https://kubernetes.default.svc.cluster.local"
],
"exp": 1686617744,
"iat": 1655081744,
"iss": "https://kubernetes.default.svc.cluster.local",
"kubernetes.io": {
"namespace": "default",
"pod": {
"name": "nginx",
"uid": "a11defcb-f510-4d49-9c4f-2e8e8da1c33c"
},
"serviceaccount": {
"name": "test",
"uid": "6af2abe9-d8d8-4b8a-9bb5-3cc96442b322"
},
"warnafter": 1655085351
},
"nbf": 1655081744,
"sub": "system:serviceaccount:default:test"}
Payload 中包含了 Pod 的名字和 UUID。但是这些信息是谁在消费呢?
不仅能够检查 Token 的完整性和有效性,甚至还可以区分出同一个 Deployment 中的两个 Pod 的区别。
这个功能很有用,原因是:
设想一个场景,在 AWS 中运行 Kubernetes 集群之中,并希望从集群中上传文件到 S3 的场景。
注意在 Azure 和 GCP 也存在同等能力。
通常来说,需要用一个角色来完成这一任务,但是 AWS 的 IAM 角色只能赋予给计算实例、而非 Pod,换句话说,AWS 对 Pod 并无认知。
2019 年底,AWS 提供了一种原生的 Kubernetes 集成 IAM 的机制,被称为 IAM Roles for Service Accounts (IRSA),IRSA 在身份和 Projected Service Account Token 之间建立了联系。
ARN
把 Role ARN 和 Projected Service Account Token 呈现在 Pod 的环境变量之中:
apiVersion: apps/v1
kind: Pod
metadata:
name: myapp
spec:
serviceAccountName: my-serviceaccount
containers:
- name: myapp
image: myapp:1.2
env:
- name: AWS_ROLE_ARN
value: arn:aws:iam::111122223333:policy/my-role
- name: AWS_WEB_IDENTITY_TOKEN_FILE
value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
volumeMounts:
- mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount
name: aws-iam-token
readOnly: true
volumes:
- name: aws-iam-token
projected:
defaultMode: 420
sources:
- serviceAccountToken:
audience: sts.amazonaws.com
expirationSeconds: 86400
path: token
有了这一配置,就能向 S3 上传文件了。
应用会使用这两个环境变量作为连接到 S3 所需要的 Token,但是如何实现的呢?
是 Kubernetes 而非 AWS 生成了 Token,那么 AWS 如何知道 Token 的有效性呢——是的 AWS 不知道。
AWS SDK 使用角色 ARN 以及 Projected Service Account Token 来交换标准的 AWS 访问凭据。
如果不用 AWS SDK 又怎么办呢?应用程序向 AWS IAM 发起请求,为当前身份(Service Account)换取一个角色。
IAM 收到这个 Token 后,会进行解压并检查 iss 字段,来判断 JWT Token 的合法性。
这个字段通常会被配置为用于创建该 Token 的公钥。
前面说过,这个 URL 指向 Kubernetes 集群:
{
"aud": [
"https://kubernetes.default.svc.cluster.local"
],
"exp": 1686617744,
"iat": 1655081744,
"iss": "https://kubernetes.default.svc.cluster.local",
注意,需要把这个 URL 改成一个完全限定名(FQDN),否则 AWS IAM 无法触达。可以用
--service-account-issuer
参数来指定
这个 URL 是一个标准的 OIDC Provider,AWS IAM 会查看两个路径:
{Issuer URL}/.well-known/openid-configuration
:
又被称为 OIDC 发现文档。
其中包含了签发者的配置元数据{Issuer URL}/openid/v1/jwks
:
其中包含了签名公钥,用于验证 Service Account Token 的真实性要注意,缺省情况下,这两个端点是不会暴露的,需要集群管理员进行设计。
首先看看 JWKS 端点:
curl {Issuer URL}/openid/v1/jwks
"keys": [
{
"use": "sig",
"kty": "RSA",
"kid": "ZO4TUgVjBzMWKVP8mmBwKLvsuyn8z-gfqUp27q9lO4w",
"alg": "RS256",
"n": "34a81xuMe…",
"e": "AQAB"
}
]
}
AWS IAM 会收到公钥,并校验 Token。下面的代码用于校验:
var jwt = require('jsonwebtoken')var jwkToPem = require('jwk-to-pem')var pem = jwkToPem(jwk /* "kid" value from the jkws file */)
jwt.verify(token /* this is the token to verify */, pem, { algorithms: ['RS256'] }, function(err, decodedToken) { // rest of the code})
如果 Token 有效,就生成一个具备指定权限的 Access Token:
{
"Credentials": {
"AccessKeyId": "ASIAWY4CVPOBS4OIBWNL",
"SecretAccessKey": "02n52u8Smc76…",
"SessionToken": "IQoJb3JpZ…",
"Expiration": "2022-06-13T10:50:25+00:00"
},
"SubjectFromWebIdentityToken": "system:serviceaccount:default:test",
"AssumedRoleUser": {
"AssumedRoleId": "AROAWY4CVPOBXUSBA5C2B:test",
"Arn": "arn:aws:sts::[aws account id]:assumed-role/oidc/test"
},
"Provider": "arn:aws:iam::[aws account id]:oidc-provider/[bucket name].s3.amazonaws.com",
"Audience": "test"}
拿到新凭据后,就可以用来访问 S3 存储桶了。
iss
字段的内容,用于验证 Token另外还有一篇文章,完整的描述了手工进行集成的过程。
这种方式可以用于访问外部资源,然而访问内部服务时,是否也需要这样操作呢?
可以用 Token Review API 来对集群创建的 Token 进行校验。
首先为 Service Account 创建一个 Token:
$ kubectl create token test
eyJhbG…
创建 YAML 资源,并在其中包含 Token:
kind: TokenReview
apiVersion: authentication.k8s.io/v1
metadata:
name: test
spec:
token: eyJhbG… # <- token
提交资源,注意 -o yaml
输出的内容:
$ kubectl apply -o yaml -f token.yaml
apiVersion: authentication.k8s.io/v1
kind: TokenReview
metadata:
name: test
spec:
token: eyJhbG…
status:
audiences:
- https://kubernetes.default.svc.cluster.local
authenticated: true
user:
groups:
- system:serviceaccounts
- system:serviceaccounts:default
- system:authenticated
uid: eccac137-25e2-4e84-9d83-18b2f9c5e5af
username: system:serviceaccount:default:test
Token Review API 的工作内容和 AWS IAM 集成类似:校验身份,并从 Token 中获取细节。当然,单一的 API 调用比 OIDC 流程要简单直接得多。
还可以使用定制 Audience 的方式来限制访问范围。
从 1.24 开始,Kubernetes 不再为 ServiceAccount 自动生成 Secret。然而你还是可以使用传统的方式来创建 Service Account 并用注解的方式来附加给一个 Secret。
例如当前的 Service Account test
中没有 secret
对象。但是可以创建用这种方式创建 Secret
(和 token
):
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
name: test
annotations:
kubernetes.io/service-account.name: "test"
提交给集群之后,进行观察:
$ kubectl describe secret test
Name: test
Namespace: default
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1111 bytes
namespace: 7 bytes
token: eyJhbG…
还可以用 Token Review API 来校验这个 Token:
kind: TokenReview
apiVersion: authentication.k8s.io/v1
metadata:
name: test
spec:
token: eyJhbG…
提交对象,并加入 -o yaml
开关:
$ kubectl apply -o yaml -f token.yaml
apiVersion: authentication.k8s.io/v1
kind: TokenReview
metadata:
name: test
spec:
token: eyJhbG…
status:
audiences:
- https://kubernetes.default.svc.cluster.local
authenticated: true
user:
groups:
- system:serviceaccounts
- system:serviceaccounts:default
- system:authenticated
uid: eccac137-25e2-4e84-9d83-18b2f9c5e5af
username: system:serviceaccount:default:test
如果把 Token 内容提交给 jwt.io
,会发现 Token 没有过期时间:
{
"iss": "kubernetes/serviceaccount",
"kubernetes.io/serviceaccount/namespace": "default",
"kubernetes.io/serviceaccount/secret.name": "test",
"kubernetes.io/serviceaccount/service-account.name": "test",
"kubernetes.io/serviceaccount/service-account.uid": "eccac137-25e2-4e84-9d83-18b2f9c5e5af",
"sub": "system:serviceaccount:default:test"}
这种情况和 Kubernetes 的传统行为是一致的。
Kubernetes 提供了以下的认证插件:
如何选择呢?
在前面一节里,我们讨论了静态 Token 文件的限制:
因此静态 Token 文件不是生产环境中的最佳选择。
X.509 客户端证书方案会略微好一些。
使用 X.509 客户端证书认证:
kube-apiserver
使用 --client-ca-file=FILE
参数来指定 CAkube-apiserver
用 CA 证书对客户端证书进行认证,如果有效,则解析其中包含的用户名和用户组。工作流和静态 Token 类似,但还是有些区别:
然而,X.509 客户端证书也并不是一个值得推荐的方案。
(临时)没有其它机制可用的应急场景下,正适合使用 X.509 认证方法。
Kubeadm 和 OpenShift 缺省会设置 API Server 的证书认证能力,这样本地的 Kubectl 就可以使用了。
除了上面的特例之外,可能最好的方式就是 OIDC 认证了。如果已经有了用于管理用户的 OpenID Connect 的基础设施,那就尤其合适了。这种情况下,可以用管理普通用户的方式来管理 Kubernetes 中的用户。
OpenID Connect Provider 能够签发 JSON Web Token(JWT),这意味着 Token 能够自动认证,无需连接到 Token 的签发方,并且会过期。
最后两种认证插件是:
认证代理 插件能够通过外部的认证代理进行透明的认证。
当用户向 Kubernetes 集群发起请求时,请求首先会被认证代理进行处理。这种认证插件可以编写自己的认证逻辑,因此用来实现其它插件不支持的认证方式是很合适的。
最后 Webhook Token 认证插件让用户能够用 HTTP Bearer Token 的方式,对 Kubernetes 请求进行自定义认证逻辑。
Webhook Token 认证插件也同样适用于没有其它机制可用的场景。
本文中阐述了 Kubernetes API Server 认证用户的能力。内容大致包括