保障KubernetesAPI服务器安全及基于角色的访问控制
立即解锁
发布时间: 2025-08-21 00:51:34 阅读量: 2 订阅数: 11 


Kubernetes实战:从入门到精通
### 保障Kubernetes API服务器安全与基于角色的访问控制
#### 1. 内置组与ServiceAccount简介
在Kubernetes中,插件返回的组只是代表任意组名的字符串,但内置组有特殊含义:
- `system:unauthenticated`组用于所有认证插件都无法认证客户端的请求。
- `system:authenticated`组会自动分配给成功认证的用户。
- `system:serviceaccounts`组包含系统中的所有ServiceAccount。
- `system:serviceaccounts:<namespace>`包含特定命名空间中的所有ServiceAccount。
ServiceAccount是运行在Pod内的应用程序向API服务器进行身份验证的一种方式。每个Pod都与一个ServiceAccount关联,该ServiceAccount代表运行在Pod中的应用程序的身份。应用程序通过在请求中传递ServiceAccount的令牌来进行身份验证。
ServiceAccount是一种资源,与Pods、Secrets、ConfigMaps等类似,并且作用域为单个命名空间。每个命名空间都会自动创建一个默认的ServiceAccount。可以使用以下命令列出ServiceAccount:
```bash
$ kubectl get sa
NAME SECRETS AGE
default 1 1d
```
注:`serviceaccount`的简写是`sa`。
每个Pod只能与一个ServiceAccount关联,但多个Pod可以使用同一个ServiceAccount,并且Pod只能使用与其在同一命名空间中的ServiceAccount。可以通过在Pod清单中指定ServiceAccount的名称来为Pod分配ServiceAccount。如果未显式分配,则Pod将使用命名空间中的默认ServiceAccount。
#### 2. 创建ServiceAccount
在Kubernetes中,虽然每个命名空间都有默认的ServiceAccount,但根据需要可以创建额外的ServiceAccount。创建额外ServiceAccount的主要原因是提高集群安全性。例如,不需要读取任何集群元数据的Pod应在受限账户下运行,该账户不允许它们检索或修改集群中部署的任何资源;需要检索资源元数据的Pod应在仅允许读取这些对象元数据的ServiceAccount下运行;需要修改这些对象的Pod应在允许修改API对象的自己的ServiceAccount下运行。
创建ServiceAccount非常简单,使用以下命令可以创建一个名为`foo`的新ServiceAccount:
```bash
$ kubectl create serviceaccount foo
serviceaccount "foo" created
```
可以使用`describe`命令检查该ServiceAccount:
```bash
$ kubectl describe sa foo
Name: foo
Namespace: default
Labels: <none>
Image pull secrets: <none>
Mountable secrets: foo-token-qzq7j
Tokens: foo-token-qzq7j
```
可以看到,已经创建了一个自定义令牌Secret并将其与该ServiceAccount关联。使用以下命令查看该Secret的数据:
```bash
$ kubectl describe secret foo-token-qzq7j
...
ca.crt: 1066 bytes
namespace: 7 bytes
token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
```
注:ServiceAccount中使用的认证令牌是JSON Web Tokens (JWT)。
当使用`kubectl describe`检查ServiceAccount时,令牌会显示在`Mountable secrets`列表中。默认情况下,Pod可以挂载任何它想要的Secret,但可以通过在ServiceAccount中添加`kubernetes.io/enforce-mountable-secrets="true"`注解来配置Pod只能挂载ServiceAccount中列出的可挂载Secret。
ServiceAccount还可以包含一个镜像拉取Secret列表,这些Secret包含从私有镜像仓库拉取容器镜像的凭据。以下是一个包含镜像拉取Secret的ServiceAccount定义示例:
```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-service-account
imagePullSecrets:
- name: my-dockerhub-secret
```
与可挂载Secret不同,镜像拉取Secret不会决定Pod可以使用哪些镜像拉取Secret,而是会自动添加到使用该ServiceAccount的所有Pod中。
#### 3. 为Pod分配ServiceAccount
创建额外的ServiceAccount后,需要将它们分配给Pod。这可以通过在Pod定义的`spec.serviceAccountName`字段中设置ServiceAccount的名称来完成。注意,Pod的ServiceAccount必须在创建Pod时设置,之后无法更改。
以下是一个使用自定义ServiceAccount的Pod定义示例:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: curl-custom-sa
spec:
serviceAccountName: foo
containers:
- name: main
image: tutum/curl
command: ["sleep", "9999999"]
- name: ambassador
image: luksa/kubectl-proxy:1.6.2
```
可以通过以下命令确认自定义ServiceAccount的令牌已挂载到容器中:
```bash
$ kubectl exec -it curl-custom-sa -c main
➥ cat /var/run/secrets/kubernetes.io/serviceaccount/token
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
```
可以通过比较该令牌字符串与之前
0
0
复制全文
相关推荐









