zoukankan      html  css  js  c++  java
  • 8-kubernetes-安全

    kubernetes安全框架

    访问K8S集群的资源需要过三关:认证、鉴权、准入控制,任意一个不通过都会失败

    普通用户若要安全访问集群API server,往往需要证书、token或者用户名+密码,pod访问需要ServiceAccout

    K8S安全控制框架主要由下面三个阶段进行控制,每个阶段都支持插件方式,通过API server配置来启用插件

    1、Authentication(鉴权)
    2、Authorization (授权)
    3、Admission Control (准入控制)
    

    1、鉴权(Authentication)

    三种客户端身份认证:

    https证书认证:基于CA证书签名的数字证书认证
    http token认证:通过一个token来识别用户
    http base认证:用户名+密码的方式认证(基本不用,安全系数低)
    

    2、授权(Authorization)

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

    根据API请求属性,决定允许还是拒绝

    user:用户
    group:用户分组
    extra:用户额外信息
    API
    请求路径:例如/api,/healthz
    API请求方法:get、list、create、update、patch、delete
    http请求方法:get、post、put、delete
    资源
    子资源
    命名空间
    API组
    

    3、准入控制(Admission Control)

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

    进入到容器中查看启用和禁用的

    kubectl exec -it kube-apiserver-k8s-master sh -n kube-system

    kube-apiserver | grep admin

    基于角色的权限访问控制:RBAC

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

    角色 

    	Role:授权特定命名空间的访问权限
    	ClusterRole:权限所有命名空间的访问权限
    

    角色绑定  

    	RoleBinding:将角色绑定到主体(即subject)
    	ClusterRolebinding:将集群角色绑定到主体
    

    主体(subject)

    	User:用户
    	Group:用户组
    	ServiceAccount:服务账号
    

    例子:指定用户授权访问不同命名空间权限

    示例:为fage用户授权default命名空间pod读取权限

    1、用K8S CA签发客户端证书
    2、生成kubeconfig授权文件
    3、创建RBAC权限策略
    

    1、生成CA签发的证书,需要K8S内的CA证书

    [root@k8s-master ~]# mkdir ssl && cd ssl

    [root@k8s-master ssl]# cat cert.sh 

    cat > ca-config.json <<EOF
    {
      "signing": {
        "default": {
          "expiry": "87600h"
        },
        "profiles": {
          "kubernetes": {
            "usages": [
                "signing",
                "key encipherment",
                "server auth",
                "client auth"
            ],
            "expiry": "87600h"
          }
        }
      }
    }
    EOF
    
    cat > fage-csr.json <<EOF
    {
      "CN": "fage",   #用户名,根据客户端证书里包含的user、group确认一个用户
      "hosts": [],
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "CN",
          "ST": "BeiJing",
          "L": "BeiJing",
          "O": "k8s",     #用户组
          "OU": "System"
        }
      ]
    }
    EOF
    #生成客户端证书
    cfssl gencert -ca=/etc/kubernetes/pki/ca.crt -ca-key=/etc/kubernetes/pki/ca.key -config=ca-config.json -profile=kubernetes fage-csr.json | cfssljson -bare aliang
    

    [root@k8s-master ssl]# bash cert.sh

    [root@k8s-master ssl]# ls | grep "fage*"

    fage.csr

    fage-csr.json

    fage-key.pem

    fage.pem

    [root@k8s-master ssl]#

    2、生成用户认证文件

    [root@k8s-master ssl]# cat kubeconfig.sh 

    kubectl config set-cluster kubernetes 
      --certificate-authority=/etc/kubernetes/pki/ca.crt    #指定ca根证书
      --embed-certs=true 
      --server=https://192.168.10.10:6443   #集群地址
      --kubeconfig=fage.kubeconfig           #生成文件的文件名
    # 设置客户端认证
    kubectl config set-credentials fage 
      --client-key=fage-key.pem          #指定CA颁发的用户证书
      --client-certificate=fage.pem 
      --embed-certs=true            #生成为配置文件,true为是false则不写入
      --kubeconfig=fage.kubeconfig   #生成用户的认证文件
    # 设置默认上下文
    kubectl config set-context kubernetes 
      --cluster=kubernetes 
      --user=fage                    #只是标识没有实际的意义。
      --kubeconfig=fage.kubeconfig    #生成用户的认证文件
    # 设置当前使用配置
    kubectl config use-context kubernetes --kubeconfig=fage.kubeconfig
    

    [root@k8s-master ssl]# bash kubeconfig.sh

    3、指定命名空间授权

    [root@k8s-master ssl]# cat rbac.yaml  

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: default
      name: pod-reader
    rules:             #权限控制位置
    - apiGroups: [""]  #要加deployments需要在这个位置加上"apps"
      resources: ["pods","services","deployments"]
      verbs: ["get", "watch", "list"]
    ---
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: read-pods
      namespace: default
    subjects:
    - kind: User
      name: fage          
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: pod-reader
      apiGroup: rbac.authorization.k8s.io
    

    [root@k8s-master ssl]#

    如果修改权限后重新生效文件即可

    kubectl apply -f rbac.yaml
    

    复制生成的文件到节点上去验证,或者给使用的同事

    scp /root/fage.kubeconfig root@192.168.10.112:/root/.kube/config
    

    网络策略

    网络策略(Network Policy)用于现在pod出入流量,提供pod级别和namespace级别网络访问控制。一些应用场景

    	应用程序之间访问控制,如微服务A允许访问微服务B,微服务C不能访问微服务A
    	开发环境命名空间不能访问测试环境命名空间pod
    	当pod暴露到外部时,需要做pod白名单
    	多租户网络环境隔离
    

    pod网络入口方向隔离

    	基于pod级网络隔离:值允许特点对象访问pod(使用标签定义),允许白名单上的IP地址或者IP段访问pod
    	基于namespace级网络隔离:多个命名空间,A和B命名空间的pod完全隔离
    

    pod网络出口方向

    	拒绝某个namespace上所有pod访问外部
    	基于目的IP的网络隔离:只允许pod访问白名单上的IP地址或IP段
    	基于目标端口的网络隔离:只允许pod访问白名单上的端口
    

    网络概述案例参考地址:

    https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/  

    字段含义

    podSelector:目标pod,根据标签选择
    policyType:策略类型,知道策略用于入栈、出站流量
    ingress: from 是可以访问的白名单,可以来自于IP段、命名空间、pod标签等,ports是可以访问的端口
    egress: 这个pod组可以访问外部的IP段和端口  

    实例:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: test-network-policy
      namespace: default
    spec:
      podSelector:        #将策略应用到那个对象中
        matchLabels:
          role: db
      policyTypes:    #应用到出口还是入口,这里出入都应用了
      - Ingress
      - Egress
      ingress:         #这里的ingress代表是入口,下面是策略明细
      - from:
        - ipBlock:
            cidr: 172.17.0.0/16    #允许访问的访问的网段
            except:
            - 172.17.1.0/24        #允许网段中除了这个网段不能访问
        - namespaceSelector:     #允许访问的命名空间
            matchLabels:
              project: myproject
        - podSelector:           #那些pod可以访问
            matchLabels:
              role: frontend
        ports:               #允许访问的端口
        - protocol: TCP
          port: 6379
      egress:         #这里egress代表出口
      - to:
        - ipBlock:
            cidr: 10.0.0.0/24
        ports:
        - protocol: TCP
          port: 5978
    

    案例:项目pod出入流量访问控制

    需求1  

    将default命名空间写到run=web标签的pod隔离,只允许default命名空间携带run=client1标签的pod访问80端口

    vim network-policy.yaml

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: test-network-policy
      namespace: default
    spec:
      posSelector:
        matchLabels:
          app: web
      policyTypes:
      - Ingress
      ingress:
      - from:
    #    - namespaceSelector:
    #      matchLabels:
    #        project: default
        - podSelector:
          matchLabels:
            run: client1
        ports:
        - protocol: TCP
          port: 80

    生效配置

    kubectl apply -f network-policy.yaml
    

    需求2  

    default命名空间下所有pod可以互相访问,也可以访问其他命名空间Pod,但其他命名空间不能访问default命名空间pod

    cat network-policy.yaml

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name:deny-from-other-namespaces
      namespace: default
    spec:
      podSelector: {}
      policyTypes:
      - Ingress
      ingress:
      - from:
        - podSelector: {}
    
  • 相关阅读:
    深入理解委托、匿名方法和 Lambda 表达式
    常见SQL问题
    LeetCode题解——四数之和
    把中台说清楚
    程序员们的三高:高并发、高性能、高可用
    论文查重是怎么查的
    LeetCode题解——最长回文子串
    六百字读懂 Git(转)
    SQL中ON和WHERE的区别
    链表排序之堆排序
  • 原文地址:https://www.cnblogs.com/huanglingfa/p/13772892.html
Copyright © 2011-2022 走看看