Ubuntu 22.04下使用Ansible自动化部署Docker:完整指南

简介

在现代应用环境中,服务器的易损性使得自动化在系统管理中扮演着至关重要的角色。配置管理工具,如Ansible,通常用于简化服务器设置的自动化过程,通过建立新服务器的标准程序,同时减少与手动设置相关的人为错误。

Ansible提供了一个简单的架构,无需在节点上安装特殊软件。它还提供了一套强大的功能和内置模块,方便编写自动化脚本。

本指南将解释如何使用Ansible自动化我们在《如何在Ubuntu 22.04上安装和使用Docker》指南中包含的步骤。Docker是一个简化容器管理的应用程序,容器是一种类似于虚拟机的资源隔离进程,但更便携、资源占用更少,并且更依赖于主机操作系统。

先决条件

为了执行本指南中提供的自动化设置,您需要:

  • 一个Ansible控制节点:一台安装并配置好Ansible的Ubuntu 22.04机器,能够使用SSH密钥连接到您的Ansible主机。请确保控制节点有一个具有sudo权限的普通用户,并且防火墙已启用,具体请参考我们的《初始服务器设置指南》。要设置Ansible,请遵循我们的《如何在Ubuntu 22.04上安装和配置Ansible》指南。
  • 一个或多个Ansible主机:一台或多台远程Ubuntu 22.04服务器,这些服务器已按照《如何使用Ansible自动化Ubuntu 22.04上的初始服务器设置》指南进行过设置。

注意:

在继续之前,您首先需要确保您的Ansible控制节点能够连接并执行命令在您的Ansible主机上。作为连接测试,请查看《如何在Ubuntu 22.04上安装和配置Ansible》的第3步。

此剧本的作用是什么?

这个Ansible剧本提供了一个替代方案,让您不必手动遵循我们在《在Ubuntu 22.04上安装和使用Docker的指南》中概述的过程。您只需设置一次剧本,之后每次安装都可以重复使用它。

运行此剧本将在您的Ansible主机上执行以下操作:

  1. 安装aptitude,这是Ansible推荐的apt软件包管理器的替代品。
  2. 安装所需的系统软件包。
  3. 安装Docker GPG APT密钥。
  4. 将官方Docker仓库添加到apt源。
  5. 安装Docker。
  6. 通过pip安装Python Docker模块。
  7. 从Docker Hub拉取由default_container_image指定的默认镜像。
  8. 根据container_count变量定义的数量创建容器,并在每个新容器中使用default_container_image定义的镜像,然后执行default_container_command中定义的命令。

一旦剧本运行完毕,根据您在配置变量中定义的选项,会创建出若干个容器。

首先,请在您的Ansible控制节点服务器上使用具有sudo权限的用户登录。

第一步 – 准备您的剧本

playbook.yml文件是定义所有任务的地方。一个任务是使用Ansible剧本可以自动化的最小操作单位。但是首先,请使用您首选的文本编辑器创建您的剧本文件。

  1. nano playbook.yml

这将打开一个空的YAML文件。在开始添加任务到您的剧本之前,首先添加以下内容:

---
- hosts: all
  become: true
  vars:
    container_count: 4
    default_container_name: docker
    default_container_image: ubuntu
    default_container_command: sleep 1

几乎每个剧本都会以类似的声明开始。hosts声明了Ansible控制节点将使用该剧本定位哪些服务器。become则表示所有命令将以提升的root权限执行。

变量允许您将数据存储在变量中。如果将来决定更改这些变量,您只需要编辑文件中的这几行即可。以下是每个变量的简要解释:

  • container_count: 要创建的容器数量。
  • default_container_name: 默认容器名称。
  • default_container_image: 创建容器时使用的默认Docker镜像。
  • default_container_command: 在新容器上运行的默认命令。

注意:

如果你想查看最终完成状态的剧本文件,请跳转到第5步。YAML文件对于缩进结构非常严格,因此在添加所有任务后,你可能需要仔细检查一下你的剧本。

第二步 – 添加软件包安装任务到您的剧本

默认情况下,Ansible按照剧本中的顺序以同步方式依次执行任务。这意味着任务的顺序很重要,您可以安全地假设一个任务会在下一个任务开始之前执行完毕。

本指南中的所有任务都可以独立存在,并且可以在您的其他指南中重复使用。

将您的首个任务添加为安装aptitude,这是一个用于与Linux软件包管理器交互的工具,并安装所需的系统软件包。Ansible将确保这些软件包始终安装在您的服务器上。

这是文章《如何使用Ansible在Ubuntu 22.04上安装和设置Docker》的第2部分(共5部分)。

  tasks:
    - name: 安装 aptitude
      apt:
        name: aptitude
        state: latest
        update_cache: true

    - name: 安装所需的系统软件包
      apt:
        pkg:
          - apt-transport-https
          - ca-certificates
          - curl
          - software-properties-common
          - python3-pip
          - virtualenv
          - python3-setuptools
        state: latest
        update_cache: true

在这里,您正在使用适当的Ansible内置模块指示Ansible安装您的软件包。Ansible中的模块是执行操作的快捷方式,否则您必须以原始的bash命令运行。如果没有aptitude可用,Ansible会安全地回退到apt来安装软件包,但Ansible历来更倾向于aptitude。

您可以根据您的喜好添加或删除软件包。这将确保所有软件包不仅存在,而且是最新版本,并在调用apt进行更新后进行操作。

第三步 – 将Docker安装任务添加到您的Playbook中

您的任务是从官方仓库安装最新版本的Docker。为了验证下载的内容,将添加Docker GPG密钥,将官方仓库添加为新的软件包源,并安装Docker。此外,还将安装Python的Docker模块。

请编写playbook.yml文件。

playbook.yml的编写:

    - name: 添加 Docker GPG apt 密钥
      apt_key:
        url: https://download.docker.com/linux/ubuntu/gpg
        state: present

    - name: 添加 Docker 仓库
      apt_repository:
        repo: deb https://download.docker.com/linux/ubuntu jammy stable
        state: present

    - name: 更新 apt 并安装 docker-ce
      apt:
        name: docker-ce
        state: latest
        update_cache: true

    - name: 为 Python 安装 Docker 模块
      pip:
        name: docker

您将看到apt_keyapt_repository这两个内置的Ansible模块首先指向正确的URL,然后被指定为确保其存在。这将允许安装最新版本的Docker,以及使用pip安装Python模块。

第四步 – 将Docker镜像和容器任务添加到您的Playbook中。

您的Docker容器的实际创建从拉取您所需的Docker镜像开始。默认情况下,这些镜像来自官方的Docker Hub。使用这个镜像,根据您在playbook顶部声明的变量规范,容器将被创建。

playbook.yml: 剧本文件
    - name: 拉取默认Docker镜像
      community.docker.docker_image:
        name: "{{ default_container_image }}"
        source: pull

    - name: 创建默认容器
      community.docker.docker_container:
        name: "{{ default_container_name }}{{ item }}"
        image: "{{ default_container_image }}"
        command: "{{ default_container_command }}"
        state: present
      with_sequence: count={{ container_count }}

docker_image 模块用于拉取您希望作为容器基础的Docker镜像。docker_container 模块允许您指定创建容器的具体信息,以及您想要传递给它们的命令。

使用 with_sequence 是Ansible创建循环的方式,在这种情况下,它将根据您指定的计数循环创建容器。这是一个基本的计数循环,因此这里的 item 变量提供了表示当前循环迭代的数字。这个数字在这里用于为您的容器命名。

步骤五 — 审查您的完整策略手册

您的操作手册应该大致如下所示,根据您的定制可能会有一些细微的差别。

使用的操作指令文件为 playbook.yml
---
- hosts: all
  become: true
  vars:
    container_count: 4
    default_container_name: docker
    default_container_image: ubuntu
    default_container_command: sleep 1d

  tasks:
    - name: 安装 aptitude
      apt:
        name: aptitude
        state: latest
        update_cache: true

    - name: 安装所需的系统软件包
      apt:
        pkg:
          - apt-transport-https
          - ca-certificates
          - curl
          - software-properties-common
          - python3-pip
          - virtualenv
          - python3-setuptools
        state: latest
        update_cache: true

    - name: 添加 Docker GPG apt 密钥
      apt_key:
        url: https://download.docker.com/linux/ubuntu/gpg
        state: present

    - name: 添加 Docker 仓库
      apt_repository:
        repo: deb https://download.docker.com/linux/ubuntu jammy stable
        state: present

    - name: 更新 apt 并安装 docker-ce
      apt:
        name: docker-ce
        state: latest
        update_cache: true

    - name: 安装 Python 的 Docker 模块
      pip:
        name: docker

    - name: 拉取默认 Docker 镜像
      community.docker.docker_image:
        name: "{{ default_container_image }}"
        source: pull

    - name: 创建默认容器
      community.docker.docker_container:
        name: "{{ default_container_name }}{{ item }}"
        image: "{{ default_container_image }}"
        command: "{{ default_container_command }}"
        state: present
      with_sequence: count={{ container_count }}

请随意修改此手册,以使其最适合你个人的工作流程需求。例如,你可以使用docker_image模块将镜像推送到 Docker Hub,或使用docker_container模块设置容器网络。

注意:这是一个温馨提示,请务必注意你的缩进。如果你遇到错误,很可能就是这个问题导致的。YAML建议使用2个空格作为缩进,就像本例中所示。

一旦你对自己的策略满意,可以关闭文本编辑器并保存。

第六步 – 运行你的Playbook

现在你已经准备好在一个或多个服务器上运行这个Playbook了。大多数Playbook默认配置为在清单中的每个服务器上执行,但这次你会指定你的服务器。

为了在连接为sammy的情况下只在server1上执行Playbook,你可以使用以下命令:

  1. ansible-playbook playbook.yml -l server1 -u sammy

-l标志指定你的服务器,-u标志指定要登录远程服务器的用户。你将获得类似于这样的输出:

输出

. . .
changed: [server1]

TASK [创建默认容器] *****************************************************************************************************************
changed: [server1] => (item=1)
changed: [server1] => (item=2)
changed: [server1] => (item=3)
changed: [server1] => (item=4)

PLAY RECAP ***************************************************************************************************************************************
server1 : ok=9 changed=8 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

注意:想要了解如何运行Ansible剧本,可以查阅我们的Ansible备忘单指南。

这表明你的服务器设置已完成!你的输出不一定要完全相同,但重要的是没有失败。

当Playbook运行完成后,通过SSH登录到由Ansible配置的服务器上,检查容器是否成功创建。

使用以下方式登录远程服务器:

  1. ssh sammy@你的_远程_服务器_IP

在远程服务器上列出你的Docker容器。

  1. sudo docker ps -a

你应该看到类似这样的输出结果。

输出

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a3fe9bfb89cf ubuntu "sleep 1d" 5 minutes ago Created docker4
8799c16cde1e ubuntu "sleep 1d" 5 minutes ago Created docker3
ad0c2123b183 ubuntu "sleep 1d" 5 minutes ago Created docker2
b9350916ffd8 ubuntu "sleep 1d" 5 minutes ago Created docker1

这意味着在Playbook中定义的容器成功创建。由于这是Playbook中的最后一个任务,也确认了Playbook在该服务器上完全执行成功。

结论

自动化基础设施设置不仅可以节省时间,还可以确保服务器遵循标准配置,并能根据需要进行定制。随着现代应用程序的分布式特性和不同分段环境的一致性需求,这样的自动化已成为许多团队开发流程中的核心组成部分。

在这篇指南中,你演示了如何使用Ansible自动化安装和设置远程服务器上的Docker过程。由于每个人在处理容器时通常有不同的需求,我们鼓励你查阅官方的Ansible文档,了解更多关于docker_container Ansible模块的信息和用例。

如果你想在这本操作手册中包含其他任务,以进一步自定义你的初始服务器设置,请参考我们的入门Ansible指南“配置管理101:编写Ansible Playbooks”。

bannerAds