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: {}

 

posted @ 2020-10-06 10:51  缺个好听的昵称  阅读(147)  评论(0编辑  收藏  举报