Kubernetes RBAC

  在Kubernetes1.6版本中新增角色訪問控制機制(Role-Based Access,RBAC)讓集羣管理員能夠針對特定使用者或服務帳號的角色,進行更精確的資源訪問控制。在RBAC中,權限與角色相關聯,用戶經過成爲適當角色的成員而獲得這些角色的權限。這就極大地簡化了權限的管理。在一個組織中,角色是爲了完成各類工做而創造,用戶則依據它的責任和資格來被指派相應的角色,用戶能夠很容易地從一個角色被指派到另外一個角色。node

 

須要理解 RBAC 一些基礎的概念和思路,RBAC 是讓用戶可以訪問 Kubernetes API 資源的受權方式。linux

a51223d13121de324b96f95079739b13

在 RBAC 中定義了兩個對象,用於描述在用戶和資源之間的鏈接權限。json

角色

角色是一系列的權限的集合,例如一個角色能夠包含讀取 Pod 的權限和列出 Pod 的權限, ClusterRole 跟 Role 相似,可是能夠在集羣中處處使用( Role 是 namespace 一級的)。api

角色綁定

RoleBinding 把角色映射到用戶,從而讓這些用戶繼承角色在 namespace 中的權限。ClusterRoleBinding 讓用戶繼承 ClusterRole 在整個集羣中的權限。app

57bdf8ca7815303ad055ddfdb208836f

 

service account原理

k8s裏面有兩種用戶,一種是User,一種就是service account,User給人用的,service account給進程用的,讓進程有相關的權限。ide

如dasboard就是一個進程,咱們就能夠建立一個service account給它,讓它去訪問k8s。測試

 

示例1: dashborad yamlspa

# ------------------- 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/v1
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:
      nodeSelector:
        node-role.kubernetes.io/master: ""
      containers:
      - name: kubernetes-dashboard
        image: registry.cn-hangzhou.aliyuncs.com/k8sth/kubernetes-dashboard-amd64:v1.8.3
        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: 30000
  selector:
    k8s-app: kubernetes-dashboard

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system


# 獲取TOken
# kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
View Code

 

示例2: 建立devuser的用戶,並賦予特定namespace下的pod只讀權限3d

第一步,安裝cfsslcode

wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
chmod +x cfssl_linux-amd64
mv cfssl_linux-amd64 /bin/cfssl

wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
chmod +x cfssljson_linux-amd64
mv cfssljson_linux-amd64 /bin/cfssljson

wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl-certinfo_linux-amd64
mv cfssl-certinfo_linux-amd64 /bin/cfssl-certinfo
View Code

 

第二步,簽發客戶端證書

建立ca-config.json文件

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

建立devuser-csr.json文件

cat > devuser-csr.json <<EOF
{
  "CN": "devuser",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF
View Code

 

第三步,生成devuser的證書

$ cfssl gencert -ca=ca.crt -ca-key=ca.key -config=ca-config.json -profile=kubernetes devuser-csr.json | cfssljson -bare devuser
View Code

就會生成3個文件:devuser.csr devuser-key.pem devuser.pem

 

第四步,生成config文件

ubeadm已經生成了admin.conf,咱們能夠直接利用這個文件,省的本身再去配置集羣參數

$ cp /etc/kubernetes/admin.conf devuser.kubeconfig

設置客戶端認證參數:

kubectl config set-credentials devuser \
--client-certificate=/etc/kubernetes/pki/devuser.pem \
--client-key=/etc/kubernetes/pki/devuser-key.pem \
--embed-certs=true \
--kubeconfig=devuser.kubeconfig

設置上下文參數:

kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=devuser \
--namespace=kube-system \
--kubeconfig=devuser.kubeconfig

設置莫認上下文:

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

以上執行一個步驟就能夠看一下 devuser.kubeconfig的變化。裏面最主要的三個東西

  • cluster: 集羣信息,包含集羣地址與公鑰
  • user: 用戶信息,客戶端證書與私鑰,正真的信息是從證書裏讀取出來的,人能看到的只是給人看的。
  • context: 維護一個三元組,namespace cluster 與 user

 

第五步,建立角色

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: kube-system
  name: pod-reader
rules:
  - apiGroups: [""] # 表示核心API Group
    resources: ["pods"]  # 可以訪問的資源對象
    verbs: ["get", "watch", "list"]  # 可以執行的操做

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: kube-system
subjects:
  - kind: User
    name: devuser
    namespace: kube-system
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

 

第六步,使用新的config文件

$ rm .kube/config && cp devuser.kubeconfig .kube/config

 

第七步,測試效果

[root@node01 ~]# kubectl get pod
NAME                                   READY     STATUS    RESTARTS   AGE
coredns-777d78ff6f-rrpx8               1/1       Running   3          8d
coredns-777d78ff6f-tql47               1/1       Running   3          8d
etcd-node01                            1/1       Running   3          8d
kube-apiserver-node01                  1/1       Running   3          8d
kube-controller-manager-node01         1/1       Running   3          8d
kube-flannel-ds-rxrp5                  1/1       Running   3          8d
kube-proxy-r6bd2                       1/1       Running   3          8d
kube-scheduler-node01                  1/1       Running   2          8d
kubernetes-dashboard-d4866d978-kpz4m   1/1       Running   0          10h
[root@node01 ~]# kubectl get service
No resources found.
Error from server (Forbidden): services is forbidden: User "devuser" cannot list services in the namespace "kube-system"

 

參考文檔:https://www.jianshu.com/p/61e8297f9838

相關文章
相關標籤/搜索