Архив автора: admin

Ресурсы в Kubernetes. Часть 2: Процессор (CPU)

В первой части мы рассмотрели два типа требований (requests и limits) к ресурсам с точки зрения Kubernetes и разобрались с указанием этих параметров применительно к памяти. В данной статье рассмотрим нюансы настройки параметров requests и limits в контексте работы процессора (CPU). Давайте разберемся!




Итак, что имеется в виду под CPU когда мы говорим о Kubernetes? Один CPU это эквивалент “одного процессорного ядра”, предоставляемого операционной системой рабочего узла, вне зависимости от того, какое это ядро — физическое (physical core), поток физического ядра (hyper-thread), виртуальное ядро (например, EC2 vCPU, которое по сути, тоже является потоком физичекого ядра).




В отличие от ограничений (limits) по памяти, лимиты по CPU с точки зрения Kubernetes являются “сжимаемыми”, следовательно может работать так называемый CPU Throttling — снижение частоты процессора, и, как следствие, производительности. Когда вы устанавливаете значение limits для CPU:




...
    resources:
      limits:
        cpu: "1"
        memory: 2Gi
...




вы на самом деле указываете время использования процессора (CPU time) на всех доступных процессорных ядрах рабочего узла (ноды), а не “привязываете” свой контейнер к конкретному ядру (или группе ядер). Это значит, что даже если вы указываете в .limits.cpu число меньшее общего количества ядер ноды, то контейнер все равно будет “видеть” и использовать все ядра, ограничиваясь только временем их использования.




К примеру, если контейнеру, который запускается на рабочем узле с общим количеством ядер 8, в значении CPU limits установить 4, то контейнер будет использовать эквивалент 4-х ядер, распределенных по всем 8 CPU ноды. В данном примере максимально допустимое использование процессора (CPU usage) на рабочем узле будет равняться 50%.




Как это выглядит с точки зрения Docker? Kubernetes управляет ограничениями CPU передавая параметры cpu-period и cpu-quota. Параметр cpu-period определяет период времени, в течении которого отслеживается использование процессора (CPU utilisation) контейнером и он всегда равен 100000µs (100ms). Параметр cpu-quota — это общее количество процессорного времени, которое контейнер может использовать в каждом cpu-period‘е. Эти два параметра влияют на работу CFS (абсолютно честного планировщика ядра, Completely Fair Scheduler). Конкретный пример соответствия значений CPU limits значениям cpu-quota в конфигурации Docker:




limits 1:	cpu-quota=100000
limits 4:	cpu-quota=400000
limits 0.5:	cpu-quota=50000




Здесь limits 1 означает, что каждые 100ms контейнером могут использоваться 100% эквивалента 1 процессорного ядра рабочего узла, limits 4 указывает, что контейнер может использовать 400% эквивалента 1 ядра (ну или 100% процессорных 4-х ядер) и т.д. Не забываем, что это использование “размазывается” на все доступные ядра рабочей ноды, без привязки к конкретным ядрам. Благодаря работе “абсюлютно честного планировщика” (CFS), любому контейнеру, превышающему свою квоту в данный период (имеется в виду cpu-period рассмотренный выше), будет запрещено использовать процессор до наступления следующего периода.




Напомню, что вы можете указать сколько процессорных ядер (CPU) необходимо для работы вашему контейнеру с помощью параметра requests — это значение (важно!) учитывается планировщиком Kubernetes при размещении контейнера на рабочих узлах кластера (общее значение параметров CPU requests всех контейнеров на конкретном рабочем узле не может быть больше, чем общее количество процессорных ядер данной ноды).




Таким образом, при использовании requests, вам гарантирован эквивалент количества указанных CPU, но что произойдет, если рабочий узел кластера будет находиться под чрезмерной нагрузкой (использование процессора на 100% или внезапные скачки LA)? В этом случае приоритет использования процессорного времени будет вычисляться исходя из значения, указанного в CPU requests и умноженного на 1024 — результат будет передан Docker’у как параметр cpu-shares. Это так называемый “вес” — если все контейнеры данного рабочего узла имеют одинаковый вес, то они будут иметь одинаковый приоритет при планировании и использовании процессорного времени при чрезмерной нагрузке; если у контейнеров рабочего узла вес разный, то контейнер с большим весом будет иметь высший приоритет и получит больше процессорного времени при чрезмерной нагрузке процессора на рабочей ноде.




В предыдущей статье мы уже упоминали о QoS (классах качества сервиса) — они справедливы и в контексте CPU. Используя класс Burstable вы можете получить дополнительные периоды времени использования CPU (при условии, что эти же ресурсы не требуются другим контейнерам). Потенциально, это позволяет более эффективно использовать ресурсы кластера, правда, за счет большей непредсказуемости — повышенное использование CPU одним контейнером на рабочем узле повлияет на “соседей”, работающих на той же ноде кластера.




Опять же, если вы новичок в Kubernetes, лучше всего обеспечить класс сервиса Guaranteed QoS, устанавливая значения requests и limits одинаковыми. Когда вы соберете больше данных (метрик) и лучше разберетесь с использованием процессорных ресурсов контейнерами, есть смысл начать использовать класс сервиса Burstable QoS для обдуманной оптимизации расходов на инфраструктуру.




Сколько CPU стоит выделить контейнеру при написании манифеста? К сожалению, не существует универсального ответа на этот вопрос — все зависит от характеристик вашего приложения, требуемой производительности, места размещения контейнера, стоимости и т. д. Но если вы достаточно хорошо знаете, как работает ваше приложение “под капотом” и при наличии приличных инструментов для сбора и анализа метрик (например, Prometheus) можно подобрать оптимальную конфигурацию. В крайнем случае, можно даже получить кое-какие цифры для анализа выполнив внутри контейнера команду:




cat /sys/fs/cgroup/cpu,cpuacct/cpu.stat

nr_periods 345489
nr_throttled 502
throttled_time 109456473902




Так можно получить общее количество периодов запуска, количество раз, когда производительность процессора для данного контейнера была принудительно снижена (CPU Throttled) и общее время троттлинга в наносекундах.




Надеюсь, теперь вы знаете больше о требованиях к ресурсам, классах сервисов и определениях памяти (memory) и процессора (CPU) в контексте работы с Docker и Kubernetes.




Источник: https://ealebed.github.io/posts/2019/ресурсы-в-kubernetes-часть-2-cpu/



2023-01-03T00:08:25
DevOps

Ресурсы в Kubernetes. Часть 1: Память (Memory)

Чтобы Kubernetes смог максимально эффективно использовать доступную инфраструктуру и корректно выделить ресурсы, необходимые для работы вашего приложения, вам следует указать требования в ресурсам каждого контейнера. В данный момент есть возможность задавать два типа требований (requests и limits) для двух типов ресурсов — памяти (memory) и процессора (CPU). В данной статье рассмотрим requests и limits применительно к памяти — давайте разберемся!




При описании пода (Pods) для каждого из его контейнеров могут быть заданы требования к ресурсам в следующем формате:




...
resources:
  limits:
    cpu: "2"
    memory: 2Gi
  requests:
    cpu: "2"
    memory: 2Gi
...




Тип требований requests используется в Kubernetes планировщиком для корректного размещения и запуска подов в существующей инфраструктуре, как бы говоря “запусти контейнеры данного пода там, где есть достаточное количество запрощенных ресурсов”. Limits — жесткое ограничение ресурсов, доступных контейнеру и среде его выполнения (тут и далее имеется в виду Docker container runtime). Превышение указанных лимитов (limits) ресурсов зачастую приводит к троттлингу или остановке (termination) контейнера.




Если значение requests для контейнера не указано, то по умолчанию будет использоваться значение установленное в limits. Если же не указано значение limits, то по умолчанию это значение будет равно 0 (если верить документации — неограниченно. На самом деле ограничивается ресурсами узла, на котором запускается под).




Возникает вопрос, стоит ли указывать значения limits больше, чем requests? Если ваше приложение стабильно использует предсказуемый объем оперативной памяти, то устанавливать разные значения параметров requests и limits для памяти нет смысла. В случае с CPU, разница между заданными значениями requests и limits может не устанавливаться (при условии, что эти же ресурсы не используются другими контейнерами и их не нужно “делить”).




Если вы новичок в Kubernetes, для начала лучше всего использовать значения limits точно такие же как и requests — это обеспечит так называемый “гарантированный класс качества сервиса” (Guaranteed QoS class, об этих классах чуть ниже). С другой стороны, класс Burstable QoS потенциально позволяет более эффективно использовать ресурсы инфраструктуры, правда, за счет большей непредсказуемости — например, рост CPU-latency может повлиять на остальные поды/контейнеры, запущенные на том же рабочем узле (ноде).




В Kubernetes QoS классы используются в соответствии с наличием и конфигурацией requests и limits (детальное описание):




  • если для всех контейнеров пода установлены отличные от 0 requests и limits для всех типов ресурсов, и эти значения равны, то под будет принадлежать к классу Guaranteed;



  • если для одного или нескольких контейнера пода установлены отличные от 0 requests и limits для одного или всех типов ресурсов и эти значения не равны, то под будет принадлежать к классу Burstable;



  • если для всех контейнеров пода не установлены значения requests и limits для всех типов ресурсов, то поду будет присвоен класс Best-Effort.




Поды класса Best-Effort обладают наименьшим приоритетом. Они могут использовать любое количество свободной памяти, доступное на рабочем узле, но будут остановлены в первую очередь, если система испытывает недостаток памяти (under memory pressure). Поды класса Burstable обычно имеют некоторое гарантированное количество ресурсов (благодаря requests), но могут использовать больше ресурсов (если такие доступны). Если система испытывает недостаток памяти (и остановка подов с классом Best-Effort не помогла), то поды данного класса, которые превысили значение заданное в requests будут остановлены. Класс Guaranteed обладает максимальным приоритетом, и поды данного класса будут остановлены только если они используют больше ресурсов, чем установлено в limits.




Итак, что же означает память (memory) в данном контексте? В нашем случае, это общее значение размера страниц памяти (Resident set size, RSS) и использования кэша страниц (page cache) контейнерами.




Примечание. В “чистом” docker’е в это значение также входит своп (swap), который предусмотрительно отключен в Kubernetes.




RSS — размер страниц памяти, выделенных процессу операционной системой и в настоящее время находящихся в ОЗУ. Например, для Java процесса это heap (куча), non-heap (стек) память, оff-heap (она же native memory) и т. д.




Кэш страниц — иногда также называемый дисковый кэшем, используется для кеширования блоков с HDD/SSD. Все операции ввода/вывода обычно происходят через этот кэш (из соображений производительности). Чем больше данных читает/записывает ваше приложение на диск, тем больший объем памяти необходим для кэша страниц. Ядро будет использовать доступную память для кэша страниц, но будет освобождать ее, если память понадобится в другом месте/процессе — таким образом производительность вашего приложения может снижаться при недостаточном объеме оперативной памяти.




Исходя из документации docker, можно сказать, что размер кэша страниц, используемых контейнером, может сильно отличаться в зависимости от того, могут ли некоторые файлы “поделены” между несколькими контейнерами, запущенными на одном рабочем узле (достигается благодаря overlayfs storage driver).




Значения параметров requests и limits измеряются в байтах, однако можно использовать и суффиксы. К примеру, настройка памяти JVM Xmx1g (1024³ bytes) будет соответствовать 1Gi в спецификации контейнера.




Ограничения по памяти (limits) с точки зрения Kubernetes считаются “несжимаемыми” (non-compressible), следовательно при превышении этих ограничений троттлинг невозможен — ядро будет агрессивно очищать кэш страниц (для освобождения ресурсов / достижения желаемого состояния рабочего узла) и контейнеры к конце концов могут быть остановлены (прерваны) хорошо известным Linux Out of Memory (OOM) Killer.




Для хорошей настройки приложения часто приходится эмпирическим путем подбирать необходимые значения requests и limits и менять их на протяжении всего жизненного цикла приложения, поэтому не стоит пренебрегать сбором метрик, мониторингом и оповещением о использовании ресурсов.




На этом все, в следующей статье рассмотрим requests и limits применительно к использованию процессора (CPU).



2023-01-03T00:07:01
DevOps

Распространенные ошибки веб-сервера Nginx

Unable to connect/Refused to Connect

Если при попытке получить доступ к вашему сайту вы видите следующую ошибку:

Firefox can’t establish a connection to the server at www.example.com

или

www.example.com refused to connect Читать

Nginx — CORS

CORS, также известный как совместное использование ресурсов из разных источников, – это метод, используемый в современных веб-браузерах, который контролирует доступ к ресурсам, размещенным на веб-сервере. CORS использует дополнительные заголовки, такие как origin, access-control-origin и многие другие, чтобы определить, есть ли у запрошенного ресурса разрешение на отправку в браузер. Читать

Pidgin: все о приложении для обмена мгновенными сообщениями в 2023 году

Pidgin: все о приложении для обмена мгновенными сообщениями в 2023 году

Pidgin: все о приложении для обмена мгновенными сообщениями в 2023 году

Продолжая наши Серия постов 2022 года, куда мы обращаемся дистрибутивы и приложения GNU/Linux, чей последний раз мы исследовали это было Много лет назад, у нас сегодня пиджин. Который хорошо известен и используется приложение для обмена мгновенными сообщениями.

Также с начала года получил новое обновление, для которого мы считаем идеальным обновить на благо всех, что предлагает текущие и новые приложение для обмена мгновенными сообщениями «Пиджин, в 2023 году».



Читать

Kubernetes — установить Cosnul

Consul — это децентрализованный отказоустойчивый discovery-сервис от компании HashiCorp (которая разрабатывает такие продукты как Vagrant, TerraForm, Otto, Atlas и другие).




Consul является децентрализованным сервисом, то есть Consul agent устанавливается на каждый хост и является полноправным участником кластера. Таким образом, сервисам не нужно знать адрес discovery в нашей сети, все запросы к discovery выполняются на локальный адрес 127.0.0.1.




В этом руководстве вы развернете центр обработки данных Consul с официальным чартом Helm.
Вам не нужно обновлять какие-либо значения в чарте Хелма для базовой установки.
Однако вы можете создать файл значений с параметрами, чтобы разрешить доступ к пользовательскому интерфейсу Consul.
Предупреждение о безопасности. Это руководство не для производственного использования. По умолчанию на диаграмме будет установлена небезопасная конфигурация Consul. Пожалуйста, обратитесь к документации Kubernetes, чтобы определить, как вы можете обеспечить безопасность Consul на Kubernetes в производстве. Кроме того, настоятельно рекомендуется использовать правильно защищенный кластер Kubernetes или убедиться, что вы понимаете и включаете рекомендуемые функции безопасности.
Для успешного выполнения этого руководства у вас должен быть существующий кластер Kubernetes и локально настроенные Helm и kubectl.




Разворачиваем Consul




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




По умолчанию в чарте будут установлены три сервера Consul и клиент на всех узлах Kubernetes.




Вы можете просмотреть значения чарта, чтобы узнать больше о настройках по умолчанию.




Скачать Helm чарт




Во-первых, вам нужно будет клонировать официальный Helm чарт из репозитория Gashub от HashiCorp.




$ git clone https://github.com/hashicorp/consul-helm.git




Вам не нужно обновлять чарт Helm перед развертыванием Консула, т.к. он имеет разумные значения по умолчанию.




Ознакомьтесь с документацией по чартам Helm, чтобы узнать больше информации.




Установка Consul через Helm




Чтобы развернуть Consul, вы должны быть в том же каталоге, что и чарт.




$ cd consul-helm




Теперь вы можете развернуть Консул с помощью установки helm.




Это позволит развернуть три сервера и агента на всех узлах Kubernetes.




Процесс должен быть быстрым, менее 5 минут.




$ helm install .



NAME:   mollified-robin LAST DEPLOYED: Mon Feb 25 15:57:18 2019 NAMESPACE: default STATUS: DEPLOYED

NAME                             READY  STATUS             RESTARTS  AGE

mollified-robin-consul-25r6z     0/1    ContainerCreating  0         0s

mollified-robin-consul-4p6hr     0/1    ContainerCreating  0         0s

mollified-robin-consul-n82j6     0/1    ContainerCreating  0         0s

mollified-robin-consul-server-0  0/1    Pending            0         0s

mollified-robin-consul-server-1  0/1    Pending            0         0s

mollified-robin-consul-server-2  0/1    Pending            0         0s




Вывод, показщанный выше был уменьшен для удобства чтения.




Однако вы можете видеть, что в этом кластере Kubernetes с тремя узлами есть три сервера Consul и три клиента Consul.




Доступ к Consul UI




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




В качестве альтернативы, если вы не хотите обновлять свой кластер, вы можете настроить переадресацию портов с помощью kubectl.




Создайте файл значений




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




# values.yaml

global:

  datacenter: hashidc1

syncCatalog:

  enabled: true

ui:

  service:

    type: 'LoadBalancer'

server:

  affinity: |

    podAntiAffinity:

      requiredDuringSchedulingIgnoredDuringExecution:

        - labelSelector:

            matchLabels:

              app: {{ template "consul.name" . }}

              release: "{{ .Release.Name }}"

              component: server

        topologyKey: kubernetes.io/hostname




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




Параметры синхронизации каталога позволят вам увидеть сервисы Kubernetes в пользовательском интерфейсе Consul.




Инициируйте обновление




Наконец, инициируйте обновление с помощью helm upgrade и флага -f, который передается в ваш новый файл значений.




Этот процесс также должен быть быстрым, менее минуты.




$ helm upgrade consul -f values.yaml




Теперь вы можете использовать kubectl get services для определения внешнего IP-адреса вашего пользовательского интерфейса Consul.




$ kubectl get services

NAME                            TYPE           CLUSTER-IP     EXTERNAL-IP             PORT(S)        AGE

consul                          ExternalName   <none>         consul.service.consul   <none>         11d

kubernetes                      ClusterIP      122.16.14.1    <none>                  443/TCP        137d

mollified-robin-consul-dns      ClusterIP      122.16.14.25   <none>                  53/TCP,53/UDP  13d

mollified-robin-consul-server   ClusterIP      None           <none>                  8500/TCP       13d

mollified-robin-consul-ui       LoadBalancer   122.16.31.395  36.276.67.195           8




Кроме того, вы можете использовать kubectl get pods для просмотра нового процесса синхронизации.




Процесс синхронизации каталога по умолчанию синхронизирует службы Consul и Kubernetes в обоих направлениях.




$ kubectl get pods

NAME                                                 READY   STATUS      RESTARTS   AGE

mollified-robin-consul-d8mnp                          1/1     Running     0         15d

mollified-robin-consul-p4m89                          1/1     Running     0         15d

mollified-robin-consul-qclqc                          1/1     Running     0         15d

mollified-robin-consul-server-0                       1/1     Running     0         15d

mollified-robin-consul-server-1                       1/1     Running     0         15d

mollified-robin-consul-server-2                       1/1     Running     0         15d

mollified-robin-consul-sync-catalog-f75cd5846-wjfdk   1/1     Running     0




Служба должна была добавитьcя по имени развертывания consul-ui.





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




Доступ к Consul




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




Kubectl




Для доступа к каталогу pod и data вы можете запустить kodectl в pod для запуска сеанса оболочки.




$ kubectl exec -it mollified-robin-consul-server-0 /bin/sh




Это позволит вам перемещаться по файловой системе и запускать консольные команды CLI на поде.




Например, вы можете просмотреть Consul members.




$ consul members

Node                                   Address           Status  Type    Build  Protocol  DC        Segment

mollified-robin-consul-server-0        172.20.2.18:8301  alive   server  1.4.2  2         hashidc1  <all>

mollified-robin-consul-server-1        172.20.0.21:8301  alive   server  1.4.2  2         hashidc1  <all>

mollified-robin-consul-server-2        172.20.1.18:8301  alive   server  1.4.2  2         hashidc1  <all>

gke-tier-2-cluster-default-pool-leri5  172.20.1.17:8301  alive   client  1.4.2  2         hashidc1  <default>

gke-tier-2-cluster-default-pool-gnv4   172.20.2.17:8301  alive   client  1.4.2  2         hashidc1  <default>

gke-tier-2-cluster-default-pool-zrr0   172.20.0.20:8301  alive   client  1.4.2




Consul HTTP API




Вы можете использовать Consul HTTP API , связавшись с локальным агентом, работающим на узле Kubernetes.




Вы можете прочитать документацию, если хотите узнать больше об использовании Consul HTTP API с Kubernetes.




Источник: https://sidmid.ru/kubernetes-установить-cosnul/



2023-01-02T06:18:22
DevOps