根据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 $'s,\x1b\\[[0-9;]*[a-zA-Z],,g')
  5. # create client key and cert
  6. openssl genrsa -out $USER_NAME.key 2048
  7. openssl req -new -key $USER_NAME.key -out $USER_NAME.csr -subj "/CN=$USER_NAME/O=$GROUP_NAME"
  8. # Sign the client certificates
  9. CERTIFICATE_NAME=$USER_NAME-$NAMESPACE
  10. cat <<EOF | kubectl create -f -
  11. apiVersion: certificates.k8s.io/v1beta1
  12. kind: CertificateSigningRequest
  13. metadata:
  14. name: $CERTIFICATE_NAME
  15. spec:
  16. groups:
  17. - system:authenticated
  18. request: $(cat $USER_NAME.csr | base64 | tr -d '\n')
  19. usages:
  20. - digital signature
  21. - key encipherment
  22. - client auth
  23. EOF
  24. kubectl certificate approve $CERTIFICATE_NAME
  25. kubectl get csr $CERTIFICATE_NAME -o jsonpath='{.status.certificate}' | base64 --decode > $USER_NAME.crt
  26. # setup RBAC Roles
  27. cat <<EOF | kubectl create -f -
  28. kind: Role
  29. apiVersion: rbac.authorization.k8s.io/v1
  30. metadata:
  31. namespace: $NAMESPACE
  32. name: $USER_NAME-role
  33. rules:
  34. - apiGroups:
  35. - ''
  36. - extensions
  37. - apps
  38. - batch
  39. resources:
  40. - '*'
  41. verbs:
  42. - '*'
  43. EOF
  44. # bind role to the user
  45. kubectl create rolebinding $USER_NAME-rolebinding --user=$USER_NAME --namespace=$NAMESPACE --role=$USER_NAME-role
  46. # setup kubectl
  47. kubectl config set-cluster $USER_NAME --server="$SERVER_URL" --insecure-skip-tls-verify
  48. kubectl config set-credentials $USER_NAME --client-certificate=$USER_NAME.crt --client-key=$USER_NAME.key
  49. kubectl config set-context $USER_NAME --cluster=$USER_NAME --user=$USER_NAME --namespace=$NAMESPACE
  50. kubectl config use-context $USER_NAME

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. }

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 $'s,\x1b\\[[0-9;]*[a-zA-Z],,g')
  4. # create sa
  5. kubectl -n $NAMESPACE create sa $SERVICE_ACCOUNT_NAME
  6. # get secret and token
  7. secret=$(kubectl -n $NAMESPACE get sa $SERVICE_ACCOUNT_NAME -o jsonpath='{.secrets[0].name}')
  8. token=$(kubectl -n $NAMESPACE get secret $secret -o jsonpath='{.data.token}' | base64 -d)
  9. kubectl -n $NAMESPACE get secret $secret -o jsonpath='{.data.ca\.crt}' | base64 --decode > ca.crt
  10. # setup RBAC Roles
  11. cat <<EOF | kubectl create -f -
  12. kind: Role
  13. apiVersion: rbac.authorization.k8s.io/v1
  14. metadata:
  15. namespace: $NAMESPACE
  16. name: $SERVICE_ACCOUNT_NAME-role
  17. rules:
  18. - apiGroups:
  19. - ''
  20. - extensions
  21. - apps
  22. - batch
  23. resources:
  24. - '*'
  25. verbs:
  26. - '*'
  27. EOF
  28. # bind sa to the role
  29. kubectl create rolebinding $SERVICE_ACCOUNT_NAME-rolebinding --serviceaccount=$NAMESPACE:$SERVICE_ACCOUNT_NAME --namespace=$NAMESPACE --role=$SERVICE_ACCOUNT_NAME-role
  30. # setup kubectl
  31. kubectl config set-cluster $SERVICE_ACCOUNT_NAME --embed-certs=true --server=${SERVER_URL} --certificate-authority=./ca.crt
  32. kubectl config set-credentials $SERVICE_ACCOUNT_NAME --token=$token
  33. kubectl config set-context $SERVICE_ACCOUNT_NAME --cluster=$SERVICE_ACCOUNT_NAME --user=$SERVICE_ACCOUNT_NAME --namespace=$NAMESPACE
  34. kubectl config use-context $SERVICE_ACCOUNT_NAME