ReplicaSet: держим N реплик
Контроллер, который сам восстанавливает нужное число копий Pod, и почему его почти никогда не пишут напрямую.
Зачем нужен ReplicaSet
Pod - наименьшая единица, которую запускает Kubernetes, одна копия приложения. Если узел упал или процесс завершил OOM-killer (механизм ядра Linux, который останавливает процессы при нехватке памяти), Pod без контроллера просто перестаёт существовать. Никто его не восстановит. Для разовой задачи это нормально, но веб-сервису нужно что-то, что будет держать нужное число копий.
ReplicaSet - контроллер, который держит ровно N копий Pod. Контроллер здесь - процесс, который постоянно сверяет реальность с планом. Если Pod меньше, чем нужно, ReplicaSet создаёт новые из шаблона. Если больше, удаляет лишние. Кто удалил Pod, не важно: человек руками или упавший узел. ReplicaSet тут же поднимет замену.
Поля манифеста
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: web-rs
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginxinc/nginx-unprivileged:1.25
ports:
- containerPort: 8080
apiVersion: apps/v1 - ReplicaSet живёт в группе apps, не в core.
Если написать просто v1, kubectl выдаст no matches for kind "ReplicaSet" in version "v1". То же касается Deployment и
StatefulSet.
spec.replicas - сколько копий держать. Можно поставить 0: тогда
контроллер уберёт все Pod, но сам объект останется. Удобно для
временного выключения.
spec.selector - как контроллер находит свои Pod. matchLabels -
набор пар ключ-значение. Все условия складываются через И. Label -
это метка на ресурсе вида ключ-значение. Запись app: web означает
«считаю своими все Pod с меткой app=web в этом namespace».
Селектор обязан совпадать с метками в template.metadata.labels. Если
в селекторе app: web, а в шаблоне app: webapp, apply упадёт с
selector does not match template labels. Контроллер создаёт Pod по
шаблону, потом ищет их по селектору и должен находить.
Есть тонкость. ReplicaSet считает своими все Pod с подходящими
метками, даже созданные не им. Если руками создать Pod с меткой
app: web в том же namespace, ReplicaSet его подхватит. А если из-за
этого реплик станет больше N, удалит случайный, чтобы вернуться к
плану.
ReplicaSet владеет любым Pod с подходящей меткой, а не только теми,
которые создал сам. Лишняя копия с app: web заставит контроллер
удалить случайную реплику, чтобы вернуться к spec.replicas.
spec.template - шаблон Pod, по которому контроллер создаёт копии. Внутри
обычная спека Pod, без apiVersion и kind.
Что показывает kubectl
kubectl get rs web-rs
# NAME DESIRED CURRENT READY AGE
# web-rs 3 3 3 12s
DESIRED: значениеspec.replicas, сколько Pod заказано.CURRENT: сколько Pod реально существует.READY: сколько из них готовы принимать трафик.
Если три числа сошлись, ReplicaSet здоров. Если READY меньше
DESIRED, причину смотрят через kubectl describe rs web-rs и
kubectl get pod.
Как выглядит самовосстановление
Один Pod удаляют руками и сразу смотрят список:
kubectl get pod -l app=web
kubectl delete pod <одно из имён>
kubectl get pod -l app=web -w
Через пару секунд появится новый Pod с другим случайным суффиксом в имени. Это и есть работа ReplicaSet.
Число реплик меняют на лету, без правки YAML:
kubectl scale rs/web-rs --replicas=5
ReplicaSet и Deployment
На практике ReplicaSet в манифестах пишут редко. Поверх него ставят Deployment - контроллер, который умеет обновлять версию образа без простоя (rolling update) и откатывать её назад. Но Deployment под капотом всё равно создаёт ReplicaSet, поэтому его поля надо понимать.
Домашка
Теорию закрепляет задание на своём кластере: 3 шага с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.
./run.sh start k8s-replicaset # развернуть стартовое состояние
./run.sh verify k8s-replicaset # проверить текущий шаг
Коротко
- ReplicaSet держит ровно
spec.replicasкопий Pod и восстанавливает удалённые. apiVersionтолькоapps/v1, иначе kubectl не найдёт такой kind.selector.matchLabelsобязан совпадать сtemplate.metadata.labels.- Селектор ловит любые подходящие Pod в namespace, даже созданные вручную.
- В реальных манифестах пишут Deployment, а ReplicaSet он создаёт сам.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс