Вызов развертывания стека докеров на хосте докеров из контейнера Jenkins

На своем хосте OS X я использую Docker CE (18.06.1-ce-mac73 (26764)) с включенным Kubernetes и оркестровкой Kubernetes. С этого хоста я могу запустить развертывание стека для развертывания контейнера в Kubernetes, используя этот простой файл для создания докеров (kube-compose.yml):

version: '3.3'
services:
  web:
    image: dockerdemos/lab-web
    volumes:
      - "./web/static:/static"
    ports:
      - "9999:80"

и эта командная строка запускается из каталога, содержащего файл компоновки:

docker stack deploy --compose-file ./kube-compose.yml simple_test

Однако, когда я пытаюсь запустить ту же команду из своего контейнера Jenkins, Jenkins возвращает:

этот узел не является менеджером роя. Используйте «docker swarm init» или «docker swarm join», чтобы подключить этот узел к swarm и повторить попытку.

Я не хочу, чтобы клиент Docker в контейнере Jenkins был инициализирован для роя, так как я не использую рой Docker на хосте.

Контейнер Jenkins определен в docker-compose, чтобы включить монтирование тома в конечную точку сокета хоста docker:

version: '3.3'
services:
  jenkins:
    # contains embedded docker client & blueocean plugin
    image: jenkinsci/blueocean:latest
    user: root
    ports:
      - "8080:8080"
      - "50000:50000"
    volumes:
      - ./jenkins_home:/var/jenkins_home
      # run Docker from the host system when the container calls it.
      - /var/run/docker.sock:/var/run/docker.sock
      # root of simple project
      - .:/home/project
    container_name: jenkins

Я также следовал этому руководству по прокси-запросам к хосту докеров с помощью socat: https://github.com/docker/for-mac/issues/770 и здесь: Docker-compose: развертывание сервиса на нескольких хостах.

Наконец, я использую следующее определение Jenkins (Jenkinsfile) для стека вызовов для развертывания на моем хосте. В Jenkins установлен подключаемый модуль докера Jenkins:

node {
    checkout scm

    stage ('Deploy To Kube') {
        docker.withServer('tcp://docker.for.mac.localhost:1234') {
            sh 'docker stack deploy app --compose-file /home/project/kube-compose.yml'
        }
    }      
}

Я также попытался изменить подпись withServer на:

docker.withServer('unix:///var/run/docker.sock')

и я получаю тот же ответ об ошибке. Однако я могу подключиться по telnet к хосту докера из контейнера Jenkins, поэтому я знаю, что он доступен. Кроме того, как я упоминал ранее, я знаю, что в сообщении говорится о запуске swarm init, но я не развертываю swarm.

Я проверил версию клиента докера в контейнере Jenkins, и это та же версия (однако вариант Linux), которую я использую на своем хосте:

Докер версии 18.06.1-ce, сборка d72f525745

Вот код, который я описал: https://github.com/ewilansky/localstackdeploy.git

Пожалуйста, дайте мне знать, возможно ли сделать то, что я надеюсь сделать из контейнера Jenkins. Цель всего этого — предоставить простую переносимую демонстрацию конвейера, а развертывание в Kubernetes — последний шаг. Я понимаю, что это не тот подход, который можно было бы использовать за пределами локальной среды разработки.


person ewilan    schedule 21.10.2018    source источник
comment
Вы выполняете развертывание в Kubernetes или Docker Swarm?   -  person Rico    schedule 22.10.2018
comment
Я выполняю развертывание в Kubernetes, который теперь интегрирован в Docker CE и настроен для оркестровки Kubernetes.   -  person ewilan    schedule 22.10.2018


Ответы (1)


Вот подход, который хорошо работает для меня, пока подключаемый модуль Jenkins Docker или команда Kubernetes Docker Stack Deploy не смогут поддерживать сценарий удаленного развертывания, который я описал.

Сейчас я использую клиент Kubernetes kubectl из контейнера Jenkins. Чтобы свести к минимуму увеличение размера контейнера Jenkins, я добавил только клиент Kubernetes в образ jenkinsci/blueocean, созданный на Alpine Linux. Этот DockerFile показывает дополнение:

FROM jenkinsci/blueocean
USER root
RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.12.0/bin/linux/amd64/kubectl
RUN chmod +x ./kubectl
RUN mv ./kubectl /usr/local/bin/kubectl
RUN mkdir /root/.kube
COPY kube-config /root/.kube/config

Я воспользовался этим подходом, который увеличил размер образа примерно на 100 МБ, а не получил пакет Alpine Linux Kubernetes, который почти удвоил размер образа в моем тестировании. Конечно, в пакете Kubernetes есть все компоненты Kubernetes, но мне нужен был только клиент Kubernetes. Это похоже на требование, чтобы клиент Docker был резидентным в контейнере Jenkins, чтобы выполнять команды Docker на хосте.

Обратите внимание, что в DockerFile есть ссылка на конфигурационный файл Kuberenetes:

kube-config /root/.kube/config

Я начал с файла конфигурации Kubernetes на моем хост-компьютере (компьютер, на котором работает Docker для Mac). Я считаю, что если вы включите Kubernetes в Docker для Mac, конфигурация клиента Kubernetes будет присутствовать в ~/.kube/config. Если нет, установите клиентские инструменты Kubernetes отдельно. В файле конфигурации Kubernetes, который вы скопируете в контейнер Jenkins через DockerFile, просто измените значение сервера, чтобы контейнер Jenkins указывал на хост Docker для Mac:

    server: https://docker.for.mac.localhost:6443

Если вы используете компьютер с Windows, я думаю, вы можете использовать docker.for.win.localhost. Здесь обсуждается это: https://github.com/docker/for-mac/issues/2705 и другие подходы, описанные здесь: https://github.com/docker/for-linux/issues/264.

После перекомпоновки контейнера Jenkins я смог использовать kubectl для создания развертывания и службы для моего приложения, которое теперь работает на хосте Kubernetes Docker для Mac. В моем случае вот две команды, которые я добавил в свой файл Jenkins:

 stage ('Deploy To Kube') {
    sh 'kubectl create -f /kube/deploy/app_set/sb-demo-deployment.yaml'
}
stage('Configure Kube Load Balancer') {
    sh 'kubectl create -f /kube/deploy/app_set/sb-demo-service.yaml'
}

Существует множество вариантов развертывания контейнеров Kubernetes. В моем случае мне просто нужно было развернуть мое веб-приложение (с репликами) за балансировщиком нагрузки. Все это определено в двух файлах yaml, вызываемых kubectl. Это немного сложнее, чем развертывание стека докеров, но дает тот же конечный результат.

person ewilan    schedule 25.10.2018