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执行程序将意味着您的命令在该虚拟机上运行,该虚拟机将具有systemctl
和docker
服务
另一种方法是使用GitLab的dind
服务 ,它可以让我们使用已经提供的共享参赛者来testing一个容器中的剧本。
这里需要两件事情:
- 一个
Dockerfile
在哪里build立一个基本的形象与运行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
文件在问题中)。