共計 10043 個字符,預計需要花費 26 分鐘才能閱讀完成。
這篇文章主要講解了“Kubernetes PodSecurityPolicy 怎么創建”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著丸趣 TV 小編的思路慢慢深入,一起來研究和學習“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/v1
kind: Deployment
metadata:
name: nginx-deploy
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
但是 replicaset 控制器卻并沒有創建 Pod,這個時候就需要使用 ServiceAccount 了。
#kubectl describe rs nginx-hostnetwork-deploy-76c46fdb6
Name: nginx-hostnetwork-deploy-76c46fdb6
Namespace: default
Selector: app=nginx,pod-template-hash=76c46fdb6
Labels: app=nginx
pod-template-hash=76c46fdb6
Annotations: deployment.kubernetes.io/desired-replicas: 1
deployment.kubernetes.io/max-replicas: 2
deployment.kubernetes.io/revision: 1
Controlled By: Deployment/nginx-hostnetwork-deploy
Replicas: 0 current / 1 desired
Pods Status: 0 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=nginx
pod-template-hash=76c46fdb6
Containers:
nginx:
Image: nginx:1.15.4
Port: none
Host Port: none
Environment: none
Mounts: none
Volumes: none
Conditions:
Type Status Reason
---- ------ ------
ReplicaFailure True FailedCreate
Events:
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-controller
calico-kube-controller
certificate-controller
clusterrole-aggregation-controller
cronjob-controller
daemon-set-controller
deployment-controller
disruption-controller
endpoint-controller
expand-controller
job-controller
namespace-controller
node-controller
pv-protection-controller
pvc-protection-controller
replicaset-controller
replication-controller
resourcequota-controller
service-account-controller
service-controller
statefulset-controller
ttl-controller
這些 ServiceAccount 指定了哪個控制器可以解析哪些策略的配置。
PodSecurityPolicy
在我們當前示例中,我們將創建 2 個策略,第一個是提供限制訪問的“默認”策略,保證使用某些特權設置時(例如使用 hostNetwork)無法創建 Pod。第二種是一個“提升”的許可策略,允許將特權設置用于某些 Pod,例如在 kube-system 命名空間下面創建的 Pod 的權限。
首先,創建一個限制性策略,作為默認策略:(psp-restrictive.yaml)
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:
- *
雖然限制性的訪問對于大多數 Pod 創建是足夠的了,但是對于需要提升訪問權限的 Pod 來說,就需要一些允許策略了,例如,kube-proxy 就需要啟用 hostNetwork,這就需要創建一個用于提升創建權限的許可策略了:(psp-permissive.yaml)
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:
- *
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: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: psp-restrictive
rules:
- apiGroups:
- extensions
resources:
- podsecuritypolicies
resourceNames:
- restrictive
verbs:
- use
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
然后現在我們再重新創建上面我們的定義的 Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
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
創建完成后同樣查看下 default 命名空間下面我們創建的一些資源對象:
# kubectl get po,rs,deploy -l app=nginx
NAME READY STATUS RESTARTS AGE
pod/nginx-deploy-77f7d4c6b4-njfdl 1/1 Running 0 13s
NAME DESIRED CURRENT READY AGE
replicaset.extensions/nginx-deploy-77f7d4c6b4 1 1 1 13s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.extensions/nginx-deploy 1/1 1 1 13s
我們可以看到 Pods 被成功創建了,但是,如果我們嘗試做一些策略不允許的事情,正常來說就應該被拒絕了。現在我們在 nginx-deploy 基礎上添加 hostNetwork: true 來使用 hostNetwork 這個特權:(nginx-hostnetwork.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-hostnetwork-deploy
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
hostNetwork: true # 注意添加 hostNetwork
創建完成后同樣查看 default 這個命名空間下面的一些資源對象:
# kubectl get po,rs,deploy -l app=nginx
NAME READY STATUS RESTARTS AGE
NAME DESIRED CURRENT READY AGE
replicaset.extensions/nginx-hostnetwork-deploy-74c8fbd687 1 0 0 44s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.extensions/nginx-hostnetwork-deploy 0/1 0 0 44s
現在我們發現 ReplicaSet 又沒有創建 Pod 了,可以使用 kubectl describe 命令去查看這里我們創建的 ReplicaSet 資源對象來了解更多的信息:
# kubectl describe rs nginx-hostnetwork-deploy-74c8fbd687
Name: 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: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: psp-permissive
rules:
- apiGroups:
- extensions
resources:
- podsecuritypolicies
resourceNames:
- permissive
verbs:
- use
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
現在,我們就可以在 kube-system 這個命名空間下面使用 hostNetwork 來創建 Pod 了,將上面的 nginx 資源清單更改成 kube-system 命名空間下面:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-hostnetwork-deploy
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 get po,rs,deploy -n kube-system -l app=nginx
NAME READY STATUS RESTARTS AGE
pod/nginx-hostnetwork-deploy-74c8fbd687-7x8px 1/1 Running 0 2m1s
NAME DESIRED CURRENT READY AGE
replicaset.extensions/nginx-hostnetwork-deploy-74c8fbd687 1 1 1 2m1s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.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/v1beta1
kind: RoleBinding
metadata:
name: specialsa-psp-permissive
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: psp-permissive
subjects:
- kind: ServiceAccount
name: specialsa
namespace: default
然后為我們上面的 Deployment 添加上 serviceAccount 屬性:(nginx-hostnetwork-sa.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-hostnetwork-deploy
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
hostNetwork: true
serviceAccount: specialsa # 注意這里使用的 sa 的權限綁定
這個時候我們查看 default 這個命名空間下面帶有 hostNetwork 的 Pod 也創建成功了:
# kubectl get po,rs,deploy -l app=nginx
NAME READY STATUS RESTARTS AGE
pod/nginx-hostnetwork-deploy-6c85dfbf95-hqt8j 1/1 Running 0 65s
NAME DESIRED CURRENT READY AGE
replicaset.extensions/nginx-hostnetwork-deploy-6c85dfbf95 1 1 1 65s
replicaset.extensions/nginx-hostnetwork-deploy-74c8fbd687 0 0 0 31m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.extensions/nginx-hostnetwork-deploy 1/1 1 1 31m
感謝各位的閱讀,以上就是“Kubernetes PodSecurityPolicy 怎么創建”的內容了,經過本文的學習后,相信大家對 Kubernetes PodSecurityPolicy 怎么創建這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是丸趣 TV,丸趣 TV 小編將為大家推送更多相關知識點的文章,歡迎關注!