1 - Привіт Minikube
З цього навчального матеріалу ви дізнаєтесь, як запустити у Kubernetes простий Hello World застосунок на Node.js за допомогою Minikube і Katacoda. Katacoda надає безплатне Kubernetes середовище, що доступне у вашому браузері.
Примітка:
Також ви можете навчатись за цим матеріалом, якщо встановили
Minikube локально.
Цілі
- Розгорнути Hello World застосунок у Minikube.
- Переглянути логи застосунку.
Перш ніж ви розпочнете
У цьому навчальному матеріалі ми використовуємо образ контейнера, зібраний із наступних файлів:
var http = require('http');
var handleRequest = function(request, response) {
console.log('Received request for URL: ' + request.url);
response.writeHead(200);
response.end('Hello World!');
};
var www = http.createServer(handleRequest);
www.listen(8080);
FROM node:6.14.2
EXPOSE 8080
COPY server.js .
CMD [ "node", "server.js" ]
Більше інформації про команду docker build ви знайдете у документації Docker.
Створення Minikube кластера
-
Натисніть кнопку Запуск термінала
Примітка:
Якщо Minikube встановлений локально, виконайте команду minikube start.
-
Відкрийте Kubernetes дашборд у браузері:
- Тільки для Katacoda: у верхній частині вікна термінала натисніть знак плюс, а потім -- Select port to view on Host 1.
- Тільки для Katacoda: введіть
30000, а потім натисніть Display Port.
Створення Deployment
Pod у Kubernetes -- це група з одного або декількох контейнерів, що об'єднані разом з метою адміністрування і роботи у мережі. У цьому навчальному матеріалі Pod має лише один контейнер. Kubernetes Deployment перевіряє стан Pod'а і перезапускає контейнер Pod'а, якщо контейнер перестає працювати. Створювати і масштабувати Pod'и рекомендується за допомогою Deployment'ів.
-
За допомогою команди kubectl create створіть Deployment, який керуватиме Pod'ом. Pod запускає контейнер на основі наданого Docker образу.
kubectl create deployment hello-node --image=registry.k8s.io/e2e-test-images/agnhost:2.53 -- /agnhost netexec --http-port=8080
-
Перегляньте інформацію про запущений Deployment:
У виводі ви побачите подібну інформацію:
NAME READY UP-TO-DATE AVAILABLE AGE
hello-node 1/1 1 1 1m
-
Перегляньте інформацію про запущені Pod'и:
У виводі ви побачите подібну інформацію:
NAME READY STATUS RESTARTS AGE
hello-node-5f76cf6ccf-br9b5 1/1 Running 0 1m
-
Перегляньте події кластера:
-
Перегляньте конфігурацію kubectl:
Створення Service
За умовчанням, Pod доступний лише за внутрішньою IP-адресою у межах Kubernetes кластера. Для того, щоб контейнер hello-node став доступний за межами віртуальної мережі Kubernetes, Pod необхідно відкрити як Kubernetes Service.
-
Відкрийте Pod для публічного доступу з інтернету за допомогою команди kubectl expose:
kubectl expose deployment hello-node --type=LoadBalancer --port=8080
Прапорець `--type=LoadBalancer` вказує, що ви хочете відкрити доступ до Service за межами кластера.
-
Перегляньте інформацію про Service, який ви щойно створили:
У виводі ви побачите подібну інформацію:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-node LoadBalancer 10.108.144.78 <pending> 8080:30369/TCP 21s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23m
Для хмарних провайдерів, що підтримують балансування навантаження, доступ до Service надається через зовнішню IP-адресу. Для Minikube, тип `LoadBalancer` робить Service доступним ззовні за допомогою команди `minikube service`.
-
Виконайте наступну команду:
minikube service hello-node
- Тільки для Katacoda: натисніть знак плюс, а потім -- Select port to view on Host 1.
-
Тільки для Katacoda: запишіть п'ятизначний номер порту, що відображається напроти 8080 у виводі сервісу. Номер цього порту генерується довільно і тому може бути іншим у вашому випадку. Введіть номер порту у призначене для цього текстове поле і натисніть Display Port. У нашому прикладі номер порту 30369.
Це відкриє вікно браузера, в якому запущений ваш застосунок, і покаже повідомлення "Hello World".
Увімкнення розширень
Minikube має ряд вбудованих розширень, які можна увімкнути, вимкнути і відкрити у локальному Kubernetes оточенні.
-
Перегляньте перелік підтримуваних розширень:
У виводі ви побачите подібну інформацію:
addon-manager: enabled
dashboard: enabled
default-storageclass: enabled
efk: disabled
freshpod: disabled
gvisor: disabled
helm-tiller: disabled
ingress: disabled
ingress-dns: disabled
logviewer: disabled
metrics-server: disabled
nvidia-driver-installer: disabled
nvidia-gpu-device-plugin: disabled
registry: disabled
registry-creds: disabled
storage-provisioner: enabled
storage-provisioner-gluster: disabled
-
Увімкніть розширення, наприклад metrics-server:
minikube addons enable metrics-server
У виводі ви побачите подібну інформацію:
metrics-server was successfully enabled
-
Перегляньте інформацію про Pod і Service, які ви щойно створили:
kubectl get pod,svc -n kube-system
У виводі ви побачите подібну інформацію:
NAME READY STATUS RESTARTS AGE
pod/coredns-5644d7b6d9-mh9ll 1/1 Running 0 34m
pod/coredns-5644d7b6d9-pqd2t 1/1 Running 0 34m
pod/metrics-server-67fb648c5 1/1 Running 0 26s
pod/etcd-minikube 1/1 Running 0 34m
pod/influxdb-grafana-b29w8 2/2 Running 0 26s
pod/kube-addon-manager-minikube 1/1 Running 0 34m
pod/kube-apiserver-minikube 1/1 Running 0 34m
pod/kube-controller-manager-minikube 1/1 Running 0 34m
pod/kube-proxy-rnlps 1/1 Running 0 34m
pod/kube-scheduler-minikube 1/1 Running 0 34m
pod/storage-provisioner 1/1 Running 0 34m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/metrics-server ClusterIP 10.96.241.45 <none> 80/TCP 26s
service/kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 34m
service/monitoring-grafana NodePort 10.99.24.54 <none> 80:30002/TCP 26s
service/monitoring-influxdb ClusterIP 10.111.169.94 <none> 8083/TCP,8086/TCP 26s
-
Вимкніть metrics-server:
minikube addons disable metrics-server
У виводі ви побачите подібну інформацію:
metrics-server was successfully disabled
Вивільнення ресурсів
Тепер ви можете видалити ресурси, які створили у вашому кластері:
kubectl delete service hello-node
kubectl delete deployment hello-node
За бажанням, зупиніть віртуальну машину (ВМ) з Minikube:
За бажанням, видаліть ВМ з Minikube:
Що далі
10 - Вивчаємо Validating та Mutating Admission Policies
Використовуйте декларативні політики допуску для перевірки або зміни ресурсів під час допуску за допомогою Common Expression Language (CEL).
Ця сторінка дозволяє вам спробувати декларативні політики допуску, які дають змогу використовувати Common Expression Language (CEL) для перевірки або зміни ресурсів.
Kubernetes 1.37 підтримує два види політик допуску:
Цей посібник охоплює обидва види політик допуску.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Щоб визначати політики допуску, ви маєте бути адміністратором кластера. Переконайтеся, що маєте доступ адміністратора до кластера, на якому навчаєтеся.
Для ValidatingAdmissionPolicy вам потрібно:
- Кластер версії 1.30 або новішої.
Для MutatingAdmissionPolicy вам потрібно:
- Кластер версії 1.36 або новішої.
Щоб перевірити версію, виконайте kubectl version. Якщо ви використовуєте старішу версію Kubernetes, перегляньте документацію для цієї версії.
Що таке декларативні політики допуску?
Декларативні політики допуску пропонують декларативну, вбудовану альтернативу вебхукам допуску.
Використовуючи Common Expression Language (CEL) для оголошення правил політики, ці політики оцінюються безпосередньо в API-сервері.
Ці політики мають широкі можливості налаштування, що дозволяє авторам політик визначати логіку, яку адміністратори кластерів можуть параметризувати та застосовувати до ресурсів залежно від потреб.
Типи API для політик допуску
Ці два типи політик мають різне призначення.
ValidatingAdmissionPolicy призначена для забезпечення обмежень.
MutatingAdmissionPolicy призначена для зміни ресурсів під час допуску.
Елементи політики
Кожна застосована політика завжди має обʼєкт політики (ValidatingAdmissionPolicy або MutatingAdmissionPolicy) та окремий обʼєкт привʼязки (ValidatingAdmissionPolicyBinding або MutatingAdmissionPolicyBinding).
Ви також можете використовувати параметри, які є необовʼязковими. Докладніше див. ресурси параметрів (ValidatingAdmissionPolicy) або ресурси параметрів (MutatingAdmissionPolicy).
Обʼєкти політики описують абстрактну логіку політики за допомогою Common Expression Language (CEL). Наприклад, ValidatingAdmissionPolicy може обмежувати кількість реплік або гарантувати наявність певних міток, тоді як MutatingAdmissionPolicy може змінювати ресурси, наприклад додавати типову мітку до простору імен.
Обʼєкти привʼязки повʼязують політику з вашим кластером і визначають область її дії. ValidatingAdmissionPolicyBinding або MutatingAdmissionPolicyBinding зʼєднує політику з конкретними ресурсами. Якщо ви хочете застосовувати політику лише до певної підмножини ресурсів, саме в привʼязці ви звужуєте область дії політики (за допомогою matchResources).
Параметри дають змогу відокремити конфігурацію поведінки політики від її визначення. Ресурси параметрів — це ресурси Kubernetes, доступні в API. Це можуть бути вбудовані типи API (як-от ConfigMap) або власні ресурси. Привʼязка політики потім використовує spec.paramRef, щоб посилатися на фактичний ресурс параметра.
Якщо політика не потребує параметрів, ви не вказуєте spec.paramKind.
Вирази CEL
Обидва види політик спираються на мову виразів, відому як Common Expression Language (CEL). Прочитайте CEL у Kubernetes, щоб дізнатися більше.
Якщо ви новачок у CEL, потренуйтеся писати дуже простий вираз, як-от false || true. Тестувати вирази CEL можна в CEL Playground.
Дії політики
Кожна привʼязка політики допуску повинна вказувати одну або кілька дій, щоб оголосити, як політика застосовується.
ValidatingAdmissionPolicyBinding
Для ValidatingAdmissionPolicyBinding підтримуваними validationActions є:
- Audit
- Помилка перевірки включається до події аудиту для API-запиту.
- Warn
- Помилка перевірки повідомляється клієнту запиту як попередження.
- Deny
- Помилка перевірки призводить до відхилення запиту.
Невдала перевірка політики або помилка, що виникла, обробляються відповідно до цих дій. Збої, визначені failurePolicy, обробляються відповідно до цих дій, лише якщо failurePolicy встановлено в Fail (або не вказано).
Докладніше про логування аудиту для політик див. у розділі Анотації аудиту: помилки перевірки.
Не можна використовувати Deny і Warn разом, оскільки така комбінація дублювала б помилку перевірки і в тілі відповіді API, і в HTTP-заголовку Warning:.
MutatingAdmissionPolicyBinding
Для MutatingAdmissionPolicyBinding дія завжди полягає у зміні обʼєкта.
Ви можете використовувати JSON Patch або apply configuration Kubernetes.
Забезпечення дотримання шляхом перевірки
Тепер спробуйте визначити ValidatingAdmissionPolicy.
Нижче наведено приклад ValidatingAdmissionPolicy, яка вимагає, щоб будь-який Deployment мав кілька реплік.
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "enforce-multiple-replicas-deployments"
annotations:
kubernetes.io/description: "Require that matching Deployments have multiple replicas"
spec:
matchConstraints:
resourceRules:
- apiGroups: ["apps"]
apiVersions: ["v1"]
resources: ["deployments"] # the Deployment API
operations: ["CREATE", "UPDATE"] # the API verb, converted to upper case
validations:
- expression: "object.spec.replicas >= 2"
spec.validations містить вирази CEL, які використовують Common Expression Language (CEL) для перевірки запиту. Якщо вираз оцінюється як false, перевірка застосовується відповідно до поля spec.failurePolicy.
Напишіть подібну політику й застосуйте її.
Або, якщо ви хочете застосувати готовий маніфест:
kubectl apply --server-side -f https://k8s.io/examples/access/manifest-admission-control/vap-min-replicas.yaml
Сама по собі вона нічого не робить.
Ви можете спробувати створити Deployment з 0 або 1 реплікою; це працюватиме (хіба що інша політика завадить цьому).
Щоб вона запрацювала, визначте ValidatingAdmissionPolicyBinding.
Виберіть простір імен, де ви будете застосовувати нову політику.
Нижче наведено приклад ValidatingAdmissionPolicyBinding для політики, яку ви створили:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: enforce-multiple-replicas-deployments-binding
spec:
policyName: "enforce-multiple-replicas-deployments"
validationActions: [Deny]
matchResources:
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: default # змініть це, щоб відповідати простору імен, який ви використовуєте
Увага:
Будь-хто з повним/адміністративним доступом до простору імен може записувати його мітки. Це включає видалення мітки з простору імен.
Мітка kubernetes.io/metadata.name захищена, але якщо ви використовуєте іншу мітку, подбайте, щоб видаляти або редагувати вибрану вами мітку могли лише довірені користувачі.
Створіть маніфест на основі цього прикладу YAML (якщо ви використовуєте простір імен default, ви можете використовувати його без змін). Застосуйте маніфест за допомогою kubectl apply.
Тестування політики
Тепер перевірте політику. Спробуйте створити Deployment, а потім масштабувати його до 0 реплік за допомогою kubectl scale. Що відбувається?
Ви можете змінити ValidatingAdmissionPolicyBinding, щоб використовувати іншу дію перевірки замість Deny. Якщо вибрати дію перевірки Warning і спробувати масштабувати Deployment до 0 реплік, що станеться?
Примітка:
Якщо ви дійсно змінили налаштування ValidatingAdmissionPolicyBinding так, щоб воно лише попереджало користувачів, то тут є проблема…
Назва неправильна! Якщо ви змінюєте ValidatingAdmissionPolicyBinding або повʼязану ValidatingAdmissionPolicy так, що вона лише попереджає людей, ви повинні перевірити, чи також потрібно змінити назву політики. Ви б змінили назву, щоб переконатися, що назва не вводить людей в оману.
Це не впливає на наявні ресурси
Якщо у вас є Deployment з 0 або 1 реплікою і ви знову перемкнете ValidatingAdmissionPolicyBinding у режим Deny, це не вплине на жодні наявні ресурси.
(Якщо ви захочете масштабувати Deployment до щонайменше 2 реплік, цього можна досягти іншим способом — наприклад, за допомогою контролера).
На цьому все для ValidatingAdmissionPolicy. Тепер ви дізнаєтеся про MutatingAdmissionPolicies.
Зміна ресурсів під час їх створення або зміни
Для цього прикладу уявіть, що ви хочете використовувати Pod security admission для забезпечення того, щоб простори імен, окрім системних просторів імен, застосовували стандарт безпеки Podʼів.
Подібно до перевірки, ви можете створити MutatingAdmissionPolicy, яка може змінювати ресурси під час допуску. Тип API, який вам потрібно змінити, — це Namespace.
Ось MutatingAdmissionPolicy, яка робить частину цього:
---
# Caution: read the notes for this default-pod-security-baseline policy before
# you apply it, so that you understand the information security consequences.
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingAdmissionPolicy
metadata:
name: "default-pod-security-baseline"
annotations:
kubernetes.io/description: "Default new namespaces to enforce the Baseline pod security standard"
spec:
reinvocationPolicy: IfNeeded
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE"]
resources: ["namespaces"]
matchConditions:
- name: "exclude-system-namespaces"
# If the name begins with "kube-", it's a system namespace.
# Assume that the API server or cluster management tooling applies relevant defaults.
expression: "!object.metadata.name.startsWith('kube-')"
- name: "no-existing-pod-security-label"
expression: "!('pod-security.kubernetes.io/enforce' in object.metadata.labels)"
mutations:
- patchType: "ApplyConfiguration"
applyConfiguration:
expression: "Object{metadata: Object.metadata{labels: {'pod-security.kubernetes.io/enforce': 'baseline'}}}"
Увага:
Ця політика встановлює типове значення. Той, хто має можливість оновлювати Namespace, може видалити мітку pod-security.kubernetes.io/enforce з простору імен.
Якщо ви не впевнені, що це означає, прочитайте документацію з безпеки або зверніться по зовнішню консультацію з інформаційної безпеки.
Щоб застосувати цю політику:
kubectl apply --server-side -f https://k8s.io/examples/access/manifest-admission-control/default-pod-security-baseline.yaml
Щоб активувати цю політику, потрібен MutatingAdmissionPolicyBinding; наприклад:
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingAdmissionPolicyBinding
metadata:
name: default-pod-security-baseline
spec:
# назва MutatingAdmissionPolicy, яку застосовувати
policyName: default-pod-security-baseline
Тестування політики
Спробуйте створити новий простір імен з назвою example:
kubectl create ns example
Перевірте його мітки:
kubectl describe ns example
Хоча ви не вказали рівень примусового застосування Pod security admission, мітку встановлено.
Далі перевірте, чи можете знайти спосіб обійти налаштування безпеки. Створіть YAML-маніфест для іншого Namespace:
apiVersion: v1
kind: Namespace
metadata:
name: another-example
labels:
pod-security.kubernetes.io/enforce: privileged
Ви можете створити цей простір імен з локального маніфесту за допомогою kubectl apply --server-side. Чи це працює?
Так, і новий простір імен дозволяє запускати привілейовані Podʼи.
Ця політика допуску не була налаштована для перевірки чи обмеження. Вона надає типове значення, але ви можете встановити власне. Однак ви можете поєднати змінювальний допуск із політикою перевірки допуску, щоб щось примусово забезпечити й водночас полегшити дотримання вимог. (Цей посібник цього не пояснює, але так можна зробити.)
Надання корисного типового значення означає, що коли люди нічого не встановлюють, вони отримують кращий результат, ніж просто повідомлення про помилку. Уявіть, що у вас є правило перевірки, згідно з яким усі простори імен мають примусово застосовувати щонайменше стандарт baseline. Той, хто не знає про це правило, може спробувати щось розгорнути й одразу побачити повідомлення про помилку, коли спробує створити простір імен.
Використання ресурсу параметра
Ресурси параметрів дають змогу відокремити конфігурацію політики від її визначення. Політика може визначати paramKind, який описує групу, версію та тип (також відомий як GVK) ресурсу параметра. Потім привʼязка політики повʼязує цю політику з областю дії, до якої її привʼязано, відповідно до налаштувань конкретного ресурсу параметра.
---
# Caution: read the notes for this default-pod-security-configurable policy before
# you apply it, so that you understand the information security consequences.
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingAdmissionPolicy
metadata:
name: "default-pod-security-configurable"
annotations:
kubernetes.io/description: "Default new namespaces to enforce the chosen pod security standard"
spec:
reinvocationPolicy: IfNeeded
paramKind:
apiVersion: v1
kind: ConfigMap
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE"]
resources: ["namespaces"]
matchConditions:
- name: "exclude-system-namespaces"
# If the name begins with "kube-", it's a system namespace.
# Assume that the API server or cluster management tooling applies relevant defaults.
expression: "!object.metadata.name.startsWith('kube-')"
- name: "no-existing-pod-security-label"
expression: "!('pod-security.kubernetes.io/enforce' in object.metadata.labels)"
mutations:
- patchType: "ApplyConfiguration"
applyConfiguration:
expression: "Object{metadata: Object.metadata{labels: {'pod-security.kubernetes.io/enforce': params.data.default}}}"
Ось зразок MutatingAdmissionPolicyBinding:
---
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingAdmissionPolicyBinding
metadata:
name: default-pod-security-configurable
spec:
# назва MutatingAdmissionPolicy, яку застосовувати
policyName: default-pod-security-configurable
# параметри для використання
paramRef:
# якщо ConfigMap відсутній або порожній, не встановлювати типове значення
# (але дозволити створення простору імен)
parameterNotFoundAction: Allow
# де знайти параметр
namespace: kube-system
name: default-pod-security-standard
і ось зразок ConfigMap, який потрібно помістити до простору імен kube-system:
---
apiVersion: v1
kind: ConfigMap
metadata:
namespace: kube-system
name: default-pod-security-standard
data:
default: baseline # також може бути "restricted"
Визначте обидва. Ви маєте спочатку створити ConfigMap; привʼязка очікує, що ресурс параметра вже існує (навіть якщо ви плануєте змінити його пізніше).
Тепер видаліть попередній MutatingAdmissionPolicyBinding:
kubectl delete mutatingadmissionpolicybindings/default-pod-security-baseline
і створіть новий простір імен:
kubectl create ns yet-another-example
kubectl describe ns yet-another-example
Чи отримали мітки типові значення?
Зміна параметра
# Ця команда запускає редактор, який дозволяє змінити .data.default для параметра
kubectl --namespace kube-system edit configmap default-pod-security-standard
Після зміни спробуйте створити ще один простір імен. Що відбувається?
Очищення
Щоб видалити створені ресурси, виконайте такі команди:
kubectl delete validatingadmissionpolices/enforce-multiple-replicas-deployments \
validatingadmissionpolicybindings/enforce-multiple-replicas-deployments
kubectl delete mutatingadmissionpolicies/default-pod-security-baseline \
mutatingadmissionpolicybindings/default-pod-security-baseline
kubectl delete mutatingadmissionpolicies/default-pod-security-configurable \
mutatingadmissionpolicybindings/default-pod-security-configurable
kubectl --namespace kube-system delete configmaps/default-pod-security-standard
kubectl delete namespaces/example namespaces/another-example namespaces/yet-another-example
Якщо ви створили тестові Podʼи або тестові простори імен, приберіть і їх.