Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Деплой в Kubernetes
kubernetes_deploy

Деплой в Kubernetes

Развёртывание в K8s через Helm, kubectl, GitOps-подходы.

Деплой в Kubernetes

Kubernetes — стандарт де-факто для оркестрации контейнеров. Изучите деплой через kubectl, Helm, GitOps-подходы и лучшие практики для production.

#Способы деплоя в Kubernetes

СпособСложностьГибкостьИспользование
kubectl applyНизкаяСредняяБыстрый деплой, development
kubectl set imageНизкаяНизкаяОбновление образа
HelmСредняяВысокаяProduction, версионирование
KustomizeСредняяВысокаяEnvironment-specific configs
GitOps (ArgoCD)ВысокаяОчень высокаяProduction, audit trail

#Деплой через kubectl

#Базовый деплой

# deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-app labels: app: my-app spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: app image: myregistry/my-app:v1.0.0 ports: - containerPort: 8080 resources: requests: memory: "128Mi" cpu: "100m" limits: memory: "256Mi" cpu: "500m" readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 5 periodSeconds: 10 livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 15 periodSeconds: 20
# Применить конфигурацию kubectl apply -f deployment.yaml # Проверить статус kubectl get deployments kubectl get pods kubectl describe deployment my-app

#Обновление образа

# Обновить image kubectl set image deployment/my-app app=myregistry/my-app:v2.0.0 # С записью причины в историю kubectl set image deployment/my-app app=myregistry/my-app:v2.0.0 --record # Проверить статус rollout kubectl rollout status deployment/my-app # Просмотреть историю ревизий kubectl rollout history deployment/my-app # Откатиться к предыдущей версии kubectl rollout undo deployment/my-app # Откатиться к конкретной ревизии kubectl rollout undo deployment/my-app --to-revision=2

#Конфигурация через ConfigMap и Secrets

# configmap.yaml apiVersion: v1 kind: ConfigMap metadata: name: my-app-config data: LOG_LEVEL: "info" API_TIMEOUT: "30s" DATABASE_HOST: "db.example.com" # secret.yaml apiVersion: v1 kind: Secret metadata: name: my-app-secret type: Opaque stringData: DATABASE_PASSWORD: "super-secret-password" API_KEY: "api-key-value"
# deployment.yaml с ConfigMap и Secret apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: template: spec: containers: - name: app image: myregistry/my-app:v1.0.0 env: - name: LOG_LEVEL valueFrom: configMapKeyRef: name: my-app-config key: LOG_LEVEL - name: DATABASE_PASSWORD valueFrom: secretKeyRef: name: my-app-secret key: DATABASE_PASSWORD envFrom: - configMapRef: name: my-app-config - secretRef: name: my-app-secret
# Создать ConfigMap и Secret kubectl apply -f configmap.yaml kubectl apply -f secret.yaml # Или создать через CLI kubectl create configmap my-app-config \ --from-literal=LOG_LEVEL=info \ --from-literal=API_TIMEOUT=30s kubectl create secret generic my-app-secret \ --from-literal=DATABASE_PASSWORD=super-secret \ --from-literal=API_KEY=api-key

#Деплой через Helm

Helm — пакетный менеджер для Kubernetes.

#Структура Helm chart

my-app/
├── Chart.yaml          # Метаданные chart
├── values.yaml         # Значения по умолчанию
├── values-staging.yaml # Переопределения для staging
├── values-prod.yaml    # Переопределения для production
└── templates/
    ├── deployment.yaml
    ├── service.yaml
    ├── configmap.yaml
    ├── secret.yaml
    ├── ingress.yaml
    └── _helpers.tpl

#Chart.yaml

apiVersion: v2 name: my-app description: My Application Helm Chart type: application version: 1.0.0 appVersion: "2.0.0" keywords: - web - api maintainers: - name: DevOps Team email: devops@example.com

#values.yaml

replicaCount: 3 image: repository: myregistry/my-app tag: "2.0.0" pullPolicy: IfNotPresent service: type: ClusterIP port: 80 targetPort: 8080 ingress: enabled: true className: nginx hosts: - host: app.example.com paths: - path: / pathType: Prefix resources: limits: cpu: 500m memory: 256Mi requests: cpu: 100m memory: 128Mi autoscaling: enabled: true minReplicas: 3 maxReplicas: 10 targetCPUUtilizationPercentage: 80 readinessProbe: httpGet: path: /health port: http initialDelaySeconds: 5 periodSeconds: 10 livenessProbe: httpGet: path: /health port: http initialDelaySeconds: 15 periodSeconds: 20

#templates/deployment.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "my-app.fullname" . }} labels: {{- include "my-app.labels" . | nindent 4 }} spec: {{- if not .Values.autoscaling.enabled }} replicas: {{ .Values.replicaCount }} {{- end }} selector: matchLabels: {{- include "my-app.selectorLabels" . | nindent 6 }} template: metadata: labels: {{- include "my-app.selectorLabels" . | nindent 8 }} spec: containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - name: http containerPort: {{ .Values.service.targetPort }} protocol: TCP readinessProbe: {{- toYaml .Values.readinessProbe | nindent 12 }} livenessProbe: {{- toYaml .Values.livenessProbe | nindent 12 }} resources: {{- toYaml .Values.resources | nindent 12 }}

#templates/service.yaml

apiVersion: v1 kind: Service metadata: name: {{ include "my-app.fullname" . }} labels: {{- include "my-app.labels" . | nindent 4 }} spec: type: {{ .Values.service.type }} ports: - port: {{ .Values.service.port }} targetPort: {{ .Values.service.targetPort }} protocol: TCP name: http selector: {{- include "my-app.selectorLabels" . | nindent 4 }}

#templates/_helpers.tpl

{{/*
Expand the name of the chart.
*/}}
{{- define "my-app.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
*/}}
{{- define "my-app.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "my-app.labels" -}}
helm.sh/chart: {{ include "my-app.chart" . }}
{{ include "my-app.selectorLabels" . }}
app.kubernetes.io/version: {{ .Values.image.tag | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "my-app.selectorLabels" -}}
app.kubernetes.io/name: {{ include "my-app.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Create chart name and version
*/}}
{{- define "my-app.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

#Helm команды

# Установить chart helm install my-app ./my-app -n production # Установить с переопределением значений helm install my-app ./my-app \ -n production \ --set image.tag=v2.0.0 \ --set replicaCount=5 # Установить с values файлом helm install my-app ./my-app \ -n production \ -f values-prod.yaml # Обновить релиз helm upgrade my-app ./my-app \ -n production \ -f values-prod.yaml \ --atomic \ --timeout 5m # Откатиться к предыдущей версии helm rollback my-app -n production # Просмотреть историю helm history my-app -n production # Удалить релиз helm uninstall my-app -n production # Проверить chart без установки helm lint ./my-app helm template my-app ./my-app -f values-prod.yaml

#Values для разных окружений

# values-staging.yaml replicaCount: 2 image: tag: "latest" resources: limits: cpu: 250m memory: 128Mi ingress: hosts: - host: staging.app.example.com paths: - path: / pathType: Prefix autoscaling: enabled: false
# values-prod.yaml replicaCount: 5 image: tag: "2.0.0" resources: limits: cpu: 1000m memory: 512Mi ingress: hosts: - host: app.example.com paths: - path: / pathType: Prefix autoscaling: enabled: true minReplicas: 5 maxReplicas: 20

#Деплой через Kustomize

Kustomize позволяет кастомизировать manifests без шаблонов.

#Структура

my-app/
├── base/
│   ├── deployment.yaml
│   ├── service.yaml
│   └── kustomization.yaml
├── overlays/
│   ├── staging/
│   │   ├── patch.yaml
│   │   └── kustomization.yaml
│   └── production/
│       ├── patch.yaml
│       └── kustomization.yaml
└── kustomization.yaml

#base/deployment.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: my-app labels: app: my-app spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: app image: myregistry/my-app:v1.0.0 ports: - containerPort: 8080

#base/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - deployment.yaml - service.yaml commonLabels: app.kubernetes.io/name: my-app app.kubernetes.io/managed-by: kustomize

#overlays/staging/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization bases: - ../../base namePrefix: staging- commonLabels: environment: staging patches: - path: patch.yaml configMapGenerator: - name: my-app-config literals: - LOG_LEVEL=debug - ENV=staging

#overlays/staging/patch.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: replicas: 2 template: spec: containers: - name: app image: myregistry/my-app:latest resources: limits: cpu: 250m memory: 128Mi

#Применение

# Preview для staging kubectl apply -k overlays/staging/ --dry-run=client # Применить staging kubectl apply -k overlays/staging/ -n staging # Применить production kubectl apply -k overlays/production/ -n production

#GitOps с ArgoCD

ArgoCD автоматически синхронизирует состояние кластера с Git репозиторием.

#Структура GitOps репозитория

k8s-gitops/
├── apps/
│   └── my-app/
│       ├── Chart.yaml
│       └── values.yaml
├── environments/
│   ├── staging/
│   │   └── my-app-values.yaml
│   └── production/
│       └── my-app-values.yaml
└── argo/
    └── applications/
        └── my-app-staging.yaml

#ArgoCD Application

# argo/applications/my-app-staging.yaml apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: my-app-staging namespace: argocd spec: project: default source: repoURL: https://github.com/org/k8s-gitops.git targetRevision: HEAD path: apps/my-app helm: valueFiles: - ../../environments/staging/my-app-values.yaml destination: server: https://kubernetes.default.svc namespace: staging syncPolicy: automated: prune: true selfHeal: true allowEmpty: false syncOptions: - CreateNamespace=true - PrunePropagationPolicy=foreground - PruneLast=true retry: limit: 5 backoff: duration: 5s factor: 2 maxDuration: 3m

#GitHub Actions для GitOps

name: GitOps Deploy on: push: branches: [main] jobs: update-gitops: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Build and push image run: | docker build -t myregistry/my-app:${{ github.sha }} . docker push myregistry/my-app:${{ github.sha }} - name: Update Helm values run: | sed -i "s/tag:.*/tag: \"${{ github.sha }}\"/" \ environments/production/my-app-values.yaml - name: Commit and push run: | git config user.name "GitHub Actions" git config user.email "actions@github.com" git add environments/production/my-app-values.yaml git commit -m "Update my-app to ${{ github.sha }}" git push

#GitHub Actions для Kubernetes

#Деплой с kubectl

name: Kubernetes Deploy on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest environment: production steps: - uses: actions/checkout@v4 - name: Set up kubectl uses: azure/setup-kubectl@v3 with: version: 'v1.29.0' - name: Configure kubectl run: | echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig export KUBECONFIG=kubeconfig - name: Deploy application run: | kubectl apply -f k8s/deployment.yaml kubectl set image deployment/my-app \ app=myregistry/my-app:${{ github.sha }} kubectl rollout status deployment/my-app --timeout=300s env: KUBECONFIG: kubeconfig - name: Verify deployment run: | kubectl get pods -l app=my-app kubectl get svc my-app env: KUBECONFIG: kubeconfig

#Деплой с Helm

name: Helm Deploy on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest environment: production steps: - uses: actions/checkout@v4 - name: Set up Helm uses: azure/setup-helm@v3 with: version: 'v3.14.0' - name: Set up kubectl uses: azure/setup-kubectl@v3 - name: Configure kubectl run: | echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig export KUBECONFIG=kubeconfig - name: Helm upgrade run: | helm upgrade my-app ./helm/my-app \ --install \ --namespace production \ --set image.tag=${{ github.sha }} \ --set image.repository=myregistry/my-app \ -f helm/values-prod.yaml \ --atomic \ --timeout 10m \ --wait \ --wait-for-jobs env: KUBECONFIG: kubeconfig

Далее: Откаты и мониторинг деплоя