Хотя это решение и работает, оно имеет ряд существенных недостатков. Первое, что то, что нам нужно дожидаться из вне, постоянным опросом POD, когда он поднимет контейнер и мы в него скопируем приложение и не должен этого делать, если контейнер не поднялся, а также обрабатывать ситуацию когда он сломает наш POD, внешние сервисы, могут опираться на статус POD, хоты сам POD будет ещё не готов, пока не будет выполнен скрипт. Вторым недостатком является то, что у нас появляется какой то внешний скрипт, который нужно логически не отделим от POD, но при этом его нужно вручную запускать из вне, где хранить и где-то должна быть инструкция по его использованию. И напоследок, этих POD у нас может быть множество. На первый взгляд, логичным решением поместить код в Dockerfile:
esschtolts@cloudshell:~/bitrix (essch)$ cat Dockerfile
FROM mattrayner/lamp:latest-1604-php5
MAINTAINER ESSch ESSchtolts@yandex.ru>
RUN cd /app/ && ( \
wget https://www.1c-bitrix.ru/download/small_business_encode.tar.gz \
&& tar -xf small_business_encode.tar.gz \
&& sed -i '5i php_value short_open_tag 1' .htaccess \
&& chmod -R 0777 . \
&& sed -i 's/#php_value display_errors 1/php_value display_errors 1/' .htaccess \
&& sed -i '5i php_value opcache.revalidate_freq 0' .htaccess \
&& sed -i 's/#php_flag default_charset UTF-8/php_flag default_charset UTF-8/' .htaccess \
) && cd ..;
EXPOSE 80 3306
CMD ["/run.sh"]
esschtolts@cloudshell:~/bitrix (essch)$ docker build -t essch/app:0.12 . | grep Successfully
Successfully built f76e656dac53
Successfully tagged essch/app:0.12
esschtolts@cloudshell:~/bitrix (essch)$ docker image push essch/app | grep digest
0.12: digest: sha256:75c92396afacefdd5a3fb2024634a4c06e584e2a1674a866fa72f8430b19ff69 size: 11309
esschtolts@cloudshell:~/bitrix (essch)$ cat deploymnet.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: Nginxlamp
namespace: development
spec:
selector:
matchLabels:
app: lamp
replicas: 1
template:
metadata:
labels:
app: lamp
spec:
containers:
name: lamp
image: essch/app:0.12
ports:
containerPort: 80
esschtolts@cloudshell:~/bitrix (essch)$ IMAGE=essch/app:0.12 kubectl create -f deploymnet.yaml
deployment.apps "Nginxlamp" created
esschtolts@cloudshell:~/bitrix (essch)$ kubectl get pods -l app=lamp
NAME READY STATUS RESTARTS AGE
Nginxlamp-55f8cd8dbc-mk9nk 1/1 Running 0 5m
esschtolts@cloudshell:~/bitrix (essch)$ kubectl exec Nginxlamp-55f8cd8dbc-mk9nk ls /app/
index.php
Это происходит потому, что разработчик образов, что правильно и написано в его документации, ожидал, что образ будет примонтирован к хосту и в скрипте запускаемого в сам конце удаляется папка app. Также в таком подходе мы столкнёмся с проблемой постоянных обновлений образов, конфигом (мы не сможем задать номер образа переменной, так как он будет исполняться на нодах кластера) и обновлений контейнеров, также мы не сможем обновлять папку, так как при пересоздании контейнера изменения будут возвращены в изначальное состояние.
Правильным решением будет примонтировать папку и включение в состав жизненно цикла POD запуск контейнера, который стартует перед основным контейнером и производит подготовительные операции окружения, часто это скачивание приложения с репозитория, сборка, прогон тестов, создания пользователей и выставление прав. Под каждую операцию правильно запускать отдельный init контейнер, в котором эта операция является базовым процессом, которые выполняются последовательно цепочкой, которая будет разорвана, если одна из операций будет выполнена с ошибкой (вернёт не нулевой код завершения процесса). Для такого контейнера предусмотрено отдельное описание в POD InitContainer, перечисляя их последовательно они будет выстраивать цепочку запусков init контейнеров в том же порядке. В нашем случае мы создали неименованный volume и с помощью InitContainer доставили в него установочные файлы. После успешного завершения InitContainer, которых может быть несколько, стартует основной. Основной контейнер уже монтируется в наш том, в котором уже есть установочные файлы, нам остаётся лишь перейти в браузер и выполнить установку:
esschtolts@cloudshell:~/bitrix (essch)$ cat deploymnet.yaml
kind: Deployment
metadata:
name: Nginxlamp
namespace: development
spec:
selector:
matchLabels:
app: lamp
replicas: 1
template:
metadata:
labels:
app: lamp
spec:
initContainers:
name: init
image: ubuntu
command:
/bin/bash
-c
|
cd /app
apt-get update && apt-get install -y wget
wget https://www.1c-bitrix.ru/download/small_business_encode.tar.gz
tar -xf small_business_encode.tar.gz
sed -i '5i php_value short_open_tag 1' .htaccess
chmod -R 0777 .
sed -i 's/#php_value display_errors 1/php_value display_errors 1/' .htaccess
sed -i '5i php_value opcache.revalidate_freq 0' .htaccess
sed -i 's/#php_flag default_charset UTF-8/php_flag default_charset UTF-8/' .htaccess
volumeMounts:
name: app
mountPath: /app
containers:
name: lamp
image: essch/app:0.12
ports:
containerPort: 80
volumeMounts:
name: app
mountPath: /app
volumes:
name: app
emptyDir: {}
Посмотреть события во время создания POD можно командой watch kubectl get events, а логи kubectl logs {ID_CONTAINER} -c init или более универсально: