目录

认证机制

API 服务器接收的请求经过认证插件列表,当遇到第一个成功返回用户名、用户ID和组信息给 API 服务器后,将停止剩余的认证调用,进入授权阶段。

ServiceAccount

镜像拉取密钥

向 ServiceAccount 中添加 imagePullSecrets,可以不必对每个 Pod 单独添加 imagePullSecrets。

创建 docker-registry Secret

kubectl create secret docker-registry mydockerhubsecret \
  --docker-username=myusername \
  --docker-password=mypassword \
  --docker-email=myemail

编写 ServiceAccount YAML 文件(sa-image-pull-secret.yaml)

apiVersion: v1
kind: ServiceAccount
metadata:
  name: image-pull-secret
imagePullSecrets:
- name: mydockerhubsecret

创建 ServiceAccount 对象

kubectl apply -f sa-image-pull-secret.yaml

编写 Pod YAML 文件(private-serviceaccount.yaml),指定 serviceAccountName 为 image-pull-secret。

apiVersion: v1
kind: Pod
metadata:
  name: private
spec:
  containers:
  - image: wangjunjian/private:latest
    name: private
  serviceAccountName: image-pull-secret

创建 Pod 对象

kubectl apply -f private-serviceaccount.yaml

RBAC

基于角色的访问控制(Role-Based Access Control)

HTTP 动词与请求动词的映射关系

HTTP 动词 请求动词
POST create
GET, HEAD get (针对单个资源)、list(针对集合)
PUT update
PATCH patch
DELETE delete(针对单个资源)、deletecollection(针对集合)

四种 RBAC 资源

RBAC API 声明了四种 Kubernetes 对象:Role、ClusterRole、RoleBinding 和 ClusterRoleBinding。

可以通过 kubectl api-resources 查看

$ kubectl api-resources | grep rbac
NAME                  SHORTNAMES   APIGROUP                    NAMESPACED   KIND
clusterrolebindings                rbac.authorization.k8s.io   false        ClusterRoleBinding
clusterroles                       rbac.authorization.k8s.io   false        ClusterRole
rolebindings                       rbac.authorization.k8s.io   true         RoleBinding
roles                              rbac.authorization.k8s.io   true         Role

测试准备

创建两个名字空间 foo 和 bar 用于接下来的测试。

$ kubectl create namespace foo
namespace/foo created
$ kubectl create namespace bar
namespace/bar created

分别在两个名字空间中创建 Pod 对象

$ kubectl run test --image=luksa/kubectl-proxy -n foo
pod/test created
$ kubectl run test --image=luksa/kubectl-proxy -n bar
pod/test created

列出 foo 名字空间中的所有 Pod 对象

$ kubectl exec -it -n foo test -- curl localhost:8001/api/v1/namespaces/foo/pods
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {
    
  },
  "status": "Failure",
  "message": "pods is forbidden: User \"system:serviceaccount:foo:default\" cannot list resource \"pods\" in API group \"\" in the namespace \"foo\"",
  "reason": "Forbidden",
  "details": {
    "kind": "pods"
  },
  "code": 403
}

这说明没有权限。

Role(角色)

编写角色 YAML 文件(pod-reader.yaml)

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: foo
  name: pod-reader
rules:
- apiGroups: [""] # "" 标明 core API 组
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

创建角色

$ kubectl apply -f pod-reader.yaml 
role.rbac.authorization.k8s.io/pod-reader created

查看角色对象

$ kubectl get role -n foo
NAME         CREATED AT
pod-reader   2021-08-04T08:53:50Z

这里通过命令的方式创建角色

$ kubectl create role pod-reader --verb=get --verb=watch --verb=list \
    --resource=pods -n bar
role.rbac.authorization.k8s.io/pod-reader created

删除角色

$ kubectl delete role pod-reader -n bar
role.rbac.authorization.k8s.io "pod-reader" deleted

RoleBinding(角色绑定)

编写角色绑定 YAML 文件(read-pods.yaml)

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: foo
subjects:
- kind: ServiceAccount
  name: default
  namespace: foo
- kind: ServiceAccount
  name: default
  namespace: bar
roleRef:
  kind: Role
  name: pod-reader    
  apiGroup: rbac.authorization.k8s.io

创建角色绑定

$ kubectl apply -f read-pods.yaml 
rolebinding.rbac.authorization.k8s.io/read-pods created

通过命令创建角色绑定

$ kubectl create rolebinding read-pods --role=pod-reader \
    --serviceaccount=foo:default -n foo
rolebinding.rbac.authorization.k8s.io/read-pods created

列出 foo 名字空间中的所有 Pod 对象

kubectl exec -it -n foo test -- curl localhost:8001/api/v1/namespaces/foo/pods
{
  "kind": "PodList",
  "apiVersion": "v1",
  "metadata": {
    "resourceVersion": "984933"
  },
  "items": [
    {
      "metadata": {
        "name": "test",
        "namespace": "foo",
        "uid": "55366a1f-307e-495e-8575-c2b61a462329",
        "resourceVersion": "983870",
        "creationTimestamp": "2021-08-04T10:42:28Z",
        "labels": {
          "run": "test"
        },
...
    }
  ]
}

删除角色绑定

$ kubectl delete rolebinding read-pods -n foo
rolebinding.rbac.authorization.k8s.io "read-pods" deleted

运行编辑命令在 subjects: 下面增加 bar 名字空间下的默认 ServiceAccount

kubectl edit rolebinding read-pods -n foo
- kind: ServiceAccount
  name: default
  namespace: bar

现在可以在 bar 名字空间下通过容器访问 foo 名字空间里的所有 Pod 对象。

$ kubectl exec -it -n bar test -- curl localhost:8001/api/v1/namespaces/foo/pods

参考资料