Docker服务不是在Ansible中启动的

我正在学习Ansible ,在笔记本电脑中本地使用它,现在我正在使用“includes”。

我想编写一个剧本来导入一些其他任务(安装基础包,设置git,vim和docker)并执行它。

所有代码都在GitLab托pipe,我正在使用他们的免费CI服务来testing这些游戏。

CI作业将运行直到检查docker服务是否正在运行。 此时,播放将失败,并显示以下消息:

 fatal: [localhost]: FAILED! => { "changed": true, "cmd": ["service", "docker", "restart"], "delta": "0:00:00.176233", "end": "2017-09-28 18:49:56.194752", "failed": true, "msg": "non-zero return code", "rc": 1, "start": "2017-09-28 18:49:56.018519", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": [] } 

我已经在我的笔记本电脑中创build了一个docker run --rm -ti debian容器( docker run --rm -ti debian ),并且在本地执行了这个游戏,并且在同一个地方失败了。

但是 ,如果使用privileged标志创build容器,我可以手动启动服务,然后重新执行播放。 这一次,它会成功完成。


所以,我的问题是:

  • 我怎样才能使用Ansible启动Ansible服务?
    • 我是否完全错误,有更好的方法来使这个工作?
  • 在笔记本电脑中运行容器时,我使用privilege模式创build了它。 这使我能够手动启动服务。
    • 由于我无法修改在GitLab-CI公共实例中创build容器的方式:
    • 可能是一个可能的解决scheme,以启用privileged标志将我自己的跑步者添加到项目中?

PS:目前,我并没有正在研究最佳实践,我只是试图让这个运行有一些东西可以玩。

环境:

  • Ansible:2.4.0
  • Python:2.7.13
  • Docker:17.09.0-ce

— — —

gitlab-ci.yml文件:

 image: debian:latest variables: HOST_INVENTORY: "./hosts" INCLUDES_DIR: "./gists/includes" before_script: - apt-get update -qq - apt-get install -y curl gcc g++ openssh-server openssh-client python python-dev python-setuptools libffi-dev libssl-dev - easy_install pip - pip install ansible stages: - syntax_check - install check: stage: syntax_check script: - ansible-playbook -i $HOST_INVENTORY $INCLUDES_DIR/play.yml --limit 'local' --syntax-check; run_includes: stage: install script: - ANSIBLE_PIPELINING=True ansible-playbook -i $HOST_INVENTORY $INCLUDES_DIR/play.yml --limit 'local'; 

play.yml很简单,只导入一些游戏:

 - hosts: local become: yes become_method: sudo pre_tasks: - import_tasks: tasks/pre.yml # update package manager cache tasks: - import_tasks: tasks/common.yml - import_tasks: tasks/docker.yml 

docker工作:

 - name: Dependencies package: name: "{{ item }}" state: installed with_items: - apt-transport-https - ca-certificates - curl - gnupg2 - software-properties-common - name: Docker module dependencies pip: name: docker-py - name: Add Docker key shell: curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | apt-key add - - name: Add Docker repo shell: echo "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo $ID) $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list - name: Install Docker apt: pkg: docker-ce state: installed update_cache: yes - name: Ensure Docker group is present group: name: docker state: present - name: Add current user to the Docker group user: name: "{{ ansible_user }}" groups: - docker append: yes - name: Ensure service is enabled command: service docker restart - name: Pull images from Docker hub docker_image: name: "{{ item }}" with_items: - debian - cern/cc7-base 

所以我在gitlab.com上创build了一个在gitlab.com上运行几个命令的示例项目

 $ echo PWD is $PWD PWD is /builds/tarunlalwani/testci $ id uid=0(root) gid=0(root) groups=0(root) $ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.1 20260 2984 ? Ss 19:41 0:00 /bin/bash root 7 0.0 0.1 20420 2652 ? S 19:41 0:00 /bin/bash root 10 0.0 0.0 17500 1996 ? R 19:41 0:00 ps aux $ which systemctl /bin/systemctl $ systemctl status docker Failed to get D-Bus connection: Unknown error -1 ERROR: Job failed: exit code 1 

正如你所看到的,我们正在一个容器内运行,因此你的可靠的脚本是不会工作的。 没有docker服务开始或结束。 此外,因为您在docker集装箱内,重新启动docker集装箱也意味着要杀死您正在运行的容器。

你需要设置一个Ubuntu VM,然后用Shell执行器设置Gitlab Runner。 shell执行程序将意味着您的命令在该虚拟机上运行,​​该虚拟机将具有systemctldocker服务

另一种方法是使用GitLab的dind服务 ,它可以让我们使用已经提供的共享参赛者来testing一个容器中的剧本。

这里需要两件事情:

  1. 一个Dockerfile在哪里build立一个基本的形象与运行Ansible的所有要求。
  2. 一个修改的gitlab-ci文件来运行容器内的作业。

例如, Dockerfile可能如下所示:

 FROM debian:latest ARG USERNAME RUN apt-get update && \ apt-get install -y curl \ git \ gcc \ g++ \ libffi-dev \ libssl-dev \ openssh-client \ openssh-server \ python \ python-dev \ python-setuptools \ sudo RUN easy_install pip && \ pip install ansible \ jmespath RUN useradd -ms /bin/bash $USERNAME USER $USERNAME WORKDIR /home/$USERNAME 

然后,在gitlab-ci.yml文件中,我们可以像这样:

 image: docker:latest services: - docker:dind variables: DOCKER_IMAGE: "registry.gitlab.com/<YOUR_USER>/<YOUR_REPO>/dummy-image" CONTAINER_NAME: "test" IMAGE_USERNAME: "dummy" stages: - build - check before_script: - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com after_script: - docker rm -f $(docker ps -aq) - docker rmi $DOCKER_IMAGE - docker logout registry.gitlab.com build_image: stage: build script: - docker build --pull -t $DOCKER_IMAGE --build-arg USERNAME=$IMAGE_USERNAME . - docker push $DOCKER_IMAGE when: manual check_version: stage: check script: - docker run -di --name $CONTAINER_NAME $DOCKER_IMAGE - docker exec $CONTAINER_NAME /bin/bash -c "ansible-playbook --version" 

这还有一个额外的好处,即Ansible运行的所有先决条件都是在build阶段设置的,并且不需要在每次CI进程运行时重复一次(就像使用原始的gitlab-ci.yml文件在问题中)。

Interesting Posts