SELinux vs Kubernetes volumes #117
Description
SELinux inside ADB is blocking using emptyDir and hostPath volumes and passing secrets to containers as volumes
emptyDir and hostPath volumes
If you create pod with volume, where volume is either emptyDir or hostPath,
SELinux is blocking access to that directory inside container.
example
busybox.yaml:
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- image: busybox
name: busybox
command:
- sleep
- "36000"
volumeMounts:
- name: storage
mountPath: /storage
volumes:
- name: storage
hostPath:
path: /tmp/storage
kubectl create -f busybox.yaml
kubectl exec -it busybox /bin/sh
/ # touch /storage/asdf
touch: /storage/asdf: Permission denied
I have to manually change context of /tmp/storage on host to get that working
chcon -Rt svirt_sandbox_file_t /tmp/storage
Same issue is with emptyDir volumes. This situation is a little bit complicated because emptyDir volumes are created in path containing pod uid /var/lib/kubelet/pods/4dd7b77b-8228-11e5-b8db-525400e09276/volumes/kubernetes.io~empty-dir/
Kubernetes secrets
SELinux is also blocking access to secret volumes so you can not pass secrets from kubernetes to containers.
example:
secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
password: dmFsdWUtMg0K
username: dmFsdWUtMQ0K
busybox.yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- image: busybox
name: busybox
command:
- sleep
- "36000"
volumeMounts:
- name: storage
mountPath: /storage
- name: secret
mountPath: /secret
volumes:
- name: storage
hostPath:
path: /tmp/storage
- name: secret
secret:
secretName: mysecret
kubectl create -f secret.yaml
kubectl create -f busybox.yaml
now you should be able to access /secret/username and /secret/password inside container
# kubectl exec -it busybox /bin/sh
# ls /secret/
ls: /secret/username: Permission denied
ls: /secret/password: Permission denied
to get this manually working is a little bit pain:
# first you need to get pod id
PODID=$(kubectl get pod busybox -o template --template="{{ .metadata.uid }}")
# thank you can change security context of volume on host
chcon -Rt svirt_sandbox_file_t /var/lib/kubelet/pods/$PODID/volumes/kubernetes.io~secret# kubectl exec -it busybox /bin/sh
# cat /secret/*
value-2
value-1
It is quite pain to work with emptyDir and secrets as volumes inside ADB, you have to always think of chcon. When you stop pod it is recreated with new uid, so you have to chcon secrets and emptyDir volumes again :-(
I don't know if this is Kubernetes problem or something with SELinux setup inside ADB.
I think that in hostDir case it is ok to require manual chcon, but with emptyDir and with secrets, that should be automatic.
My idea is to automatically label everything in /var/lib/kubelet/pods/*/volumes/ svirt_sandbox_file_t.