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: {}
                    
                
                
            
        
浙公网安备 33010602011771号