Как изменить ресурсы (CPU/RAM) у работающих контейнеров?

Ответ

В нативной среде Docker изменить лимиты CPU/RAM для запущенного контейнера без его остановки невозможно. Docker требует пересоздания контейнера с новыми параметрами.

Однако в оркестраторах, таких как Kubernetes, можно обновить конфигурацию ресурсов для рабочих нагрузок (Deployment, StatefulSet), что приведет к плавному редеплою — старые поды будут заменены новыми с новыми лимитами.

Способ 1: Патчинг манифеста Deployment в Kubernetes

# Меняем requests и limits для контейнера 'app' в Deployment 'my-service'
kubectl patch deployment my-service --type='json' -p='[
  {
    "op": "replace",
    "path": "/spec/template/spec/containers/0/resources",
    "value": {
      "requests": { "cpu": "200m", "memory": "256Mi" },
      "limits": { "cpu": "500m", "memory": "512Mi" }
    }
  }
]'

После этой команды Kubernetes запустит новые поды с обновленными ресурсами и постепенно завершит старые, соблюдая стратегию обновления.

Способ 2: Прямое редактирование манифеста

kubectl edit deployment my-service
# В редакторе находим блок `resources`, меняем значения, сохраняем и выходим.

Способ 3: Для standalone Docker-контейнера Единственный вариант — остановить контейнер и запустить заново с флагами --cpus и --memory.

docker stop my_container
docker run -d --name my_container --cpus="1.5" --memory="1g" my_image:latest

Важные ограничения:

  • Уменьшение лимита памяти ниже текущего потребления процесса может привести к немедленному завершению контейнера (OOMKill).
  • Изменение requests в Kubernetes влияет на планирование (scheduling) новых подов, но не на уже работающие.

Ответ 18+ 🔞

А, ну это классика, блядь! Ситуация, знакомая каждому, кто хоть раз пытался подкрутить настройки на лету. Сидит контейнер, жрёт ресурсов, как не в себя, а ты такой: «Да ладно, сейчас я ему память понижу, пусть поскромнее себя ведёт». И тут тебе — ёперный театр!

В нативном Docker, чувак, это невозможно. Вообще. Ну то есть совсем. Ты не можешь подойти к запущенному контейнеру и шепнуть ему на ушко: «Слушай, дружок, теперь у тебя не 4 гига, а 2, будь добр». Он тебя просто не услышит. Docker так не умеет. Тут только один путь — впиздюрить его нахер и запустить заново с новыми флагами. Всё, точка.

Но! Если ты работаешь с Kubernetes, то тут уже совсем другая история, блядь. Это как перейти с заправки самообслуживания на личного механика с ямой. В оркестраторах такая хуйня заложена по умолчанию.

Способ 1: Быстрый патч через консоль (для тех, кто не любит редакторы) Допустим, у тебя есть Deployment с говорящим названием my-service, и там контейнер app халявничает. Чтобы дать ему новые рамки, делаешь так:

# Меняем requests и limits для контейнера 'app' в Deployment 'my-service'
kubectl patch deployment my-service --type='json' -p='[
  {
    "op": "replace",
    "path": "/spec/template/spec/containers/0/resources",
    "value": {
      "requests": { "cpu": "200m", "memory": "256Mi" },
      "limits": { "cpu": "500m", "memory": "512Mi" }
    }
  }
]'

И всё, я тебя обманул? Нет. Кубер сам, плавненько, по своей стратегии обновления, начнёт создавать новые поды с новыми лимитами, а старые — прибивать. Красота.

Способ 2: Для ценителей тонкой настройки (или если патч не лезет) Тут уже надо открывать редактор. Страшного ничего нет.

kubectl edit deployment my-service
# В редакторе находим блок `resources`, меняем значения, сохраняем и выходим.

Главное — не нахулиганить там и не сломать весь манифест, а то будет тебе хиросима и нигасраки.

Способ 3: Для одиноких волков на голом Docker Тут всё просто и грустно, как хуй с горы. Останавливаешь и пересоздаёшь.

docker stop my_container
docker run -d --name my_container --cpus="1.5" --memory="1g" my_image:latest

Но, чувак, внимание, важный момент! Это не просто так. Есть подводные буфера, о которые можно расшибиться.

  • Если ты понизишь лимит памяти (memory limit) ниже, чем процесс уже успел нажрать, контейнеру мгновенно прилетит OOMKill. Это как дать обеденному мужику тарелку размером с блюдце — всё мимо пойдёт, и он накроется медным тазом. Доверия ебать ноль к таким фокусам.
  • В Kubernetes изменение requests влияет только на то, куда новые поды будут размещаться. Старые-то поды уже живут своей жизнью, их это не колышет. Так что подозрение ебать чувствую, когда кто-то думает, что это магически всё починит.

Короче, суть в чём: в современном стеке без оркестратора — да похуй, перезапускай и не парься. А с оркестратором — пользуйся его крутыми фичами, но головой думай, э бошка думай, прежде чем лимиты резать.