在远程Docker群群集上运行手动GitLab CI作业时遇到问题

问题描述

这里有一些背景知识:我有一个Django应用程序运行在预先安装了Docker 19.03.1〜3的DigitalOcean Droplet上。我正在运行一个单节点群集集群,该应用程序在大多数情况下都可以正常运行。

这是我遇到的问题:我试图将一些管理命令放入手动触发的GitLab CI作业中,因此我不必通过SSH进入Droplet并运行命令(migrate和{{ 1}})。当SSH进入Droplet时,我可以成功运行这些命令。例如,要运行collectstatic,我将查找Django容器(collectstatic)的容器ID,然后运行:

e710394e5449

要运行管理命令,我想我可以做这样的事情:

docker exec -it e710394e5449 python3 manage.py collectstatic

这是我在GitLab CI作业日志中看到的错误:

docker exec $(docker ps -q -f name="backend") python3 manage.py collectstatic --no-input

您可以从远程docker主机上的GitLab CI作业运行error during connect: Get http://docker/v1.40/containers/e710394e5449/json: command [ssh -l root 123.45.6.789 -- docker system dial-stdio] has exited with exit status 255,please make sure the URL is valid,and Docker 18.09 or later is installed on the remote host: stderr=ssh: connect to host 123.45.6.789 port 22: Connection refused 吗?我可以获取容器ID(docker exec),但是外部$(docker ps -q -f name="backend")命令失败。我可以从笔记本电脑上毫无问题地运行命令(docker exec

这是我的 docker exec $(docker ps -q -f name="backend") python3 manage.py collectstatic --no-input文件。 .gitlab-ci.yml作业为我如何运行命令提供了两个选项:一个使用django-collectstatic在现有容器中运行该命令,另一个使用docker exec。这些选项都不起作用,这只是为了展示我的尝试。

docker run

请告诉我是否还有其他事情可以帮助您澄清我的问题。

解决方法

到目前为止,我认为最简单的方法是直接通过SSH运行docker命令,而不是使用DOCKER_HOST环境变量连接我的docker CLI(在GitLab CI中)。

这最终看起来像这样:

django-migrate:
  before_script:
    - apk update && apk add openssh-client bash
    - mkdir -p ~/.ssh
    - echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - eval "$(ssh-agent -s)"
    - ssh-add ~/.ssh/id_rsa
    - ssh-keyscan -H $DROPLET_IP >> ~/.ssh/known_hosts
  stage: management
  rules:
    - when: manual
  script:
    - ssh root@$DROPLET_IP \
      'docker exec $(docker ps -q -f name="backend") python3 manage.py migrate --no-input'

无论出于何种原因,运行docker exec $(docker ps -q -f name="backend") python3 manage.py migrate --no-input都会失败。我将能够获得容器ID(docker ps命令将成功完成,但是docker exec命令将由于连接被拒绝而失败。

我不确定通过SSH连接运行docker命令的安全性。

该命令的输出确实很好地显示在GitLab CI作业的日志中,这正是我想要的。

,

我回答了相同的问题here,您可以使用选项-h或DOCKER_HOST env在远程主机上运行docker命令,如果尚未完成,则需要启用TLS。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...