用户管理
根据Kubernetes 认证文档,Kubernetes 本身并不直接提供用户管理的特性,不支持 User 对象,更不会存储 User 对象。但是它支持一系列的插件,比如 X509 证书、OpenID、Webhook等,用户可以基于这些插件跟外部的用户管理系统进行对接,再配合 RBAC 实现权限管理的机制。
实际上,你也可以使用 Certificate Signing Request (CSR) 或者 ServiceAccount 来创建和管理受限的用户。

Certificate Signing Request (CSR)

Kubernetes 提供了 certificates.k8s.io API,可让您配置由您控制的证书颁发机构(CA)签名的TLS证书,工作负载可以使用这些CA和证书来建立信任。
Kubernetes controller manager 提供了一个签名者的默认实现。 要启用它,请将--cluster-signing-cert-file--cluster-signing-key-file 参数传递给 controller manager,并配置具有证书颁发机构的密钥对的路径。
假设已经为 kubectl 配置好了管理员 kubeconfig,以下是通过 openssl 和 CSR 创建一个新用户配置的步骤。
1
NAMESPACE=${NAMESPACE:-"default"}
2
USER_NAME=${USER_NAME:-"user1"}
3
GROUP_NAME=${GROUP_NAME:-"group1"}
4
SERVER_URL=$(kubectl cluster-info | awk '/Kubernetes master/{print $NF}' | sed #x27;s,\x1b\\[[0-9;]*[a-zA-Z],,g')
5
6
# create client key and cert
7
openssl genrsa -out $USER_NAME.key 2048
8
openssl req -new -key $USER_NAME.key -out $USER_NAME.csr -subj "/CN=$USER_NAME/O=$GROUP_NAME"
9
10
# Sign the client certificates
11
CERTIFICATE_NAME=$USER_NAME-$NAMESPACE
12
cat <<EOF | kubectl create -f -
13
apiVersion: certificates.k8s.io/v1beta1
14
kind: CertificateSigningRequest
15
metadata:
16
name: $CERTIFICATE_NAME
17
spec:
18
groups:
19
- system:authenticated
20
request: $(cat $USER_NAME.csr | base64 | tr -d '\n')
21
usages:
22
- digital signature
23
- key encipherment
24
- client auth
25
EOF
26
kubectl certificate approve $CERTIFICATE_NAME
27
kubectl get csr $CERTIFICATE_NAME -o jsonpath='{.status.certificate}' | base64 --decode > $USER_NAME.crt
28
29
# setup RBAC Roles
30
cat <<EOF | kubectl create -f -
31
kind: Role
32
apiVersion: rbac.authorization.k8s.io/v1
33
metadata:
34
namespace: $NAMESPACE
35
name: $USER_NAME-role
36
rules:
37
- apiGroups:
38
- ''
39
- extensions
40
- apps
41
- batch
42
resources:
43
- '*'
44
verbs:
45
- '*'
46
EOF
47
48
# bind role to the user
49
kubectl create rolebinding $USER_NAME-rolebinding --user=$USER_NAME --namespace=$NAMESPACE --role=$USER_NAME-role
50
51
# setup kubectl
52
kubectl config set-cluster $USER_NAME --server="$SERVER_URL" --insecure-skip-tls-verify
53
kubectl config set-credentials $USER_NAME --client-certificate=$USER_NAME.crt --client-key=$USER_NAME.key
54
kubectl config set-context $USER_NAME --cluster=$USER_NAME --user=$USER_NAME --namespace=$NAMESPACE
55
kubectl config use-context $USER_NAME
Copied!

ServiceAccount

ServiceAccount 是 Kubernetes 自动生成的,并会自动挂载到容器的 /var/run/secrets/kubernetes.io/serviceaccount 目录中。
在认证时,ServiceAccount 的用户名格式为 system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT),并从属于两个 group:system:serviceaccountssystem:serviceaccounts:(NAMESPACE)

Pod 内部访问 API

在 Pod 内部,你可以通过下面的方式来访问 API:
1
$ TOKEN=$(cat /run/secrets/kubernetes.io/serviceaccount/token)
2
$ CACERT=/run/secrets/kubernetes.io/serviceaccount/ca.crt
3
$ curl --cacert $CACERT --header "Authorization: Bearer $TOKEN" https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api
4
{
5
"kind": "APIVersions",
6
"versions": [
7
"v1"
8
],
9
"serverAddressByClientCIDRs": [
10
{
11
"clientCIDR": "0.0.0.0/0",
12
"serverAddress": "10.0.1.149:443"
13
}
14
]
15
}
Copied!

kubectl 访问 API

假设已经为 kubectl 配置好了管理员 kubeconfig,以下是通过 ServiceAccount 创建一个新用户配置的步骤。
1
NAMESPACE=${NAMESPACE:-"default"}
2
SERVICE_ACCOUNT_NAME=${SERVICE_ACCOUNT_NAME:-"demo"}
3
SERVER_URL=$(kubectl cluster-info | awk '/Kubernetes master/{print $NF}' | sed #x27;s,\x1b\\[[0-9;]*[a-zA-Z],,g')
4
5
# create sa
6
kubectl -n $NAMESPACE create sa $SERVICE_ACCOUNT_NAME
7
8
# get secret and token
9
secret=$(kubectl -n $NAMESPACE get sa $SERVICE_ACCOUNT_NAME -o jsonpath='{.secrets[0].name}')
10
token=$(kubectl -n $NAMESPACE get secret $secret -o jsonpath='{.data.token}' | base64 -d)
11
kubectl -n $NAMESPACE get secret $secret -o jsonpath='{.data.ca\.crt}' | base64 --decode > ca.crt
12
13
# setup RBAC Roles
14
cat <<EOF | kubectl create -f -
15
kind: Role
16
apiVersion: rbac.authorization.k8s.io/v1
17
metadata:
18
namespace: $NAMESPACE
19
name: $SERVICE_ACCOUNT_NAME-role
20
rules:
21
- apiGroups:
22
- ''
23
- extensions
24
- apps
25
- batch
26
resources:
27
- '*'
28
verbs:
29
- '*'
30
EOF
31
32
# bind sa to the role
33
kubectl create rolebinding $SERVICE_ACCOUNT_NAME-rolebinding --serviceaccount=$NAMESPACE:$SERVICE_ACCOUNT_NAME --namespace=$NAMESPACE --role=$SERVICE_ACCOUNT_NAME-role
34
35
# setup kubectl
36
kubectl config set-cluster $SERVICE_ACCOUNT_NAME --embed-certs=true --server=${SERVER_URL} --certificate-authority=./ca.crt
37
kubectl config set-credentials $SERVICE_ACCOUNT_NAME --token=$token
38
kubectl config set-context $SERVICE_ACCOUNT_NAME --cluster=$SERVICE_ACCOUNT_NAME --user=$SERVICE_ACCOUNT_NAME --namespace=$NAMESPACE
39
kubectl config use-context $SERVICE_ACCOUNT_NAME
Copied!