Kubernetes 用户认证
从Dashboard鉴权认识Kubernetes的用户认证
从签发用户证书认识Kubernetes的用户认证
接上篇从Dashboard鉴权认识Kubernetes的用户认证 ,我们通过给普通用户签发证书,来认识Kubernetes用户认证。
请注意!本文可以作为签发证书的教程,但只需要参照章节1.1、1.2、3.1、3.2.1。其他内容仅为测试内容。
目录
1. 使用CertificateSigningRequest方式自动签发证书 这是k8s集群的证书签发的标准动作,按照下面的步骤操作,你将获得一个用户名为dave
,组名为foo
的用户,证书有效期一天。
1. 创建私钥和证书请求文件 openssl csr openssl genrsa -out dave.key 2048 req -new -key dave.key -out dave.csr -subj /CN=dave/O=foo/C=CN
2. CertificateSigningRequest(证书签发请求) 签发申请 CSR=`cat dave.csr | base64 | tr -d "\n" `cat <<EOF | kubectl apply -f - apiVersion: certificates.k8s.io/v1 kind: CertificateSigningRequest metadata: name: dave spec: request: $CSR signerName: kubernetes.io/kube-apiserver-client expirationSeconds: 86400 usages: - client auth EOF
获取证书请求记录,验证是否提交成功 dama@node1:~/tmp$ kubectl get csr NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION dave 5s kubernetes.io/kube-apiserver-client system:serviceaccount:kubernetes-dashboard:admin-user 24h Pending
批准 CSR kubectl certificate approve dave
再次获取CSR列表,dave的请求状态已经变更为Approved,Issued
导出证书 kubectl get csr dave -o jsonpath='{.status.certificate}' | base64 -d > dave.crt
验证证书信息 dama@node1:~/tmp$ openssl x509 -in dave.crt -noout -subject -dates subject=C = CN, O = foo, CN = dave notBefore=Sep 20 08:51:51 2023 GMT notAfter=Sep 21 08:51:51 2023 GMT
证书已经签发成功了,有效期1天
2. 使用集群CA手动签发 除了使用CertificateSigningRequest签发证书,我们还可以使用集群CA手动签发证书。这个签发证书与普通证书签发过程无异。
1. 创建私钥和证书请求文件 openssl csr openssl genrsa -out jane.key 2048 req -new -key jane.key -out jane.csr -subj /CN=jane/O=foo/C=CN
2. 使用集群CA证书签发客户证书 openssl new cert sudo openssl x509 -req -in jane.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out jane.crt -days 1
验证证书信息 dama@node1:~/tmp$ openssl x509 -in jane.crt -noout -subject -dates subject=CN = jane, O = foo, C = CN notBefore=Sep 20 09:11:28 2023 GMT notAfter=Sep 21 09:11:28 2023 GMT
证书已经签发成功了,有效期1天
3. 用户权限设置 1. 配置kubeconfig .kube/config kubectl config set-credentials dave \ --client-certificate=dave.crt --client-key=dave.key \ --embed-certs && \ kubectl config set-context foo-dave --user=dave --cluster=kubernetes kubectl config set-credentials jane \ --client-certificate=jane.crt --client-key=jane.key \ --embed-certs && \ kubectl config set-context foo-jane --user=jane --cluster=kubernetes
验证配置 dama@node1:~/tmp$ kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority-data: DATA+OMITTED server: https://127.0.0.1:6443 name: kubernetes contexts: - context: cluster: kubernetes user: admin-user name: dashboard - context: cluster: kubernetes user: jane name: foo-jane - context: cluster: kubernetes user: dave name: foo-dave - context: cluster: kubernetes namespace: qietv user: admin-user name: godev current-context: dashboard kind: Config preferences: {}users : - name: admin-user user: token: REDACTED - name: jane user: client-certificate-data: DATA+OMITTED client-key-data: DATA+OMITTED - name: dave user: client-certificate-data: DATA+OMITTED client-key-data: DATA+OMITTED - name: godev user: client-certificate-data: DATA+OMITTED client-key-data: DATA+OMITTED
2. 配置用户权限 Kubernetes鉴权游RBAC、ABAC、Node三种。基于角色(Role)的访问控制(RBAC)是最常用的方式,权限控制力度可以是用户可以是用户组。
1. 使用Role和RoleBinding设置dave
的权限
案例中dave拥有对daveown
Namespace的全部权限
创建namespace kubectl create ns daveown
创建Role cat << EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: daveown name: superdave rules: - apiGroups: ["*"] resources: ["*"] verbs: ["*"] EOF
创建RoleBinding cat << EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 # 此角色绑定允许 "dave" kind: RoleBinding metadata: name: dave-can-do-everything namespace: daveown subjects: - kind: User name: dave apiGroup: rbac.authorization.k8s.io roleRef: kind: Role # 此字段必须是 Role 或 ClusterRole name: superdave # 此字段必须与你要绑定的 Role 或 ClusterRole 的名称匹配 apiGroup: rbac.authorization.k8s.io EOF
验证dave的权限 kubectl config use-context foo-dave && \ kubectl get pod -n daveown && \cat << EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: busybox namespace: daveown spec: containers: - image: busybox command: - sleep - "3600" imagePullPolicy: IfNotPresent name: busybox restartPolicy: Always EOF
busybox pod created by dave kubectl get pod -n daveown
2. 修改RoleBinding是jane
拥有相同的权限 创建RoleBinding cat << EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 # 此角色绑定允许 "dave" kind: RoleBinding metadata: name: dave-can-do-everything namespace: daveown subjects: - kind: User name: dave apiGroup: rbac.authorization.k8s.io #!注意这里,jane和dave都在foo用户组 - kind: Group name: foo apiGroup: rbac.authorization.k8s.io roleRef: kind: Role # 此字段必须是 Role 或 ClusterRole name: superdave # 此字段必须与你要绑定的 Role 或 ClusterRole 的名称匹配 apiGroup: rbac.authorization.k8s.io EOF
修改完的RoleBinding,是foo组所有用户拥有了daveown
的所有操作权限。
验证jane的权限 dama@node1:~$ kubectl config use-context foo-jane && \ > kubectl get pod -n daveown Switched to context "foo-jane" . NAME READY STATUS RESTARTS AGE busybox 1/1 Running 0 10m
3. 配置jane拥有集群所有pod的访问权限 这里采用RBAC的另外一个资源ClusterRoleBinding。
define a new ClusterRole cat << EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: foo-can-read-all-pods rules: - apiGroups: [""] resources: ["pods"] verbs: ["get","list","watch"] EOF
ClusterRoleBinding Define cat << EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: foo-can-read-all-pods subjects: - kind: Group name: foo apiGroup: rbac.authorization.k8s.io - kind: User name: alice apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: foo-can-read-all-pods apiGroup: rbac.authorization.k8s.io EOF
验证jane的权限 kubectl config use-context foo-jane dama@node1:~$ kubectl get pod --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE daveown busybox 1/1 Running 0 24m istio-system grafana-78588947bf-9mgt6 1/1 Running 35 56d
这里可能有些名词需要解释一下 apiGroups: 可以使用的api组。 verbs: 用户可以执行的动作,包括get create list delete
等。 resources:Kubernetes资源,pod service deployment等资源。 更多关于RBAC的内容可以查看Kubernetes Reference
4. 手动签名与自动签名有差异吗? 没有。https://github.com/kubernetes/kubernetes/blob/master/pkg/controller/certificates/signer/signer.go#L195