我们为示例创建一个名称空间和一个serviceaccount.我们使用这个serviceaccount来模拟一个非管理员用户
kubectl create namespace psp-example kubectl create serviceaccount -n psp-example fake-user kubectl create rolebinding -n psp-example fake-editor --clusterrole=edit --serviceaccount=psp-example:fake-user为了方便辨认我们使用的账户,我们创建两个别名
alias kubectl-admin='kubectl -n psp-example' alias kubectl-user='kubectl --as=system:serviceaccount:psp-example:fake-user -n psp-example' 创建一个策略和一个pod以下定义文件定义了一个简单pod安全策略(PodSecurityPolicy),这个策略仅仅阻止创建特权pod
apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: example spec: privileged: false # Don't allow privileged pods! # The rest fills in some required fields. seLinux: rule: RunAsAny supplementalGroups: rule: RunAsAny runAsUser: rule: RunAsAny fsGroup: rule: RunAsAny volumes: - '*'我们使用kubectl命令来应用以上文件.
现在,做为一个非特权用户,我们创建一个简单pod
kubectl-user create -f- <<EOF apiVersion: v1 kind: Pod metadata: name: pause spec: containers: - name: pause image: k8s.gcr.io/pause EOF Error from server (Forbidden): error when creating "STDIN": pods "pause" is forbidden: unable to validate against any pod security policy: []发生了什么?尽管pod安全策略已创建,不管是pod的serviceaccount还是fack-user都没有权限使用这个策略.
kubectl-user auth can-i use podsecuritypolicy/example no创建一个rolebing来授权fake-user来使用example策略(example是前面创建的策略的名称)
但是请注意这里并不是首选方式!后面的示例将介绍首选的方式
kubectl-admin create role psp:unprivileged \ --verb=use \ --resource=podsecuritypolicy \ --resource-name=example role "psp:unprivileged" created kubectl-admin create rolebinding fake-user:psp:unprivileged \ --role=psp:unprivileged \ --serviceaccount=psp-example:fake-user rolebinding "fake-user:psp:unprivileged" created kubectl-user auth can-i use podsecuritypolicy/example yes此时,再重新尝试创建pod
kubectl-user create -f- <<EOF apiVersion: v1 kind: Pod metadata: name: pause spec: containers: - name: pause image: k8s.gcr.io/pause EOF pod "pause" created这次正如我们期待的一样,可以正常工作.但是试图创建特权pod仍然会被阻止(因此策略本身阻止创建特权pod)
kubectl-user create -f- <<EOF apiVersion: v1 kind: Pod metadata: name: privileged spec: containers: - name: pause image: k8s.gcr.io/pause securityContext: privileged: true EOF Error from server (Forbidden): error when creating "STDIN": pods "privileged" is forbidden: unable to validate against any pod security policy: [spec.containers[0].securityContext.privileged: Invalid value: true: Privileged containers are not allowed] 再运行一个其它pod我们再尝试创建一个pod,这次有一点不同
ubectl-user run pause --image=k8s.gcr.io/pause deployment "pause" created kubectl-user get pods No resources found. kubectl-user get events | head -n 2 LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON SOURCE MESSAGE 1m 2m 15 pause-7774d79b5 ReplicaSet Warning FailedCreate replicaset-controller Error creating: pods "pause-7774d79b5-" is forbidden: no providers available to validate pod request从以上可以看到deployment已经成功创建(kubectl run 实际上会创建一个deployment).但是使用kubectl get pod命令却没有发现pod被创建.这是为什么?问题的答案隐藏在replicaset控制器里.Fake-user成功创建的deployment(deployment又成功创建replicaset),但是当replicaset尝试创建pod的时候,它并没有被授权使用example定义的策略.
为了解决这个问题,需要把psp:unprivileged角色(前面创建的)绑定到pod的serviceaccount上(前面我们是绑定在了fake-user上).这里serviceaccount是default(因为我们没有指定其它用户)
看到这里如果你仍然觉得难以理解,可以回头再看看,还是无法理解的话则需要补充关于角色,用户和RBAC相关的知识.
kubectl-admin create rolebinding default:psp:unprivileged \ --role=psp:unprivileged \ --serviceaccount=psp-example:default rolebinding "default:psp:unprivileged" created这时候等待若干分钟,replicaset的控制器最终会成功创建pod
kubectl-user get pods --watch NAME READY STATUS RESTARTS AGE pause-7774d79b5-qrgcb 0/1 Pending 0 1s pause-7774d79b5-qrgcb 0/1 Pending 0 1s pause-7774d79b5-qrgcb 0/1 ContainerCreating 0 1s pause-7774d79b5-qrgcb 1/1 Running 0 2s 清理工作删除名称空间以删除绝大部分示例中用到的资源
kubectl-admin delete ns psp-example namespace "psp-example" deleted注意现在刚刚创建的pod安全策略已经没有了名称空间,并且需要单独被清除
kubectl-admin delete psp example podsecuritypolicy "example" deleted 策略示例