zoukankan      html  css  js  c++  java
  • kubernetes-身份与权限认证(十四)

    Kubernetes的安全框架

    https://kubernetes.io/docs/reference/access-authn-authz/rbac/

    •访问K8S集群的资源需要过三关:认证、鉴权、准入控制
    •普通用户若要安全访问集群API Server,往往需要证书、Token或者用户名+密码;Pod访问,需要ServiceAccount
    •K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段都支持插件方式,通过API Server配置来启用插件。
    1.Authentication
    2.Authorization
    3.Admission Control

    三种客户端身份认证:   

      •HTTPS 证书认证:基于CA证书签名的数字证书认证
      •HTTP Token认证:通过一个Token来识别用户
      •HTTP Base认证:用户名+密码的方式认证

    授权:RBAC(Role-Based Access Control,基于角色的访问控制):负责完成授权(Authorization)工作。

    准入控制:AdminssionControl实际上是一个准入控制器插件列表,发送到APIServer的请求都需要经过这个列表中的每个准入控制器插件的检查,检查不通过,则拒绝请求。

    使用RBAC授权

    RBAC(Role-Based Access Control,基于角色的访问控制),允许通过Kubernetes API动态配置策略。

    角色
      •Role:授权特定命名空间的访问权限
      •ClusterRole:授权所有命名空间的访问权限
    角色绑定
      •RoleBinding:将角色绑定到主体(即subject)
      •ClusterRoleBinding:将集群角色绑定到主体
    主体(subject)
      •User:用户
      •Group:用户组
      •ServiceAccount:服务账号

    使用RBAC授权对pod读取权限示例

    创建角色
    [root@k8s-master1 ~]# vim role-demo.yaml 
    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      namespace: developent
      name: pod-reader
    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get", "watch", "list"]
    
    [root@k8s-master1 ~]# kubectl apply -f role-demo.yaml
    role.rbac.authorization.k8s.io/pod-reader created
    [root@k8s-master1 ~]# kubectl get role -n developent
    NAME         AGE
    pod-reader   50s
    创建角色绑定
    [root@k8s-master1 ~]# vim rolebinding-demo.yaml
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: dev-read-pods
      namespace: developent
    subjects:
    - kind: User
      name: jane
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: pod-reader
      apiGroup: rbac.authorization.k8s.io
    
    [root@k8s-master1 ~]# kubectl get rolebinding -n developent
    NAME            AGE
    dev-read-pods   3s
    
    [root@k8s-master1 ~]# kubectl describe rolebinding dev-read-pods -n developent
    Name:         dev-read-pods
    Labels:       <none>
    Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                    {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"name":"dev-read-pods","namespace":"develop...
    Role:
      Kind:  Role
      Name:  pod-reader
    Subjects:
      Kind  Name  Namespace
      ----  ----  ---------
      User  jane
     基于证书配置客户端身份认证

    创建证书

    [root@k8s-master1 ~]# vim jane-csr.json
    {
      "CN": "jane",
      "hosts": [],
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "CN",
          "L": "BeiJing",
          "ST": "BeiJing"
        }
      ]
    }
    
    [root@k8s-master1 ~]# cfssl gencert -ca=/opt/kubernetes/ssl/ca.pem -ca-key=/opt/kubernetes/ssl/ca-key.pem -config=/opt/kubernetes/ssl/ca-config.json -profile=kubernetes jane-csr.json | cfssljson -bare jane

    创建kubeconfig文件

    kubectl config set-cluster kubernetes 
      --certificate-authority=/opt/kubernetes/ssl/ca.pem 
      --embed-certs=true 
      --server=https://192.168.0.130:6443 
      --kubeconfig=jane-kubeconfig
      
    kubectl config set-credentials jane 
      --client-key=jane-key.pem 
      --client-certificate=jane.pem 
      --embed-certs=true 
      --kubeconfig=jane-kubeconfig
    
    kubectl config set-context default 
      --cluster=kubernetes 
      --user=jane 
      --kubeconfig=jane-kubeconfig
    
    kubectl config use-context default --kubeconfig=jane-kubeconfig
    测试仅对developent命名空间查看pod权限
    [root@k8s-master1 ~]# kubectl get pod -n developent
    NAME                     READY   STATUS    RESTARTS   AGE
    nginx-7cdbd8cdc9-5dd7x   1/1     Running   0          16s
    nginx-7cdbd8cdc9-dthp7   1/1     Running   0          16s
    nginx-7cdbd8cdc9-lwzjf   1/1     Running   0          16s
    [root@k8s-master1 ~]# kubectl --kubeconfig=jane-kubeconfig get pod -n developent
    NAME                     READY   STATUS    RESTARTS   AGE
    nginx-7cdbd8cdc9-5dd7x   1/1     Running   0          2m13s
    nginx-7cdbd8cdc9-dthp7   1/1     Running   0          2m13s
    nginx-7cdbd8cdc9-lwzjf   1/1     Running   0          2m13s
    [root@k8s-master1 ~]# kubectl --kubeconfig=jane-kubeconfig get pod 
    Error from server (Forbidden): pods is forbidden: User "jane" cannot list resource "pods" in API group "" in the namespace "default"

    使用RBAC授权UI权限示例

    serviceAccount

    当创建 pod 的时候,如果没有指定一个 service account,系统会自动在与该pod 相同的 namespace 下为其指派一个default service account。而pod和apiserver之间进行通信的账号,称为serviceAccountName。如下:

    [root@k8s-master1 ~]# kubectl get pod
    NAME                                    READY   STATUS    RESTARTS   AGE
    nfs-client-provisioner-f69cd5cf-rfbdb   1/1     Running   0          4h31m
    web-0                                   1/1     Running   0          4h16m
    web-1                                   1/1     Running   0          4h16m
    [root@k8s-master1 ~]# kubectl get pod/web-0 -o yaml |grep "serviceAccountName"
      serviceAccountName: default
    [root@k8s-master1 ~]# kubectl describe pod web-0
    Name:               web-0
    Namespace:          default
    . . . . .
    Volumes:
      www:
        Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
        ClaimName:  www-web-0
        ReadOnly:   false
      default-token-7vs6s:
        Type:        Secret (a volume populated by a Secret)
        SecretName:  default-token-7vs6s
        Optional:    false

    从上面可以看到每个Pod无论定义与否都会有个存储卷,这个存储卷为default-token-*** token令牌,这就是pod和serviceaccount认证信息。通过secret进行定义,由于认证信息属于敏感信息,所以需要保存在secret资源当中,并以存储卷的方式挂载到Pod当中。从而让Pod内运行的应用通过对应的secret中的信息来连接apiserver,并完成认证。每个 namespace 中都有一个默认的叫做 default 的 service account 资源。进行查看名称空间内的secret,也可以看到对应的default-token。让当前名称空间中所有的pod在连接apiserver时可以使用的预制认证信息,从而保证pod之间的通信。

    [root@k8s-master1 ~]# kubectl get sa 
    NAME                     SECRETS   AGE
    default                  1         9d
    nfs-client-provisioner   1         4h37m
    [root@k8s-master1 ~]# kubectl get secret
    NAME                                 TYPE                                  DATA   AGE
    default-token-7vs6s                  kubernetes.io/service-account-token   3      9d
    nfs-client-provisioner-token-glqhl   kubernetes.io/service-account-token   3      4h38m
    registry-pull-secret                 kubernetes.io/dockerconfigjson        1      8d

    而默认的service account 仅仅只能获取当前Pod自身的相关属性,无法观察到其他名称空间Pod的相关属性信息。如果想要扩展Pod,假设有一个Pod需要用于管理其他Pod或者是其他资源对象,是无法通过自身的名称空间的serviceaccount进行获取其他Pod的相关属性信息的,此时就需要进行手动创建一个serviceaccount,并在创建Pod时进行定义。那么serviceaccount该如何进行定义呢???实际上,service accout也属于一个k8s资源。如下查看service account的定义方式:

    [root@k8s-master1 ~]# kubectl explain sa
    service account的创建
    [root@k8s-master1 ~]# kubectl create sa devsa -o yaml -n developent --dry-run  #不执行查看定义方式
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      creationTimestamp: null
      name: devsa
      namespace: developent
    [root@k8s-master1 ~]# kubectl create sa devsa -o yaml -n developent --dry-run > sa.yaml    #导出yaml文件
    [root@k8s-master1 ~]# kubectl apply -f sa.yaml    #创建
    serviceaccount/devsa created
    [root@k8s-master1 ~]# kubectl get sa -n developent    #查看
    NAME      SECRETS   AGE
    default   1         5m46s
    devsa     1         28s
    [root@k8s-master1 ~]# kubectl get sa devsa -n developent -o yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      annotations:
        kubectl.kubernetes.io/last-applied-configuration: |
          {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"creationTimestamp":null,"name":"devsa","namespace":"developent"}}
      creationTimestamp: "2018-12-28T07:01:01Z"
      name: devsa
      namespace: developent
      resourceVersion: "780489"
      selfLink: /api/v1/namespaces/developent/serviceaccounts/devsa
      uid: 56125cdc-0a6e-11e9-b58a-000c298a2b5f
    secrets:
    - name: devsa-token-krgp7
    创建角色绑定
    [root@k8s-master1 ~]# vim sa-rolebinding-demo.yaml 
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: sa-read-pods
      namespace: developent
    subjects:
    - kind: ServiceAccount
      name: devsa
    roleRef:
      kind: Role
      name: pod-reader
      apiGroup: rbac.authorization.k8s.io
    
    [root@k8s-master1 ~]# kubectl apply -f sa-rolebinding-demo.yaml
    rolebinding.rbac.authorization.k8s.io/sa-read-pods created

    获取token

    [root@k8s-master1 ~]# kubectl get secret -n developent
    NAME                  TYPE                                  DATA   AGE
    default-token-2zhxk   kubernetes.io/service-account-token   3      148m
    devsa-token-pktnh     kubernetes.io/service-account-token   3      2m20s
    [root@k8s-master1 ~]# kubectl describe secret devsa-token-pktnh -n developent
    Name:         devsa-token-pktnh
    Namespace:    developent
    Labels:       <none>
    Annotations:  kubernetes.io/service-account.name: devsa
                  kubernetes.io/service-account.uid: f69d0ff3-0a81-11e9-b58a-000c298a2b5f
    
    Type:  kubernetes.io/service-account-token
    
    Data
    ====
    ca.crt:     1359 bytes
    namespace:  10 bytes
    token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZXZlbG9wZW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRldnNhLXRva2VuLXBrdG5oIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRldnNhIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZjY5ZDBmZjMtMGE4MS0xMWU5LWI1OGEtMDAwYzI5OGEyYjVmIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRldmVsb3BlbnQ6ZGV2c2EifQ.tkA8I8zHF0yjAS4aitd2NhltvASCx8KTug_cdAs3ImYe-5QkxgeO9VTck6L5F6SlMewg8keMYQ9hhgE89aQC4Vs1t89U_ftZ8lo725SrNxIBqhucPUHpvBWfc4OWc96p7PGYNH59AnudXVIKEXuYZyL-KLoQeAjddPRrYXPqUtBpxpQStLWe6qvl-hXY2yj-FyMXAbYRH516ZCMGetRJbYjla7JAPdPt9nAqZoJe00NvOUfw0xXVp_8H7tcvp0tQbQ5GE06zuCRHMfDV9RWj6XUoXKvKirk1yd2nSNJdygTp-1q5JGKxYY2a_tuq2NSCurNBI28Rpj7dV7eIkehkTw

    访问dashboard,仅对developent命名空间读取pod的权限

  • 相关阅读:
    C++ 对象模型学习记录(2) 第3章 data语义学
    C++ 对象模型学习记录(1) 第2章 构造函数语义学
    C ++ 对象模型学习记录(4) function 语义学 (未完待续)
    C++ 对象模型学习记录(3) 第1章 关于对象(未完)
    设计模式复习 之 代理模式
    大数运算
    effective C ++ 学习笔记之 item 31 将文件间的编译依赖关系降至最低(未完成)
    Java 复习 之1 多线程
    SQL中char varchar nchar nvarchar ntext区别和使用(资料汇总)
    .Net中的加密解密
  • 原文地址:https://www.cnblogs.com/yuezhimi/p/10191177.html
Copyright © 2011-2022 走看看