Kubernetes Pod Security Policy

這是關於如何加固kubernetes集羣安全的文章。在測試環境下使用默認的users和service accounts的默認受權建立pods並無問題,可是在生產環境下,這可能會致使不可預料的災難。Kubernetes提供pod security policy用來限制users和service account的權限。nginx

概覽

在minikube建立的集羣中實踐pod security policy前,在這裏我將作一些理論基礎的介紹。api

實驗條件

讀者在實踐pod security policy以前必須先要對下面這些名詞的概念有充分的理解:數組

  • Minikube
  • Namespace
  • Pod
  • Replica Set
  • Service Account
  • Cluster Role
  • Cluster Role Binding

Pod Securities Policy

Pod Security Policies(Adminssion Controller)授予users和service accounts建立或更新pods使用資源的權限。這是一種集羣級別的資源類型,用來限制pod對敏感資源的使用。安全

Adminssion Controller

Addmission controller會攔截髮往Kubernetes API Server調用資源的請求,驗證請求調用的users和service accout是否已經受權和認證使用被調用的資源對象。例如:Admission controller會驗證請求者是否擁有使用hostNetwork等kubernetes資源的權限。bash

Policy

對受權資源使用權限的規則定義在YAML文件中。app

Policy Definition Guidelines

規則有兩種:一種是限制(restrictive)使用資源的規則,另外一種是容許(permission)使用資源的規則。ide

Pod Security Policy應該遵循如下的規範:測試

  • 若是要限制user和service account使用集羣中的資源,須要對相應的用戶綁定限制策略
  • 若是要容許user和service account使用集羣中的資源,須要對相應的用戶綁定容許策略

例子

在這部分中咱們將開始在集羣中實踐 pod security policy。ui

Enabling Pod Security Policy

PSP(Pod Security Policy) 在默認狀況下並不會開啓。經過將PodSecurityPolicy關鍵詞添加到 --enbale-admission-plugins 配置數組後,能夠開啓PSP權限認證功能。spa

Example

--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PodSecurityPolicy
複製代碼

注意:開啓PodSecurityPolicy功能後,即便沒有使用任何安全策略,都會使得建立pods(包括調度任務從新建立pods)失敗

Testing

經過下面的deployment yaml文件測試在沒有PSP策略的狀況下是否能夠建立pod:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: default
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.4
複製代碼

使用下面的命令建立deployment資源:

sudo kubectl apply -f nginx-deployment.yaml
複製代碼

使用下面的命令檢查pod是否建立:

kubectl get pods,replicasets,deployments
複製代碼

經過上圖可見deployments和relicaset正在運行,因爲缺乏PSP policy,集羣並無建立相應的pods。

Defining Policies

下面將建立兩個policies,

  1. Restrictive Policy

下面是典型的限制資源使用的restrictive policy:

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restrictive
spec:
  privileged: false
  hostNetwork: false
  allowPrivilegeEscalation: false
  defaultAllowPrivilegeEscalation: false
  hostPID: false
  hostIPC: false
  runAsUser:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  volumes:
  - 'configMap'
  - 'downwardAPI'
  - 'emptyDir'
  - 'persistentVolumeClaim'
  - 'secret'
  - 'projected'
  allowedCapabilities:
  - '*'
複製代碼
  1. Permissive Policy

下面是容許使用資源的permissive policy,多條permissive policy規則被用來設置相應user或者sevice account使用相關類型的資源。

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: permissive
spec:
  privileged: true
  hostNetwork: true
  hostIPC: true
  hostPID: true
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  runAsUser:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  hostPorts:
  - min: 0
    max: 65535
  volumes:
  - '*'
複製代碼

上面兩種poicies可使用下面的命令建立對應的PSP資源:

kubectl apply -f default-restrict-psp.yaml

kubectl apply -f permissive-psp.yaml
複製代碼

覈對psp是否建立成功與否:

sudo kubectl get psp
複製代碼

下面將經過cluster role和cluster role binding在集羣中使用剛纔定義的安全策略(Pod Security Policy)。

Cluster Role

  • 關於restrictive policy的restrictive cluster role
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: psp-restrictive
rules:
- apiGroups:
  - extensions
  resources:
  - podsecuritypolicies
  resourceNames:
  - restrictive
  verbs:
  - use
複製代碼
  • 關於permissive policy的permissive cluster role
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: psp-permissive
rules:
- apiGroups:
  - extensions
  resources:
  - podsecuritypolicies
  resourceNames:
  - permissive
  verbs:
  - use
複製代碼

經過下面命令建立相應的cluster role資源:

kubectl apply -f psp-restrictive-cluster-roleyaml

kubectl apply -f psp-permissive-cluster-roleyaml
複製代碼

Cluster Role Bindings

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: psp-default
subjects:
- kind: Group
  name: system:serviceaccounts
  namespace: kube-system
roleRef:
  kind: ClusterRole
  name: psp-restrictive
  apiGroup: rbac.authorization.k8s.io
複製代碼

上面的role binding會將restrictive cluster role綁定到全部的system service account。

使用下面的命令生成role binding資源:

kubectl apply -f psp-restrictive-cluster-role-binding.yaml
複製代碼

Testing

已經定義了restrictive policy而且將對應的psp綁定到對應的service account,我將經過從新生成開篇的deployment資源來驗證pods是否能夠建立。

首先,刪除已經存在的deployment資源。

kubectl delete deploy nginx-deployment

kubectl get po,rs,deploy
複製代碼

從新建立deployment:

kubectl apply -f nginx-deployment.yaml

kubectl get po,rs,deploy
複製代碼

注意:經過圖可見在policies建立後,能夠建立pod資源。

3. Breaking Policy Rules

在這部分,我將在deployment中使用已經在restrictive policy中禁止的「hostNetwork」。

首先,清楚前面建立的deployment資源。

kubectl delete deploy ninx-deployment

kubectl get po.rs,deploy
複製代碼

使用下面的命令和yaml文件從新建立相應資源:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-hostnetwork-deployment
  namespace: kube-system
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.4
      hostNetwork: true
複製代碼
kubectl apply -f   nginx-host-network-deployment.yaml

kubectl get po,rs,deploy
複製代碼

可見replica set controller並無建立相對應的pod,緣由以下:

Warning FailedCreate 2m38s (x17 over 8m5s) replicaset-controller Error creating: pods "nginx-hostnetwork-deployment-fd75d78b-" is forbidden: unable to validate against any pod security policy: [spec.securityContext.hostNetwork: Invalid value: true: Host network is not allowed to be used]

注意:

上面的錯誤顯示在建立deployment時試圖獲取已經被限制的資源,k8s集羣不容許這樣的行爲。

  1. Creating deployment with privileged access

在這部分,我將經過對一些controllers(deamon-set-controller,replicaset-controller,job-controller)的調用user和service account授予一些特殊權限。

首先,我先建立role binding。

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: psp-permissive
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: psp-permissive
subjects:
- kind: ServiceAccount
  name: daemon-set-controller
  namespace: kube-system
- kind: ServiceAccount
  name: replicaset-controller
  namespace: kube-system
- kind: ServiceAccount
  name: job-controller
  namespace: kube-system
複製代碼

使用如下命令建立role binding:

kubectl apply -f psp-permissive-cluster-role-binding.yaml
複製代碼

接下來我將從新建立deployment並在pod中使用被restrictive policy限制使用的資源。當前deployment與前面deployment的區別在於如今在kube-system命名空間中建立deployment,之前則是在default命名空間中,這主要是因爲剛剛對kube-system授予permissive policy權限。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-hostnetwork-deployment
  namespace: kube-system
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.4
      hostNetwork: true
複製代碼

使用下面命令,從新建立deployment資源:

kubectl apply -f nginx-host-network-deployment-kube-system.yaml
複製代碼

使用下面命令,驗證pod是否正常運行:

kubectl get po,rs,deploy -n kube-system | grep hostnetwork
複製代碼

注意:因爲已經對kube-system命名空間的user和service account受權使用hostNetwork,可見nginx-hostnetwork-deployment pod已經部署在kube-system命名空間。

總結

上面的內容演示瞭如何經過使用PSP受權使用特殊資源,在k8s集羣中實現Pod Security Policy安全策略。

本文翻譯自Kubernetes Pod Security Policy,行文時略有修改

相關文章
相關標籤/搜索