千家信息网

Kubernetes PodSecurityPolicy怎么创建

发表于:2024-10-06 作者:千家信息网编辑
千家信息网最后更新 2024年10月06日,这篇文章主要讲解了"Kubernetes PodSecurityPolicy怎么创建",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Kubernetes
千家信息网最后更新 2024年10月06日Kubernetes PodSecurityPolicy怎么创建

这篇文章主要讲解了"Kubernetes PodSecurityPolicy怎么创建",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Kubernetes PodSecurityPolicy怎么创建"吧!

PodSecurityPolicy介绍

默认情况下,Kubernetes 允许创建一个有特权容器的 Pod,这些容器很可能会威胁系统安全,而 PodSecurityPolicy(PSP)则通过确保请求者有权限按配置来创建 Pod,从而来保护集群免受特权 Pod 的影响。

PodSecurityPolicy是集群级别的资源,它能够控制 Pod 运行的行为,以及它具有访问什么的能力。 PodSecurityPolicy对象定义了一组条件,指示 Pod 必须按系统所能接受条件运行。

以下是PodSecurityPolicy可以控制的内容:

PodSecurityPolicy 是 Kubernetes API 对象,你可以在不对 Kubernetes 进行任何修改的情况下创建它们,但是,默认情况下不会强制执行我们创建的一些策略,我们需要一个准入控制器、kube-controller-manager 配置以及 RBAC 权限配置,下面我们就来对这些配置进行一一说明。

Admission Controller

编辑/etc/kubernetes/manifest/kube-apiserver.yaml,添加PodSecurityPolicy,启用PSP的控制器。

- --enable-admission-plugins=NodeRestriction,PodSecurityPolicy

但是此时我们集群中现在缺少一些安全策略,那么新的 Pod 创建就会失败。 通过下面文件创建Pod:

apiVersion: apps/v1kind: Deploymentmetadata:  name: nginx-deploy  namespace: default  labels:    app: nginxspec:  replicas: 1  selector:    matchLabels:      app: nginx  template:    metadata:      labels:        app: nginx    spec:      containers:      - name: nginx        image: nginx:1.15.4

但是 replicaset 控制器却并没有创建 Pod,这个时候就需要使用 ServiceAccount 了。

#kubectl describe rs nginx-hostnetwork-deploy-76c46fdb6                                                                                Name:           nginx-hostnetwork-deploy-76c46fdb6Namespace:      defaultSelector:       app=nginx,pod-template-hash=76c46fdb6Labels:         app=nginx                pod-template-hash=76c46fdb6Annotations:    deployment.kubernetes.io/desired-replicas: 1                deployment.kubernetes.io/max-replicas: 2                deployment.kubernetes.io/revision: 1Controlled By:  Deployment/nginx-hostnetwork-deployReplicas:       0 current / 1 desiredPods Status:    0 Running / 0 Waiting / 0 Succeeded / 0 FailedPod Template:  Labels:  app=nginx           pod-template-hash=76c46fdb6  Containers:   nginx:    Image:        nginx:1.15.4    Port:             Host Port:        Environment:      Mounts:         Volumes:        Conditions:  Type             Status  Reason  ----             ------  ------  ReplicaFailure   True    FailedCreateEvents:  Type     Reason        Age                From                   Message  ----     ------        ----               ----                   -------  Warning  FailedCreate  1s (x12 over 11s)  replicaset-controller  Error creating: pods "nginx-hostnetwork-deploy-76c46fdb6-" is forbidden: PodSecurityPolicy: no providers available to validate pod request

ServiceAccount Controller Manager

一般来说用户很少会直接创建 Pod,通常是通过 Deployment、StatefulSet、Job 或者 DasemonSet 这些控制器来创建 Pod 的,我们这里需要配置 kube-controller-manager 来为其包含的每个控制器使用单独的 ServiceAccount,我们可以通过在其命令启动参数中添加如下标志来实现。编辑/etc/kubernetes/manifest/kube-controller-manager.yaml,添加:

--use-service-account-credentials=true

一般情况下上面这个标志在大多数安装工具(如 kubeadm)中都是默认开启的,所以不需要单独配置了。

当 kube-controller-manager 开启上面的标志后,它将使用由 Kubernetes 自动生成的以下 ServiceAccount:

# kubectl get serviceaccount -n kube-system | egrep -o '[A-Za-z0-9-]+-controller'attachdetach-controllercalico-kube-controllercertificate-controllerclusterrole-aggregation-controllercronjob-controllerdaemon-set-controllerdeployment-controllerdisruption-controllerendpoint-controllerexpand-controllerjob-controllernamespace-controllernode-controllerpv-protection-controllerpvc-protection-controllerreplicaset-controllerreplication-controllerresourcequota-controllerservice-account-controllerservice-controllerstatefulset-controllerttl-controller

这些 ServiceAccount 指定了哪个控制器可以解析哪些策略的配置。

PodSecurityPolicy

在我们当前示例中,我们将创建2个策略,第一个是提供限制访问的"默认"策略,保证使用某些特权设置时(例如使用 hostNetwork)无法创建 Pod。第二种是一个"提升"的许可策略,允许将特权设置用于某些 Pod,例如在 kube-system 命名空间下面创建的 Pod 的权限。

首先,创建一个限制性策略,作为默认策略:(psp-restrictive.yaml)

apiVersion: policy/v1beta1kind: PodSecurityPolicymetadata:  name: restrictivespec:  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:  - '*'

虽然限制性的访问对于大多数 Pod 创建是足够的了,但是对于需要提升访问权限的 Pod 来说,就需要一些允许策略了,例如,kube-proxy 就需要启用 hostNetwork,这就需要创建一个用于提升创建权限的许可策略了:(psp-permissive.yaml)

apiVersion: policy/v1beta1kind: PodSecurityPolicymetadata:  name: permissivespec:  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:  - '*'

RBAC

现在配置都已经就绪了,但是我们需要引入到 Kubernetes 授权,这样才可以确定请求 Pod 创建的用户或者 ServiceAccount 是否解决了限制性或许可性策略,这就需要用到 RBAC 了。

在我们启用 Pod 安全策略的时候,可能会对 RBAC 引起混淆。它确定了一个账户可以使用的策略,使用集群范围的 ClusterRoleBinding 可以为 ServiceAccount(例如 replicaset-controller)提供对限制性策略的访问权限。使用命名空间范围的 RoleBinding,可以启用对许可策略的访问,这样可以在特定的命名空间(如 kube-system)中进行操作。下面演示了 daemonset-controller 创建 kube-proxy Pod 的解析路径:

首先创建允许使用restrictive策略的 ClusterRole。然后创建一个 ClusterRoleBinding,将restrictive策略和系统中kube-system命名空间内所有的控制器 ServiceAccount 进行绑定:(psp-restrictive-rbac.yaml)

kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1metadata:  name: psp-restrictiverules:- apiGroups:  - extensions  resources:  - podsecuritypolicies  resourceNames:  - restrictive  verbs:  - use---kind: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata:  name: psp-defaultsubjects:- kind: Group  name: system:serviceaccounts  namespace: kube-systemroleRef:  kind: ClusterRole  name: psp-restrictive  apiGroup: rbac.authorization.k8s.io

然后现在我们再重新创建上面我们的定义的 Deployment:

apiVersion: apps/v1kind: Deploymentmetadata:  name: nginx-deploy  namespace: default  labels:    app: nginxspec:  replicas: 1  selector:    matchLabels:      app: nginx  template:    metadata:      labels:        app: nginx    spec:      containers:      - name: nginx        image: nginx:1.15.4

创建完成后同样查看下 default 命名空间下面我们创建的一些资源对象:

# kubectl get po,rs,deploy -l app=nginxNAME                                       READY   STATUS      RESTARTS   AGEpod/nginx-deploy-77f7d4c6b4-njfdl          1/1     Running     0          13sNAME                                            DESIRED   CURRENT   READY   AGEreplicaset.extensions/nginx-deploy-77f7d4c6b4   1         1         1       13sNAME                                 READY   UP-TO-DATE   AVAILABLE   AGEdeployment.extensions/nginx-deploy   1/1     1            1           13s

我们可以看到 Pods 被成功创建了,但是,如果我们尝试做一些策略不允许的事情,正常来说就应该被拒绝了。 现在我们在 nginx-deploy 基础上添加hostNetwork: true来使用 hostNetwork 这个特权:(nginx-hostnetwork.yaml)

apiVersion: apps/v1kind: Deploymentmetadata:  name: nginx-hostnetwork-deploy  namespace: default  labels:    app: nginxspec:  replicas: 1  selector:    matchLabels:      app: nginx  template:    metadata:      labels:        app: nginx    spec:      containers:      - name: nginx        image: nginx:1.15.4      hostNetwork: true  # 注意添加hostNetwork

创建完成后同样查看 default 这个命名空间下面的一些资源对象:

# kubectl get po,rs,deploy -l app=nginxNAME                                       READY   STATUS      RESTARTS   AGENAME                                                        DESIRED   CURRENT   READY   AGEreplicaset.extensions/nginx-hostnetwork-deploy-74c8fbd687   1         0         0       44sNAME                                             READY   UP-TO-DATE   AVAILABLE   AGEdeployment.extensions/nginx-hostnetwork-deploy   0/1     0            0           44s

现在我们发现 ReplicaSet 又没有创建 Pod 了,可以使用kubectl describe命令去查看这里我们创建的 ReplicaSet 资源对象来了解更多的信息:

# kubectl describe rs nginx-hostnetwork-deploy-74c8fbd687Name:           nginx-hostnetwork-deploy-74c8fbd687......Events:  Type     Reason        Age                   From                   Message  ----     ------        ----                  ----                   -------  Warning  FailedCreate  80s (x15 over 2m42s)  replicaset-controller  Error creating: pods "nginx-hostnetwork-deploy-74c8fbd687-" is forbidden: unable to validate against any pod security policy: [spec.securityContext.hostNetwork: Invalid value: true: Host network is not allowed to be used]

我们可以看到很明显 Hostnetwork 不被允许使用,但是在某些情况下,我们的确有在某个命名空间(比如 kube-system)下面创建使用 hostNetwork 的 Pod,这里就需要我们创建一个允许执行的 ClusterRole,然后为特定的命名空间创建一个 RoleBinding,将这里的 ClusterRole 和相关的控制器 ServiceAccount 进行绑定:(psp-permissive-rbac.yaml)

kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1metadata:  name: psp-permissiverules:- apiGroups:  - extensions  resources:  - podsecuritypolicies  resourceNames:  - permissive  verbs:  - use---apiVersion: rbac.authorization.k8s.io/v1beta1kind: RoleBindingmetadata:  name: psp-permissive  namespace: kube-systemroleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: psp-permissivesubjects:- 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

现在,我们就可以在 kube-system 这个命名空间下面使用 hostNetwork 来创建 Pod 了,将上面的 nginx 资源清单更改成 kube-system 命名空间下面:

apiVersion: apps/v1kind: Deploymentmetadata:  name: nginx-hostnetwork-deploy  namespace: kube-system  labels:    app: nginxspec:  replicas: 1  selector:    matchLabels:      app: nginx  template:    metadata:      labels:        app: nginx    spec:      containers:      - name: nginx        image: nginx:1.15.4      hostNetwork: true

创建完成后同样查看下对应的资源对象创建情况:

# kubectl get po,rs,deploy -n kube-system -l app=nginxNAME                                            READY   STATUS    RESTARTS   AGEpod/nginx-hostnetwork-deploy-74c8fbd687-7x8px   1/1     Running   0          2m1sNAME                                                        DESIRED   CURRENT   READY   AGEreplicaset.extensions/nginx-hostnetwork-deploy-74c8fbd687   1         1         1       2m1sNAME                                             READY   UP-TO-DATE   AVAILABLE   AGEdeployment.extensions/nginx-hostnetwork-deploy   1/1     1            1           2m1s

现在我们可以看到 Pod 在 kube-system 这个命名空间下面创建成功了。

特定应用的ServiceAccount

如果我们现在有这样的一个需求,在某个命名空间下面要强制执行我们创建的 restrictive(限制性)策略,但是这个命名空间下面的某个应用需要使用 permissive(许可)策略,那么应该怎么办呢?在当前模型中,我们只有集群级别和命名空间级别的解析。为了给某个应用提供单独的许可策略,我们可以为应用的 ServiceAccount 提供使用 permissive 这个 ClusterRole 的能力。

比如,还是在默认的命名空间下面创建一个名为 specialsa 的 ServiceAccount:

kubectl create serviceaccount specialsa

然后创建一个 RoleBinding 将 specialsa 绑定到上面的 psp-permissive 这个 CluterRole 上:(specialsa-psp.yaml)

apiVersion: rbac.authorization.k8s.io/v1beta1kind: RoleBindingmetadata:  name: specialsa-psp-permissive  namespace: defaultroleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: psp-permissivesubjects:- kind: ServiceAccount  name: specialsa  namespace: default

然后为我们上面的 Deployment 添加上 serviceAccount 属性:(nginx-hostnetwork-sa.yaml)

apiVersion: apps/v1kind: Deploymentmetadata:  name: nginx-hostnetwork-deploy  namespace: default  labels:    app: nginxspec:  replicas: 1  selector:    matchLabels:      app: nginx  template:    metadata:      labels:        app: nginx    spec:      containers:      - name: nginx        image: nginx:1.15.4      hostNetwork: true      serviceAccount: specialsa  # 注意这里使用的sa的权限绑定

这个时候我们查看 default 这个命名空间下面带有 hostNetwork 的 Pod 也创建成功了:

# kubectl get po,rs,deploy -l app=nginxNAME                                            READY   STATUS    RESTARTS   AGEpod/nginx-hostnetwork-deploy-6c85dfbf95-hqt8j   1/1     Running   0          65sNAME                                                        DESIRED   CURRENT   READY   AGEreplicaset.extensions/nginx-hostnetwork-deploy-6c85dfbf95   1         1         1       65sreplicaset.extensions/nginx-hostnetwork-deploy-74c8fbd687   0         0         0       31mNAME                                             READY   UP-TO-DATE   AVAILABLE   AGEdeployment.extensions/nginx-hostnetwork-deploy   1/1     1            1           31m

感谢各位的阅读,以上就是"Kubernetes PodSecurityPolicy怎么创建"的内容了,经过本文的学习后,相信大家对Kubernetes PodSecurityPolicy怎么创建这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0