zoukankan      html  css  js  c++  java
  • 第8章:Kubernetes 安全

    Kubernetes 安全

    1. Kubernetes 安全框架

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

    image

    2. 认证,授权,准入控制

    鉴权(Authentication)

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

    授权(Authorization)

    RBAC(Role-Based Access Control,基于角色的访问控制):负责完成授权(Authorization)工作。
    根据API请求属性,决定允许还是拒绝。
    • user:用户名
    • group:用户分组
    • extra:用户额外信息
    • API
    • 请求路径:例如/api,/healthz
    • API请求方法:get,list,create,update,patch,watch,delete
    • HTTP请求方法:get,post,put,delete
    • 资源
    • 子资源
    • 命名空间
    • API组

    准入控制(Admission Control)

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

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

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

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

    image

    4. 案例:为指定用户授权访问不同命名空间权限

    示例:为aliang用户授权default命名空间Pod读取权限
    1. 用K8S CA签发客户端证书
    2. 生成kubeconfig授权文件
    3. 创建RBAC权限策略

    image

    证书内容生成

    [root@k8s-m1 rbac]# 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 > lewen-csr.json <<EOF
    {
      "CN": "lewen",
      "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 lewen-csr.json | cfssljson -bare lewen
    
    cert.sh

    k8s签发证书

    [root@k8s-m1 rbac]# cat kubeconfig.sh
    
    kubectl config set-cluster kubernetes 
      --certificate-authority=/etc/kubernetes/pki/ca.crt 
      --embed-certs=true 
      --server=https://10.0.0.23:6443 
      --kubeconfig=lewen.kubeconfig
    
    # 设置客户端认证
    kubectl config set-credentials lewen 
      --client-key=lewen-key.pem 
      --client-certificate=lewen.pem 
      --embed-certs=true 
      --kubeconfig=lewen.kubeconfig
    
    # 设置默认上下文
    kubectl config set-context kubernetes 
      --cluster=kubernetes 
      --user=lewen 
      --kubeconfig=lewen.kubeconfig
    
    # 设置当前使用配置
    kubectl config use-context kubernetes --kubeconfig=lewen.kubeconfig
    kubeconfig.sh

    创建用户访问权限

    [root@k8s-m1 rbac]# cat rbac.yaml
    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      namespace: default
      name: pod-reader
    rules:
    - apiGroups: ["","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: lewen
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: pod-reader
      apiGroup: rbac.authorization.k8s.io
    
    rbac.yaml

    测试访问

    把生成的 lewen.kubeconfig 拷贝到 root/.kube/config

    就可以访问资源了

    5. 网络策略概述

    网络策略(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访问白名单上的端口

    6. 案例:对项目Pod出入流量访问控制

    需求1:将default 命名空间携带run=web-nginx-0811标签的Pod隔离,只允 许default命名空间携带run=client标签的Pod访问80端口。

    [root@k8s-m1 chp8]# cat test-network-policy.yml 
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: test-network-policy
      namespace: default
    spec:
      podSelector:
        matchLabels:
          app: web-nginx-0811
      policyTypes:
      - Ingress
      - Egress
      ingress:
      - from:
        - podSelector:
            matchLabels:
              run: client
        ports:
        - protocol: TCP
          port: 80
    
    test-network-policy.yml
    # 创建一个pod用来测试
    kubectl run -l run=client --image=busybox -- sh
    
    [root@k8s-m1 ~]# kubectl get pod sh --show-labels # 查看pod的标签,要和网络策略里面的一直
    NAME   READY   STATUS    RESTARTS   AGE   LABELS
    sh     1/1     Running   0          96s   run=client
    
    # 查看一下限流pod的IP地址
    [root@k8s-m1 chp8]# kubectl get ep web-nginx-0811
    NAME             ENDPOINTS                                               AGE
    web-nginx-0811   10.244.111.212:80,10.244.111.213:80,10.244.111.220:80   8d
    
    
    # 然后去到允许访问的pod里面,发起测试
    [root@k8s-m1 ~]# kubectl exec sh -it -- sh
    / # ls
    bin   dev   etc   home  proc  root  sys   tmp   usr   var
    
    # 能够成功获取页面
    / # wget 10.244.111.213
    Connecting to 10.244.111.213 (10.244.111.213:80)
    saving to 'index.html'
    index.html           100% |*************|   612  0:00:00 ETA
    'index.html' saved
    
    # 测试一下端口
    / # telnet 10.244.111.213 80
    Connected to 10.244.111.213
    Connection closed by foreign host
    
    # 创建另外一个非允许的标签 pod
    kubectl run -l run=client-other -it --image=busybox -- bash
    [root@k8s-m1 ~]# kubectl get pod bash --show-labels 
    NAME   READY   STATUS    RESTARTS   AGE   LABELS
    bash   1/1     Running   0          96s   run=client-other
    
    # 发现其他非允许的pod 无法访问 web-nginx-0811
    [root@k8s-m1 ~]# kubectl exec bash -it -- sh
    / # wget 10.244.111.213
    Connecting to 10.244.111.213 (10.244.111.213:80)
    wget: can't connect to remote host (10.244.111.213): Connection timed out
    / # telnet 10.244.111.213 80
    

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

    [root@k8s-m1 chp8]# cat deny-from-other-namespaces.yml 
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: deny-from-other-namespaces
      namespace: default
    spec:
      podSelector: {}
      policyTypes:
      - Ingress
      ingress:
      - from:
        - podSelector: {}
    
    deny-from-other-namespaces.yml
    # 创建一个 kube-system 命名空间的
    
    [root@k8s-m1 chp8]# kubectl run client2 -it --image=busybox -n kube-system -- sh
    / # ping 10.244.111.213
    PING 10.244.111.213 (10.244.111.213): 56 data bytes
    64 bytes from 10.244.111.213: seq=0 ttl=63 time=0.271 ms
    64 bytes from 10.244.111.213: seq=1 ttl=63 time=0.115 ms
    64 bytes from 10.244.111.213: seq=2 ttl=63 time=0.113 ms
    ^C
    --- 10.244.111.213 ping statistics ---
    3 packets transmitted, 3 packets received, 0% packet loss
    round-trip min/avg/max = 0.113/0.166/0.271 ms
    / # wget 10.244.111.213
    Connecting to 10.244.111.213 (10.244.111.213:80)
    saving to 'index.html'
    index.html           100% |*********************************************|   612  0:00:00 ETA
    'index.html' saved
    
    # 创建执行命令后,不通了
    [root@k8s-m1 chp8]# kubectl apply -f deny-from-other-namespaces.yml 
    networkpolicy.networking.k8s.io/deny-from-other-namespaces created
    
    / # ping 10.244.111.213
    PING 10.244.111.213 (10.244.111.213): 56 data bytes
    ^C
    --- 10.244.111.213 ping statistics ---
    2 packets transmitted, 0 packets received, 100% packet loss
    / # wget 10.244.111.213
    Connecting to 10.244.111.213 (10.244.111.213:80)
    ^C
    
    # 创建一个默认名称空间的pod,发现可以访问
    [root@k8s-m1 chp8]# kubectl run client-default -it --image=busybox -- sh
    If you don't see a command prompt, try pressing enter.
    / # ping 10.244.111.213
    PING 10.244.111.213 (10.244.111.213): 56 data bytes
    64 bytes from 10.244.111.213: seq=0 ttl=63 time=0.110 ms
    64 bytes from 10.244.111.213: seq=1 ttl=63 time=0.064 ms
    64 bytes from 10.244.111.213: seq=2 ttl=63 time=0.073 ms
    ^C
    --- 10.244.111.213 ping statistics ---
    3 packets transmitted, 3 packets received, 0% packet loss
    round-trip min/avg/max = 0.064/0.082/0.110 ms
    / # wget 10.244.111.213
    Connecting to 10.244.111.213 (10.244.111.213:80)
    saving to 'index.html'
    index.html           100% |*********************************************|   612  0:00:00 ETA
    'index.html' saved
    / # 
    


    课后作业

    1、完成案例1:为指定用户授权访问不同命名空间权限
    2、完成案例2:对项目Pod出入流量访问控制

  • 相关阅读:
    自定义UILabel的对齐方式
    获取iOS系统版本 --- UIDevice的使用
    iOS 照片多选
    iOS 手势+触摸事件
    IOS消息推送
    设置tableViewCell的背景颜色
    IOS_修改TableView的删除按钮的文本
    UIScrollView控件实现轮播图
    判断设备是不是第一次进入应用
    英语口语
  • 原文地址:https://www.cnblogs.com/wenyule/p/13533916.html
Copyright © 2011-2022 走看看