Polaris кластера Kubernetes «физический осмотр»

задняя часть Kubernetes
Polaris кластера Kubernetes «физический осмотр»

«Эта статья участвовала в мероприятии Haowen Convocation Order, щелкните, чтобы просмотреть:Двойные заявки на внутреннюю и внешнюю стороны, призовой фонд в 20 000 юаней ждет вас, чтобы бросить вызов!"

1 Введение в Polaris

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

2 функции Polaris

Polaris — это компонент проверки работоспособности, который анализирует конфигурацию развертывания для поиска проблем в кластере. Конечно, цель Polaris — не только найти проблемы, но и предложить решения, позволяющие их избежать и обеспечить работоспособность кластера. Основные функции Polaris будут представлены ниже: Polaris состоит из 3-х компонентов, которые реализуют разные функции:

  • Панель инструментов — просмотр рабочего состояния и точек оптимизации текущих рабочих нагрузок Kubernetes на графике.
  • Webhook - предотвращает установку нестандартного приложения в кластере
  • CLI - проверьте локальные файлы yaml, можно использовать с CI/CD

2.1 Dashboard

Dashboard — это инструмент визуализации, предоставляемый polaris для просмотра обзора состояния рабочих нагрузок Kubernetes и точек оптимизации. Вы также можете просматривать по категориям, пространствам имен и рабочей нагрузке.

2.1.1 Обзор состояния кластера

  • Просмотр показателя работоспособности кластера
  • Посмотреть результаты проверки кластера
  • Просмотр версии кластера, количества узлов, модулей, пространств имен
# kubectl apply -f https://github.com/fairwindsops/polaris/releases/latest/download/dashboard.yaml
# kubectl port-forward --namespace polaris svc/polaris-dashboard 8080:80

Просмотр результатов проверки по категориям

  • Health Checks
  • Images
  • Networking
  • Resources
  • Security

Просмотр результатов проверки по пространству имен

2.1.2 Проверьте локальный файл yaml для запуска

polaris dashboard --port 8080 --audit-path=/Users/mervinwang/Tencent/Code/Kubernetes/app/nginx

2.2 Webhook

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

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

2.3 CLI

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

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

3 Установка и использование

полярная поддержкаkubectl, helm and local binaryСуществует три метода установки. В этой статье выбирается самый простой способ установки и рассказывается об установке трех компонентов.

3.1 Установка приборной панели

Helm

Добавить репозиторий рулевых диаграмм

helm repo add reactiveops-stable https://charts.reactiveops.com/stable 

Обновите репозиторий графиков и установите компонент Dashboard.

helm upgrade --install polaris reactiveops-stable/polaris --namespace polaris 

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

kubectl port-forward --namespace polaris svc/polaris-dashboard 8080:80 

3.2 Установка вебхука

После установки компонента Webhook в кластере он предотвратит развертывание несовместимых приложений в кластере.

helm

Добавить репозиторий рулевых диаграмм

helm repo add reactiveops-stable https://charts.reactiveops.com/stable 

Обновите репозиторий графиков и установите компонент Webhook.

helm upgrade --install polaris reactiveops-stable/polaris --namespace polaris \
  --set webhook.enable=true --set dashboard.enable=false 

3.3 Установка интерфейса командной строки

Если вам нужно протестировать polaris локально, вы можете скачать бинарный файл для установкиreleases page, вы также можете использоватьHomebrewУстановить:

brew tap reactiveops/tap
brew install reactiveops/tap/polaris
polaris --version

Проверьте локальные файлы конфигурации с помощью CLI

polaris --audit --audit-path ./deploy/ 

Может сохранять результаты сканирования в файл yaml

polaris --audit --output-format yaml > report.yaml 

4 Использование Polaris

Вышеизложенное кратко знакомит с установкой и основным использованием поляриса. Однако, если мы хотим объединить полярис в соответствии с реальной ситуацией нашего проекта, использование конфигурации по умолчанию не будет соответствовать требованиям. Поэтому нам также нужно знать, как определить файл конфигурации правил проверки polaris для реализации пользовательской конфигурации. Прежде чем настраивать конфигурацию polaris, нам нужно понять уровень проверок polaris и поддерживаемые типы проверок. Уровни серьезности проверок polaris делятся наerror,warningиignore, полярис не проверитignoreЭлемент конфигурации уровня. Типы проверки, поддерживаемые polaris:Health Checks,Images,Networking,Resources,Security, мы будем вводить их один за другим:

4.1 Проверка работоспособности

Polaris поддерживает проверку наличия датчиков готовности и работоспособности в модулях.

key default description
readinessProbeMissing warning Не настроен для PodreadinessСбой зонда
livenessProbeMissing warning Не настроен для PodlivenessСбой зонда
tagNotSpecified danger Для изображения не указан тег или указанный тегlatestне удалось
pullPolicyNotAlways warning Когда стратегия извлечения изображений неalwaysне удалось
priorityClassNotSet ignore Если не настроен для PodpriorityClassNameне удалось
multipleReplicasForDeployment ignore когдаDeploymentизReplicasтерпит неудачу, когда 1
missingPodDisruptionBudget ignore

4.2 Ресурсы

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

key default description
cpuRequestsMissing warning нет конфигурацииresources.requests.cpuне удалось
memoryRequestsMissing warning нет конфигурацииresources.requests.memoryне удалось
cpuLimitsMissing warning нет конфигурацииresources.limits.cpuне удалось
memoryLimitsMissing warning нет конфигурацииresources.limits.memoryне удалось

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

limits:
  type: object
  required:
  - memory
  - cpu
    properties:
    memory:
      type: string
      resourceMinimum: 100M
      resourceMaximum: 6G
    cpu:
      type: string
      resourceMinimum: 100m
      resourceMaximum: "2" 

4.3 Безопасность

key default description
hostIPCSet danger Fails when hostIPC attribute is configured.
hostPIDSet danger Fails when hostPID attribute is configured.
notReadOnlyRootFilesystem warning Fails when securityContext.readOnlyRootFilesystem is not true.
privilegeEscalationAllowed danger Fails when securityContext.allowPrivilegeEscalation is true.
runAsRootAllowed warning Fails when securityContext.runAsNonRoot is not true.
runAsPrivileged danger Fails when securityContext.privileged is true.
insecureCapabilities warning Fails when securityContext.capabilities includes one of the capabilities listed here(opens new window)
dangerousCapabilities danger Fails when securityContext.capabilities includes one of the capabilities listed here(opens new window)
hostNetworkSet warning Fails when hostNetwork attribute is configured.
hostPortSet warning Fails when hostPort attribute is configured.
tlsSettingsMissing warning Fails when an Ingress lacks TLS settings.

4.4 Пользовательские правила сканирования

Согласно приведенному выше введению, мы уже можем определить нашу собственную конфигурацию сканирования в соответствии с реальной ситуацией в проекте. Если мы чувствуем, что правила проверки, предоставленные polaris, не соответствуют нашим потребностям, мы также можем настроить правила проверки. Например: мы можем настроить правила для проверки источника зеркала, когда зеркало исходит изquay.ioбросить предупреждение

checks:
  imageRegistry: warning
customChecks:
  imageRegistry:
    successMessage: Image comes from allowed registries
    failureMessage: Image should not be from disallowed registry
    category: Images
    target: Container # target can be "Container" or "Pod"
    schema:
      '$schema': http://json-schema.org/draft-07/schema
      type: object
      properties:
        image:
          type: string
          not:
            pattern: ^quay.io 

Также можно указать элементы проверки

checks:
  cpuRequestsMissing: danger
  memoryRequestsMissing: danger
  cpuLimitsMissing: danger
  memoryLimitsMissing: danger
 polaris audit -c check_config.yaml --.......

5 Проверьте результаты

{
  "PolarisOutputVersion": "1.0",
  "AuditTime": "2021-07-01T15:07:00+08:00",
  "SourceType": "Path",
  "SourceName": "/Users/mervinwang/Tencent/Code/Kubernetes/app/nginx",
  "DisplayName": "/Users/mervinwang/Tencent/Code/Kubernetes/app/nginx",
  "ClusterInfo": {
    "Version": "unknown",
    "Nodes": 0,
    "Pods": 0,
    "Namespaces": 0,
    "Controllers": 1
  },
  "Results": [
    {
      "Name": "nginx-config",
      "Namespace": "",
      "Kind": "ConfigMap",
      "Results": {},
      "PodResult": null,
      "CreatedTime": "0001-01-01T00:00:00Z"
    },
    {
      "Name": "nginx-deployment",
      "Namespace": "",
      "Kind": "Deployment",
      "Results": {},
      "PodResult": {
        "Name": "",
        "Results": {},
        "ContainerResults": [
          {
            "Name": "nginx",
            "Results": {
              "cpuLimitsMissing": {
                "ID": "cpuLimitsMissing",
                "Message": "CPU limits should be set",
                "Details": null,
                "Success": false,
                "Severity": "danger",
                "Category": "Efficiency"
              },
              "cpuRequestsMissing": {
                "ID": "cpuRequestsMissing",
                "Message": "CPU requests should be set",
                "Details": null,
                "Success": false,
                "Severity": "danger",
                "Category": "Efficiency"
              },
              "memoryLimitsMissing": {
                "ID": "memoryLimitsMissing",
                "Message": "Memory limits should be set",
                "Details": null,
                "Success": false,
                "Severity": "danger",
                "Category": "Efficiency"
              },
              "memoryRequestsMissing": {
                "ID": "memoryRequestsMissing",
                "Message": "Memory requests should be set",
                "Details": null,
                "Success": false,
                "Severity": "danger",
                "Category": "Efficiency"
              }
            }
          }
        ]
      },
      "CreatedTime": "0001-01-01T00:00:00Z"
    }
  ],
  "Score": 0
}

6 Результаты проверки обработки Python

После запуска проверки Pollaris на кластере возвращаемый результат - json, что не интуитивно понятно Мы используем Python для обработки результатов и вывода их на лист Excel для удобства просмотра.

import yaml
import os
import xlsxwriter

# config
fileNamePath = os.path.split(os.path.realpath(__file__))[0]
config = os.path.join(fileNamePath,'check_config.yaml')
cluster_config = os.path.join(fileNamePath,'cluster_list.yaml')

# variable
scan_controller_type = ["Deployment", "DaemonSet", "StatefulSet"]
def read_cluster():
    f = open(cluster_config,'r',encoding='utf-8')
    cont = f.read()
    return yaml.load(cont, Loader=yaml.FullLoader)


def generate_report(cluster_id: str):
    scan_command = f"polaris audit -c {config} --kubeconfig ~/.kube/config --only-show-failed-tests true --output-file result/{cluster_id}.yaml"
    try:
        os.system(scan_command)
    except Exception as e:
        print(e)

def format_data(cluster):
    cluster_report = os.path.join(fileNamePath, 'result/{}.yaml'.format(cluster))
    f = open(cluster_report, 'r', encoding='utf-8')
    cont = f.read()
    x = yaml.load(cont, Loader=yaml.FullLoader)
    data_result = x["Results"]
    data_list = []
    for item in data_result:
        if item["Kind"] in scan_controller_type and item['PodResult']["ContainerResults"][0]["Results"]:
            pod_scan_result = []
            for pod_result in item['PodResult']["ContainerResults"]:
                pod_name = pod_result["Name"]
                pod_scan_result.append([item for item in pod_result["Results"]])
                obj = [cluster, item["Kind"], item["Namespace"], item["Name"], pod_name, str(pod_scan_result[0])]
                data_list.append(obj)
    return data_list

def excel_config(workbook):
    column_name = ['ClusterID', 'Kind', 'NameSpace', 'Name', 'PodName', 'Scan Result']

    merge_format = workbook.add_format({
        'font_size': 22,
        'bold': True,
        'font_color': '#FFFFFF',
        'border': 1,
        'font_name':u'苹方-简',
        'align': 'center',
        'valign': 'vcenter',
        'fg_color': '#0174DF'
    })
    Title_format = workbook.add_format({
        'font_size': 18,
        'border': 1,
        'bold': True,
        'align': 'center',
        'font_name': u'苹方-简',
        'valign': 'vcenter',
    })
    data_format = workbook.add_format({
        'font_size': 16,
        'border': 1,
        'align': 'center',
        'font_name': u'苹方-简',
        'valign': 'vcenter',
    })
    return column_name, merge_format, Title_format, data_format


def generate_excel():
    workbook = xlsxwriter.Workbook("scan_result.xlsx")
    column_name, merge_format, Title_format, data_format = excel_config(workbook)
    for cluster in read_cluster()["clusters"]:
        print(f"Scan cluster start: {cluster}")
        generate_report(cluster)
        worksheet = workbook.add_worksheet(cluster)
        worksheet.merge_range('A1:F1', f'集群 {cluster} Requests/Limits 扫描结果', merge_format)
        worksheet.set_column('A:F', 35)
        worksheet.set_column('F:F', 130)
        worksheet.set_row(0, 50)
        global ECSNUM
        ECSNUM = 3
        scan_result = format_data(cluster)
        if scan_result != None:
            worksheet.write_row('A2', column_name, Title_format)
            # 如果结不为空,则代表有资源,则写入数据
            for item in scan_result:
                worksheet.write_row('A' + str(ECSNUM), item, data_format)
                ECSNUM += 1
        # 否则,代表该地域无资源,写入 NULL
        else:
            worksheet.merge_range('A3:F3', 'NOT Found INFO', data_format)

    workbook.close()

if __name__ == '__main__':
    generate_excel()