Вы когда-нибудь входили в учетную запись электронной почты или свое банковское приложение? Конечно у вас есть! Вы, наверное, делаете это каждый день. Когда вы это делаете, вы взаимодействуете с приложением с отслеживанием состояния. Приложение с отслеживанием состояния — это способ хранения данных, которые нужны снова и снова.

Вопрос для этого сообщения в блоге; у вас есть такие приложения внутри Kubernetes?

Разберемся вместе!

Что такое StatefulSets

Как упоминалось в первом абзаце этой записи в блоге, приложение с отслеживанием состояния — это процесс, который можно возвращать снова и снова. Примером этого является электронная почта. Каждый раз, когда вы входите в электронную почту, вы являетесь «процессом» приложения с отслеживанием состояния, которое возвращается снова и снова. Если ваша учетная запись электронной почты не сохраняла состояние, это означает, что все ваши электронные письма и все остальное (подписи, черновики и т. д.) исчезнут.

В Kubernetes StatefulSets пытаются решить проблему удаления ваших данных при уничтожении модуля Kubernetes. Короче говоря, StatefulSet — это объект API в Kubernetes, который обрабатывает приложения с отслеживанием состояния.

Объект StatefulSet делает это следующим образом:

  • Уникальные сетевые идентификаторы, которые остаются с модулями, когда они появляются и исчезают.
  • Постоянного хранения
  • Масштабирование изящно. Новые реплики не появятся, пока не будет запущена и запущена предыдущая реплика.
  • Последовательные обновления

По сути, Kubernetes сохраняет уникальность каждого модуля, даже если модуль выходит из строя. Когда появляется новый, он имеет тот же сетевой идентификатор и хранилище, что помогает приложению узнать, где находятся данные.

StatefulSet против безгражданства

Есть, более или менее, два типа приложений:

  • Приложения с отслеживанием состояния
  • Приложения без сохранения состояния

Вы уже узнали о приложениях с сохранением состояния, поэтому давайте поговорим о приложениях без сохранения состояния.

Когда развертывается приложение без сохранения состояния, оно, по сути, всегда развертывается с нуля. К нему не привязаны никакие данные. Нет истории запуска приложения. С ним не развертывается постоянное хранилище.

Хорошим примером приложения без сохранения состояния является поиск чего-либо в Google. Допустим, вы открываете Google и ищете «как испечь хлеб». Если вы случайно закроете поисковый веб-браузер, вы просто откроете новый веб-браузер, вернетесь в Google и снова выполните поиск «как испечь хлеб». Вы начинаете процесс заново. Это то, что делают приложения без сохранения состояния. Когда новое приложение без сохранения состояния запускается и появляется, оно начинается с нуля.

Пример разбивки StatefulSet (спецификация развертывания и спецификация StatefulSet)

Теперь, когда вы знаете, что такое stateless и stateful, давайте рассмотрим несколько примеров с помощью манифестов Kubernetes.

Первый пример — приложение без сохранения состояния.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

Приведенный выше манифест Kubernetes развертывает приложение Nginx. Используемый образ Docker имеет версию latest и работает на порту 80. Обратите внимание, что нет места для хранения или чего-то в этом роде. Когда это приложение запускается, оно запускается. Когда оно уходит, оно уходит. Когда он снова запускается, он начинается заново.

Обратите внимание на спецификацию Deployment. Вы увидите это во второй строке; kind: Deployment. Запомните это на минуту.

Теперь давайте посмотрим на приложение с отслеживанием состояния.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

Приведенный выше манифест Kubernetes также развертывает приложение Nginx, за исключением того, что на этот раз вы увидите несколько новых частей, в том числе:

  • kind теперь StatefulSet
  • Есть тома
  • Пути монтирования существуют для хранения данных

Давайте поговорим о спецификации Deployment и различиях StatefulSet.

Спецификация развертывания против спецификации StatefulSet

Спецификации развертывания и спецификации StatefulSet очень похожи. Они оба имеют функции самовосстановления, масштабируемости и количество реплик. Ключевое различие между ними заключается в том, что спецификация StatefulSet поддерживает фиксированную идентичность для каждого модуля. Помните в предыдущем разделе, когда вы узнали, что с StatefulSets поды сохраняют идентификаторы сети, и они уникальны? Это то, что имелось в виду.

Вы можете создавать тома для приложений без сохранения состояния и хранить данные через приложение без сохранения состояния, используя спецификацию развертывания. Ключевым отличием, о котором следует помнить, является различие в уникальном идентификаторе сети между StatefulSet и Deployments.

StatefulSets для производства?

Чтобы ответить на этот вопрос, вы должны подумать об этом двумя способами:

  • С технической точки зрения
  • С точки зрения пользователя

С технической точки зрения да, StatefulSet абсолютно готов к работе. API Kubernetes является частью основной группы API, поэтому он не находится в стадии бета-тестирования или чего-то подобного, что означает, что API был тщательно протестирован и работает так, как ожидалось. Уже доказано, что поды будут хранить идентификаторы сети, поэтому приложения с отслеживанием состояния останутся с отслеживанием состояния. Хранение данных приложений с помощью Kubernetes Volumes идеально подходит практически для любого сценария. Так что да, с технической точки зрения StatefulSets готовы к производству.

С точки зрения пользователя, некоторые люди по-прежнему считают, что StatefulSet не готов к работе. Я могу ошибаться здесь, но аргументы, которые я слышу по этой теме, во многом связаны с тем, что по определению контейнеры должны быть эфемерными. Они должны подняться, опуститься, и все. Они не должны хранить данные о состоянии. Это очень верно, но из-за того, как StatefulSets настроены и сохраняют сетевой идентификатор Pod и используют тома, контейнеры внутри Pod могут выходить из строя весь день каждый день, и приложение по-прежнему будет сохранять состояние.