Kubernetes защита узлов кластера и сети

Поды могут использовать сетевой интерфейс хоста, тогда отличие в испльзовании службы, будет такое

Чтобы использовать сеть хоста, указываем при создании пода

spec:
  hostNetwork: true

Чтобы не привязывать всё сетевую систему узла в Pod, достаточно пробросить один порт

apiVersion: v1
kind: Pod
metadata:
  name: kubia-hostport
spec:
  containers:
  - image: luksa/kubia
    name: kubia
    ports:
    - containerPort: 8080
      hostPort: 9000
      protocol: TCP

Если включить следующие опции hostPID и hostIPC — то контейнер увидит все процессы на узле и сможет с ними взимодействовать

Конфигурирование контекста безопасности

  •  Позволяет указать идентификатор пользователя, под которым будет выполняться процесс в контейнере
  • не допустит контейнеру выполниться как root
  • Может разрешить доступ к ядру
  • Можно настроить привелегии, в соответствии с требованиями
  • установить параметры seLinux
  • не дать процессу писать в файловую систему контейнера

Меняем PID пользователя

kubectl run pod-with-defaults --image alpine --restart Never -- /bin/sleep 999999
kubectl exec pod-with-defaults id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)

Контейнер выполняется от идентификатора UID (0) и группы GID (0)

Создадим под который будет работать под заданным пользователем, а не с тем который определён при создании контейнера

apiVersion: v1
kind: Pod
  name: pod-as-user-guest
spec:
  containers:
  - name: main
    image: alpine
    command: ["/bin/sleep","9999999"]
    securityContext:
      runAsUser: 405
kubectl exec pod-as-user-guest id
uid=405(guest) gid=100(users)

Для того чтобы запретить выполняться контейнерам в качестве root

Есть директива

securityContext:
  runAsNonRoot: true

Привелигированный режим

Нужен таким контейнерам как kube-proxy для того чтобы взаимодействовать с узлом, kube-proxy взаимодействует с правилами iptables

apiVersion: v1
kind: Pod
metadata:
  name: pod-privileged
spec:
  containers:
  - name: main
    image: alpine
    command: ["/bin/sleep", "999999"]
    securityContext:
      privileged: true

Для того чтобы проверить в чём разница, проверим каккие устройства доступны в обычном контейнере и в привилегированном

kubectl exec -ti pod-with-defaults ls /dev
core             null             shm              termination-log
fd               ptmx             stderr           tty
full             pts              stdin            urandom
mqueue           random           stdout           zero

$ kubectl exec -ti pod-privileged ls /dev
autofs              stdin               tty48
bsg                 stdout              tty49
btrfs-control       termination-log     tty5
core                tty                 tty50
cpu                 tty0                tty51
cpu_dma_latency     tty1                tty52
fd                  tty10               tty53
full                tty11               tty54
----

Таким образом привилегированный контейнер может взаимодействовать с устройствами, которые не доступны в обычном контейнере

Добавление отдельных возможностей ядра

Например, в контейнере нельзя изменить время

kubectl exec -ti pod-with-defaults -- date +%T -s "12:00:00"
date: can't set date: Operation not permitted
12:00:00
apiVersion: v1
kind: Pod
metadata:
  name: pod-add-settime-capability
spec:
  containers:
  - name: main
    image: alpine
    command: ["/bin/sleep", "999999"]
    securityContext:
      capabilities:
        add:
        - SYS_TIME
kubectl exec -ti pod-add-settime-capability -- date +%T -s "12:00:00"
12:00:00
$ kubectl exec -ti pod-add-settime-capability -- date
Wed Apr 17 12:00:03 UTC 2019

Удаление возможностей ядра

Для примера отключим возможность менять овнера

apiVersion: v1
kind: Pod
metadata:
  name: pod-drop-chown-capability
spec:
  containers:
  - name: main
    image: alpine
    command: ["/bin/sleep", "999999"]
    securityContext:
      capabilities:
        drop:
        - CHOWN
kubectl exec -ti pod-drop-chown-capability -- chown guest -R /tmp && ls -lht /
chown: /tmp: Operation not permitted
chown: /tmp: Operation not permitted
command terminated with exit code 1

Запрет записи в файловую систему контейнера

Можно запретить контейнеру писать в свою файлову систему, оставив для записи только смонтированные каталоги

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-readonly-filesystem
spec:
  containers:
  - name: main
    image: alpine
    command: ["/bin/sleep", "9999999"]
    securityContext:
      readOnlyRootFilesystem: true
    volumeMounts:
    - name: my-volume
      mountPath: /volume
      readOnly: false
  volumes:
  - name: my-volume
    emptyDir:
kubectl exec -ti pod-with-readonly-filesystem  -- touch 1
touch: 1: Read-only file system
command terminated with exit code 1
$ kubectl exec -ti pod-with-readonly-filesystem  -- touch /volume/1

До этого все параметры задавались для всех контейнеров пода, можно перенести настройки внутрь определённого контейнера и получить внутри одного пода контейнеры с различными правами

Использование одного тома для контейнеров с разными пользователями

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-shared-volume-fsgroup
spec:
  securityContext:
    fsGroup: 555
    supplementalGroups: [666, 777]
  containers:
  - name: first
    image: alpine
    command: ["/bin/sleep", "999999"]
    securityContext:
      runAsUser: 1111
    volumeMounts:
    - name: shared-volume
      mountPath: /volume
      readOnly: false
  - name: second
    image: alpine
    command: ["/bin/sleep", "999999"]
    securityContext:
      runAsUser: 2222
    volumeMounts:
    - name: shared-volume
      mountPath: /volume
      readOnly: false
  volumes:
  - name: shared-volume
    emptyDir:

Создадим через каждый контейнер файл на смонтированном диске и проверим права

kubectl exec -ti pod-with-shared-volume-fsgroup -c first -- ls -lh /volume/
total 0
-rw-r--r--    1 1111     555            0 Apr 17 12:06 first
-rw-r--r--    1 2222     555            0 Apr 17 12:06 second

 

K8S

Related Articles

0 Comment

Leave a Comment

Ваш адрес email не будет опубликован.