263 lines
8.8 KiB
Go
Executable file
263 lines
8.8 KiB
Go
Executable file
package devopsmodules
|
||
|
||
import (
|
||
"fmt"
|
||
"rubric/utils"
|
||
)
|
||
|
||
var KubernetesModule = Module{
|
||
Key: "kubernetes",
|
||
Aliases: []string{"k8s", "k", "kube"},
|
||
Title: "Kubernetes",
|
||
Description: "Архитектура, Pod/Deployment/Service, kubectl, ConfigMap, Ingress, Helm",
|
||
Run: showKubernetes,
|
||
}
|
||
|
||
func showKubernetes() {
|
||
utils.Header("DevOps — Kubernetes")
|
||
|
||
utils.Section("Архитектура кластера")
|
||
utils.Code(`Control Plane (мастер-узлы):
|
||
kube-apiserver — API-сервер, точка входа для всех запросов
|
||
etcd — распределённая БД, хранит состояние кластера
|
||
kube-scheduler — решает на какой узел помещать Pod
|
||
kube-controller-manager — следит за состоянием (ReplicaSet, Node...)
|
||
cloud-controller-manager — интеграция с облаком (AWS, GCP, Azure)
|
||
|
||
Worker Nodes (рабочие узлы):
|
||
kubelet — агент, запускает и следит за Pod-ами
|
||
kube-proxy — сетевые правила (iptables/ipvs)
|
||
Container Runtime — containerd, CRI-O (запуск контейнеров)
|
||
|
||
Основные объекты:
|
||
Pod — минимальная единица, 1+ контейнеров с общей сетью
|
||
ReplicaSet — поддерживает N копий Pod-а
|
||
Deployment — управляет ReplicaSet, rolling updates
|
||
Service — стабильный IP/DNS для набора Pod-ов
|
||
Ingress — HTTP-маршрутизация снаружи в Service
|
||
ConfigMap — конфигурация (не секреты)
|
||
Secret — секреты (base64)
|
||
Namespace — логическое разделение кластера
|
||
PV/PVC — постоянное хранилище
|
||
StatefulSet — Pod-ы с постоянной идентичностью (БД)
|
||
DaemonSet — по одному Pod-у на каждый узел
|
||
Job/CronJob — разовые и периодические задачи`)
|
||
|
||
utils.Section("kubectl — основные команды")
|
||
utils.Code(`# Контексты и кластеры:
|
||
kubectl config get-contexts # список контекстов
|
||
kubectl config use-context prod # переключить кластер
|
||
kubectl config current-context
|
||
export KUBECONFIG=~/.kube/config`)
|
||
|
||
utils.Println(utils.ColorBold + "Просмотр ресурсов:" + utils.ColorReset)
|
||
utils.Command("kubectl get pods", "Pod-ы в текущем namespace")
|
||
utils.Command("kubectl get pods -n kube-system", "в namespace kube-system")
|
||
utils.Command("kubectl get pods -A", "во всех namespace")
|
||
utils.Command("kubectl get pods -o wide", "с IP и узлом")
|
||
utils.Command("kubectl get all", "все ресурсы namespace")
|
||
utils.Command("kubectl describe pod mypod", "подробная информация")
|
||
utils.Command("kubectl logs mypod", "логи Pod-а")
|
||
utils.Command("kubectl logs -f mypod -c mycontainer", "следить, конкретный контейнер")
|
||
utils.Command("kubectl exec -it mypod -- bash", "shell в Pod-е")
|
||
utils.Command("kubectl top pods", "использование ресурсов")
|
||
utils.Command("kubectl top nodes", "ресурсы узлов")
|
||
fmt.Println()
|
||
utils.Println(utils.ColorBold + "Применение манифестов:" + utils.ColorReset)
|
||
utils.Command("kubectl apply -f deployment.yaml", "применить манифест")
|
||
utils.Command("kubectl apply -f ./manifests/", "применить директорию")
|
||
utils.Command("kubectl delete -f deployment.yaml", "удалить по манифесту")
|
||
utils.Command("kubectl delete pod mypod", "удалить Pod")
|
||
utils.Command("kubectl get pod mypod -o yaml", "экспортировать манифест")
|
||
utils.Command("kubectl edit deployment myapp", "редактировать в редакторе")
|
||
|
||
utils.Section("Основные объекты — манифесты")
|
||
utils.Code(`# Pod (редко создаётся напрямую):
|
||
apiVersion: v1
|
||
kind: Pod
|
||
metadata:
|
||
name: mypod
|
||
labels:
|
||
app: myapp
|
||
spec:
|
||
containers:
|
||
- name: myapp
|
||
image: myapp:1.0
|
||
ports:
|
||
- containerPort: 8000
|
||
resources:
|
||
requests:
|
||
memory: "64Mi"
|
||
cpu: "100m"
|
||
limits:
|
||
memory: "128Mi"
|
||
cpu: "500m"
|
||
env:
|
||
- name: DATABASE_URL
|
||
valueFrom:
|
||
secretKeyRef:
|
||
name: myapp-secret
|
||
key: db-url
|
||
livenessProbe:
|
||
httpGet:
|
||
path: /health
|
||
port: 8000
|
||
initialDelaySeconds: 10
|
||
periodSeconds: 15
|
||
readinessProbe:
|
||
httpGet:
|
||
path: /ready
|
||
port: 8000`)
|
||
|
||
utils.Code(`# Deployment:
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: myapp
|
||
namespace: production
|
||
spec:
|
||
replicas: 3
|
||
selector:
|
||
matchLabels:
|
||
app: myapp
|
||
strategy:
|
||
type: RollingUpdate
|
||
rollingUpdate:
|
||
maxSurge: 1
|
||
maxUnavailable: 0
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: myapp
|
||
spec:
|
||
containers:
|
||
- name: myapp
|
||
image: myapp:1.0
|
||
ports:
|
||
- containerPort: 8000`)
|
||
|
||
utils.Code(`# Service:
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: myapp-svc
|
||
spec:
|
||
selector:
|
||
app: myapp
|
||
ports:
|
||
- port: 80
|
||
targetPort: 8000
|
||
type: ClusterIP # ClusterIP / NodePort / LoadBalancer
|
||
|
||
# ClusterIP — только внутри кластера
|
||
# NodePort — доступен снаружи на порту 30000-32767
|
||
# LoadBalancer — облачный балансировщик`)
|
||
|
||
utils.Code(`# Ingress:
|
||
apiVersion: networking.k8s.io/v1
|
||
kind: Ingress
|
||
metadata:
|
||
name: myapp-ingress
|
||
annotations:
|
||
nginx.ingress.kubernetes.io/rewrite-target: /
|
||
spec:
|
||
ingressClassName: nginx
|
||
rules:
|
||
- host: myapp.example.com
|
||
http:
|
||
paths:
|
||
- path: /
|
||
pathType: Prefix
|
||
backend:
|
||
service:
|
||
name: myapp-svc
|
||
port:
|
||
number: 80
|
||
tls:
|
||
- hosts:
|
||
- myapp.example.com
|
||
secretName: myapp-tls`)
|
||
|
||
utils.Code(`# ConfigMap:
|
||
apiVersion: v1
|
||
kind: ConfigMap
|
||
metadata:
|
||
name: myapp-config
|
||
data:
|
||
LOG_LEVEL: "info"
|
||
APP_PORT: "8000"
|
||
nginx.conf: |
|
||
server {
|
||
listen 80;
|
||
location / { proxy_pass http://backend; }
|
||
}
|
||
|
||
# Secret (значения в base64):
|
||
apiVersion: v1
|
||
kind: Secret
|
||
metadata:
|
||
name: myapp-secret
|
||
type: Opaque
|
||
data:
|
||
db-password: cGFzc3dvcmQ= # echo -n 'password' | base64
|
||
stringData:
|
||
db-url: "postgresql://user:pass@db:5432/mydb" # автоматически base64`)
|
||
|
||
utils.Section("Масштабирование и обновление")
|
||
utils.Command("kubectl scale deployment myapp --replicas=5", "масштабировать")
|
||
utils.Command("kubectl rollout status deployment/myapp", "статус обновления")
|
||
utils.Command("kubectl rollout history deployment/myapp", "история обновлений")
|
||
utils.Command("kubectl rollout undo deployment/myapp", "откатить обновление")
|
||
utils.Command("kubectl rollout undo deployment/myapp --to-revision=2", "к конкретной версии")
|
||
utils.Command("kubectl set image deployment/myapp myapp=myapp:2.0", "обновить образ")
|
||
|
||
utils.Section("Namespaces и RBAC")
|
||
utils.Code(`kubectl create namespace staging
|
||
kubectl get namespaces
|
||
|
||
# ResourceQuota — ограничения ресурсов namespace:
|
||
apiVersion: v1
|
||
kind: ResourceQuota
|
||
metadata:
|
||
name: staging-quota
|
||
namespace: staging
|
||
spec:
|
||
hard:
|
||
requests.cpu: "4"
|
||
requests.memory: 8Gi
|
||
limits.cpu: "8"
|
||
limits.memory: 16Gi
|
||
pods: "50"
|
||
|
||
# RBAC — управление доступом:
|
||
# Role → namespace, ClusterRole → весь кластер
|
||
# RoleBinding / ClusterRoleBinding → привязка к субъекту
|
||
kubectl create role developer --verb=get,list,create --resource=pods -n staging
|
||
kubectl create rolebinding alice-developer \
|
||
--role=developer --user=alice -n staging`)
|
||
|
||
utils.Section("Helm — пакетный менеджер Kubernetes")
|
||
utils.Code(`# Установка: https://helm.sh/docs/intro/install/
|
||
|
||
helm repo add bitnami https://charts.bitnami.com/bitnami
|
||
helm repo update
|
||
helm search repo bitnami/postgresql
|
||
|
||
helm install mydb bitnami/postgresql \
|
||
--set auth.postgresPassword=secret \
|
||
--set primary.persistence.size=20Gi \
|
||
--namespace db --create-namespace
|
||
|
||
helm list -A # установленные релизы
|
||
helm status mydb # статус релиза
|
||
helm upgrade mydb bitnami/postgresql --set auth.postgresPassword=newsecret
|
||
helm rollback mydb 1 # откатить
|
||
helm uninstall mydb
|
||
|
||
# Создать свой chart:
|
||
helm create mychart
|
||
helm template mychart ./mychart/ # рендеринг без установки
|
||
helm install myapp ./mychart/ -f values.yaml`)
|
||
|
||
utils.Footer()
|
||
}
|