company_banner

Практика с dapp. Часть 2. Деплой Docker-образов в Kubernetes с помощью Helm

    dapp — наша Open Source-утилита, помогающая DevOps-инженерам сопровождать процессы CI/CD (Обновлено 13 августа 2019 г.: в настоящее время проект dapp переименован в werf, его код полностью переписан на Go, а документация значительно улучшена) (подробнее о ней читайте в анонсе). В документации к ней приведён пример сборки простого приложения, а подробнее этот процесс (с демонстрацией основных возможностей dapp) был представлен в первой части статьи. Теперь, на основе того же простого приложения, покажу, как dapp работает с кластером Kubernetes.



    Как и в первой статье, все дополнения для кода приложения symfony-demo есть в нашем репозитории. Но обойтись Vagrantfile в этот раз не получится: Docker и dapp придётся поставить локально.

    Чтобы пройти всё по шагам, нужно начать с ветки dapp_build, куда был добавлен Dappfile в первой статье.

    $ git clone https://github.com/flant/symfony-demo.git
    $ cd symfony-demo
    $ git checkout dapp_build
    $ git checkout -b kube_test
    $ dapp dimg build

    Запуск кластера с помощью Minikube


    Теперь нужно создать кластер Kubernetes, где dapp запустит приложение. Для этого будем использовать Minikube как рекомендуемый способ запуска кластера на локальной машине.

    Установка проста и заключается в скачивании Minikube и утилиты kubectl. Инструкции доступны по ссылкам:


    Примечание: Читайте также наш перевод статьи «Начало работы в Kubernetes с помощью Minikube».

    После установки нужно запустить minikube setup. Minikube скачает ISO и запустит из него виртуальную машину в VirtualBox.

    После успешного старта можно посмотреть, что есть в кластере:

    $ kubectl get all
    
    NAME                                READY     STATUS    RESTARTS   AGE
    po/hello-minikube-938614450-zx7m6   1/1       Running   3          71d
    
    NAME                 CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
    svc/hello-minikube   10.0.0.102   <nodes>       8080:31429/TCP   71d
    svc/kubernetes       10.0.0.1     <none>        443/TCP          71d
    
    NAME                    DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    deploy/hello-minikube   1         1         1            1           71d
    
    NAME                          DESIRED   CURRENT   READY     AGE
    rs/hello-minikube-938614450   1         1         1         71d

    Команда покажет все ресурсы в пространстве имён (namespace) по умолчанию (default). Список всех namespaces можно посмотреть через kubectl get ns.

    Подготовка, шаг №1: реестр для образов


    Итак, мы запустили кластер Kubernetes в виртуальной машине. Что ещё понадобится для запуска приложения?

    Во-первых, для этого нужно загрузить образ туда, откуда кластер сможет его получить. Можно использовать общий Docker Registry или же установить свой Registry в кластере (мы так делаем для production-кластеров). Для локальной разработки тоже лучше подойдет второй вариант, а реализовать его с dapp совсем просто — для этого есть специальная команда:

    $ dapp kube minikube setup
    Restart minikube                                                                                                         [RUNNING]
    minikube: Running
    localkube: Running
    kubectl: Correctly Configured: pointing to minikube-vm at 192.168.99.100
    Starting local Kubernetes v1.6.4 cluster...
    Starting VM...
    Moving files into cluster...
    Setting up certs...
    Starting cluster components...
    Connecting to cluster...
    Setting up kubeconfig...
    Kubectl is now configured to use the cluster.
    Restart minikube                                                                                                              [OK] 34.18 sec
    Wait till minikube ready                                                                                                 [RUNNING]
    Wait till minikube ready                                                                                                      [OK] 0.05 sec
    Run registry                                                                                                             [RUNNING]
    Run registry                                                                                                                  [OK] 61.44 sec
    Run registry forwarder daemon                                                                                            [RUNNING]
    Run registry forwarder daemon                                                                                                 [OK] 5.01 sec

    После её выполнения в списке системных процессах появляется такое перенаправление:

    username  13317  0.5  0.4  57184 36076 pts/17   Sl   14:03   0:00 kubectl port-forward --namespace kube-system kube-registry-6nw7m 5000:5000

    … а в namespace под названием kube-system создаётся Registry и прокси к нему:

    $ kubectl get -n kube-system all
    NAME                             READY     STATUS    RESTARTS   AGE
    po/kube-addon-manager-minikube   1/1       Running   2          22m
    po/kube-dns-1301475494-7kk6l     3/3       Running   3          22m
    po/kube-dns-v20-g7hr9            3/3       Running   9          71d
    po/kube-registry-6nw7m           1/1       Running   0          3m
    po/kube-registry-proxy           1/1       Running   0          3m
    po/kubernetes-dashboard-9zsv8    1/1       Running   3          71d
    po/kubernetes-dashboard-f4tp1    1/1       Running   1          22m
    
    NAME                      DESIRED   CURRENT   READY     AGE
    rc/kube-dns-v20           1         1         1         71d
    rc/kube-registry          1         1         1         3m
    rc/kubernetes-dashboard   1         1         1         71d
    
    NAME                       CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
    svc/kube-dns               10.0.0.10    <none>        53/UDP,53/TCP   71d
    svc/kube-registry          10.0.0.142   <none>        5000/TCP        3m
    svc/kubernetes-dashboard   10.0.0.249   <nodes>       80:30000/TCP    71d
    
    NAME              DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    deploy/kube-dns   1         1         1            1           22m
    
    NAME                     DESIRED   CURRENT   READY     AGE
    rs/kube-dns-1301475494   1         1         1         22m

    Протестируем запущенный Registry, выложив в него наш образ командой dapp dimg push --tag-branch :minikube. Используемый здесь :minikube — это встроенный в dapp алиас специально для Minikube, который будет преобразован в localhost:5000/symfony-demo.

    $ dapp dimg push --tag-branch :minikube
    symfony-demo-app
      localhost:5000/symfony-demo:symfony-demo-app-kube_test               [PUSHING]
        pushing image `localhost:5000/symfony-demo:symfony-demo-app-kube_test`                                     [RUNNING]
    The push refers to a repository [localhost:5000/symfony-demo]
    0ea2a2940c53: Preparing
    ffe608c425e1: Preparing
    5c2cc2aa6663: Preparing
    edbfc49bce31: Preparing
    308e5999b491: Preparing
    9688e9ffce23: Preparing
    0566c118947e: Preparing
    6f9cf951edf5: Preparing
    182d2a55830d: Preparing
    5a4c2c9a24fc: Preparing
    cb11ba605400: Preparing
    6f9cf951edf5: Waiting
    182d2a55830d: Waiting
    5a4c2c9a24fc: Waiting
    cb11ba605400: Waiting
    9688e9ffce23: Waiting
    0566c118947e: Waiting
    0ea2a2940c53: Layer already exists
    308e5999b491: Layer already exists
    ffe608c425e1: Layer already exists
    edbfc49bce31: Layer already exists
    5c2cc2aa6663: Layer already exists
    0566c118947e: Layer already exists
    9688e9ffce23: Layer already exists
    182d2a55830d: Layer already exists
    6f9cf951edf5: Layer already exists
    cb11ba605400: Layer already exists
    5a4c2c9a24fc: Layer already exists
    symfony-demo-app-kube_test: digest: sha256:5c55386de5f40895e0d8292b041d4dbb09373b78d398695a1f3e9bf23ee7e123 size: 2616
        pushing image `localhost:5000/symfony-demo:symfony-demo-app-kube_test`                                          [OK] 0.54 sec

    Видно, что тег образа в Registry составлен из имени dimg и имени ветки (через дефис).

    Подготовка, шаг №2: конфигурация ресурсов (Helm)


    Вторая часть, необходимая для запуска приложения в кластере, — это конфигурация ресурсов. Стандартной утилитой управления кластером Kubernetes является kubectl. Если нужно создать новый ресурс (Deployment, Service, Ingress и т.д.) или изменить свойства существующего ресурса, то на вход утилите передаётся YAML-файл с конфигурацией.

    Однако dapp не использует напрямую kubectl, а работает с так называемым пакетным менеджером — Helm, — который предоставляет шаблонизацию YAML-файлов и сам управляет выкатом в кластер.

    Поэтому наш следующий шаг — это установка Helm. Официальную инструкцию можно найти в документации проекта.

    После установки необходимо запустить helm init. Что она делает? Helm состоит из клиентской части, которую мы установили, и серверной. Команда helm init устанавливает серверную часть (tiller). Посмотрим, что появилось в namespace kube-system:

    $ kubectl get -n kube-system all
    
    NAME                                READY     STATUS    RESTARTS   AGE
    po/kube-addon-manager-minikube      1/1       Running   2          1h
    po/kube-dns-1301475494-7kk6l        3/3       Running   3          1h
    po/kube-dns-v20-g7hr9               3/3       Running   9          71d
    po/kube-registry-6nw7m              1/1       Running   0          1h
    po/kube-registry-proxy              1/1       Running   0          1h
    po/kubernetes-dashboard-9zsv8       1/1       Running   3          71d
    po/kubernetes-dashboard-f4tp1       1/1       Running   1          1h
    !!! po/tiller-deploy-3703072393-bdqn8   1/1       Running   0          3m
    
    NAME                      DESIRED   CURRENT   READY     AGE
    rc/kube-dns-v20           1         1         1         71d
    rc/kube-registry          1         1         1         1h
    rc/kubernetes-dashboard   1         1         1         71d
    
    NAME                       CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
    svc/kube-dns               10.0.0.10    <none>        53/UDP,53/TCP   71d
    svc/kube-registry          10.0.0.142   <none>        5000/TCP        1h
    svc/kubernetes-dashboard   10.0.0.249   <nodes>       80:30000/TCP    71d
    !!! svc/tiller-deploy          10.0.0.196   <none>        44134/TCP       3m
    
    NAME                   DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    deploy/kube-dns        1         1         1            1           1h
    !!! deploy/tiller-deploy   1         1         1            1           3m
    
    NAME                          DESIRED   CURRENT   READY     AGE
    rs/kube-dns-1301475494        1         1         1         1h
    !!! rs/tiller-deploy-3703072393   1         1         1         3m

    (Здесь и далее знаком «!!!» вручную выделены строки, на которые стоит обратить внимание.)

    То есть: появился Deployment под названием tiller-deploy с одним ReplicaSet и одним подом (Pod). Для Deployment сделан одноимённый Service (tiller-deploy), который открывает доступ через порт 44134.

    Подготовка, шаг №3: IngressController


    Третья часть — сама конфигурация для приложения. На данном этапе нужно понять, что требуется выложить в кластер, чтобы приложение заработало.

    Предлагается следующая схема:

    • приложение — это Deployment. Для начала это будет один ReplicaSet из одного пода, как сделано для Registry;
    • приложение отвечает на порту 8000, поэтому нужно определить Service, чтобы под смог отвечать на запросы извне;
    • у нас веб-приложение, поэтому нужен способ получать пакеты от пользователей на 80-м порту. Это делается ресурсом Ingress. Для работы таких ресурсов нужно настроить IngressController.

    IngressController — это дополнительный компонент кластера Kubernetes для организации веб-приложений с балансировкой нагрузки. По сути это nginx, конфигурация которого зависит от ресурсов Ingress, добавляемых в кластер. Компонент нужно ставить отдельно, а для minikube существует addon. Подробнее о нём можно почитать в этой статье на английском, а пока просто запустим установку IngressController:

    $ minikube addons enable ingress
    ingress was successfully enabled

    … и посмотрим, что появилось в кластере:

    $ kubectl get -n kube-system all
    NAME                                READY     STATUS    RESTARTS   AGE
    !!! po/default-http-backend-vbrf3       1/1       Running   0          2m
    po/kube-addon-manager-minikube      1/1       Running   2          3h
    po/kube-dns-1301475494-7kk6l        3/3       Running   3          3h
    po/kube-dns-v20-g7hr9               3/3       Running   9          72d
    po/kube-registry-6nw7m              1/1       Running   0          3h
    po/kube-registry-proxy              1/1       Running   0          3h
    po/kubernetes-dashboard-9zsv8       1/1       Running   3          72d
    po/kubernetes-dashboard-f4tp1       1/1       Running   1          3h
    !!! po/nginx-ingress-controller-hmvg9   1/1       Running   0          2m
    po/tiller-deploy-3703072393-bdqn8   1/1       Running   0          1h
    
    NAME                          DESIRED   CURRENT   READY     AGE
    !!! rc/default-http-backend       1         1         1         2m
    rc/kube-dns-v20               1         1         1         72d
    rc/kube-registry              1         1         1         3h
    rc/kubernetes-dashboard       1         1         1         72d
    !!! rc/nginx-ingress-controller   1         1         1         2m
    
    NAME                       CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
    !!! svc/default-http-backend   10.0.0.131   <nodes>       80:30001/TCP    2m
    svc/kube-dns               10.0.0.10    <none>        53/UDP,53/TCP   72d
    svc/kube-registry          10.0.0.142   <none>        5000/TCP        3h
    svc/kubernetes-dashboard   10.0.0.249   <nodes>       80:30000/TCP    72d
    svc/tiller-deploy          10.0.0.196   <none>        44134/TCP       1h
    
    NAME                   DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    deploy/kube-dns        1         1         1            1           3h
    deploy/tiller-deploy   1         1         1            1           1h
    
    NAME                          DESIRED   CURRENT   READY     AGE
    rs/kube-dns-1301475494        1         1         1         3h
    rs/tiller-deploy-3703072393   1         1         1         1h

    Как проверить? IngressController в своём составе имеет default-http-backend, который отвечает ошибкой 404 на все страницы, для которых нет обработчика. Это можно увидеть такой командой:

    $ curl -i $(minikube ip)
    HTTP/1.1 404 Not Found
    Server: nginx/1.13.1
    Date: Fri, 14 Jul 2017 14:29:46 GMT
    Content-Type: text/plain; charset=utf-8
    Content-Length: 21
    Connection: keep-alive
    Strict-Transport-Security: max-age=15724800; includeSubDomains;
    
    default backend - 404

    Результат положительный — приходит ответ от nginx со строкой default backend - 404.

    Описание конфигурации для Helm


    Теперь можно описать конфигурацию приложения. Базовую конфигурацию поможет сгенерировать команда helm create имя_приложения:

    $ helm create symfony-demo
    $ tree symfony-demo
    symfony-demo/
    ├── charts
    ├── Chart.yaml
    ├── templates
    │   ├── deployment.yaml
    │   ├── _helpers.tpl
    │   ├── ingress.yaml
    │   ├── NOTES.txt
    │   └── service.yaml
    └── values.yaml

    dapp ожидает эту структуру в директории под названием .helm (см. документацию), поэтому нужно переименовать symfony-demo в .helm.

    Мы сейчас создали описание chart'а. Chart — это единица конфигурации для Helm, можно думать о нём как о неком пакете. Например, есть chart для nginx, для MySQL, для Redis. И с помощью таких chart'ов можно собрать нужную конфигурацию в кластере. Helm выкладывает в Kubernetes не отдельные образы, а именно Chart'ы (официальная документация).

    Файл Chart.yaml — это описание chart'а нашего приложения. Здесь нужно указать как минимум имя приложения и версию:

    $ cat Chart.yaml
    apiVersion: v1
    description: A Helm chart for Kubernetes
    name: symfony-demo
    version: 0.1.0

    Файл values.yaml — описание переменных, которые будут доступны в шаблонах. Например, в сгенерированном файле есть image: repository: nginx. Эта переменная будет доступна через такую конструкцию: {{ .Values.image.repository }}.

    Директория charts пока пуста, потому что наш chart приложения пока не использует внешние chart'ы.

    Наконец, директория templates — здесь хранятся шаблоны YAML-файлов с описанием ресурсов для их размещения в кластере. Сгенерированные шаблоны не сильно нужны, поэтому с ними можно ознакомиться и удалить.

    Для начала опишем простой вариант Deployment для нашего приложения:

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: {{ .Chart.Name }}-backend
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: {{ .Chart.Name }}-backend
        spec:
          containers:
          - command: [ '/opt/start.sh' ]
            image: {{ tuple "symfony-demo-app" . |  include "dimg" }}
            imagePullPolicy: Always
            name: {{ .Chart.Name }}-backend
            ports:
            - containerPort: 8000
              name: http
              protocol: TCP
            env:
           - name: KUBERNETES_DEPLOYED
              value: "{{ now }}"

    В конфигурации описано, что нам нужна пока что одна реплика, а в template указано, какие поды нужно реплицировать. В этом описании указывается образ, который будет запускаться и порты, которые доступны другим контейнерам в поде.

    Упомянутое в конфиге .Chart.Name — это значение из charts.yaml.

    Переменая KUBERNETES_DEPLOYED нужна, чтобы Helm обновлял поды, если мы обновим образ без изменения тега. Это удобно для отладки и локальной разработки.

    Далее опишем Service:

    apiVersion: v1
    kind: Service
    metadata:
      name: {{ .Chart.Name }}-srv
    spec:
      type: ClusterIP
      selector:
        app: {{ .Chart.Name }}-backend
      ports:
      - name: http
        port: 8000
        protocol: TCP

    Этим ресурсом мы создаём DNS-запись symfony-demo-app-srv, по которой другие Deployments смогут получать доступ к приложению.

    Эти два описания объединяются через --- и записываются в .helm/templates/backend.yaml, после чего можно разворачивать приложение!

    Первый деплой


    Теперь всё готово, чтобы запустить dapp kube deploy (Обновлено 13 августа 2019 г.: подробнее см. в документации werf):

    $ dapp kube deploy :minikube --image-version kube_test
    
    
    Deploy release symfony-demo-default                                              [RUNNING]
    Release "symfony-demo-default" has been upgraded. Happy Helming!
    LAST DEPLOYED: Fri Jul 14 18:32:38 2017
    NAMESPACE: default
    STATUS: DEPLOYED
    
    RESOURCES:
    ==> v1beta1/Deployment
    NAME                      DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
    symfony-demo-app-backend  1        1        1           0          7s
    
    ==> v1/Service
    NAME                  CLUSTER-IP  EXTERNAL-IP  PORT(S)   AGE
    symfony-demo-app-srv  10.0.0.173  <none>       8000/TCP  7s
    
    
    Deploy release symfony-demo-default                                                   [OK] 7.02 sec

    Видим, что в кластере появляется под в состоянии ContainerCreating:

    po/symfony-demo-app-backend-3899272958-hzk4l   0/1       ContainerCreating   0          24s

    … и через некоторое время всё работает:

    $ kubectl get all
    NAME                                           READY     STATUS    RESTARTS   AGE
    po/hello-minikube-938614450-zx7m6              1/1       Running   3          72d
    !!! po/symfony-demo-app-backend-3899272958-hzk4l   1/1       Running   0          47s
    
    NAME                       CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
    svc/hello-minikube         10.0.0.102   <nodes>       8080:31429/TCP   72d
    svc/kubernetes             10.0.0.1     <none>        443/TCP          72d
    !!! svc/symfony-demo-app-srv   10.0.0.173   <none>        8000/TCP         47s
    
    NAME                              DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    deploy/hello-minikube             1         1         1            1           72d
    deploy/symfony-demo-app-backend   1         1         1            1           47s
    
    NAME                                     DESIRED   CURRENT   READY     AGE
    rs/hello-minikube-938614450              1         1         1         72d
    !!! rs/symfony-demo-app-backend-3899272958   1         1         1         47s

    Создан ReplicaSet, Pod, Service, то есть приложение запущено. Это можно проверить «по старинке», зайдя в контейнер:

    $ kubectl exec -ti symfony-demo-app-backend-3899272958-hzk4l bash
    root@symfony-demo-app-backend-3899272958-hzk4l:/# curl localhost:8000

    Открываем доступ


    Теперь, чтобы приложение стало доступно по $(minikube ip), добавим ресурс Ingress. Для этого опишем его в .helm/templates/backend-ingress.yaml так:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: {{ .Chart.Name }}
      annotations:
        kubernetes.io/ingress.class: "nginx"
    spec:
      rules:
      - http:
          paths:
          - path: /
            backend:
              serviceName: {{ .Chart.Name }}-srv
              servicePort: 8000

    serviceName должно совпадать с именем Service, которое было объявлено в backend.yaml. Разворачиваем приложение ещё раз:

    $ dapp kube deploy :minikube --image-version kube_test
    Deploy release symfony-demo-default                                              [RUNNING]
    Release "symfony-demo-default" has been upgraded. Happy Helming!
    LAST DEPLOYED: Fri Jul 14 19:00:28 2017
    NAMESPACE: default
    STATUS: DEPLOYED
    
    RESOURCES:
    ==> v1/Service
    NAME                  CLUSTER-IP  EXTERNAL-IP  PORT(S)   AGE
    symfony-demo-app-srv  10.0.0.173  <none>       8000/TCP  27m
    
    ==> v1beta1/Deployment
    NAME                      DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
    symfony-demo-app-backend  1        1        1           1          27m
    
    ==> v1beta1/Ingress
    NAME              HOSTS  ADDRESS         PORTS  AGE
    symfony-demo-app  *      192.168.99.100  80     2s
    
    
    Deploy release symfony-demo-default                                                   [OK] 3.06 sec

    Появился v1beta1/Ingress! Попробуем обратиться к приложению через IngressController. Это можно сделать через IP кластера:

    $ curl -Lik $(minikube ip)
    HTTP/1.1 301 Moved Permanently
    Server: nginx/1.13.1
    Date: Fri, 14 Jul 2017 16:13:45 GMT
    Content-Type: text/html
    Content-Length: 185
    Connection: keep-alive
    Location: https://192.168.99.100/
    Strict-Transport-Security: max-age=15724800; includeSubDomains;
    
    HTTP/1.1 403 Forbidden
    Server: nginx/1.13.1
    Date: Fri, 14 Jul 2017 16:13:45 GMT
    Content-Type: text/html; charset=UTF-8
    Transfer-Encoding: chunked
    Connection: keep-alive
    Host: 192.168.99.100
    X-Powered-By: PHP/7.0.18-0ubuntu0.16.04.1
    Strict-Transport-Security: max-age=15724800; includeSubDomains;
    
    You are not allowed to access this file. Check app_dev.php for more information.

    В целом можно считать, что развёртывание приложения в Minikube удалось. Из запроса видно, что IngressController перебрасывает на 443-й порт и приложение отвечает, что нужно проверить app_dev.php. Это уже специфика выбранного приложения (symfony), потому что в файле web/app_dev.php легко заметить:

    // This check prevents access to debug front controllers that are deployed by
    // accident to production servers. Feel free to remove this, extend it, or make
    // something more sophisticated.
    if (isset($_SERVER['HTTP_CLIENT_IP'])
        || isset($_SERVER['HTTP_X_FORWARDED_FOR'])
        || !(in_array(@$_SERVER['REMOTE_ADDR'], ['127.0.0.1', 'fe80::1', '::1']) || php_sapi_name() === 'cli-server')
    ) {
        header('HTTP/1.0 403 Forbidden');
        exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
    }

    Чтобы увидеть нормальную страницу приложения, нужно развернуть приложение с другой настройкой либо для тестов закомментировать этот блок. Повторный деплой в Kubernetes (после правок в коде приложения) выглядит так:

    $ dapp dimg build
    ...
     Git artifacts: latest patch ...                                                     [OK] 1.86 sec
        signature: dimgstage-symfony-demo:13a2487a078364c07999d1820d4496763c2143343fb94e0d608ce1a527254dd3
      Docker instructions ...                                                             [OK] 1.46 sec
        signature: dimgstage-symfony-demo:e0226872a5d324e7b695855b427e8b34a2ab6340ded1e06b907b165589a45c3b
        instructions:
          EXPOSE 8000
    
    
    $ dapp dimg push --tag-branch :minikube
    ...
    symfony-demo-app-kube_test: digest: sha256:eff826014809d5aed8a82a2c5cfb786a13192ae3c8f565b19bcd08c399e15fc2 size: 2824
        pushing image `localhost:5000/symfony-demo:symfony-demo-app-kube_test`            [OK] 1.16 sec
      localhost:5000/symfony-demo:symfony-demo-app-kube_test                              [OK] 1.41 sec
    
    
    
    $ dapp kube deploy :minikube --image-version kube_test
    $ kubectl get all
    !!! po/symfony-demo-app-backend-3438105059-tgfsq   1/1       Running   0          1m

    Под пересоздался, можно зайти браузером и увидеть красивую картинку:



    Итог


    С помощью Minikube и Helm можно тестировать свои приложения в кластере Kubernetes, а dapp поможет в сборке, развёртывании своего Registry и самого приложения.

    В статье не упомянуты секретные переменные, которые можно использовать в шаблонах для приватных ключей, паролей и прочей закрытой информации. Об этом напишем отдельно.

    P.S.


    Читайте также в нашем блоге:

    • +17
    • 10,5k
    • 2
    Флант
    621,52
    Специалисты по DevOps и Kubernetes
    Поделиться публикацией

    Комментарии 2

      0
      Статей из ряда «как начать использовать helm» = 100500.

      Вот бы кто рассказал зачем? С примерами в сравнении с kubectl.

      При ~100 сервисов, лично я не увидел пользы от helm. Скорее минусы…
      Может толк станет заметен при 1000, 10000+ сервисах?
        +1
        Простите, вкладкой ошибся. Не к этому материалу вопрос.

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

      Самое читаемое