One place for hosting & domains

      Мониторинг объявлений и мероприятий по BGP при помощи BGPalerter в Ubuntu 18.04


      Автор выбрал COVID-19 Relief Fund для получения пожертвования в рамках программы Write for DOnations.

      Введение

      BGP (таблица пограничного межсетевого протокола) — один из ключевых протоколов, отвечающих за маршрутизацию пакетов через Интернет, поэтому когда он работает неправильно, могут возникать серьезные перебои с Интернетом. Например, в 2019 году небольшой интернет-провайдер создал неправильную конфигурацию BGP, которая, к сожалению, распространилась на более высокие уровни и вывела большие сегменты Cloudflare и AWS оффлайн более чем на час. Кроме того, годом ранее был осуществлен захват BGP, чтобы перехватить трафик к известному провайдеру криптовалютных кошельков и похитить средства ничего не подозревающих клиентов.

      BGPalerter — сетевое средство мониторинга с открытым исходным кодом, которое может предоставлять уведомления в реальном времени об активности BGP, включая видимость маршрутов и новые сообщения о маршрутах, а также потенциально опасную деятельность — например, перехваты маршрутов или утечки маршрутов. BGPalerter автоматически принимает общедоступную информацию о маршрутизации, т.е. ему не нужен какой-либо уровень привилегированного доступа или интеграции с сетью/сетями, которые вы хотите отслеживать.

      Примечание: BGPalerter автоматически принимает общедоступную информацию о маршрутизации, т.е. ему не нужен какой-либо уровень привилегированного доступа или интеграции с сетью/сетями, которые вы хотите отслеживать. Весь мониторинг полностью соответствует Закону о компьютерных злоупотреблениях, Закону о мошенничестве с использованием компьютеров и иным аналогичным законам. Тем не менее, рекомендуется ответственно относиться к передаче любой соответствующей информации пострадавшему сетевому оператору.

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

      Предварительные требования

      Для данного обучающего руководства вам потребуется следующее:

      • Сервер Ubuntu 18.04, настроенный согласно руководству по первоначальной настройке сервера с Ubuntu 18.04, включая пользователя non-root user с привилегиями sudo.

      • Одна или несколько сетей и устройств, которые вы хотите отслеживать, например:

        • Ваш сервер
        • Сеть вашей компании
        • Ваш локальный интернет-провайдер

      Для каждого устройства или сети вам потребуется идентифицировать либо отдельный IP-адрес, диапазон IP-адресов, либо номер автономной системы в этом диапазоне. Эти действия рассматриваются в шаге 1.

      Подготовив все вышеперечисленное, войдите на сервер в качестве non-root user, чтобы начать подготовку.

      Шаг 1 — Определение сетей для мониторинга

      На этом шаге вы узнаете соответствующие данные о сетях, которые вы хотите отслеживать.

      BGPalerter может выполнять мониторинг на основе отдельных IP-адресов или сетевых префиксов. Он также может отслеживать целые сети на основе номера автономной системы — уникального в глобальном масштабе идентификатора сети, принадлежащего конкретному административному объекту.

      Для нахождения этой информации вы можете использовать службу пооиска IP-to-ASN WHOIS, которую предоставляет служба разведки угроз Team Cymru. Это пользовательский сервер WHOIS, предназначенный для просмотра IP-адресов и информации о сетевой маршрутизации.

      Если у вас не установлен whois, вы можете сделать это с помощью следующих команд:

      • sudo apt update
      • sudo apt install whois

      Как только вы убедились, что whois установлен, начните с поиска IP-адресов вашего собственного сервера с помощью аргумента -h для указания настраиваемого сервера:

      • whois -h whois.cymru.com your-ip-address

      Это выведет примерно следующий результат, где указано имя и номер AS, в котором находится ваш сервер. Как правило, это будет AS вашего хостинг-провайдера — например, DigitalOcean.

      Output

      AS | IP | AS Name 14061 | your-ip-address | DIGITALOCEAN-ASN, US

      Далее вы можете выполнить поиск для определения префикса/диапазона сети, в которой находится ваш сервер. Это можно сделать, добавив к запросу аргумент -p:

      • whois -h whois.cymru.com " -p your-ip-address"

      Вывод будет очень похож на предыдущую команду, но теперь он будет показывать префикс IP-адреса, к которому относится IP-адрес вашего сервера:

      Output

      AS | IP | BGP Prefix | AS Name 14061 | your-ip-address | 157.230.80.0/20 | DIGITALOCEAN-ASN, US

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

      Подставьте номер AS, который вы определили с помощью предыдущих команд. Вы используете аргумент -v для активации вывода подробной информации с отображением всех соответствующих данных:

      • whois -h whois.cymru.com " -v as14061"

      При этом будет показана дополнительная информация об AS:

      Output

      AS | CC | Registry | Allocated | AS Name 14061 | US | arin | 2012-09-25 | DIGITALOCEAN-ASN, US

      Вы определили ключевую информацию о сетях, которые вы хотите отслеживать. Запишите эти данные, т.к. они потребуются вам позднее. Далее вы начнете настройку BGPalerter.

      Шаг 2 — Создание непривилегированного пользователя для BGPalerter

      На этом шаге вы создадите новую учетную запись непривилегированного пользователя для BGPalerter, т.к. для работы этой программы не требуются права sudo/root.

      Сначала создайте нового пользователя с отключенным паролем:

      • sudo adduser --disabled-password bgpalerter

      Вам не нужно настраивать пароль или ключи SSH, поскольку вы будете использовать этого пользователя только в качестве служебной учетной записи для работы/обслуживания BGPalerter.

      Войдите под именем нового пользователя с помощью команды su:

      Вы вошли как новый пользователь:

      bgpalerter@droplet:/home/user$
      

      Используйте команду cd для перехода в домашнюю директорию нового пользователя:

      bgpalerter@droplet:/home/user$ cd
      bgpalerter@droplet:~$
      

      Вы создали нового непривилегированного пользователя для BGPalerter. Далее вы установите и настроите BGPalerter в своей системе.

      Шаг 3 — Установка и настройка BGPalerter

      На этом шаге вы установите и настроите BGPalerter. Убедитесь, что вы все еще в системе под именем своего нового непривилегированного пользователя.

      Сначала вам нужно определить последний выпуск BGPalerter, чтобы убедиться, что вы загружаете актуальную версию. Перейдите на страницу Выпуски BGPalerter и скопируйте ссылки на загрузку самой последней версии Linux x64.

      Теперь вы можете загрузить копию BGPalerter с помощью wget, если подставите правильную ссылку на загрузку:

      • wget https://github.com/nttgin/BGPalerter/releases/download/v1.24.0/bgpalerter-linux-x64

      Когда файл загрузится, отметьте его как исполняемый:

      • chmod +x bgpalerter-linux-x64

      Затем убедитесь, что BGPalerter загружен и успешно установлен, сверив номер версии:

      • ./bgpalerter-linux-x64 --version

      В результате будет выведен текущий номер версии:

      Output

      1.24.0

      Чтобы корректно запустить BGPalerter, необходимо сначала определить сети, которые вы хотите отслеживать в файле конфигурации. Создайте и откройте файл prefixes.yml в предпочитаемом текстовом редакторе:

      В этом файле конфигурации вы укажете каждый пользовательский IP-адрес, диапазоны IP-адресов и номера AS, которые вы хотите отслеживать.

      Добавьте следующий пример и измените значения конфигурации, как необходимо, используя сетевую информацию, которую вы определили на шаге 1:

      ~/prefixes.yml

      your-ip-address/32:
        description: My Server
        asn:
          - 14061
        ignoreMorespecifics: false
      
      157.230.80.0/20:
        description: IP range for my Server
        asn:
          - 14061
        ignoreMorespecifics: false
      
      options:
        monitorASns:
          '14061':
            group: default
      

      Вы можете отслеживать столько диапазонов IP-адресов или номеров AS, сколько захотите. Чтобы отслеживать отдельные IP-адреса, указывайте /32 для IPv4 и /128 для IPvv6.

      Значение ignoreMorespecifics используется, чтобы контролировать, должен ли BGPalerter игнорировать деятельность на маршрутах, более специфичных (меньших) по сравнению с тем, который вы отслеживаете. Например, если вы отслеживаете /20, и изменение маршрутизации обнаружено в нем для /24, то это считается более специфичным маршрутом. В большинстве случаев их не нужно игнорировать, но если вы отслеживаете большую сеть с несколькими префиксами делегированных пользователей, то это может снизить фоновый шум.

      Теперь вы можете запустить BGPalerter в первый раз, чтобы начать отслеживать свои сети:

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

      Output

      Impossible to load config.yml. A default configuration file has been generated. BGPalerter, version: 1.24.0 environment: production Loaded config: /home/bgpalerter/config.yml Monitoring 157.230.80.0/20 Monitoring your-ip-address/32 Monitoring AS 14061

      BGPalerter будет продолжать работать, пока вы не остановите его нажатием Ctrl+C.

      На следующем шаге вы перейдете к интерпретации некоторых предупреждений, которые может создавать BGPalerter.

      Шаг 4 — Интерпретация интерфейсов BGPalerter

      На этом шаге вы рассмотрите несколько типовых предупреждений BGPalerter. BGPalerter будет выдавать предупреждения в основном потоке выдачи, а также, опционально, в любые дополнительные конечные точки отчетности, которые можно настроить в файле config.yml, как указано в документации BGPalerter.

      По умолчанию BGPalerter отслеживает и предупреждает о следующем:

      • Route hijacks: выдается в случае, когда AS объявляет запрещенный префикс, вызывая ошибочную маршрутизацию трафика. Это может быть либо преднамеренным нападением, либо случайной ошибки в конфигурации.

      • Потеря видимости маршрута: маршрут считается видимым, когда большинство маршрутизаторов BGP в Интернете может надежно создавать маршруты к нему. Потеря видимости указывает на потенциальную недоступность вашей сети — например, если ваш BGP peering прекращает работать.

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

      • Деятельность в рамках вашего AS: обычно используется для новых сообщений о маршрутах. Трафик считается «новым», если BGPalerter еще не знает о нем.

      Ниже представлены некоторые примеры предупреждений, а также краткое описание их значения:

      Alert #1

      The prefix 203.0.113.0/24 is announced by AS64496 instead of AS65540
      

      Это предупреждение свидетельствует о захвате маршрута, т.к. AS64496 объявил 203.013.0/24, хотя ожидается, что этот маршрут будет объявлен AS65540. Это надежный показатель ошибочной конфигурации, приводящей к утечке маршрута, либо преднамеренного захвата злоумышленником.

      Alert #2

      The prefix 203.0.113.0/24 has been withdrawn. It is no longer visible from 6 peers
      

      Это предупреждение говорит о том, что сеть 203.013.0/24 стала невидимой. Это может быть связано с проблемой исходящей маршрутизации, либо произошел сбой питания маршрутизатора.

      Alert #3

      A new prefix 203.0.113.0/25 is announced by AS64496. It should be instead 203.0.113.0/24 announced by AS64496
      

      Это предупреждение показывает, что был объявлен более специфичный префикс там, где это не ожидалось — например, /25, когда ожидалось только /24. Скорее всего, это ошибочная конфигурация, но в некоторых случаях это может свидетельствовать о захвате маршрута.

      Alert #4

      AS64496 is announcing 192.0.2.0/24 but this prefix is not in the configured list of announced prefixes
      

      Помимо этого, данное предупреждение показывает, что AS64496 объявил префикс, который BGPalerter еще не знает. Это может быть связано с тем, что вы обоснованно объявляете новый префикс, или может говорить об ошибочной конфигурации, из-за которой вы случайно объявили чужой префикс.

      На этом шаге вы рассмотрели несколько примеров предупреждений BGPalerter. Далее вы настроите BGPalerter для автоматического запуска во время начальной загрузки.

      Шаг 5 — Запуск BGPalerter во время начальной загрузки

      На этом последнем шаге вы настроите BGPalerter для запуска во время начальной загрузки.

      Убедитесь, что вы все еще в системе под именем нового непривилегированного пользователя, затем откройте crontab:

      Добавьте следующую строку внизу файла crontab:

      crontab

      @reboot sleep 10; screen -dmS bgpalerter "./bgpalerter-linux-x64"
      

      При каждой загрузке системы будет создаваться отдельная экранная сессия с именем bgpalerter, в которой будет запускаться BGPalerter.

      Сохраните изменения и закройте редактор crontab. Теперь можно перезагрузить систему, чтобы убедиться, что BGPalerter корректно запускается во время начальной загрузки.

      Сначала нужно выйти из вашего пользователя BGPalerter:

      Затем перезагрузите систему, как обычно:

      После перезагрузки системы снова войдите на сервер и при помощи su еще раз получите доступ к вашему пользователю BGPalerter:

      Затем можно в любой момент присоединиться к сессии для просмотра вывода BGPalerter:

      На этом последнем шаге вы настроили BGPalerter для запуска во время начальной загрузки.

      Заключение

      В этой статье вы настроили BGPalerter и использовали его для отслеживания сетей с целью внесения изменений в маршрутизацию BGP.

      Если хотите сделать BGPalerter более удобным для пользователя, то можно настроить его для отправки предупреждений через канал Slack посредством веб-хука:

      Если хотите узнать больше о самой системе BGP, но у нас нет доступа к производственной среде BGP, то вам может пригодиться DN42 для экспериментов с BGP в безопасной изолированной среде:



      Source link

      Знакомство с параметрами JavaScript по умолчанию


      Автор выбрал COVID-19 Relief Fund для получения пожертвования в рамках программы Write for DOnations.

      Введение

      В ECMAScript 2015 были введены параметры функций по умолчанию для языка JavaScript. Они позволяют разработчикам инициализировать функции со значениями по умолчанию, если при вызове функции не указываются аргументы. Такая инициализация параметров функций упрощает чтение функций, снижает вероятность ошибок и задает поведение функций по умолчанию. Это позволит избежать ошибок, вытекающих из передачи неопределенных (undefined​​) аргументов и деструктуризации несуществующих объектов.

      В этой статье мы рассмотрим разницу между параметрами и аргументами, узнаем об использовании параметров функций по умолчанию, увидим альтернативные способы поддержки параметров по умолчанию и выясним, какие значения и выражения можно использовать в качестве параметров по умолчанию. Также мы рассмотрим примеры, демонстрирующие работу параметров по умолчанию в JavaScript.

      Аргументы и параметры

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

      В следующем блоке кода мы создадим функцию, возвращающую куб заданного числа, определяемого как x:

      // Define a function to cube a number
      function cube(x) {
        return x * x * x
      }
      

      Переменная x в этом примере является параметром, то есть переменной с именем, которая передается функции. Параметр всегда должен содержаться в переменной и никогда не может иметь прямого значения.

      Теперь рассмотрим следующий блок кода, вызывающий созданную нами функцию cube:

      // Invoke cube function
      cube(10)
      

      Результат будет выглядеть следующим образом:

      Output

      1000

      В данном случае 10 — это аргумент, то есть значение, передаваемое функции при ее вызове. Значение часто может также содержаться в переменной, как показано в следующем примере:

      // Assign a number to a variable
      const number = 10
      
      // Invoke cube function
      cube(number)
      

      Результат будет таким же:

      Output

      1000

      Если вы не передадите аргумент в функцию, которая ожидает его получить, функция будет использовать подразумеваемое значение undefined:

      // Invoke the cube function without passing an argument
      cube()
      

      Результат будет выглядеть следующим образом:

      Output

      NaN

      В данном случае cube() пытается рассчитать значение undefined * undefined * undefined и получает результат NaN («не число»). Дополнительную информацию можно найти в посвященном числам разделе статьи Типы данных в JavaScript.

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

      Синтаксис параметра по умолчанию

      С добавлением параметров по умолчанию в ES2015 вы можете назначать для любого параметра значение по умолчанию, которое функция будет использовать вместо undefined, если эта функция будет вызвана без аргумента. В этом разделе мы покажем, как сделать это вручную, и поможем вам настроить параметры по умолчанию.

      Без параметров по умолчанию нам нужно будет явно проверять наличие значений undefined, чтобы задать значения по умолчанию, как показано в этом примере:

      // Check for undefined manually
      function cube(x) {
        if (typeof x === 'undefined') {
          x = 5
        }
      
        return x * x * x
      }
      
      cube()
      

      Здесь используется условное выражение для проверки автоматической передачи значения undefined, а затем задается значение x, равное 5. Результат выглядит следующим образом:

      Output

      125

      Использование параметров по умолчанию позволяет добиться того же результата с намного меньшим количеством кода. Вы можете задать значение по умолчанию для параметра функции cube, используя оператор равенства (=), как показано здесь:

      // Define a cube function with a default value
      function cube(x = 5) {
        return x * x * x
      }
      

      Теперь при вызове функции cube без аргумента она будет присваивать значение 5 переменной x и выводить результат расчета вместо NaN:

      // Invoke cube function without an argument
      cube()
      

      Output

      125

      При наличии аргумента функция будет выполняться обычным образом, игнорируя значение по умолчанию:

      // Invoke cube function with an argument
      cube(2)
      

      Output

      8

      Однако стоит отметить, что значение параметра по умолчанию также заменяет явно переданный функции аргумент undefined, как показано в этом примере:

      // Invoke cube function with undefined
      cube(undefined)
      

      В результате будет провизведен расчет с переменной x, равной 5:

      Output

      125

      В этом случае были рассчитаны значения для параметра по умолчанию, и явно переданное значение undefined не заменило этот параметр.

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

      Типы данных параметров по умолчанию

      Любое примитивное значение или объект можно использовать в качестве значения параметра по умолчанию. В этом разделе вы увидите, как подобная гибкость расширяет возможности использования параметров по умолчанию.

      Задайте параметры, используя число, строку, логическое значение, объект, массив и нулевое значение в качестве значения по умолчанию. В этом примере будет использоваться синтаксис функции arrow:

      // Create functions with a default value for each data type
      const defaultNumber = (number = 42) => console.log(number)
      const defaultString = (string = 'Shark') => console.log(string)
      const defaultBoolean = (boolean = true) => console.log(boolean)
      const defaultObject = (object = { id: 7 }) => console.log(object)
      const defaultArray = (array = [1, 2, 3]) => console.log(array)
      const defaultNull = (nullValue = null) => console.log(nullValue)
      

      При вызове этих функций без параметров будут использоваться значения по умолчанию:

      // Invoke each function
      defaultNumber()
      defaultString()
      defaultBoolean()
      defaultObject()
      defaultArray()
      defaultNull()
      

      Output

      42 "Shark" true {id: 7} (3) [1, 2, 3] null

      Любой объект, создаваемый в параметре по умолчанию, будет создаваться при каждом вызове функции. Часто такое поведение параметров по умолчанию используется для получения значений из объекта. Если вы пытаетесь провести деструктурирование или получить значение из несуществующего объекта, будет выведена ошибка. Если же параметр по умолчанию представляет собой пустой объект, он просто выдаст значения undefined вместо ошибки:

      // Define a settings function with a default object
      function settings(options = {}) {
        const { theme, debug } = options
      
        // Do something with settings
      }
      

      Это позволяет избежать ошибок, вызванных деструктурированием несуществующих объектов.

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

      Использование нескольких параметров по умолчанию

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

      Вначале декларируем функцию sum() с несколькими параметрами по умолчанию:

      // Define a function to add two values
      function sum(a = 1, b = 2) {
        return a + b
      }
      
      sum()
      

      По умолчанию производится следующий расчет:

      Output

      3

      Кроме того, значение параметра может использоваться в любом последующем параметре по умолчанию, слева направо. Например, данная функция createUser создает пользовательский объект userObj как третий параметр, и функция просто возвращает userObj с первыми двумя параметрами:

      // Define a function to create a user object using parameters
      function createUser(name, rank, userObj = { name, rank }) {
        return userObj
      }
      
      // Create user
      const user = createUser('Jean-Luc Picard', 'Captain')
      

      Если вы вызовете user, вы получите следующий результат:

      Output

      {name: "Jean-Luc Picard", rank: "Captain"}

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

      Вот пример с параметром по умолчанию в начале списка:

      // Define a function with a default parameter at the start of the list
      function defaultFirst(a = 1, b) {
        return a + b
      }
      

      При вызове этой функции нужно вызвать defaultFirst() с двумя аргументами:

      defaultFirst(undefined, 2)
      

      Результат будет выглядеть следующим образом:

      Output

      3

      Вот пример с параметром по умолчанию в конце списка:

      // Define a function with a default parameter at the end of the list
      function defaultLast(a, b = 1) {
        return a + b
      }
      
      defaultLast(2)
      

      В результате будет получено то же значение:

      Output

      3

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

      Приведем реальный пример функции, которая создает элемент DOM и добавляет текстовый ярлык и классы, если они существуют.

      // Define function to create an element
      function createNewElement(tag, text, classNames = []) {
        const el = document.createElement(tag)
        el.textContent = text
      
        classNames.forEach(className => {
          el.classList.add(className)
        })
      
        return el
      }
      

      Вы можете вызвать функцию с несколькими классами в массиве:

      const greeting = createNewElement('p', 'Hello!', ['greeting', 'active'])
      

      При вызове greeting значение будет следующим:

      Output

      <p class="greeting active">Hello!</p>

      Если вы оставите массив classNames вне вызова функции, функция все равно сработает.

      const greeting2 = createNewElement('p', 'Hello!')
      

      greeting2 теперь имеет следующее значение:

      Output

      <p>Hello!</p>

      В этом примере forEach() можно вызвать для пустого массива без каких-либо проблем. Если бы пустой массив не был задан в параметре по умолчанию, мы получили бы следующее сообщение об ошибке:

      Output

      VM2673:5 Uncaught TypeError: Cannot read property 'forEach' of undefined at createNewElement (<anonymous>:5:14) at <anonymous>:12:18

      Мы увидели, как могут взаимодействовать разные параметры по умолчанию, и теперь можем перейти к следующему разделу и посмотреть, как работают вызовы функций в качестве параметров по умолчанию.

      Вызовы функций как параметры по умолчанию

      Помимо примитивов и объектов, в качестве параметра по умолчанию можно использовать результат вызова функции.

      В этом блоке кода мы создадим функцию, возвращающую случайное число, и используем результат как значение параметра по умолчанию для функции cube:

      // Define a function to return a random number from 1 to 10
      function getRandomNumber() {
        return Math.floor(Math.random() * 10)
      }
      
      // Use the random number function as a default parameter for the cube function
      function cube(x = getRandomNumber()) {
        return x * x * x
      }
      

      Теперь при каждом вызове функции cube без параметра результаты могут отличаться:

      // Invoke cube function twice for two potentially different results
      cube()
      cube()
      

      Вывод вызова этих функций будет отличаться:

      Output

      512 64

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

      В следующем примере в качестве значения x назначается случайное число, которое используется как параметр для созданной нами функции cube. Параметр y рассчитывает кубический корень числа и проверяет равенство x и y:

      // Assign a random number to x
      // Assign the cube root of the result of the cube function and x to y
      function doesXEqualY(x = getRandomNumber(), y = Math.cbrt(cube(x))) {
        return x === y
      }
      
      doesXEqualY()
      

      В результате вы получите следующий вывод:

      Output

      true

      Параметр по умолчанию даже может представлять собой определение функции, как видно в этом примере, где параметр определяется как внутренняя функция и возвращается вызов функции parameter:

      // Define a function with a default parameter that is an anonymous function
      function outer(
        parameter = function inner() {
          return 100
        }
      ) {
        return parameter()
      }
      
      // Invoke outer function
      outer()
      

      Output

      100

      Внутренняя функция создается с нуля каждый раз при вызове внешней функции.

      Заключение

      Из этой статьи вы узнали, что представляют собой параметры функций по умолчанию и как их использовать. Теперь вы можете использовать параметры по умолчанию для оптимизации функций и повышения удобства их чтения. Также вы можете назначать для параметров пустые объекты и массивы, чтобы уменьшить сложность и оптимизировать код в таких ситуациях, как извлечение значений из объекта или применение цикла к массиву.

      Если вы хотите узнать больше о JavaScript, перейдите на главную страницу нашей серии материалов Написание кода на JavaScript или перейдите к нашей серии Написание кода на Node.js для изучения материалов по серверной разработке.



      Source link

      Рекомендуемые шаги по обеспечению безопасности кластера DigitalOcean Kubernetes


      Автор выбрал организацию Open Sourcing Mental Illness Ltd для получения пожертвований в рамках программы Write for DOnations.

      Введение

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

      Учитывая составные части Kubernetes, а также разнообразие сценариев развертывания, защита Kubernetes иногда может быть сопряжена с трудностями. Поэтому цель этой статьи заключается в том, чтобы заложить прочную основу безопасности для кластера DigitalOcean Kubernetes (DOKS). Необходимо отметить, что настоящий обучающий модуль охватывает базовые меры безопасности для Kubernetes и служит отправной точкой, а не исчерпывающим руководством. Дополнительные шаги можно найти в официальной документации Kubernetes.

      В этом руководстве вы будете выполнять основные шаги для защиты кластера DigitalOcean Kubernetes. Вы настроите защищенную локальную аутентификацию с сертификатами TLS/SSL, предоставите разрешения локальным пользователям с помощью механизмов управления доступом на базе ролей (RBAC), предоставите разрешения приложениям Kubernetes и развертыванию со служебными учетными записями, а также установите ограничения ресурсов при помощи контроллеров допуска ResourceQuota и LimitRange.

      Предварительные требования

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

      • Управляемый кластер DigitalOcean Kubernetes (DOKS) с тремя стандартными узлами, имеющими не менее чем 2 Гбайт ОЗУ и 1 виртуального процессора каждый. Подробные инструкции по созданию кластера DOKS можно найти в обучающем модуле Начало работы с Kubernetes. В этом обучающем руководстве используется версия DOKS 1.16.2-do.1.
      • Локальный клиент, настроенный для управления кластером DOKS, с файлом конфигурации кластера, загружаемым из панели управления DigitalOcean и сохраняемым как ~/.kube/config. Подробные инструкции по настройке удаленного управления DOKS можно найти в нашем руководстве «Подключение к кластеру DigitalOcean Kubernetes». В частности, вам потребуется следующее:
        • Интерфейс командной строки kubectl, установленный на локальном компьютере. Дополнительную информацию об установке и настройке kubectl можно найти в официальной документации. В этом обучающем руководстве будет использоваться версия kubectl 1.17.0-00.
        • Официальный инструмент командной строки DigitalOcean — doctl. Информацию о выполнении установки можно найти на странице doctl GitHub. В этом обучающем руководстве будет использоваться версия doctl 1.36.0.

      Шаг 1 — Активация аутентификации удаленного пользователя

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

      В этом разделе вы будете выполнять аутентификацию новых пользователей в удаленном кластере DOKS из локальных клиентов при помощи защищенных сертификатов SSL/TLS. Этот процесс будет проходить в три этапа: во-первых, вы создадите запросы подписи сертификатов (CSR) для каждого пользователя, а затем вы будете одобрять эти сертификаты непосредственно в кластере через kubectl. Наконец, вы создадите для каждого пользователя файл kubeconfig с соответствующими сертификатами. Расширенную информацию о дополнительных методах аутентификации при поддержке Kubernetes можно найти в документации по аутентификации Kubernetes.

      Создание запросов подписи сертификатов для новых пользователей

      Перед началом необходимо проверить подключение кластера DOKS к локальному компьютеру, настроенному с предварительными условиями:

      В зависимости от конфигурации, вы увидите примерно следующее:

      Output

      Kubernetes master is running at https://a6616782-5b7f-4381-9c0f-91d6004217c7.k8s.ondigitalocean.com CoreDNS is running at https://a6616782-5b7f-4381-9c0f-91d6004217c7.k8s.ondigitalocean.com/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

      Это означает, что вы подключены к кластеру DOKS.

      Далее создайте локальную папку для сертификатов клиента. Для целей настоящего руководства будет использоваться папка ~/certs для хранения всех сертификатов:

      В этом обучающем руководстве мы дадим новому пользователю с именем sammy доступ к кластеру. Вы можете изменить это на любого пользователя по вашему выбору. Используя библиотеку SSL и TLS OpenSSL, создайте новый закрытый ключ для вашего пользователя с помощью следующей команды:

      • openssl genrsa -out ~/certs/sammy.key 4096

      Флаг -out будет создавать выходной файл ~/certs/sammy.key, а 4096 устанавливает ключ длиной 4096 бит. Дополнительную информацию по OpenSSL можно найти в нашем руководстве по основам OpenSSL.

      Теперь создайте файл конфигурации запроса подписи сертификатов. Откройте следующий файл в текстовом редакторе (в этом обучающем модуле мы будем использовать nano):

      • nano ~/certs/sammy.csr.cnf

      Добавьте в файл sammy.csr.cnf следующее содержимое, чтобы задать в строке темы желаемое имя пользователя как обычное имя (CN) и группу в качестве организации (O):

      ~/certs/sammy.csr.cnf

      [ req ]
      default_bits = 2048
      prompt = no
      default_md = sha256
      distinguished_name = dn
      [ dn ]
      CN = sammy
      O = developers
      [ v3_ext ]
      authorityKeyIdentifier=keyid,issuer:always
      basicConstraints=CA:FALSE
      keyUsage=keyEncipherment,dataEncipherment
      extendedKeyUsage=serverAuth,clientAuth
      

      Файл конфигурации запроса подписи сертификатов содержит всю необходимую информацию, идентификационные данные пользователя и соответствующие параметры использования для данного пользователя. Последний аргумент extendedKeyUsage=serverAuth,clientAuth позволит пользователям аутентифицировать локальных клиентов с кластером DOKS при помощи сертификата после его подписания.

      Далее создайте запрос подписи сертификатов пользователя sammy:

      • openssl req -config ~/certs/sammy.csr.cnf -new -key ~/certs/sammy.key -nodes -out ~/certs/sammy.csr

      Параметр -config позволяет задать файл конфигурации для CSR, а сигналы -new, которые вы создаете — для нового CSR для ключа, указанного в -key.

      Вы можете проверить запрос подписи сертификатов посредством следующей команды:

      • openssl req -in ~/certs/sammy.csr -noout -text

      Здесь вы передаете в CSR с -in и используете -text, чтобы распечатать запрос сертификата в текстовом сообщении.

      В результатах будет показан запрос сертификатов, начало которого будет выглядеть следующим образом:

      Output

      Certificate Request: Data: Version: 1 (0x0) Subject: CN = sammy, O = developers Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (4096 bit) ...

      Повторите эту же процедуру для создания CSR для всех дополнительных пользователей. Когда все запросы подписи сертификатов будут сохранены в папке администратора ~/certs, выполните следующий шаг для их утверждения.

      Управление запросами подписи сертификатов с API Kubernetes

      Вы можете одобрять или отклонять сертификаты TLS, выданные для API Kubernetes, используя инструмент командной строки kubectl. Это дает возможность убедиться, что запрошенный доступ соответствует данному пользователю. В этом разделе мы направим запрос сертификатов для пользователя sammy и одобрим его.

      Чтобы направить CSR в кластер DOKS, используйте следующую команду:

      cat <<EOF | kubectl apply -f -
      apiVersion: certificates.k8s.io/v1beta1
      kind: CertificateSigningRequest
      metadata:
        name: sammy-authentication
      spec:
        groups:
        - system:authenticated
        request: $(cat ~/certs/sammy.csr | base64 | tr -d 'n')
        usages:
        - digital signature
        - key encipherment
        - server auth
        - client auth
      EOF
      

      Используя heredoc-синтаксис в Bash, эта команда использует cat для передачи запроса сертификатов в команду kubectl apply.

      Рассмотрим запрос сертификатов более подробно:

      • name: sammy-authentication создает идентификатор метаданных, в данном случае с именем sammy-authentication.
      • request: $(cat ~/certs/sammy.csr | bar64 | tr -d 'n' направляет запрос подписи сертификатов sammy.csr в кластер, кодифицированный как base64.
      • В server auth и client auth указывается предполагаемое использование сертификата. В данном случае цель — аутентификация пользователя.

      Результат будет выглядеть примерно следующим образом:

      Output

      certificatesigningrequest.certificates.k8s.io/sammy-authentication created

      Вы можете проверить состояние запроса подписи сертификатов с помощью команды:

      В зависимости от конфигурации кластера, вы увидите примерно следующее:

      Output

      NAME AGE REQUESTOR CONDITION sammy-authentication 37s your_DO_email Pending

      Далее одобрите CSR с помощью команды:

      • kubectl certificate approve sammy-authentication

      Вы получите сообщение, подтверждающее операцию:

      Output

      certificatesigningrequest.certificates.k8s.io/sammy-authentication approved

      Примечание: Как администратор, вы также можете отклонить CSR посредством команды ​​​kubectl certificate deny sammy-authentication. Дополнительную информацию по управлению сертификатами TLS можно найти в официальной документации Kubernetes.

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

      • kubectl get csr sammy-authentication -o jsonpath='{.status.certificate}' | base64 --decode > ~/certs/sammy.crt

      Эта команда декодирует сертификат Base64 для надлежащего использования с помощью kubectl, а затем сохраняет его как ~/certs/sammy.crt.

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

      Создание удаленных пользователей Kubeconfig

      Далее вы создадите специальный файл kubeconfig для пользователя sammy. Это позволит лучше контролировать возможность доступа пользователя к вашему кластеру.

      Первый шаг в создании нового kubeconfig — создание копии текущего файла kubeconfig. Для целей настоящего руководства новый файл kubeconfig будет иметь имя config-sammy:

      • cp ~/.kube/config ~/.kube/config-sammy

      Далее, измените новый файл:

      • nano ~/.kube/config-sammy

      Сохраните первые восемь строк этого файла, поскольку они содержат необходимую информацию для подключения SSL/TLS к кластеру. Далее, начиная с параметра user, замените текст следующими выделенными строками, чтобы файл выглядел примерно следующим образом:

      config-sammy

      apiVersion: v1
      clusters:
      - cluster:
          certificate-authority-data: certificate_data
        name: do-nyc1-do-cluster
      contexts:
      - context:
          cluster: do-nyc1-do-cluster
          user: sammy
        name: do-nyc1-do-cluster
      current-context: do-nyc1-do-cluster
      kind: Config
      preferences: {}
      users:
      - name: sammy
        user:
          client-certificate: /home/your_local_user/certs/sammy.crt
          client-key: /home/your_local_user/certs/sammy.key
      

      Примечание: для client-certificate и client-key используйте абсолютный путь к соответствующему местоположению их сертификатов. В противном случае kubectl выдаст ошибку.

      Сохраните и закройте файл.

      Вы можете протестировать новое подключение пользователя с помощью kubectl cluster-info:

      • kubectl --kubeconfig=/home/your_local_user/.kube/config-sammy cluster-info

      Ошибка будет выглядеть примерно так:

      Output

      To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. Error from server (Forbidden): services is forbidden: User "sammy" cannot list resource "services" in API group "" in the namespace "kube-system"

      Эта ошибка ожидается, поскольку пользователь sammy еще не имеет разрешения на запись каких-либо ресурсов в кластер. На следующем шаге будет рассмотрено предоставление разрешений пользователям. В результате вы увидите, что подключение SSL/TLS прошло успешно, а данные аутентификации sammy приняты в Kubernetes API.

      Шаг 2 — Авторизация пользователй через систему контроля доступа на основе ролей (RBAC)

      После аутентификации пользователя API определяет свои разрешения с помощью встроенной модели Kubernetes по контролю доступа на основе ролей (RBAC) RBAC — эффективный способ ограничения прав пользователя на основании его роли. С точки зрения безопасности, RBAC разрешает устанавливать детальные разрешения, чтобы ограничить возможность доступа пользователей к чувствительным данным или выполнения команд уровня суперпользователя. Более подробная информация о ролях пользователей содержится в документации Kubernetes RBAC.

      На этом шаге вы будете использовать kubectl для назначения заранее определенной роли edit пользователю sammy в области имен default. В производственной среде можно использовать настраиваемые роли и/или привязки ролей.

      Предоставление разрешений

      В Kubernetes предоставление разрешений означает назначение требуемой роли пользователю. Назначьте разрешения edit пользователю sammy в пространстве имен default с помощью следующей команды:

      • kubectl create rolebinding sammy-edit-role --clusterrole=edit --user=sammy --namespace=default

      Результат будет выглядеть примерно следующим образом:

      Output

      rolebinding.rbac.authorization.k8s.io/sammy-edit-role created

      Рассмотрим эту команду более подробно:

      • create rolebinding sammy-edit-role создает новую привязку ролей, в данном случае с именем sammy-edit-role.
      • --clusterrole=edit назначает заранее определенную роль edit в глобальном масштабе (роль кластера).
      • --user=sammy указывает, к какому пользователю следует привязать роль.
      • --namespace=default предоставляет пользователю разрешения ролей в пределах указанного пространства имен, в данном случае default.

      Далее проверьте разрешения пользователя посредством указания подов в пространстве имен default. Если ошибки не отображаются, то это означает, что авторизация RBAC работает так, как ожидается.

      • kubectl --kubeconfig=/home/your_local_user/.kube/config-sammy auth can-i get pods

      Результат будет выглядеть следующим образом:

      Output

      yes

      Теперь, когда вы назначили разрешения пользователю sammy, вы можете (в качестве упражнения) отозвать эти разрешения в следующем разделе.

      Отзыв разрешений

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

      В этом обучающем модуле мы удалим роль edit пользователя sammy посредством следующей команды:

      • kubectl delete rolebinding sammy-edit-role

      Результат будет выглядеть следующим образом:

      Output

      rolebinding.rbac.authorization.k8s.io "sammy-edit-role" deleted

      Убедитесь, что разрешения пользователя были правильно отозваны посредством указания подов в пространстве имен default:

      • kubectl --kubeconfig=/home/localuser/.kube/config-sammy --namespace=default get pods

      Вы получите следующую ошибку:

      Output

      Error from server (Forbidden): pods is forbidden: User "sammy" cannot list resource "pods" in API group "" in the namespace "default"

      Это показывает, что авторизация отозвана.

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

      Дополнительную информацию об авторизации RBAC и создании настраиваемых ролей можно найти в официальной документации.

      Шаг 3 — Управление разрешениями приложений со служебными учетными записями

      Как упоминалось в предыдущем разделе, механизмы авторизации RBAC распространяются не только на физических пользователей. Виртуальные пользователи кластера — например, приложения, службы и процессы, запущенные внутри подов — аутентифицируются на сервере API при помощи того, что в Kubernetes называется «служебные учетные записи». Когда под создается в пространстве имен, вы можете либо позволить ему использовать служебную учетную запись default, либо определить служебную учетную запись по своему выбору. Благодаря способности назначать отдельные служебные учетные записи приложениям и процессам администраторы получают возможность предоставлять или отзывать разрешения, по мере необходимости. Кроме того, назначение конкретных служебных учетных записей для приложений, критичных для производства, считается наилучшей практикой безопасности. Поскольку учетные записи используются для аутентификации и, т.о., для проверки авторизации RBAC, администраторы кластеров могут устранять угрозы безопасности посредством изменения прав доступа к служебным учетным записям и изоляции процесса, угрожающего безопасности.

      Чтобы продемонстрировать служебные учетные записи, в этом обучающем руководстве будет использоваться веб-сервер Nginx как образец приложения.

      Перед назначением конкретной служебной учетной записи для вашего приложения ее необходимо создать. Создайте новую учетную запись с именем nginx-sa в пространстве имен default:

      • kubectl create sa nginx-sa

      Вы получите следующее:

      Output

      serviceaccount/nginx-sa created

      Убедитесь, что служебная учетная запись создана посредством следующей команды:

      В результате вы получите список ваших служебных учетных записей:

      Output

      NAME SECRETS AGE default 1 22h nginx-sa 1 80s

      Теперь вы назначите эту роль для служебной учетной записи nginx-sa. В данном примере необходимо предоставить для nginx-sa те же разрешения, что и для пользователя sammy:

      • kubectl create rolebinding nginx-sa-edit
      • --clusterrole=edit
      • --serviceaccount=default:nginx-sa
      • --namespace=default

      В результате будет получено следующее:

      Output

      rolebinding.rbac.authorization.k8s.io/nginx-sa-edit created

      Эта команда использует такой же формат, как для пользователя sammy, кроме флага --serviceaccount=default:nginx-sa, где вы назначаете служебную учетную запись nginx-sa в области имен default.

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

      Результат будет выглядеть следующим образом:

      Output

      NAME AGE nginx-sa-edit 23s

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

      В этом обучающем модуле в качестве образца приложения мы будем использовать под nginx. Создайте новый под и укажите служебную учетную запись nginx-sa с помощью следующей команды:

      • kubectl run nginx --image=nginx --port 80 --serviceaccount="nginx-sa"

      Первая часть команды создает новый под на веб-сервере nginx на порту :80, а последняя часть --serviceaccount="nginx-sa" "nginx-sa" показывает, что данный под должен использовать служебную учетную запись nginx-sa, а не служебную учетную запись default.

      Результат будет выглядеть примерно следующим образом:

      Output

      deployment.apps/nginx created

      Убедитесь, что новое приложение использует служебную учетную запись с помощью kubectl describe:

      • kubectl describe deployment nginx

      В результате будет выведено подробное описание параметров развертывания. В разделе Pod Template вы увидите примерно следующее:

      Output

      ... Pod Template: Labels: run=nginx Service Account: nginx-sa ...

      В этом разделе мы создали служебную учетную запись nginx-sa в пространстве имен default и назначили ее для веб-сервера nginx. Теперь вы можете контролировать разрешения nginx в реальном времени посредством изменения его роли, по мере необходимости. Также вы можете группировать приложения посредством назначения одной служебной учетной записи для каждого из них и последующего внесения массовых изменений в разрешения. Наконец, вы можете изолировать критические приложения посредством назначения для них уникальной служебной учетной записи.

      В целом, смысл назначения ролей для ваших приложений/развертываний состоит в отладке разрешений. В реальной производственной среде может быть установлено несколько развертываний, требующих различных разрешений — от «только для чтения» до полных административных прав. Использование RBAC обеспечивает гибкость для ограничения доступа к кластеру, по мере необходимости.

      Далее вы настроите контроллеры допуска для контроля ресурсов и защиты от атак, вызывающих нехватку ресурсов.

      Шаг 4 — Настройка контроллеров допуска

      Контроллеры допуска Kubernetes — это опциональные плагины, компилируемые в двоичный файл kube-apiserver для расширения возможностей безопасности. Контроллеры допуска перехватывают запросы после прохождения этапа аутентификации и авторизации. После перехвата запроса контроллеры допуска выполняют указанный код непосредственно перед применением запроса.

      Результаты проверки аутентификации или разрешения являются булевыми величинами, разрешающими или отклоняющими запрос, а контроллеры допуска могут быть значительно более разнообразными. Контроллеры допуска могут подтверждать запросы таким же образом, как аутентификация, но также могут изменять запросы и объекты перед их допуском.

      На данном шаге мы будем использовать контроллеры допуска ResourceQuota и LimitRange допуска для защиты кластера посредством изменения запросов, которые могут способствовать возникновению нехватки ресурсов или DoS-атак. Контроллер допуска ResourceQuota позволяет администраторам ограничивать вычислительные ресурсы, ресурсы хранения, а также количество любых объектов в пространстве имен, а контроллер допуска LimitRange ограничивает количество ресурсов, используемых контейнерами. При совместном использовании этих двух контроллеров допуска ваш кластер будет защищен от атак, приводящих к недоступности ресурсов.

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

      • nano resource-quota-default.yaml

      Добавьте следующее определение объекта для определения ограничений использования ресурсов в пространстве имен default. Вы можете изменить значения, если потребуется, в зависимости от физических ресурсов ваших узлов:

      resource-quota-default.yaml

      apiVersion: v1
      kind: ResourceQuota
      metadata:
        name: resource-quota-default
      spec:
        hard:
          pods: "2"
          requests.cpu: "500m"
          requests.memory: 1Gi
          limits.cpu: "1000m"
          limits.memory: 2Gi
          configmaps: "5"
          persistentvolumeclaims: "2"
          replicationcontrollers: "10"
          secrets: "3"
          services: "4"
          services.loadbalancers: "2"
      

      В этом определении используется ключевое слово hard для определения жестких ограничений — например, максимальное количество подов, карт configmaps, объектов PersistentVolumeClaims, контроллеров ReplicationControllers, объектов secrets, сервисов services и типов loadbalancers. В результате также устанавливаются ограничения вычислительных ресурсов:

      • requests.cpu, устанавливающий максимальное значение ЦП запросов в milliCPU, или одну тысячную ядра ЦП.
      • requests.memory, устанавливающий максимальное значение памяти запросов в байтах.
      • limits.cpu, устанавливающий максимальное значение ЦП предельных значений в milliCPU.
      • limits.memory, устанавливающий максимальное значение памяти предельных значений в байтах.

      Сохраните и закройте файл.

      Теперь создайте объект в пространстве имен при помощи следующей команды:

      • kubectl create -f resource-quota-default.yaml --namespace=default

      В результате вы получите следующее:

      Output

      resourcequota/resource-quota-default created

      Обратите внимание, что вы используете флаг -f для указания в Kubernetes места расположения файла ResourceQuota и флаг --namespace для указания, в каком пространстве будет обновлено пространство имен.

      После создания объекта ваш файл ResourceQuota будет активен. Вы можете проверить квоты пространств имен default с помощью describe quota:

      • kubectl describe quota --namespace=default

      Результат будет выглядеть примерно так, с жесткими ограничениями, которые вы задали в файле resource-quota-default.yaml:

      Output

      Name: resource-quota-default Namespace: default Resource Used Hard -------- ---- ---- configmaps 0 5 limits.cpu 0 1 limits.memory 0 2Gi persistentvolumeclaims 0 2 pods 1 2 replicationcontrollers 0 10 requests.cpu 0 500m requests.memory 0 1Gi secrets 2 3 services 1 4 services.loadbalancers 0 2

      ResourceQuotas выражаются в абсолютных единицах, поэтому добавление дополнительных узлов не будет автоматически увеличивать значения, определенные здесь. При добавлении дополнительных узлов вам потребуется вручную изменить эти значения для пропорционального распределения ресурсов. ResourceQuotas могут изменяться так часто, как вам потребуется, но они не могут удаляться, за исключением случаев, когда удаляется все пространство имен.

      Если вам потребуется изменить определенный файл ResourceQuota, обновите соответствующий файл .yaml и примените изменения с помощью следующей команды:

      • kubectl apply -f resource-quota-default.yaml --namespace=default

      Дополнительную информацию по контроллеру допуска ResourceQuota можно найти в официальной документации.

      После настройки вашего ResourceQuota вы перейдете к настройке контроллера допуска LimitRange. Аналогично тому, как ResourceQuota ограничивает пространства имен, LimitRange обеспечивает ограничения, заданные посредством подтверждения контейнеров и их изменения.

      Как и ранее, необходимо начать с создания файла объекта:

      • nano limit-range-default.yaml

      Теперь вы можете использовать объект LimitRange для ограничения использования ресурсов, по мере необходимости. Добавьте следующее содержимое в качестве образца типичного случая использования:

      limit-ranges-default.yaml

      apiVersion: v1
      kind: LimitRange
      metadata:
        name: limit-range-default
      spec:
        limits:
        - max:
            cpu: "400m"
            memory: "1Gi"
          min:
            cpu: "100m"
            memory: "100Mi"
          default:
            cpu: "250m"
            memory: "800Mi"
          defaultRequest:
            cpu: "150m"
            memory: "256Mi"
          type: Container
      

      Шаблонные значения, используемые в limit-ranges-default.yaml , ограничивают память контейнера максимальным значением 1Gi и ограничивают загрузку ЦП максимальным значением 400m — метрический эквивалент 400 milliCPU в Kubernetes, что означает, что контейнер ограничен использованием почти половины его ядра.

      Далее, разверните объект для сервера API с помощью следующей команды:

      • kubectl create -f limit-range-default.yaml --namespace=default

      Результат будет выглядеть следующим образом:

      Output

      limitrange/limit-range-default created

      Теперь вы можете проверить новые пределы с помощью следующей команды:

      • kubectl describe limits --namespace=default

      Результат будет выглядеть примерно следующим образом:

      Output

      Name: limit-range-default Namespace: default Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio ---- -------- --- --- --------------- ------------- ----------------------- Container cpu 100m 400m 150m 250m - Container memory 100Mi 1Gi 256Mi 800Mi -

      Чтобы увидеть LimitRanger в действии, разверните стандартный контейнер nginx с помощью следующей команды:

      • kubectl run nginx --image=nginx --port=80 --restart=Never

      Результат будет выглядеть следующим образом:

      Output

      pod/nginx created

      Проверьте, как контроллер допуска изменил контейнер, с помощью следующей команды:

      • kubectl get pod nginx -o yaml

      В результате будет получено много строк результатов. Посмотрите раздел спецификаций контейнера, чтобы узнать ограничения ресурсов, указанные контроллером допуска LimitRange:

      Output

      ... spec: containers: - image: nginx imagePullPolicy: IfNotPresent name: nginx ports: - containerPort: 80 protocol: TCP resources: limits: cpu: 250m memory: 800Mi requests: cpu: 150m memory: 256Mi ...

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

      На данном шаге вы использовали контроллеры допуска ResourceQuota и LimitRange для защиты от нападений злоумышленников на ресурсы вашего кластера. Дополнительную информацию по контроллеру допуска LimitRange можно найти в официальной документации.

      Заключение

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

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



      Source link