k8s(十四)、RBAC权限控制

前言

kubernetes 集群相关所有的交互都通过apiserver来完成,对于这样集中式管理的系统来说,权限管理尤其重要,在1.5版的时候引入了RBAC(Role Base Access Control)的权限控制机制.

RBAC也是初接触k8s的用户较难理解的一部分,同时RBAC作为集群管理的基础组件之一,本该放在最前面几篇,但是最近才想起来这个方面的知识点,赶紧梳理总结输出了本篇

工作流程

流程图

k8s(十四)、RBAC权限控制_第1张图片

流程拆解

一、基于资源申明和管理方法申明组成rule规则,和Role(命名空间范围))或ClusterRole(集群范围)对象进行绑定,Role类的对象将拥有所申明资源及的指定方法的权限。
二、将Role权限落到实际用户或程序上,即RoleBinding(命名空间范围)或CLusterRoleBinding(集群范围)

有两种方式:
1.用户使用:如果是用户需求权限,则将Role与User(或Group)绑定(这需要创建User/Group);
2.程序使用:如果是程序需求权限,将Role与ServiceAccount指定(这需要创建ServiceAccount并且在deployment中指定ServiceAccount)。
相当于Role是一个类,用作权限申明,User/Group/ServiceAccount将成为类的实例

实战

一、用户使用

安装cfssl工具,生成ca-config.json文件。这一步骤在安装集群的时候已经做过,这里不再复述,参考:
k8s(一)、 1.9.0高可用集群本地离线部署记录

准备ca配置json文件如下:

cat >  ca-config.json <<EOF
{
"signing": {
"default": {
  "expiry": "8760h"
},
"profiles": {
  "kubernetes": {
    "usages": [
        "signing",
        "key encipherment",
        "server auth",
        "client auth"
    ],
    "expiry": "8760h"
  }
}
}
}
EOF

安装好的k8s集群,默认在ca文件在如下路径:

~ /rbac-test# ls /etc/kubernetes/pki/ca*
/etc/kubernetes/pki/ca.crt  /etc/kubernetes/pki/ca.key

创建用户的证书签署请求配置json文件:

~/rbac-test# cat opsuser-csr.json
{
  "CN": "opsuser",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}

CN即comman name,后面用户证书认证时使用的用户名

生成opsuser的证书:

cfssl gencert -ca=/etc/kubernetes/pki/ca.crt -ca-key=/etc/kubernetes/pki/ca.key -config=./ca-config.json -profile=kubernetes ./opsuser-csr.json | cfssljson -bare opsuser

会生成下面3个文件:

opsuser-key.pem  opsuser.pem  opsuser.csr

生成用户的专属配置文件
完整的配置文件包含3块,分别是cluster/context/user部分,包含相应的内容,分3个步骤生成,后方详解

1.cluster部分:
生成此部分需要有集群的ca.pem文件,此文件在/etc/kubernetes/pki目录下默认没有,可以使用openssl命令基于ca.key文件去生成ca.pem文件;也可以直接使用已有的/etc/kubernetes/admin.conf文件中cluster部分:

# 只取cluster的上下文
~/rbac-test# cat /etc/kubernetes/admin.conf 
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: [CERT DATA]
    server: https://10.90.1.238:6443
  name: kubernetes

# 将cluster部分写入opsuser的配置文件内
cat >  opsuser.kubeconfig <apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: [CERT DATA]
    server: https://10.90.1.238:6443
  name: kubernetes
EOF

2.context部分

kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=opsuser \
--namespace=default \
--kubeconfig=opsuser.kubeconfig

3.user认证部分

kubectl config set-credentials opsuser \
--client-certificate=./opsuser.pem \
--client-key=./opsuser-key.pem \
--embed-certs=true \
--kubeconfig=opsuser.kubeconfig

查看最终生成的配置文件:

# cat opsuser.kubeconfig 
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: [CRET DATA]
    server: https://10.90.1.238:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    namespace: default
    user: opsuser
  name: kubernetes
current-context: kubernetes
kind: Config
preferences: {}
users:
- name: opsuser
  user:
    as-user-extra: {}
    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURZekNDQWt1Z0F3SUJBZ0lVV2ZKMlNLb1NJWWhBMHFJdzRaVUZERnlWY1pzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZURVRNQkVHQTFVRUF4TUthM1ZpWlhKdVpYUmxjekFlRncweE9ERXlNRFV3T0RNek1EQmFGdzB4T1RFeQpNRFV3T0RNek1EQmFNR0l4Q3pBSkJnTlZCQVlUQWtOT01SQXdEZ1lEVlFRSUV3ZENaV2xLYVc1bk1SQXdEZ1lEClZRUUhFd2RDWldsS2FXNW5NUXd3Q2dZRFZRUUtFd05yT0hNeER6QU5CZ05WQkFzVEJsTjVjM1JsYlRFUU1BNEcKQTFVRUF4TUhiM0J6ZFhObGNqQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU93Wgo4d1hpdFhrOGtKNk9PSkFvUHZGaWw2ZkdKUDFWT3VyYWFqTWMyZ2ROSkV0Q3o2Mzk2eTNIZGw1T2NXdlBNNURvCjJ3a0NGKzlJd09jVzljVHhTZFZMUEg3OVEvQVhHcm9Nd2ltZk9WRUNlYm9aVkswRUx3azk1K2piRUpVVHY4eTYKMForM2JvMGtwL2p2Q2pzdmwxWUR3RGtGeGtwckZ3SXliOGt0cVBLMVFkb2ZrOE16Z3NTMnNZYTR1MWFydHd0dQozSTZZbEViUFNIOXhGbmx1UUFvbjZnSmkrM0c1YTdVRGxvRm9MSHlqL00wMStPRi9YWVpEcWgwK3hoZTlVRWdHClZBZkNSQkYyZlg2WjdCaFkybnpsblZOejV5SXhmSlpJclNIYnFhUlAxZXY1Tk1ndVNRcnl3UGQ5OG5jM201RnkKMkVXa28xeEJmQ1FXSHJKd04vMENBd0VBQWFOZU1Gd3dEZ1lEVlIwUEFRSC9CQVFEQWdXZ01CMEdBMVVkSlFRVwpNQlFHQ0NzR0FRVUZCd01CQmdnckJnRUZCUWNEQWpBTUJnTlZIUk1CQWY4RUFqQUFNQjBHQTFVZERnUVdCQlFXCmpDR2NYVjRPOTRqZlV1Mk9Kd2hqTC9xMVZEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFBeXdlZk5uckNKU0MKdDdrT2tHL1RUSHA1NG1tT0QxS2FPZW82TnpycFRuNVQwa0h3VEdrYmNHcWxvcDIvM1lhQXJDUHo2Q1J4VDd0QQpaTUNiOXhRZkJ0cllpeHJUdGF0TTZ4YlJuQTBqaC96Y2tvRHVuYjFEYkhxbG1JQW5jLzdaTEthQklKSnA5L0IwCjB2NnJXTEd2N0F1YmZJT1ZZVTdBVTVnZmh1LzJoWC93MzFJWlgwaXZ0WEtDR0lJb1Bya2hsL3NvUTEwdVFhUmgKeFFBdzhUbTc0dTBJTDE3OFFsRlhSYm1JQXpuWk42Skh1YW5QZE82TVI1Z0dobVMzRDRaUDg2RE5DenZCOVZFcQpWa0w4R0E2bHJHNm1sem5MN0pxODlQajdOdElwZnRaeDBsdTBYRmsxTm9DWk9VMFl5Yk9peWlPS2N0NVNia3VKClVLUjVYMC9GTUE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBN0JuekJlSzFlVHlRbm80NGtDZys4V0tYcDhZay9WVTY2dHBxTXh6YUIwMGtTMExQCnJmM3JMY2QyWGs1eGE4OHprT2piQ1FJWDcwakE1eGIxeFBGSjFVczhmdjFEOEJjYXVnekNLWjg1VVFKNXVobFUKclFRdkNUM242TnNRbFJPL3pMclJuN2R1alNTbitPOEtPeStYVmdQQU9RWEdTbXNYQWpKdnlTMm84clZCMmgrVAp3ek9DeExheGhyaTdWcXUzQzI3Y2pwaVVSczlJZjNFV2VXNUFDaWZxQW1MN2NibHJ0UU9XZ1dnc2ZLUDh6VFg0CjRYOWRoa09xSFQ3R0Y3MVFTQVpVQjhKRUVYWjlmcG5zR0ZqYWZPV2RVM1BuSWpGOGxraXRJZHVwcEUvVjYvazAKeUM1SkN2TEE5MzN5ZHplYmtYTFlSYVNqWEVGOEpCWWVzbkEzL1FJREFRQUJBb0lCQVFEQ0F6amUxME5FMHU0TQpQTlppTDVBNWowa01CeGtTUzkxVWJCTGsyWXFZZ1YyWHN0a3lJdndFN0dscWFZOXVoaC9icmwxL2M0YnpqSmRuCnprZzdoQU9tRUdNdi96SzZzbUcyRFJIb1hmMGRncWxBc2R3UktPVDE5VGNDOURFV0w5cG1oQVlKOXhRVFM5SDAKRDRvYXhLclpkYytaakJNN3gvQnFUOFBvVDJzTHRTN1FuTjhpNGNpTjVSeTl1TUsrOFZJcitPUVJqNWlVSHpDLwoyWXRBT0daYlJHekhZaXR1a2xtZG45RmhYV1NreGFBY0p0RkdWcGlMS2FWdjdoYVZsZm40SUJaSkZrdkJNQkxCClR4N2JCb25MYkF1K2Ezd0ZzYzlMd1NTNUJXK296eUZJYlJoWVV0SmhTdmZLUjZxTVJFMHRMV2IwUFJoRDVjZEUKenR5dWRoWEpBb0dCQVBYanVOYXA1TGNSSnUwaDhvVWxLTE9SZ1psYXFKSlpCUThrQ3A4ZTBJNXNpdFlxMEZlRwpOMnJibGdPV0RKSW5TR0pCc0I2VzFhOHI2S1F5L3dlcG9wTHJSQUE1VFo2YVMzMDBQeEgyY1paUE1aMHJpTmVXCnpLZGdIalczM0FORWtGQm5nVlA3Y3M2UENXSVlkajhyRElDUGowbWhkZEhWckd4elNycXNwWFczQW9HQkFQWFAKTWZjcEVQdVA1dGNvS0tnSXF5ZzVrNzRlZ0J0M2JUT2NHR05TellDeGV0bjJseHJWRW1nMktlOWNrMElGT0hFaAovUnFqNnJtY1VNV0JnRWExS0pNajlCRW56NWo4S2pGN3l2Z3o5ZDJPNHVkTlMyeG50R2MrZVJ1T0NpU0JNejRhCkFVZ2xSdGRJZXhkeWdoVWJsNVhMaitTeFRYVXRmWDgzZENMZEZCL3JBb0dCQUlsOU5LeHJRT1VRSlNqeEUyOVoKa01HZmVjenJBVmtiaDVXb3ZIdXV1a1Q0OGtUQW1kQm16dlBrSnFTSXNTekQ1RmgwakdyK1FpdDVyTktyWlNpKwp0SlhjRVNEaTZjRG1XNUY5dGtwdjk2RnBWTCtpU1JqclRESEdyLzJ2ZWNrbC9GL0pFR3FLTGU3TDBoNVV1VUdtCjY0MnpPQmFldm9kL0o3TllZQSt6VzYxUEFvR0JBUEFWQU01UTg5OWdlNnlsOHArOFo3K1FEUGRpUHVtVXlibmcKdWdrNHRMTC9wZWdCYXpDdjc1eU5Xb1FKUFdMOFNsWmxSaHFoQXY5cTU1RWduVE55ZVVETm12S3VtWnJvb0NWWQpyYk9pdkg4N3NlOE1sYUE1NGYvOUNyaVpFTnI2dmh2bnRseksyOWdsV09SYjJTWFluME9WWU9PVE1QNUVBaEVoCkRuT0d6c01sQW9HQUtrSXJ3Z2Y5dnVubnBTeGJCMU9UeCtUR2pkUEN3RThDUWNxWTBBeUhXZnk2eTBNaTNTSXMKTXBKZmpmbXN3NlRDSHZ1VFUvOXBkL3dYWEZ6ZU03OHBwWU5wcHZBVjQzVEVQNTdHRXZRV3VBSkNFQklvekZhdQpXZWVrRGd6bzBCc3NCMFFOUnRnUS9HdTBnaDRCWjFMdDB4QmJmWHhrMjRMTmJpSFBHTHRQL3pjPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=

最后,加载启用此配置文件

kubectl config use-context kubernetes --kubeconfig=opsuser.kubeconfig

此时,用户已经创建完成,下面开始进行RoleBinding步骤赋予权限。

RoleBinding绑定
创建Role:

~/rbac-test# cat pod-reader.yaml 
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: kube-system
  name: pod-reader
rules:
- apiGroups: [""] # ""代表核心api组
  resources: ["pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

~/rbac-test# cat opsuser-role-bind.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-pods
  namespace: kube-system
subjects:
- kind: User
  name: opsuser   # 目标用户
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader  # 角色信息
  apiGroup: rbac.authorization.k8s.io

kubectl apply -f pod-reader.yaml
kubectl apply -f opsuser-role-bind.yaml

RoleBinding步骤已完成
检验

# 将此配置文件作为当前kubectl配置文件使用
~/rbac-test# mv /root/.kube/config /root/.kube/config.bak
~/rbac-test# cp opsuser.kubeconfig /root/.kube/config

# 查看资源
:~/rbac-test# kubectl get pods 
NAME                                     READY     STATUS             RESTARTS   AGE
appdev-5c4b65bbbb-t4lvr                  1/1       Running            2          44d
deptest13dev-fb79d9957-d55vb             0/1       Pending            0          35d
deptest13test-8687769d58-lzm2r           0/1       Pending            0          41d
deptest14dbtm-ffbd5c56c-ph68l            0/2       Pending            0          41d
deptest14test-7cb7bf6cc-xnrxw            0/1       Pending            0          41d

:~/rbac-test# kubectl get nodes
Error from server (Forbidden): nodes is forbidden: User "opsuser" cannot list nodes at the cluster scope

可以看到,基于生成的用户配置文件,已经可以管理申明的pod资源,无法管理申明以外的资源类型。测试成功

二、程序使用

与用户使用User不同的是,程序的权限赋予是通过ServiceAccount来作为权限载体的,因此,首先要拥有程序/deployment/ServiceAccount等资源,这里以前面文章里没有讲的kube dashboard为例进行说明。

首先我们来看官方最新版本的kube dashboard的yaml文件(服务暴露方式稍作修改成了NodePort):

~/dashboard# cat kubernetes-dashboard.yaml
# ------------------- Dashboard Secret ------------------- #

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-certs
  namespace: kube-system
type: Opaque

---
# ------------------- Dashboard Service Account ------------------- #

apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system

---
# ------------------- Dashboard Role & Role Binding ------------------- #

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: kubernetes-dashboard-minimal
  namespace: kube-system
rules:
  # Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["create"]
  # Allow Dashboard to create 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["create"]
  # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
  verbs: ["get", "update", "delete"]
  # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["kubernetes-dashboard-settings"]
  verbs: ["get", "update"]
  # Allow Dashboard to get metrics from heapster.
- apiGroups: [""]
  resources: ["services"]
  resourceNames: ["heapster"]
  verbs: ["proxy"]
- apiGroups: [""]
  resources: ["services/proxy"]
  resourceNames: ["heapster", "http:heapster:", "https:heapster:"]
  verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: kubernetes-dashboard-minimal
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: kubernetes-dashboard-minimal
subjects:
- kind: ServiceAccount
  name: kubernetes-dashboard
  namespace: kube-system

---
# ------------------- Dashboard Deployment ------------------- #

kind: Deployment
apiVersion: apps/v1beta2
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: kubernetes-dashboard
  template:
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
    spec:
      containers:
      - name: kubernetes-dashboard
        image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.0
        ports:
        - containerPort: 8443
          protocol: TCP
        args:
          - --auto-generate-certificates
          # Uncomment the following line to manually specify Kubernetes API server Host
          # If not specified, Dashboard will attempt to auto discover the API server and connect
          # to it. Uncomment only if the default does not work.
          # - --apiserver-host=http://my-address:port
        volumeMounts:
        - name: kubernetes-dashboard-certs
          mountPath: /certs
          # Create on-disk volume to store exec logs
        - mountPath: /tmp
          name: tmp-volume
        livenessProbe:
          httpGet:
            scheme: HTTPS
            path: /
            port: 8443
          initialDelaySeconds: 30
          timeoutSeconds: 30
      volumes:
      - name: kubernetes-dashboard-certs
        secret:
          secretName: kubernetes-dashboard-certs
      - name: tmp-volume
        emptyDir: {}
      serviceAccountName: kubernetes-dashboard
      # Comment the following tolerations if Dashboard must not be deployed on master
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule

---
# ------------------- Dashboard Service ------------------- #

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system
spec:
  type: NodePort
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 30001
  selector:
    k8s-app: kubernetes-dashboard
:~/dashboard# ls
admin-token.yaml  kubernetes-dashboard.yaml
:~/dashboard# vim kubernetes-dashboard.yaml 
:~/dashboard# cat kubernetes-dashboard.yaml 
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# ------------------- Dashboard Secret ------------------- #

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-certs
  namespace: kube-system
type: Opaque

---
# ------------------- Dashboard Service Account ------------------- #

apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system

---
# ------------------- Dashboard Role & Role Binding ------------------- #

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: kubernetes-dashboard-minimal
  namespace: kube-system
rules:
  # Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["create"]
  # Allow Dashboard to create 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["create"]
  # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
  verbs: ["get", "update", "delete"]
  # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["kubernetes-dashboard-settings"]
  verbs: ["get", "update"]
  # Allow Dashboard to get metrics from heapster.
- apiGroups: [""]
  resources: ["services"]
  resourceNames: ["heapster"]
  verbs: ["proxy"]
- apiGroups: [""]
  resources: ["services/proxy"]
  resourceNames: ["heapster", "http:heapster:", "https:heapster:"]
  verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: kubernetes-dashboard-minimal
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: kubernetes-dashboard-minimal
subjects:
- kind: ServiceAccount
  name: kubernetes-dashboard
  namespace: kube-system

---
# ------------------- Dashboard Deployment ------------------- #

kind: Deployment
apiVersion: apps/v1beta2
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: kubernetes-dashboard
  template:
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
    spec:
      containers:
      - name: kubernetes-dashboard
        image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.0
        ports:
        - containerPort: 8443
          protocol: TCP
        args:
          - --auto-generate-certificates
          # Uncomment the following line to manually specify Kubernetes API server Host
          # If not specified, Dashboard will attempt to auto discover the API server and connect
          # to it. Uncomment only if the default does not work.
          # - --apiserver-host=http://my-address:port
        volumeMounts:
        - name: kubernetes-dashboard-certs
          mountPath: /certs
          # Create on-disk volume to store exec logs
        - mountPath: /tmp
          name: tmp-volume
        livenessProbe:
          httpGet:
            scheme: HTTPS
            path: /
            port: 8443
          initialDelaySeconds: 30
          timeoutSeconds: 30
      volumes:
      - name: kubernetes-dashboard-certs
        secret:
          secretName: kubernetes-dashboard-certs
      - name: tmp-volume
        emptyDir: {}
      serviceAccountName: kubernetes-dashboard
      # Comment the following tolerations if Dashboard must not be deployed on master
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule

---
# ------------------- Dashboard Service ------------------- #

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system
spec:
  type: NodePort
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 30001
  selector:
    k8s-app: kubernetes-dashboard

部署dashboard:

kubectl apply -f kubernetes-dashboard.yaml 

浏览器访问dashboard需要token,或者kube-config文件,这里使用token,在创建好ServiceAccount且和role进行bind绑定之后,会自动创建一个名为${ServiceAccountName}-token-xxx 的Secret,其内包含token,为base64编码,可以使用kubectl describe直接查看:

:~/dashboard# kubectl get secret -o wide -n kube-system | grep kubernetes-dashboard
istio.kubernetes-dashboard                       istio.io/key-and-cert                 3         2d
kubernetes-dashboard-certs                       Opaque                                0         2d
kubernetes-dashboard-key-holder                  Opaque                                2         2d
kubernetes-dashboard-token-t2mmr                 kubernetes.io/service-account-token   3         2d


:~/dashboard# kubectl describe secret -n kube-system kubernetes-dashboard-token-t2mmr
Name:         kubernetes-dashboard-token-t2mmr
Namespace:    kube-system
Labels:       <none>
Annotations:  kubernetes.io/service-account.name=kubernetes-dashboard
              kubernetes.io/service-account.uid=4f237c6c-f7ad-11e8-9859-0050569da8f2

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1025 bytes
namespace:  11 bytes
token:      eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZC10b2tlbi10Mm1tciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjRmMjM3YzZjLWY3YWQtMTFlOC05ODU5LTAwNTA1NjlkYThmMiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTprdWJlcm5ldGVzLWRhc2hib2FyZCJ9.UEJ0MBO9RhSF_fzZHPKezWqkZsWG3atFQQgoPGlyyIDXtQN-ZYlZPEScjunwp4FVgX5uRMpxHGyexJN5e8zYouMTRrGaDaIu7cGj5ICP80iabi8wyMCnJrR5_p0Tmy2PkNZDCyh0MbDCJE6lbOv7Lu7CldivEMtr4BAvxvMmBdmoT0CixQexfw2tioeeoYBwEKgxjL6mMBIGKE0spGZQova7bzTN8f2ZGpNn8jFI_EW9Y7Et5sitw3rCRwxxMSDwUwwCOv26NXPnPVA7cWJeuzPRTS0BHE0euRYojQN7F77NkfwCynx8iWGpM2MEuHIj6coCUcTuCyN5yMD1Zag2zg

使用此token登录dashboard:
k8s(十四)、RBAC权限控制_第2张图片

k8s(十四)、RBAC权限控制_第3张图片

第二张截图可以发现,dashboard无多种资源类型的list权限,这是因为在上面的yaml文件中,定义的role权限是限定的:

# ------------------- Dashboard Role & Role Binding ------------------- #

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: kubernetes-dashboard-minimal
  namespace: kube-system
rules:
  # Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["create"]
  # Allow Dashboard to create 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["create"]
  # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
  verbs: ["get", "update", "delete"]
  # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["kubernetes-dashboard-settings"]
  verbs: ["get", "update"]
  # Allow Dashboard to get metrics from heapster.
- apiGroups: [""]
  resources: ["services"]
  resourceNames: ["heapster"]
  verbs: ["proxy"]
- apiGroups: [""]
  resources: ["services/proxy"]
  resourceNames: ["heapster", "http:heapster:", "https:heapster:"]
  verbs: ["get"]

可以修改这里的Role内部的权限,也可以自行配置更高级的权限,我这里为了方便,直接配置了一个admin的ServiceAccount:

~/dashboard# cat admin-token.yaml

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: admin
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
roleRef:
  kind: ClusterRole  # ClusterRole拥有集群级别权限,于此同时绑定时不能再使用RoleBinding而应该使用ClusterRoleBinding
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
  name: admin
  namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin
  namespace: kube-system
  labels:
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile

创建:

~/dashboard# kubectl apply -f admin-token.yaml

查看token:

:~/dashboard# kubectl get secret -n kube-system | grep admin
admin-token-b9r26                                kubernetes.io/service-account-token   3         1d

~/dashboard# kubectl describe secret -n kube-system admin-token-b9r26
Name:         admin-token-b9r26
Namespace:    kube-system
Labels:       <none>
Annotations:  kubernetes.io/service-account.name=admin
              kubernetes.io/service-account.uid=d471a78c-f833-11e8-9859-0050569da8f2

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1025 bytes
namespace:  11 bytes
token:      eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi10b2tlbi1iOXIyNiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImQ0NzFhNzhjLWY4MzMtMTFlOC05ODU5LTAwNTA1NjlkYThmMiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTphZG1pbiJ9.euwxJkmtt7mjbpzHdMzJWmxO0swuVRjYFGkEwzX1E6caXrUj1XXrSQO4J3mttJvMOVQaGEztInI-cKMiTDzLYHE_85VISHbZTUA8dcSFDIuGOt4SRI_XoA11pIlUAmH4b_4kxgaA3DA5TdUX6O2mo93QEvLOOngBkLO55Z9y980H_J5JiBgbndnycOGXVIW-gEgEjBewtiH1ZCiha-lwUlTvSNJkLrTPlm5Rjoao8lONn4vcD1sgzrSrW8VMxxclw8Cu3C79zyujHo0F_YuwHteIlBwOPSTaiokbuyQr-IS2UTpwUxlzf__wXgidc_SXqTC9vecM7hcRVhEi_d_hnw

dashboard退出之前的账号,使用admin-token重新登录,可以发现已经拥有全部权限:
k8s(十四)、RBAC权限控制_第4张图片

总结

k8s角色授权使用的流程有多个环节多种资源类型搭配完成,权限粒度明确、用户与进程分工有序,理解了顶部的流程图,相信你将不再为RBAC疑惑。

你可能感兴趣的:(kubernetes,kubernetes那些事儿)