«Эта статья участвовала в мероприятии 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()