zoukankan      html  css  js  c++  java
  • 11 . KubernetesRBAC认证及ServiceAccount、Dashboard

    简介

    简介摘自Kubernetes权威指南

    RBAC(Role-Based Access Control,基于角色的访问控制)在Kubernetes的1.5版本中引入,在1.6版本时升级为Beta版本,在1.8版本时升级为GA。作为kubeadm安装方式的默认选项,足见其重要程度。相对于其他访问控制方式,新的RBAC具有如下优势。

    ◎ 对集群中的资源和非资源权限均有完整的覆盖。
    ◎ 整个RBAC完全由几个API对象完成,同其他API对象一样,可以用kubectl或API进行操作”
    ◎ 可以在运行时调整,无须重新启动API Server
    
    # 要想使用RBAC授权模式,需要在API Server的启动参数加上--authorization-mode=RBAC. 
    
    Kubernetes RBAC角色权限控制

    RBAC是基于角色的访问控制 (Role-Based Access Control) 在RBAC中,权限与角色相关联。Kubernetes 基于角色的访问控制使用rbac.authorization.k8s.io API组来实现权限控制,RBAC允许管理员通过Kubernetes API动态的配置权限策略。如果需要开启RBAC授权需要在apiserver组件中指定--authorization-mode=Node,RBAC

    ServiceAccount

    什么是service account? 顾名思义,相对于user account(比如:kubectl访问APIServer时用的就是user account),service account就是Pod中的Process用于访问Kubernetes API的account,它为Pod中的Process提供了一种身份标识。相比于user account的全局性权限,service account更适合一些轻量级的task,更聚焦于授权给某些特定Pod中的Process所使用。

    Dashboard

    Dashboard 是基于网页的 Kubernetes 用户界面。您可以使用 Dashboard 将容器应用部署到 Kubernetes 集群中,也可以对容器应用排错,还能管理集群本身及其附属资源。您可以使用 Dashboard 获取运行在集群中的应用的概览信息,也可以创建或者修改 Kubernetes 资源(如 Deployment,Job,DaemonSet 等等)。例如,您可以对 Deployment 实现弹性伸缩、发起滚动升级、重启 Pod 或者使用向导创建新的应用。

    Kubernetes RBAC

    在Kubernetes中所有的API对象都保存在ETCD里,可是,对这些API对象的操作,却一定是通过访问kube-apiserver实现的。我们需要APIServer来帮助我们授权工作,而在Kubernetes项目中,负责完成授权(Authorization)的工作机制就是RBAC: 基于角色的访问控制 (Role-Based Access Control)

    RBAC是基于角色的访问控制 (Role-Based Access Control) 在RBAC中,权限与角色相关联。Kubernetes 基于角色的访问控制使用rbac.authorization.k8s.io API组来实现权限控制,RBAC允许管理员通过Kubernetes API动态的配置权限策略。如果需要开启RBAC授权需要在apiserver组件中指定--authorization-mode=Node,RBAC

    修改完毕后需要重启apiserver,在我提供的二进制安装已经将下面参数添加进去。如果使用的是kubeadm安装在1.6版本默认已经启用了RBAC

    RBAC API对象

    Kubernetes有一个很基本的特性就是它的所有资源都是模型化的API对象,允许执行CRUD(Create、Read、Update、Delete)操作。资源如下

    # Pods
    # ConfigMaps
    # Deployments
    # Nodes
    # Secrets
    # Namespaces
    
    # 资源对象可能存在的操作有如下
    # create
    # get
    # delete
    # list
    # update
    # edit
    # watch
    # exec
    
    # 这些资源和API Group进行关联,比如Pods属于Core API Group,而Deployment属于apps API Group,
    # 要在kubernetes中进行RBAC授权
    
    RBAC概念

    RBAC引入了4个新的顶级资源对象: Role, ClusterRole,RoleBinding和ClusterRoleBinding. 同其他API资源对象一样,用户可以使用kubectl 或者API调用等方式操作这些资源对象.

    我们首先要明确下面三个概念

    # Role: 角色,它定义了一组规则,定义了一组对Kubernetes API对象的操作权限
    
    # Subject: 被作用者,既可以是”人”,也可以是机器,
    # 当然也可以是我们Kubernetes中定义的用户(ServiceAccount主要负责kubernetes内置用户)
    
    # RoleBinding: 定义了”被作用者”和”角色”的绑定关系
    

    k8s1

    角色(Role)

    一个角色就是一组权限的集合,这里的权限都是许可形式的,不存在拒绝的规则,在一个命名空间中,可以用角色来定义一个角色,如果是集群级别的,就需要使用ClusterRole了.

    角色只能对命名空间内的资源进行授权,在下面例子中定义的角色具备读取Pod的权限:

    实际上, Role 本身就是一个kubernetes的API对象,定义文件如下:

    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      namespace: test
      name: test-role
    rules:
    - apiGroups: [""]  # ""空字符串,表示核心API群
      resources: ["pods"]
      verbs: ["get", "watch", "list"]
    

    文件解释

    # 首先,Role对象指定了它能产生作用的Namespace(mynamespace)。# Namespace是kubernetes项目中的一个逻辑管理单位。不同Namespace的API对象,
    # 在通过kubectl命令进行操作的时候,是互相隔离的
    # namespace并不会提供任何实际的隔离或者多租户能力,如果没有设置namespace默认则是default
    
    # apiGroups: 支持的API组列表,例如"“apiVersion: batch/v1”“apiVersion: extensions:v1beta1”“apiVersion: apps/v1beta1”等”
    
    # resources: 支持的资源对象列表,例如Pods,deployments,jobs等
    
    # verbs: 对资源对象的操作方法列表,例如get,watch,list,delete,replace,patch等
    
    # rules字段定义它的是权限规则,这条规则的含义就是允许"被作用者" ,对namespace下面Pod(resources中定义)有哪些权限;
    
    # 用户的权限对应的API资源对象已经创建了,但是还没有绑定,也就是只有一个规则没有规定哪些用户有这个权限
    
    集群角色(ClusterRole)

    对于某一个role想要作用的namespace的时候,就必须需要使用ClusterRole和ClusterRoleBinding两个组合。这两个API 对象的用法跟Role和Rolebinding完全一样

    集群角色除了具有和角色一致的命名空间内资源的管理能力,因其集群级别的范围,还可以用于以下特殊元素的授权.

    # 集群范围的资源,例如Node.
    # 非资源型的路径, 例如"/ealthz"
    # 包含全部命名空间的资源,例如Pods(用于kubectl get pods  --all-namespaces这样的操作授权)
    
    # 下面的集群角色可以让用户有权访问任意一个或所有命名空间的secrets(视其绑定方式而定)
    

    Example

    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      # ClusterRole 不受限于命名空间,所以无需设置namespace的名称
    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get", "watch", "list"]
    
    ---
    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: example-clusterrolebinding
    subjects:
    - kind: User
      name: example-user
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: ClusterRole
      name: example-clusterrole
      apiGroup: rbac.authorization.k8s.io
    

    在上面的例子中,ClusterRole和ClusterRoleBinding的组合,意味着名叫example-user的用户,拥有对所有namespace里的Pod进行Get、Watch、List操作的权限。

    类似的,Role对象的rules字段也可以进一步细化,可以只针对某一个具体权限对象进行设置

    rules:
    - apiGroups: [""]
      resources: ["configmaps"]
      resourceNames: ["my-config"]
      verbs: ["get"]
    

    上面的例子表示,这条规则的”被作用者”,只对my-config的configmap对象有权限进行get操作

    前面也说过,在Kubernetes中已经内置了很多个位系统保留的ClusterRole,它们的名字都是以system:开头。一般来说,这些内置的ClusterRole,是绑定给Kubernetes系统组件对应的ServiceAccount使用

    #我们可以通过下面的命令获取到
    [root@master ~]# kubectl get clusterroles
    

    此外,kubernetes还提供了预先定义好的ClusterRole来提供用户直接使用

    cluster-admin
    admin
    edit
    view
    
    # 我们可以通过下面的命令查看clusterrole的权限
    [root@master ~]# kubectl describe clusterrole cluster-admin -n kube-system
    Name:         cluster-admin
    Labels:       kubernetes.io/bootstrapping=rbac-defaults
    Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
    PolicyRule:
      Resources  Non-Resource URLs  Resource Names  Verbs
      ---------  -----------------  --------------  -----
      *.*        []                 []              [*]
                 [*]                []              [*]
    
    (角色绑定)Rolebinding和集群角色绑定(ClusterRoleBinding)

    角色绑定或集群角色绑定用来把一个角色绑定到一个目标上,绑定目标可以是User(用户)、Group(组)或者Service Account。使用RoleBinding为某个命名空间授权,使用ClusterRoleBinding为集群范围内授权。
    RoleBinding可以引用Role进行授权。下面的例子中的RoleBinding将在default命名空间中把pod-reader角色授予用户jane,这一操作可以让jane读取default命名空间中的Pod:

    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: example-rolebinding
      namespace: default
    subjects:
    - kind: User
      name: youmen
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: example-role
      apiGroup: rbac.authorization.k8s.io
    

    在Rolebinding中定义了一个subject字段,即”被作用者”。它的类型是User,即Kubernetes里的用户,名称为youmen

    在kubernetes里的User,也就是用户,只是一个授权系统里的逻辑概念。它需要通过外部认证服务,比如Keystone,来提供。或者直接给APIServer指定一个用户名、密码文件。那么kubernetes的授权系统就能够从这个文件里找到对象的用户.

    Rolebinding对象通过roleRef字段可以直接通过名字,来引用前面定义的Role对象(example-role),从而定义了”被作用者(Subject)”和”角色(Role)”之间的绑定关系

    Role和RoleBinding 他们的权限限制规则仅仅在他们自己的namespace内有效,roleRef也只能引用当前namespace里的Role对象

    “RoleBinding也可以引用ClusterRole,对属于同一命名空间内ClusterRole定义的资源主体进行授权。一种常见的做法是集群管理员为集群范围预先定义好一组ClusterRole,然后在多个命名空间中重复使用这些ClusterRole。
    例如,在下面的例子中,虽然secret-reader是一个集群角色,但是因为使用了RoleBinding,所以dave只能读取development命名空间中的secret

    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: read-secrets
      namespace: development
      # 集群角色中,只有development命名空间的权限才能赋予davesubjects
    subjects:
    - kind: User
      name: dave
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: ClusterRole
      name: secret-reader
      apiGroup: rbac.authorization.k8s.io
    
    对资源的引用方式

    多数资源可以用其名称的字符串来表达,也就是Endpoint中的URL相对路径,例如pods。然而,某些Kubernetes API包含下级资源,例如Pod的日志(logs)。Pod日志的Endpoint是GET/ api/v1/namespaces/{namespace}/pods/{name}/log。

    在这个例子中,Pod是一个命名空间内的资源,log就是一个下级资源。要在一个RBAC角色中体现,就需要用斜线“/”来分隔资源和下级资源。若想授权让某个主体同时能够读取Pod和Pod log,则可以配置resources为一个数组

    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      namespace: test
      name: test-role
    rules:
    - apiGroups: [""]  # ""空字符串,表示核心API群
      resources: ["pods","pods/log"]
      verbs: ["get", "watch", "list"]
    

    资源还可以通过名称(ResourceName)进行引用,在指定ResourceName后,使用get,delete,update和patch动词的请求,就会被限制在这个资源实例范围内,例如,下面,下面的声明让一个主体只能对一个ConFigmap进行get和update操作

    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      namespace: test
      name: test-role
    rules:
    - apiGroups: [""]  # ""空字符串,表示核心API群
      resources: ["configmap]
      verbs: ["get", "watch", "list"]
    

    可想而知,resourceName这种用法对list,watch,create或deletecollection的操作是无效的,这是因为必须要通过URL进行授权,而资源名称在list,watch,create或deletecollection请求中只是请求Body数据的一部分.

    常见角色实例

    我们先创建一个角色

    [root@master serviceaccount]# cat read-pods.yaml 
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: read-pods
      namespace: test
    subjects:
    - kind: User
      name: youmen
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: pods-reader
      apiGroup: rbac.authorization.k8s.io
    [root@master serviceaccount]# cat pods-reader.yaml 
    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      namespace: test
      name: pods-reader
    rules:
    - apiGroups: [""]
      resources: ["pods","pods/log"]
      verbs: ["get","list","watch"]
        
    [root@master serviceaccount]# kubectl get roles -n test
    NAME          CREATED AT
    pods-reader   2020-07-04T09:21:50Z
    

    允许读取核心API组中的Pod资源

    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get","list","watch"]
    

    允许读写extensions和apps两个API组中的deployment资源

    rules:
    - apiGroups: ["extensions","apps"]
      resources: ["deployments"]
      verbs: ["get","list","watch","create","update","pathch","delete"]
    

    允许读取Pods及读写Jobs

    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get","list","watch"] 
      
    - apiGroups: ["batch","extensions"]
      resources: ["jobs"]
     verbs:  ["get","list","watch","create","update","pathch","delete"]
    

    允许读取一个名为my-config的ConfigMap(必须绑定到一个RoleBinding来限制到一个Namespace下的ConfigMap)

    rules:
    - apiGroups: [""]
      resources: ["configmaps"]
      resourceNames: ["my-config"]
      verbs: ["get"]
    
    常用角色绑定示例

    注意,下面例子只包含subjects部分内容

    用户名alice@example.com

    subjects:
    - kind: User
      name: "alice@example.com"
      apiGroup: rbac.authorization.k8s.io
    

    组名frontend-admins

    subjects:
    - kind: Group
      name: "frontend-admins"
      apiGroup: rbac.authorization.k8s.io
    

    kube-system命名空间中的默认Service Account

    subjects:
    - kind: ServiceAccount
      name: default
      namespace: kube-system
    

    所有Service Account

    subjects:
    - kind: Group
      name: system:serviceaccounts
      apiGroup: rbac.authorization.k8s.io
    

    所有认证用户和未认证用户

    # 认证用户
    subjects:
    - kind: Group
      name: system:authenticated
      apiGroup: rbac.authorization.k8s.io
      
      
    # 未认证用户
    subjects:
    - kind: Group
      name: system:unauthenticated
      apiGroup: rbac.authorization.k8s.io
    

    ServiceAccount

    ServiceAccount主要负责kubernetes内置用户,下面简单定义一个ServiceAccount

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      namespace: mynamespace
      name: example-sa
    

    我们定义了一个ServerAccount对象,只需要name以及namespace最基础字段就可以,然后通过编写rolebinding的yaml文件,来为这个ServiceAccount分配权限

    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: example-rolebinding
      namespace: mynamespace
    subjects:
    - kind: ServiceAccount
      name: example-sa
      namespace: mynamespace
    roleRef:
      kind: Role
      name: example-role
      apiGroup: rbac.authorization.k8s.io
    

    在Rolebinding对象里,subject字段的类型(kind),不在是一个User,而是一个名叫example-sa的ServerAccount。而roleRef引用的Role对象,依然名叫example-role。也就是我们上面定义的;

    Example

    [root@master rbac]# cat namespace.yaml 
    ---
    apiVersion: v1
    kind: Namespace
    metadata:
      name: test
      labels:
        name: test
        
    
    [root@master rbac]# cat pod-sa.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      namespace: test 
      name: test
    spec:
      containers:
      - name: nginx 
        image: daocloud.io/library/nginx
      serviceAccountName: test 
    

    APIServer是整个访问请求进入的网关接口,认证用于实现身份识别,授权用于权限检查.
    K8s有两类账号

    # 一种是用户账号user,一般是现实中人使用账号   
    # 第二种是service账号,服务账号,Pod运行在K8s集群上,想访问K8s集群APIServer里面要用到的认证信息,账号密码等.  
    API   
    Request path   
    http://localhost:6443/apis/apps/v1/namespaces/defaults/myapp-deplyoy/   
        
    HTTP requests verb:   
     get,post,put,delete   
        
    API requets verb:   
     get,list,create,update,patch,watch,proxy,redirect,delete,deletecollection   
        
    Resource:   
     Subresource:   
     Namespace   
     API group   
    
    创建Serviceaccount

    快速创建一个yaml框架

    kubectl create serviceaccount mysa -o yaml --dry-run > serviceaccount.yaml   
        
    kubectl get pods nginx-deployment-5dcb7cf7db-mjlsq  -o yaml --export   
    

    创建ServiceAccount

    kubectl create serviceaccount admin   
        
    kubectl get sa   
    NAME      SECRETS   AGE   
    admin     1         4s   
    default   1         4d8h   
    mysa      1         3m45s   
        
    # 这些认证不一定等于授权   
    kubectl get secret   
    NAME                  TYPE                                  DATA   AGE   
    admin-token-9sxbn     kubernetes.io/service-account-token   3      35s   
    default-token-kr5s2   kubernetes.io/service-account-token   3      4d8h   
    mysa-token-rg974      kubernetes.io/service-account-token   3      4m16s   
        
    cat pod-demo1.yaml   
    apiVersion: v1   
    kind: Pod   
    metadata:   
     name: pod-sa-demo   
     namespace: default   
     labels:   
     app: myapp   
     tier: frontend   
     annotations:   
     youmen.com/create-by: "youmen admin"   
    spec:   
     containers:   
     - name: myapp   
     image: ikubernetes/myapp:v1   
     ports:   
     - name: http   
     containerPort: 80   
    kubectl describe pod pod-sa-demo |grep token   
     /var/run/secrets/kubernetes.io/serviceaccount from admin-token-9sxbn (ro)   
     admin-token-9sxbn:   
     SecretName:  admin-token-9sxbn   
    

    Serviceaccount认证

    我们正常敲kubectl get pods时候有哪些认证

    kubectl config view   
    apiVersion: v1   
    clusters:  # 集群列表   
    - cluster:   
     certificate-authority-data: DATA+OMITTED   
     server: https://192.168.78.7:6443   
     name: kubernetes   
    contexts:  # 上下文列表   
    - context:   
     cluster: kubernetes   
     user: kubernetes-admin   
     name: kubernetes-admin@kubernetes   
    current-context: kubernetes-admin@kubernetes   
    kind: Config   
    preferences: {}   
    users:  # 用户列表   
    - name: kubernetes-admin   
     user:   
     client-certificate-data: REDACTED   
     client-key-data: REDACTED   
    

    创建自己的一个用户

    cd /etc/kubernetes/pki/   
    # 创建私钥   
    (umask 077;openssl genrsa -out youmen.key 2048)   
    openssl  req -new -key youmen.key -out youmen.csr -subj "/CN=youmen"   
    openssl x509 -req -in youmen.csr -CA ./ca.crt    
    -CAkey ./ca.key -CAcreateserial -out youmen.crt -days 365   
        
    openssl x509 -in youmen.crt -text -noout   
    Certificate:   
     Data:   
     Version: 1 (0x0)   
     Serial Number:   
     e6:1c:db:0b:a5:ca:01:db   
     Signature Algorithm: sha256WithRSAEncryption   
     Issuer: CN=kubernetes   
     Validity   
     Not Before: Dec 25 15:35:54 2019 GMT   
     Not After : Dec 24 15:35:54 2020 GMT   
     Subject: CN=youmen   
     Subject Public Key Info:   
     Public Key Algorithm: rsaEncryption   
     Public-Key: (2048 bit)   
        
    kubectl config set-credentials youmen --client-certificate=./youmen.crt --client-key=./youmen.key --embed-certs=true   
        
    kubectl config view   
    apiVersion: v1   
    clusters:   
    - cluster:   
     certificate-authority-data: DATA+OMITTED   
     server: https://192.168.78.7:6443   
     name: kubernetes   
    contexts:   
    - context:   
     cluster: kubernetes   
     user: kubernetes-admin   
     name: kubernetes-admin@kubernetes   
    current-context: kubernetes-admin@kubernetes   
    kind: Config   
    preferences: {}   
    users:   
    - name: kubernetes-admin   
     user:   
     client-certificate-data: REDACTED   
     client-key-data: REDACTED   
    - name: youmen   
     user:   
     client-certificate-data: REDACTED   
     client-key-data: REDACTED   
    

    创建一个上下文可以访问集群

    kubectl config set-context youmen@kubernetes --cluster=kubernetes --user=youmen   
    Context "youmen@kubernetes" created.   
    [root@master pki]# kubectl config view   
    apiVersion: v1   
    clusters:   
    - cluster:   
     certificate-authority-data: DATA+OMITTED   
     server: https://192.168.78.7:6443   
     name: kubernetes   
    contexts:   
    - context:   
     cluster: kubernetes   
     user: kubernetes-admin   
     name: kubernetes-admin@kubernetes   
    - context:   
     cluster: kubernetes   
     user: youmen   
     name: youmen@kubernetes   
    current-context: kubernetes-admin@kubernetes   
    kind: Config   
    preferences: {}   
    users:   
    - name: kubernetes-admin   
     user:   
     client-certificate-data: REDACTED   
     client-key-data: REDACTED   
    - name: youmen   
     user:   
     client-certificate-data: REDACTED   
     client-key-data: REDACTED   
    

    我们切换到youmen用户尝试一下

    kubectl config use-context youmen@kubernetes   
    Switched to context "youmen@kubernetes".   
        
    kubectl get pods   
    Error from server (Forbidden): pods is forbidden: User "youmen" cannot list resource "pods" in API group "" in the namespace "default"   
    

    自己创建一个cluster集群

    kubectl config set-cluster mycluster    
    --kubeconfig=/tmp/test.conf    
    --server="https://172.19.0.41:6443"    
    --certificate-authority=/etc/kubernetes/pki/ca.crt    
    --embed-certs=true   
        
     kubectl config view --kubeconfig=/tmp/test.conf   
    apiVersion: v1   
    clusters:   
    - cluster:   
     certificate-authority-data: DATA+OMITTED   
     server: https://172.19.0.41:6443   
     name: mycluster   
    contexts: null   
    current-context: ""   
    kind: Config   
    preferences: {}   
    users: null   
    

    RBAC授权
    之前我们切换用户get pods时候发现报错,还未赋予权限
    k8s授权请求是http的请求
    /apis/[GROUP]/[VERSION]/namespace/[NAMESPACE_NAME]/[KIND]/[OBJECT_ID]
    k8s授权方式分为:
    serviceccount和自己签证ca证书的账号,及签证ca的用户组(group)上(授权给这个组的权限)

    role:

    # 1. 允许的操作,如get,list等   
    # 2. 允许操作的对象,如pod,svc等   
    

    rolebinding:

    # 将那个用户绑定到那个role或clusterrrole上   
    # clusterrole: (集群角色)   
    # clusterolebinding:(绑定到集群)  
    

    如果使用rolebinding绑定到clusterrole上,表示绑定的用户只能用于当前namespace的权限

    kubectl create role pods-reader --verb=get,list,watch --resource=pods  --dry-run -o yaml>role-demo.yaml   
        
    cat role-demo.yaml   
    apiVersion: rbac.authorization.k8s.io/v1   
    kind: Role   
    metadata:   
     creationTimestamp: null   
     name: pods-reader   
     namespace: default   
    rules:   
    - apiGroups:   
     - ""   
     resources:   
     - pods   
     verbs:   
     - get   
     - list   
     - watch   
        
    kubectl get role   
    NAME          AGE   
    pods-reader   48s   
        
    kubectl describe role pods-reader   
    Name:         pods-reader   
    Labels:       <none>   
    Annotations:  kubectl.kubernetes.io/last-applied-configuration:   
     {"apiVersion":"rbac.authorization.k8s.io/v1","kind":   
    "Role","metadata":{"annotations":{},"creationTimestamp":null,"name":"pods-reader","nam...   
    PolicyRule:   
     Resources  Non-Resource URLs  Resource Names  Verbs   
     ---------  -----------------  --------------  -----   
     pods       []                 []              [get list watch]   
        
    # 绑定rolebinding   
    kubectl create rolebinding youmen-read-pods --role=pods-reader --user=youmen   
    kubectl create rolebinding youmen-read-pods --role=pods-reader --user=youmen --dry-run    
    -o yaml > rolebind-demo.yaml   
    

    查看并验证绑定授权用户

    kubectl describe rolebinding youmen-read-pods   
    Name:         youmen-read-pods   
    Labels:       <none>   
    Annotations:  <none>   
    Role:   
     Kind:  Role   
     Name:  pods-reader   
    Subjects:   
     Kind  Name    Namespace   
     ----  ----    ---------   
     User  youmen   
        
    kubectl config use-context youmen@kubernetes   
    Switched to context "youmen@kubernetes".   
    [root@master pki]# kubectl get pods   
    NAME      READY   STATUS    RESTARTS   AGE   
    myapp-0   1/1     Running   0          16h   
    myapp-1   1/1     Running   0          16h   
    myapp-2   1/1     Running   0          16h   
    myapp-3   1/1     Running   0          16h   
        
    # 但是如果换了一个明成空间就会失效   
    kubectl get pods -n kube-system   
    Error from server (Forbidden): pods is forbidden: User "youmen" cannot list resource "pods" in API group "" in the namespace "kube-system"   
    

    创建clusterrole,可以访问全部的namespace

        
    kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods -o yaml --dry-run    
    > clusterrole-demo.yaml   
     useradd k8s   
     cp -rp .kube/ /home/k8s/   
     chown -R k8s:k8s /home/k8s/   
    su - k8s   
    kubectl config view   
    apiVersion: v1   
    clusters:   
    - cluster:   
     certificate-authority-data: DATA+OMITTED   
     server: https://172.19.0.26:6443   
     name: kubernetes   
    contexts:   
    - context:   
     cluster: kubernetes   
     user: kubernetes-admin   
     name: kubernetes-admin@kubernetes   
    - context:   
     cluster: kubernetes   
     user: youmen   
     name: youmen@kubernetes   
    current-context: youmen@kubernetes   
    kind: Config   
    preferences: {}   
    users:   
    - name: kubernetes-admin   
     user:   
     client-certificate-data: REDACTED   
     client-key-data: REDACTED   
    - name: youmen   
     user:   
     client-certificate-data: REDACTED   
     client-key-data: REDACTED   
    
    cat cluterrole-demo.yaml   
    apiVersion: rbac.authorization.k8s.io/v1   
    kind: ClusterRole   
    metadata:   
     name: cluster-reader   
    rules:   
    - apiGroups:   
     - ""   
     resources:   
     - pods   
     verbs:   
     - get   
     - list   
     - watch   
        
    kubectl apply -f cluterrole-demo.yaml   
        
    # 我们将之前的role删掉,然后会发现立马就没权限查看Pod了   
    kubectl delete rolebinding youmen-read-pods   
    kubectl get pods   
    Error from server (Forbidden): pods is forbidden: User "youmen" cannot list resource "pods" in API group "" in the namespace "default"   
    # 接下来我们使用clusterrolebinding更大的权限**   
    kubectl create clusterrolebinding youmen-read-all-pods --clusterrole=cluster-reader --user=youmen   
    kubectl create clusterrolebinding youmen-read-all-pods --clusterrole=cluster-reader --user=youmen --dry-run -o yaml > clusterrolebinding-demo.yaml   
    vim clusterrolebinding-demo.yaml   
    apiVersion: rbac.authorization.k8s.io/v1beta1   
    kind: ClusterRoleBinding   
    metadata:   
     creationTimestamp: null   
     name: youmen-read-all-pods   
    roleRef:   
     apiGroup: rbac.authorization.k8s.io   
     kind: ClusterRole   
     name: cluster-reader   
    subjects:   
    - apiGroup: rbac.authorization.k8s.io   
     kind: User   
     name: youmen   
        
    kubectl get clusterrolebinding |grep youmen   
    youmen-read-all-pods                                   2m18s   
    kubectl describe clusterrolebinding youmen-read-all-pods   
    Name:         youmen-read-all-pods   
    Labels:       <none>   
    Annotations:  <none>   
    Role:   
     Kind:  ClusterRole   
     Name:  cluster-reader   
    Subjects:   
     Kind  Name    Namespace   
     ----  ----    ---------   
     User  youmen   
    

    验证clusterrolebinding

    kubectl get pods -n kube-system   
    NAME                             READY   STATUS    RESTARTS   AGE   
    coredns-6955765f44-5jlbk         1/1     Running   1          7d17h   
    coredns-6955765f44-xnr7f         1/1     Running   1          7d17h   
    etcd-master                      1/1     Running   1          7d17h   
    kube-apiserver-master            1/1     Running   1          7d17h   
        
    kubectl delete clusterrolebinding youmen-read-all-pods   
    # 我们将它删除,在创建一个新的clusterrolebinding   
    kubectl create rolebinding youmen-read-pods    
    --clusterrole=cluster-reader    
    --user=youmen --dry-run -o yaml > rolebinding-clusterrole.demo.yaml   
        
    cat rolebinding-clusterrole.demo.yaml   
    apiVersion: rbac.authorization.k8s.io/v1   
    kind: RoleBinding   
    metadata:   
     creationTimestamp: null   
     name: youmen-read-pods   
     namespace: default   
    roleRef:   
     apiGroup: rbac.authorization.k8s.io   
     kind: ClusterRole   
     name: cluster-reader   
    subjects:   
    - apiGroup: rbac.authorization.k8s.io   
     kind: User   
     name: youmen   
    kubectl apply -f rolebinding-clusterrole.demo.yaml   
        
    kubectl describe rolebinding youmen-read-pods   
    Name:         youmen-read-pods   
    Labels:       <none>   
    Annotations:  kubectl.kubernetes.io/last-applied-configuration:   
     {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding",   
    "metadata":{"annotations":{},"creationTimestamp":null,"name":"youmen-rea...   
    Role:   
     Kind:  ClusterRole   
     Name:  cluster-reader   
    Subjects:   
     Kind  Name    Namespace   
     ----  ----    ---------   
     User  youmen   
        
    kubectl get pods   
    NAME      READY   STATUS    RESTARTS   AGE   
    myapp-0   1/1     Running   0          17h   
    myapp-1   1/1     Running   0          17h   
    myapp-2   1/1     Running   0          17h   
    myapp-3   1/1     Running   0          17h   
    # 我们可以发现服务被降级了   
    [k8s@master ~]$ kubectl get pods -n kube-system   
    Error from server (Forbidden): pods is forbidden: User "youmen" cannot list resource "pods" in API group "" in the namespace "kube-system"   
    

    flannel控制

    kubectl get pods -n kube-system kube-flannel-ds-amd64-jw4xk -o yaml   
    

    Dashboard

    Kubernetes集群的管理方式:

    1. 命令式: create,run,expose,delete,..

    2. 命令式配置文件: create -f /PATH/TO/RESOURCE_CONFGURATION_FILE ,delete -f ,replace -f

    3. 声明式配置文件: apply -f,patch

    4. 部署
      kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml

    5. 将Service改为NodePort

    6. 认证

    • 认证时账号必须为ServiceAccount,被dashboard pod拿来由kubernetes进行认证.
      token:
      1. 创建ServiceAccount,根据其管理目标,使用rolebinding或clusterrolebinding绑定至合理role或clusterrole;
      2. 获取此ServiceAccount的secret,查看secret的详细信息,其中就有token;

    config: (把ServiceAccount的token封装为kubeconfig文件)
    1. 创建ServiceAccount,根据其管理目标,使用rolebinding或clusterrolebinding绑定至合理role或clusterrole;
    2.kubectl get secret |awk '/^ServiceAccount/{print $1}'
    DEF_NS_ADMIN_TOKEN=$(kubectl get secret def-ns-admin-token-mnpph -o jsonpath={.data.token} |base64 -d )
    3. 生成kubeconfig文件
    kubectl config set-cluster --kubeconfig=/PATH/TO/SOMEFILE
    kubectl config set-credentials NAME --token=$KUBE_TOKEN --kubeconfig=/PATH/TO/SOMEFILE
    kubectl config set-context
    kubectl config use-context

    # 我们通过打补丁实现NodePort外部访问k8sUI  (不建议)  
    kubectl patch -n kubernetes-dashboard svc kubernetes-dashboard -p '{"spec":{"type":"NodePort"}}'   
    service/kubernetes-dashboard patched   
    [root@master dashboard]# kubectl get svc -n kubernetes-dashboard   
    NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE   
    dashboard-metrics-scraper   ClusterIP   10.96.191.177   <none>        8000/TCP        27m   
    kubernetes-dashboard        NodePort    10.96.123.181   <none>        443:32630/TCP   27m   
    # 此时访问需要用Pod所在节点的IP,但是因为证书问题,需要部署Dashboard指定有效的证书,才可以访问. 
    # 谷歌浏览器必须要换证书,火狐可以忽略跳过去.
    

    因为其他浏览器打不开是因为证书过期,我们可以解决证书过期问题

    # 首先需要生成证书
    

    API Server访问Dashboard(推荐)

    # 如果Kubernetes API服务器是公开的,并可以从外部访问,我们可以直接使用API Server的方式来访问.  
    # https://<master-ip>:<apiserver-port>/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/  
    # https://172.19.0.26:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/  
    # 如果返回一下结果不要慌,这是因为新版的K8s默认启用了RBAC,并未认证用户赋予了一个默认的身份: anconymous  
    # 对于API Server来说,他是使用证书进行认证的,我们需要创建一个证书  
    

    # 1. 首先找到kubectl命令的配置文件,默认情况下为/etc/kubernetes/admin.conf  
    # 2. 然后我们使用client-certificate-data和client-key-data生成一个*p12*文件,可使用下列命令:  
      
    # 生成client-certificate-data   
    grep 'client-certificate-data' ~/.kube/config | head -n 1 | awk '{print $2}' | base64 -d >> kubecfg.crt   
      
    # 生成client-key-data   
    grep 'client-key-data' ~/.kube/config | head -n 1 | awk '{print $2}' | base64 -d >> kubecfg.key   
      
    # 生成p12   
    openssl pkcs12 -export -clcerts -inkey kubecfg.key -in kubecfg.crt -out kubecfg.p12 -name "kubernetes-client"  
      
    ls  
    kubecfg.crt  kubecfg.key  kubecfg.p12  
    # 最后导入上面生成的p12文件,重新打开浏览器,显示如下  
    

    使用Token登录

    kubectl create serviceaccount dashboard-admin -n kube-system
    kubectl create clusterrolebinding dashboard-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
    kubectl get secret -n kube-system |grep dashboard
    dashboard-admin-token-drb8d                      kubernetes.io/service-account-token   3      2m43s
    dashboard-cert                                   Opaque                                2      21m
    
    kubectl describe secret dashboard-admin-token-drb8d -n kube-system
    

    在创建一个账号,拥有对default名称空间的权限

    kubectl create serviceaccount def-ns-admin -n default
    kubectl create rolebinding def-ns-admin --clusterrole=admin --serviceaccount=default:def-ns-admin
    
    kubectl get secret
    NAME                       TYPE                                  DATA   AGE
    def-ns-admin-token-mnpph   kubernetes.io/service-account-token   3      2m29s
    default-token-qw5gz        kubernetes.io/service-account-token   3      18h
    [root@master pki]# kubectl describe secret def-ns-admin-token-mnpph
    

    配置文件认证

    kubectl config set-cluster kubernetes --certificate-authority=./ca.crt --server="https://172.19.0.26:6443"  --embed-certs=true --kubeconfig=/root/def-ns-admin.conf
    Cluster "kubernetes" set.
    [root@master pki]# kubectl config view --kubeconfig=/roo/def-ns-admin.conf
    apiVersion: v1
    clusters: null
    contexts: null
    current-context: ""
    kind: Config
    preferences: {}
    users: null
    kubectl get secret def-ns-admin-token-mnpph -o json
    DEF_NS_ADMIN_TOKEN=$(kubectl get secret def-ns-admin-token-mnpph -o jsonpath={.data.token} |base64 -d )
    kubectl config set-credentials def-ns-admin --token=$DEF_NS_ADMIN_TOKEN --kubeconfig=/root/def-ns-admin.conf
    kubectl config view --kubeconfig=/root/def-ns-admin.conf
    
    kubectl config set-context def-ns-admin@kubernetes --cluster=kubernetes --user=def-ns-admin --kubeconfig=/root/def-ns-admin.conf
    
    kubectl config use-context def-ns-admin@kubernetes --kubeconfig=/root/def-ns-admin.conf
    
    kubectl config view --kubeconfig=/root/def-ns-admin.conf
    # 将此文件上传到电脑目录上.
    

  • 相关阅读:
    SQL Server 【应用】行列转换Pivot&Unpivot
    SQL Server 【优化】in & exists & not in & not exists
    SQL Server 【提高】 死锁
    SQL Server 【提高】 锁
    SQL Server 【提高】 游标
    .Net 【基础回顾】关键字
    .Net 【基础回顾】值类型与引用类型
    mysql中point类型数据的操作
    CGI环境配置(Ubuntu)
    CGI环境配置(CentOS)
  • 原文地址:https://www.cnblogs.com/you-men/p/13232886.html
Copyright © 2011-2022 走看看