Понимание команд запуска
Содержание
Overview
Команды запуска в Kubernetes определяют основной исполняемый файл, который запускается при старте контейнера. Они соответствуют полю command
в спецификациях Pod Kubernetes и переопределяют стандартную инструкцию ENTRYPOINT, заданную в образах контейнеров. Команды запуска обеспечивают полный контроль над тем, какой процесс выполняется внутри ваших контейнеров.
Core Concepts
Что такое команды запуска?
Команды запуска — это:
- Основной исполняемый файл, который запускается при старте контейнера
- Переопределяют инструкцию ENTRYPOINT в Docker-образах
- Определяют главный процесс (PID 1) внутри контейнера
- Работают совместно с параметрами (args) для формирования полной командной строки
Взаимосвязь с Docker и параметрами
Понимание взаимосвязи между инструкциями Docker и полями Kubernetes:
Docker | Kubernetes | Назначение |
---|
ENTRYPOINT | command | Определяет исполняемый файл |
CMD | args | Задает аргументы по умолчанию |
# Пример Dockerfile
FROM ubuntu:20.04
ENTRYPOINT ["/usr/bin/myapp"]
CMD ["--config=/etc/default.conf"]
# Переопределение в Kubernetes
apiVersion: v1
kind: Pod
spec:
containers:
- name: myapp
image: myapp:latest
command: ["/usr/bin/myapp"]
args: ["--config=/etc/custom.conf", "--debug"]
Взаимодействие command и args
Сценарий | Docker Image | Спецификация Kubernetes | Итоговая команда |
---|
По умолчанию | ENTRYPOINT + CMD | (отсутствует) | ENTRYPOINT + CMD |
Переопределение только args | ENTRYPOINT + CMD | args: ["new-args"] | ENTRYPOINT + new-args |
Переопределение только command | ENTRYPOINT + CMD | command: ["new-cmd"] | new-cmd |
Переопределение обоих | ENTRYPOINT + CMD | command: ["new-cmd"]
args: ["new-args"] | new-cmd + new-args |
Сценарии использования
1. Пользовательский запуск приложения
Запуск разных приложений с использованием одного базового образа:
apiVersion: v1
kind: Pod
metadata:
name: web-server
spec:
containers:
- name: nginx
image: ubuntu:20.04
command: ["/usr/sbin/nginx"]
args: ["-g", "daemon off;", "-c", "/etc/nginx/nginx.conf"]
2. Отладка и устранение неполадок
Переопределение команды по умолчанию для запуска оболочки для отладки:
apiVersion: v1
kind: Pod
metadata:
name: debug-pod
spec:
containers:
- name: debug
image: myapp:latest
command: ["/bin/bash"]
args: ["-c", "sleep 3600"]
3. Скрипты инициализации
Запуск пользовательской инициализации перед стартом основного приложения:
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: myapp:latest
command: ["/bin/sh"]
args:
- "-c"
- |
echo "Инициализация приложения..."
/scripts/init.sh
echo "Запуск основного приложения..."
exec /usr/bin/myapp --config=/etc/app.conf
4. Многоцелевые образы
Использование одного образа для разных задач:
# Веб-сервер
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
template:
spec:
containers:
- name: web
image: myapp:latest
command: ["/usr/bin/myapp"]
args: ["server", "--port=8080"]
---
# Фоновый воркер
apiVersion: apps/v1
kind: Deployment
metadata:
name: worker
spec:
template:
spec:
containers:
- name: worker
image: myapp:latest
command: ["/usr/bin/myapp"]
args: ["worker", "--queue=tasks"]
---
# Миграция базы данных
apiVersion: batch/v1
kind: Job
metadata:
name: migrate
spec:
template:
spec:
containers:
- name: migrate
image: myapp:latest
command: ["/usr/bin/myapp"]
args: ["migrate", "--up"]
restartPolicy: Never
Примеры CLI и практическое использование
Использование kubectl run
# Полное переопределение команды
kubectl run debug --image=nginx:alpine --command -- /bin/sh -c "sleep 3600"
# Запуск интерактивной оболочки
kubectl run -it debug --image=ubuntu:20.04 --restart=Never --command -- /bin/bash
# Пользовательский запуск приложения
kubectl run myapp --image=myapp:latest --command -- /usr/local/bin/start.sh --config=/etc/app.conf
# Одноразовая задача
kubectl run task --image=busybox --restart=Never --command -- /bin/sh -c "echo 'Task completed'"
Использование kubectl create job
# Создание job с пользовательской командой
kubectl create job backup --image=postgres:13 --dry-run=client -o yaml -- pg_dump -h db.example.com mydb > backup.yaml
# Применение job
kubectl apply -f backup.yaml
Сложные примеры команд запуска
Многоэтапная инициализация
apiVersion: v1
kind: Pod
metadata:
name: complex-init
spec:
containers:
- name: app
image: myapp:latest
command: ["/bin/bash"]
args:
- "-c"
- |
set -e
echo "Шаг 1: Проверка зависимостей..."
/scripts/check-deps.sh
echo "Шаг 2: Настройка конфигурации..."
/scripts/setup-config.sh
echo "Шаг 3: Выполнение миграций базы данных..."
/scripts/migrate.sh
echo "Шаг 4: Запуск приложения..."
exec /usr/bin/myapp --config=/etc/app/config.yaml
volumeMounts:
- name: scripts
mountPath: /scripts
- name: config
mountPath: /etc/app
volumes:
- name: scripts
configMap:
name: init-scripts
defaultMode: 0755
- name: config
configMap:
name: app-config
Условная логика запуска
apiVersion: apps/v1
kind: Deployment
metadata:
name: conditional-app
spec:
template:
spec:
containers:
- name: app
image: myapp:latest
command: ["/bin/sh"]
args:
- "-c"
- |
if [ "$APP_MODE" = "worker" ]; then
exec /usr/bin/myapp worker --queue=$QUEUE_NAME
elif [ "$APP_MODE" = "scheduler" ]; then
exec /usr/bin/myapp scheduler --interval=60
else
exec /usr/bin/myapp server --port=8080
fi
env:
- name: APP_MODE
value: "server"
- name: QUEUE_NAME
value: "default"
Лучшие практики
1. Обработка сигналов и корректное завершение
# ✅ Корректная обработка сигналов
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: myapp:latest
command: ["/bin/bash"]
args:
- "-c"
- |
# Перехват SIGTERM для корректного завершения
trap 'echo "Получен SIGTERM, завершаемся корректно..."; kill -TERM $PID; wait $PID' TERM
# Запуск основного приложения в фоне
/usr/bin/myapp --config=/etc/app.conf &
PID=$!
# Ожидание процесса
wait $PID
2. Обработка ошибок и логирование
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: myapp:latest
command: ["/bin/bash"]
args:
- "-c"
- |
set -euo pipefail # Выход при ошибках, неопределённых переменных и сбоях в пайпах
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >&2
}
log "Запуск инициализации приложения..."
if ! /scripts/health-check.sh; then
log "ОШИБКА: Проверка состояния не пройдена"
exit 1
fi
log "Запуск основного приложения..."
exec /usr/bin/myapp --config=/etc/app.conf
3. Вопросы безопасности
# ✅ Запуск от имени непривилегированного пользователя
apiVersion: v1
kind: Pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
containers:
- name: app
image: myapp:latest
command: ["/usr/bin/myapp"]
args: ["--config=/etc/app.conf"]
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
4. Управление ресурсами
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: myapp:latest
command: ["/usr/bin/myapp"]
args: ["--config=/etc/app.conf"]
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
Расширенные шаблоны использования
1. Init-контейнеры с пользовательскими командами
apiVersion: v1
kind: Pod
spec:
initContainers:
- name: setup
image: busybox
command: ["/bin/sh"]
args:
- "-c"
- |
echo "Настройка общих данных..."
mkdir -p /shared/data
echo "Настройка завершена" > /shared/data/status
volumeMounts:
- name: shared-data
mountPath: /shared
containers:
- name: app
image: myapp:latest
command: ["/bin/sh"]
args:
- "-c"
- |
while [ ! -f /shared/data/status ]; do
echo "Ожидание завершения настройки..."
sleep 1
done
echo "Запуск приложения..."
exec /usr/bin/myapp
volumeMounts:
- name: shared-data
mountPath: /shared
volumes:
- name: shared-data
emptyDir: {}
2. Sidecar-контейнеры с разными командами
apiVersion: v1
kind: Pod
spec:
containers:
# Основное приложение
- name: app
image: myapp:latest
command: ["/usr/bin/myapp"]
args: ["--config=/etc/app.conf"]
# Sidecar для отправки логов
- name: log-shipper
image: fluent/fluent-bit:latest
command: ["/fluent-bit/bin/fluent-bit"]
args: ["--config=/fluent-bit/etc/fluent-bit.conf"]
# Sidecar для экспорта метрик
- name: metrics
image: prom/node-exporter:latest
command: ["/bin/node_exporter"]
args: ["--path.rootfs=/host"]
3. Шаблоны Job с пользовательскими командами
# Job для резервного копирования
apiVersion: batch/v1
kind: Job
metadata:
name: database-backup
spec:
template:
spec:
containers:
- name: backup
image: postgres:13
command: ["/bin/bash"]
args:
- "-c"
- |
set -e
echo "Начало резервного копирования: $(date)"
pg_dump -h $DB_HOST -U $DB_USER $DB_NAME > /backup/dump-$(date +%Y%m%d-%H%M%S).sql
echo "Резервное копирование завершено: $(date)"
env:
- name: DB_HOST
value: "postgres.example.com"
- name: DB_USER
value: "backup_user"
- name: DB_NAME
value: "myapp"
volumeMounts:
- name: backup-storage
mountPath: /backup
restartPolicy: Never
volumes:
- name: backup-storage
persistentVolumeClaim:
claimName: backup-pvc
Команды запуска обеспечивают полный контроль над выполнением контейнеров в Kubernetes. Понимая, как правильно настраивать и использовать команды запуска, вы можете создавать гибкие, поддерживаемые и надежные контейнеризированные приложения, соответствующие вашим конкретным требованиям.