首页 文章

Docker服务未在Ansible中启动

提问于
浏览
1

我正在学习 Ansible ,想在我的笔记本电脑本地使用它,目前我正在使用"includes" .

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

所有代码都托管在GitLab中,我正在使用他们的免费CI服务来测试游戏 .

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": []
}

我已经在我的笔记本电脑中创建了一个docker容器( docker run --rm -ti debian ),并在本地执行了该游戏,并且它在同一位置失败 .

However ,如果使用 privileged 标志创建容器,我可以手动启动服务,然后重新执行播放 . 这一次,它将成功完成 .


所以,我的问题是:

  • 如何使用 Ansible 启动 docker 服务?

  • 我完全错了,有更好的办法让这个工作吗?

  • 在我的笔记本电脑中运行容器时,我在 privilege 模式下创建了它 . 这让我可以手动启动服务 .

  • 由于我无法修改 GitLab-CI 公共实例中容器的创建方式:

  • 可能是一个可能的解决方案,在启用 privileged 标志的情况下将我自己的跑步者添加到项目中?

PS: 目前,我只是试图让这个运行起来有所作为 .

Environment:

  • 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

2 回答

  • 0

    所以我在 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
    

    正如您所看到的,我们在容器内运行,因此您的ansible脚本无法运行 . 没有泊坞服务可以开始或结束 . 此外,由于您位于docker容器内,因此重新启动docker容器也意味着终止正在运行的容器 .

    您需要设置一个Ubuntu VM,然后使用Shell Actuator 设置Gitlab Runner . shell执行程序将意味着您的命令在该VM上运行,该VM将具有 systemctldocker 服务

  • 3

    另一种方法是使用GitLab's dind service,让我们使用已经提供的共享运行器测试容器内的playbooks .

    这里需要两件事:

    • A Dockerfile 在哪里构建一个基本映像,其中包含运行Ansible的所有要求 .

    • 已修改的 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 文件一样) .

相关问题