Как заставить созданный модуль запускать приложение (команду и аргументы) и в то же время иметь развертывание и службу, ссылающуюся на него?

Контекст:
Технология: Java, Docker Toolbox, Minikube.
У меня есть веб-приложение java (уже упакованное как web-tool.jar), которое я хочу чтобы работать, имея все преимущества кубернетов.
Чтобы дать кубернетам команду брать изображение локально, я использую тег изображения:

docker build -t despot/web-tool:1.0 .

а затем сделать его доступным для minikube:

docker save despot/web-tool:1.0 | (eval $(minikube docker-env) && docker load)

файл докера:

FROM openjdk:11-jre
ADD target/web-tool-1.0-SNAPSHOT.jar app.jar
EXPOSE 1111
EXPOSE 2222

1. Как я могу создать модуль, запустить приложение Java и в то же время иметь развертывание и службу, ссылающуюся на него?

1.1. Могу ли я создать развертывание, которое будет распространять команду и аргументы при создании модуля? (лучше всего для меня, так как я гарантирую создание развертывания и службы до создания модуля)
1.2. Если 1.1. невыполнимо, могу ли я kubectl применить некоторую конфигурацию модуля с помощью команды и аргументов к уже созданному развертыванию / модулю / службе? (худшее решение, как дополнительные ручные шаги)
1.3. Если 1.2. невозможно, возможно ли создать развертывание / службу и прикрепить ее к уже работающему модулю (который был запущен с помощью "kubectl run ... java -jar app.jar reg")?

Я пробовал:
a) Создайте развертывание (которое автоматически запускает модуль) и предоставьте доступ (создана служба):

kubectl create deployment reggo --image=despot/web-tool:1.0

При этом создается модуль с состоянием CrashLoopBackoff, поскольку в нем еще не запущен процесс переднего плана.

б) Пробовал следующее в надежде на то, что развертывание примет команду и аргументы, которые будут распространяться на создание модуля (1.1.):

kubectl create deployment reggo --image=despot/web-tool:1.0 -- java -jar app.jar reg

Тот же результат, что и модуль, поскольку развертывание не принимает команды и аргументы.

c) Пытался применить конфигурацию модуля с помощью команды и аргументов после того, как развертывание создало модуль, поэтому я выполнил команду из а), нашел идентификатор (reggo-858ccdcddd-mswzs) модуля с помощью (kubectl get pods), а затем я выполнено:

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: reggo-858ccdcddd-mswzs
spec:
  containers:
  - name: reggo-858ccdcddd-mswzs
    command: ["java"]
    args: ["-jar", "app.jar", "reg"]
EOF

но я получил:

Предупреждение: kubectl apply следует использовать для ресурса, созданного с помощью kubectl create --save-config или kubectl apply. Подставка "reggo-858ccdcddd-mswzs" недействительна:
* spec.containers [0] .image: Обязательное значение
* spec.containers: Запрещено: обновления модуля не могут добавлять или удалять контейнеры

это позволяет мне думать, что я не могу выполнить команду, применив конфигурацию command / args.

Решение (с использованием ответа Arghya):

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: reggo
spec:
  selector:
    matchLabels:
      app: reggo-label
  template:
    metadata:
      labels:
        app: reggo-label
    spec:
     containers:
     - name: reggo
       image: "despot/web-tool:1.0"
       command: ["java"]
       args: ["-jar", "app.jar", "reg"]
       ports:
       - containerPort: 1111
EOF

и выполнение:

kubectl expose deployment reggo  --type=NodePort --port=1111

person despot    schedule 26.04.2020    source источник
comment
Вы можете либо добавить CMD к своему Dockerfile, говоря, какую команду выполнять, либо указать его в спецификации развертывания в формате YAML. Я бы предпочел написать Kubernetes YAML (и проверить его в системе управления версиями) и развернуть его с kubectl apply, а не с императивными командами типа kubectl create.   -  person David Maze    schedule 26.04.2020


Ответы (2)


У вас может быть команда java -jar как ENTRYPOINT в самом файле докера, которая сообщает Docker, что нужно запустить приложение Java.

FROM openjdk:11-jre
ADD target/web-tool-1.0-SNAPSHOT.jar app.jar
EXPOSE 1111
EXPOSE 2222
ENTRYPOINT ["java", "-jar", "app.jar", "reg"]

В качестве альтернативы то же самое можно сделать с помощью разделов command и args в yaml kubernetes.

containers:
- name: myapp
  image: myregistry.azurecr.io/myapp:0.1.7
  command: ["java"]
  args: ["-jar", "app.jar", "reg"]

Теперь переходим к ошибке Forbidden: pod updates may not add or remove containers. Причина, по которой она происходит, заключается в том, что вы пытаетесь изменить раздел containers существующего объекта модуля, что недопустимо. Вместо этого вы можете получить весь yaml развертывания, открыть его в редакторе и отредактировать, чтобы добавить раздел команд, а затем удалить существующее развертывание и, наконец, применить измененный yaml развертывания к кластеру.

  1. kubectl get deploy reggo -o yaml --export > deployment.yaml
  2. Удалите существующее развертывание с помощью kubectl delete deploy reggo
  3. Отредактируйте deployment.yaml, чтобы добавить нужную команду
  4. Примените yaml к кластеру kubectl apply -f deployment.yaml
person Arghya Sadhu    schedule 26.04.2020
comment
Спасибо. Я не использовал подход ENTRYPOINT, поскольку я использую один и тот же образ докера для 2 контейнеров / модулей с разными командами и аргументами. Другой подход соответствовал моим требованиям, хотя я пропустил разделы imagePullPolicy и ports в yaml. Они не обязательны. Я также разделил команду на команду и аргументы. Точное решение размещено в вопросе. - person despot; 04.05.2020
comment
Хорошо, я обновил ответ командой и аргументами отдельно - person Arghya Sadhu; 04.05.2020
comment
Не нужно было менять ответ;) просто уведомлял о моих выводах на случай, если кому-то понадобится сделать то же самое. - person despot; 06.05.2020

Как уже упоминалось, рекомендуется добавить ENTRYPOINT в ваш файл Docker с помощью команды, которую вы хотите использовать.

Однако, если вы хотите создать развертывание с помощью команды kubectl, вы можете запустить

kubectl run $DEPLOYMENT_NAME --image=despot/web-tool:1.0 --command -- java -jar app.jar reg

Кроме того, если вы хотите раскрыть развертывание с помощью той же команды, вы можете передать:

--expose=true аргумент, который создаст службу типа ClusterIP и

--port=$PORT_NUMBER выбрать порт, на который он будет выставляться.

чтобы изменить тип порта на NodePort, вы должны запустить:

kubectl run $DEPLOYMENT_NAME --image=despot/web-tool:1.0 --expose=true --service-overrides='{ "spec": { "type": "NodePort" } }' --port=$PORT_NUMBER --command -- java -jar app.jar reg
person Mariusz K.    schedule 27.04.2020
comment
Спасибо! kubectl run (kubernetes.io/docs/reference/generated/kubectl/) конкретный образ в модуле .. а) Действительно ли он создает развертывание параллельно с созданием модуля? (если этого не произойдет, изменение расписания модуля сделает его бесполезным) б) Мне нужен тип службы NodePort вместо ClusterIP. Можно ли этого добиться? б.1) Можно ли этого достичь с помощью параметра service-overrides, и если да, то каким будет пример JSON для этого параметра? - person despot; 04.05.2020
comment
Он действительно создает развертывание, я добавил, как изменить тип службы с ClusterIP по умолчанию на NodePort. - person Mariusz K.; 05.05.2020