The Linkerd control plane comes with its own minimally privileged
Pod Security Policy
and the associated RBAC resources. This Pod Security Policy is enforced only if
PodSecurityPolicy admission controller is enabled.
To view the definition of the control plane's Pod Security Policy, run:
kubectl describe psp -l linkerd.io/control-plane-ns=linkerd
Adjust the value of the above label to match your control plane's namespace.
Notice that to minimize attack surface, all Linux capabilities are dropped from
the control plane's Pod Security Policy, with the exception of the
NET_RAW capabilities. These capabilities provide the
container with runtime privilege to rewrite the pod's
iptable. Note that adding
these capabilities to the Pod Security Policy doesn't make the container a
container. The control plane's Pod Security Policy prevents container privilege
escalation with the
allowPrivilegeEscalation: false policy. To understand the
full implication of the
NET_RAW capabilities, refer to the
Linux capabilities manual.
More information on the
iptables rules used by the
container can be found on the Architecture
If your environment disallows the operation of containers with escalated Linux
capabilities, Linkerd can be installed with its CNI plugin,
which doesn't require the
Linkerd doesn't provide any default Pod Security Policy for the data plane because the policies will vary depending on the security requirements of your application. The security context requirement for the Linkerd proxy sidecar container will be very similar to that defined in the control plane's Pod Security Policy.
For example, the following Pod Security Policy and RBAC will work with the injected
emojivoto demo application:
apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: linkerd-emojivoto-data-plane spec: allowPrivilegeEscalation: false fsGroup: ranges: - max: 65535 min: 10001 rule: MustRunAs readOnlyRootFilesystem: true allowedCapabilities: - NET_ADMIN - NET_RAW - NET_BIND_SERVICE requiredDropCapabilities: - ALL runAsUser: rule: RunAsAny seLinux: rule: RunAsAny supplementalGroups: ranges: - max: 65535 min: 10001 rule: MustRunAs volumes: - configMap - emptyDir - projected - secret - downwardAPI - persistentVolumeClaim --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: emojivoto-psp namespace: emojivoto rules: - apiGroups: ['policy','extensions'] resources: ['podsecuritypolicies'] verbs: ['use'] resourceNames: ['linkerd-emojivoto-data-plane'] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: emojivoto-psp namespace: emojivoto roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: emojivoto-psp subjects: - kind: ServiceAccount name: default namespace: emojivoto - kind: ServiceAccount name: emoji namespace: emojivoto - kind: ServiceAccount name: voting namespace: emojivoto - kind: ServiceAccount name: web namespace: emojivoto
Note that the Linkerd proxy only requires the
capabilities, and it's run with UID
NET_BIND_SERVICE capability is
needed by the
web application because its container binds to port 80.