OpenShift — Примеры

Пример 1 — Образ, которому нужно привилегированное исключение

Образ сервиса писали для собранного вручную кластера: он стартует от root и пишет в каталог, созданный на этапе сборки. Платформа его отвергает, и администратор предложил привилегированное исключение вместо этого. Измените образ так, чтобы исключение не понадобилось.

FROM app-base
WORKDIR /app
COPY . .
RUN mkdir /app/cache && chmod -R 777 /app/cache
USER root
ENTRYPOINT ["start-service"]

Решение

FROM app-base
WORKDIR /app
COPY . .
RUN mkdir -p /var/data && chgrp -R 0 /var/data && chmod -R g=u /var/data
USER appuser
ENTRYPOINT ["start-service"]
# кластер назначает uid процесса; процессу нужен лишь путь, в который он может писать
смонтируйте записываемый путь в /var/data и запускайтесь под произвольным пользователем
исключение отозвано, поэтому рабочая нагрузка обновляется вместе с платформой

Сборка под произвольного пользователя со смонтированным путём для записи — это то, чего ожидает строгая модель. Отозвать исключение так же важно: рабочая нагрузка с исключением больше не обновляется как часть платформы. Обычная ошибка — выдать исключение, которое работает сегодня, а на следующем обновлении оставляет сервис позади.

Пример 2 — Конвейер с правами на весь кластер

Конвейер сборки и развёртывания работает как рабочая нагрузка внутри кластера, что даёт ему ту же наблюдаемость, что и всему остальному. Его сервисный аккаунт был привязан к роли уровня кластера, чтобы развёртывать где угодно, а доступ выдавался вручную созданными локальными аккаунтами. Ограничьте и то и другое.

kind: RoleBinding
metadata: { name: pipeline, namespace: shop }
roleRef:  { kind: ClusterRole, name: cluster-wide-deploy }
subjects: [{ kind: ServiceAccount, name: pipeline }]

Решение

kind: RoleBinding
metadata: { name: pipeline, namespace: shop }
roleRef:  { kind: Role, name: deploy-workloads }   # только в пределах проекта
subjects: [{ kind: ServiceAccount, name: pipeline }]
пользователи конвейера приходят от внешнего поставщика идентичности и наследуют роли проекта
локальные аккаунты отключены, поэтому отключение происходит в каталоге

Работа конвейера в кластере означает, что скомпрометированная сборка наследует всё, что умеет кластер, поэтому сервисный аккаунт ограничен объектами, которые он развёртывает, и своим проектом. Брать идентичности из каталога, а не создавать локальных пользователей, — вот что заставляет проекты и права работать. Обычная ошибка — оставить права на весь кластер, потому что первому развёртыванию они понадобились в другом месте.