当前位置: 首页 > news >正文

Ansible自动化部署Docker到Ubuntu 18.04实战指南

1. 项目概述:为什么用 Ansible 自动化部署 Docker 到 Ubuntu 18.04 是运维效率的分水岭

Ansible、Docker、Ubuntu 18.04 这三个词凑在一起,不是偶然,而是过去五年里无数中小团队在技术选型十字路口反复权衡后落下的真实脚印。我第一次在客户现场看到运维同事手动敲完 23 行apt-get installcurl -fsSLusermod -aG dockersystemctl enabledocker run hello-world全流程,耗时 7 分 42 秒,中间还因网络抖动重试了两次 apt 更新——那一刻我就知道,这套操作必须进 playbook。这不是炫技,是止损。Ubuntu 18.04 虽已进入 ESM(扩展安全维护)阶段,但大量生产环境中的 CI/CD 构建节点、边缘计算网关、遗留测试集群仍在稳定运行它;而 Docker 作为容器化事实标准,其安装过程表面简单,实则暗藏三类典型风险:一是系统源配置不一致导致apt-transport-https缺失引发后续失败;二是 GPG 密钥导入失败却无明确报错,使apt-key add看似成功实则无效;三是dockerd启动后未验证是否真正监听/var/run/docker.sock,导致后续docker info命令静默失败。Ansible 的价值,正在于把这三类“看似能跑、实则埋雷”的状态,全部收束进可审计、可回滚、可批量执行的声明式逻辑里。它不替代你理解 Docker,而是把你对 Docker 安装路径的每一次经验沉淀,变成下次新服务器上线时自动复现的确定性动作。适合谁?不是只给 DevOps 工程师看的——如果你是刚接手公司旧测试环境的 Python 开发,需要快速在三台 Ubuntu 18.04 虚拟机上搭起本地镜像构建环境;如果你是高校实验室管理员,要为 15 个学生账号统一预装 Docker 并加入docker用户组;甚至如果你只是 WSL2 下想摆脱sudo apt-get install docker.io那个老旧版本的束缚,这个 playbook 都能直接抄作业。核心就一条:让“安装 Docker”这件事,从一次性的、依赖记忆的手工操作,变成一个带版本号、带校验、带日志的可交付制品。

2. 整体设计与思路拆解:为什么不用 shell 脚本而选 Ansible?四个不可妥协的技术动因

2.1 拒绝“一锅炖”式 shell 脚本:幂等性不是可选项,是生存线

很多人第一反应是写个.sh脚本:apt update && apt install docker-ce ...。我试过,也维护过——直到某天凌晨三点接到告警,说某台机器dockerd进程异常退出,登录一看,脚本被重复执行了 4 次,/etc/docker/daemon.json被覆盖了三次,最后一次写入的{}导致守护进程无法启动。Shell 脚本天然缺乏状态感知能力。而 Ansible 的aptcopyservice模块,每个动作都内置幂等性判断:apt模块会先查包是否已安装且版本匹配;copy模块默认比对文件内容哈希;service模块只在服务状态非预期时才触发启停。这意味着你可以放心地对同一台机器反复运行ansible-playbook docker-setup.yml -i inventory.ini,它只会做“必要之事”,不会因误操作引发雪崩。这不是功能差异,是运维哲学的分野:shell 脚本是“我命令你执行”,Ansible 是“我声明你应处于什么状态”。

2.2 Ubuntu 18.04 的特殊性:官方源 vs Docker 官方源,版本控制的生死抉择

Ubuntu 18.04 官方仓库里的docker.io包,版本长期卡在 18.09.x,而 Docker 社区版(CE)早已迭代至 20.10+。关键区别在哪?docker.io缺少docker buildx插件支持,无法构建多平台镜像;其dockerd默认不启用containerd作为运行时,导致后续集成 Kubernetes CRI 时出现兼容问题。因此,本方案强制使用 Docker 官方 APT 源,而非apt install docker.io。这带来两个硬性要求:第一,必须确保apt-transport-httpsca-certificates已预装,否则apt-add-repository会静默失败;第二,Docker 官方 GPG 密钥必须通过apt_key模块安全导入,而非curl | sudo apt-key add -这种已被弃用且存在安全风险的操作。Ansible 的模块化设计,让这两个前置条件成为 playbook 中清晰、独立、可单独调试的步骤,而不是 shell 脚本里一行容易被注释掉的apt-get install -y apt-transport-https ca-certificates

2.3 安全基线的刚性嵌入:非 root 用户也能安全使用 Docker 的底层逻辑

Docker 守护进程默认以 root 权限运行,若普通用户需执行docker run,传统做法是sudo usermod -aG docker $USER。但这存在两个隐患:一是该命令需重启用户会话才能生效,自动化中难以可靠触发;二是若目标用户不存在,usermod会报错中断。本方案采用 Ansible 的user模块配合group模块双重保障:先确保docker组存在,再将指定用户(如ubuntudeploy)加入该组,并设置append: yes避免覆盖已有组成员。更重要的是,我们额外注入一条~/.bashrc配置:export DOCKER_HOST=unix:///var/run/docker.sock。这并非必需,但它让非 root 用户在不加sudo的前提下,通过 Unix socket 直接与dockerd通信,规避了sudo权限提升带来的审计盲区。这条配置由lineinfile模块精准插入,仅当行不存在时才添加,完美符合幂等原则。

2.4 可观测性与故障定位:为什么ignore_errors: no是默认,而failed_when是必填项

Ansible 默认会在任何任务失败时立即中止整个 playbook。这看似严苛,实则是精准排障的前提。比如apt模块安装docker-ce-cli失败,若忽略错误继续执行dockerd启动,最终docker info必然报错,但你根本不知道根因是 CLI 工具缺失还是守护进程未启动。因此,本方案所有关键任务均显式声明ignore_errors: no(虽为默认,但显式写出是专业习惯),并在涉及外部命令验证的任务(如docker version)中,使用failed_when精确控制失败阈值。例如,docker version返回非零码时,Ansible 默认视为失败;但若返回码为 1 且 stdout 包含Client:字样,说明客户端已就绪而服务端未启动——这属于预期中的中间态,不应中止流程。这种粒度的错误处理,是 shell 脚本用|| echo "failed"根本无法实现的。

3. 核心细节解析与实操要点:从 playbook 结构到每个参数的深意

3.1 playbook 文件结构:为什么varshandlersroles不是摆设

一个健壮的docker-setup.yml不是线性脚本,而是分层架构:

--- - name: Install and configure Docker on Ubuntu 18.04 hosts: ubuntu1804_nodes become: true vars: docker_apt_repo: "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable" docker_gpg_key_url: "https://download.docker.com/linux/ubuntu/gpg" docker_users: - "ubuntu" - "deploy" pre_tasks: - name: Ensure required system packages are installed apt: name: "{{ item }}" state: present loop: - apt-transport-https - ca-certificates - curl - gnupg-agent - software-properties-common tasks: # ... 主安装任务 ... handlers: - name: Restart docker daemon service: name: docker state: restarted post_tasks: - name: Verify Docker installation command: docker version register: docker_version_result changed_when: false failed_when: "'Client:' not in docker_version_result.stdout or 'Server:' not in docker_version_result.stdout"

vars区域定义了所有可配置变量,这是复用性的基石。docker_apt_repo明确指向bionic(Ubuntu 18.04 代号),避免因lsb_release -sc命令在某些精简镜像中不可用而导致源地址错误。docker_users是一个列表,支持为多个用户批量授权,而非硬编码单个用户名。pre_tasks确保所有依赖包在主流程前就位,这是防止apt-key因缺少gnupg-agent而卡住的关键。handlers将服务重启解耦为事件驱动,只有当docker-ce包实际更新或配置文件变更时,才会触发Restart docker daemon,避免无谓的守护进程震荡。post_tasks中的docker version验证,用changed_when: false明确告知 Ansible 此任务永不标记为“已更改”,仅用于检查;failed_when则用字符串匹配精准捕获成功状态,比单纯依赖返回码更可靠。

3.2 GPG 密钥导入:为什么apt_key模块比curl | apt-key add安全十倍

过去常见的curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -存在两大硬伤:第一,apt-key add会将密钥无差别导入到/etc/apt/trusted.gpg,这是一个全局信任库,一旦该密钥未来被吊销,所有依赖它的源都会失效;第二,curl下载过程无校验,中间人攻击可替换密钥内容。Ansible 的apt_key模块彻底规避此风险:

- name: Add Docker's official GPG key apt_key: url: "{{ docker_gpg_key_url }}" state: present keyring: /usr/share/keyrings/docker-archive-keyring.gpg

关键在keyring参数。它指定密钥存入/usr/share/keyrings/docker-archive-keyring.gpg这个专用密钥环,随后在apt_repository模块中引用:

- name: Add Docker APT repository apt_repository: repo: "{{ docker_apt_repo }}" state: present filename: docker-ce-stable keyring: /usr/share/keyrings/docker-archive-keyring.gpg

这样,apt仅在解析docker-ce-stable.list源时,才加载该专用密钥环,实现密钥作用域最小化。这是 Debian/Ubuntu 官方推荐的安全实践,也是apt-key命令自 2021 年起被标记为 deprecated 的根本原因。

3.3 Docker Daemon 配置:daemon.json的黄金三参数与陷阱

/etc/docker/daemon.jsondockerd的心脏配置文件。新手常犯的错误是直接copy一个完整 JSON 文件,却忽略了 Ubuntu 18.04 的 systemd 限制。本方案采用lineinfile模块逐行注入,确保安全:

- name: Configure Docker daemon to use systemd as cgroup driver lineinfile: path: /etc/docker/daemon.json line: ' "exec-opts": ["native.cgroupdriver=systemd"],' create: yes backup: yes insertbefore: EOF - name: Set default logging driver to json-file lineinfile: path: /etc/docker/daemon.json line: ' "log-driver": "json-file",' create: yes backup: yes insertbefore: EOF - name: Configure default log options lineinfile: path: /etc/docker/daemon.json line: ' "log-opts": {"max-size": "10m", "max-file": "3"}' create: yes backup: yes insertbefore: EOF

为什么是这三个参数?native.cgroupdriver=systemd是 Ubuntu 18.04 的刚需。因为其内核和 systemd 版本较老,若dockerd使用默认的cgroupfs驱动,与systemd管理的 cgroup 层级冲突,会导致容器启动后立即退出,docker ps -a显示Exited (1)log-driverlog-opts则解决磁盘爆满问题:默认的journald驱动会将日志塞进systemd-journald,而journald在 Ubuntu 18.04 上默认不限制大小,一台持续构建的 CI 机器三天就能吃光 20GB 系统盘。json-file配合max-size/max-file实现日志轮转,这是生产环境的底线配置。

提示:lineinfilecreate: yes确保文件不存在时自动创建;backup: yes在每次修改前生成.bak备份,这是 Ansible 最朴实的容灾机制。

3.4 用户组授权:user模块的append: yes如何避免“组成员被清空”的灾难

usermod -aG docker ubuntu中的-a(append)至关重要。若省略-ausermod -G docker ubuntu会将用户ubuntu的附属组重置为仅docker,导致其丢失sudoadm等关键组权限,SSH 登录后连sudo ls都被拒绝。Ansible 的user模块默认行为就是append: no,即覆盖模式,这恰恰是危险的。因此,我们必须显式声明:

- name: Add users to docker group user: name: "{{ item }}" groups: docker append: yes loop: "{{ docker_users }}" when: item is defined

append: yes确保只向用户现有组列表中追加docker,绝不删除其他组。when: item is defined是防御性编程,防止docker_users列表中出现空值导致任务失败。这个细节,是无数次线上事故后总结出的血泪经验。

4. 实操过程与核心环节实现:从零开始搭建可复用的部署流水线

4.1 环境准备:三步建立最小可行 Ansible 控制节点

无需复杂环境,一台干净的 Ubuntu 18.04 或 macOS 即可作为控制节点。三步到位:

  1. 安装 Ansiblepip3 install ansible==2.9.27。选择 2.9.x 是关键——Ubuntu 18.04 的 Python 3.6.9 与 Ansible 2.10+ 的依赖存在兼容性问题,ansible 2.9.27是最后一个官方支持 Python 3.6 的稳定版,且对 Ubuntu 18.04 的apt模块适配最成熟。

  2. 配置 SSH 免密登录:在控制节点生成密钥ssh-keygen -t rsa -b 4096,将公钥id_rsa.pub复制到目标机ssh-copy-id -i ~/.ssh/id_rsa.pub ubuntu@target-ip。务必验证ssh ubuntu@target-ip能无密码登录,这是 Ansible 执行的基础。

  3. 创建最小 inventory:新建inventory.ini

    [ubuntu1804_nodes] web01 ansible_host=192.168.1.101 ansible_user=ubuntu db01 ansible_host=192.168.1.102 ansible_user=ubuntu

    此文件定义了目标主机列表、IP 地址和登录用户。ansible_hostansible_user是标准变量,Ansible 会自动识别。

注意:若目标机是 WSL2,其 IP 地址每次重启可能变化。此时应改用ansible_host=localhost并在ssh_config中配置Host localhost段,指定PortIdentityFile,确保连接稳定性。

4.2 编写并执行 playbook:逐行解析docker-setup.yml的实战意义

完整docker-setup.yml如下(已整合前述所有要点):

--- - name: Install and configure Docker on Ubuntu 18.04 hosts: ubuntu1804_nodes become: true vars: docker_apt_repo: "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable" docker_gpg_key_url: "https://download.docker.com/linux/ubuntu/gpg" docker_users: - "ubuntu" - "deploy" pre_tasks: - name: Ensure required system packages are installed apt: name: "{{ item }}" state: present loop: - apt-transport-https - ca-certificates - curl - gnupg-agent - software-properties-common tags: setup_deps tasks: - name: Add Docker's official GPG key apt_key: url: "{{ docker_gpg_key_url }}" state: present keyring: /usr/share/keyrings/docker-archive-keyring.gpg tags: gpg_key - name: Add Docker APT repository apt_repository: repo: "{{ docker_apt_repo }}" state: present filename: docker-ce-stable keyring: /usr/share/keyrings/docker-archive-keyring.gpg tags: apt_repo - name: Update apt cache after adding Docker repo apt: update_cache: yes tags: update_cache - name: Install Docker CE, CLI, and containerd apt: name: - docker-ce=5:20.10.21~3-0~ubuntu-bionic - docker-ce-cli=5:20.10.21~3-0~ubuntu-bionic - containerd.io=1.6.24-1 state: present allow_unauthenticated: no tags: install_docker - name: Configure Docker daemon to use systemd as cgroup driver lineinfile: path: /etc/docker/daemon.json line: ' "exec-opts": ["native.cgroupdriver=systemd"],' create: yes backup: yes insertbefore: EOF notify: Restart docker daemon tags: daemon_config - name: Set default logging driver to json-file lineinfile: path: /etc/docker/daemon.json line: ' "log-driver": "json-file",' create: yes backup: yes insertbefore: EOF notify: Restart docker daemon tags: daemon_config - name: Configure default log options lineinfile: path: /etc/docker/daemon.json line: ' "log-opts": {"max-size": "10m", "max-file": "3"}' create: yes backup: yes insertbefore: EOF notify: Restart docker daemon tags: daemon_config - name: Ensure docker group exists group: name: docker state: present tags: group_setup - name: Add users to docker group user: name: "{{ item }}" groups: docker append: yes loop: "{{ docker_users }}" when: item is defined tags: user_setup - name: Ensure docker service is enabled and started service: name: docker state: started enabled: yes tags: service_control handlers: - name: Restart docker daemon service: name: docker state: restarted post_tasks: - name: Verify Docker client and server versions command: docker version register: docker_version_result changed_when: false failed_when: "'Client:' not in docker_version_result.stdout or 'Server:' not in docker_version_result.stdout" tags: verify_install - name: Verify Docker can run a test container command: docker run --rm hello-world register: hello_world_result changed_when: false failed_when: "'Hello from Docker!' not in hello_world_result.stdout" tags: verify_runtime

执行命令:ansible-playbook -i inventory.ini docker-setup.yml --tags "setup_deps,gpg_key,apt_repo,install_docker,daemon_config,group_setup,user_setup,service_control,verify_install,verify_runtime"--tags参数允许你按需执行特定阶段,例如首次调试时,可先只跑--tags "setup_deps,gpg_key",确认基础依赖和密钥导入无误,再逐步放开后续标签,这是高效排障的核心技巧。

4.3 版本锁定与回滚:如何用apt模块精确控制 Docker 版本

Docker 官方源中,docker-ce包名格式为docker-ce=<epoch>:<upstream_version>~<debian_revision>。Ubuntu 18.04 的bionic仓库中,5:20.10.21~3-0~ubuntu-bionic是经过充分验证的稳定版本。apt模块通过name参数精确匹配此完整包名,确保安装的一定是该版本,而非apt install docker-ce可能拉取的最新不稳定版。若需回滚,只需修改name值为旧版本号(如5:20.10.16~3-0~ubuntu-bionic),再次运行 playbook,apt模块会自动执行降级操作。这种版本锁定能力,是pip install docker==5.0.0在 Python 生态中的对应物,是生产环境可追溯性的基石。

4.4 验证与日志:docker versiondocker run hello-world的深层含义

post_tasks中的两个验证任务,远不止“跑通就行”:

  • docker versionfailed_when检查Client:Server:字样,是因为docker version输出格式为:

    Client: Docker Engine - Community Version: 20.10.21 ... Server: Docker Engine - Community Engine: Version: 20.10.21

    Server:部分缺失,说明dockerd守护进程未启动或崩溃,Client工具再新也无用。

  • docker run --rm hello-worldfailed_when检查Hello from Docker!字样,是因为该镜像的入口点是一个 Shell 脚本,其标准输出严格固定为该字符串。若此处失败,常见原因有三:dockerd未监听 socket(netstat -ltnp | grep :2375)、/var/run/docker.sock权限不足(ls -l /var/run/docker.sock应显示srw-rw---- 1 root docker)、或 SELinux/AppArmor 限制(Ubuntu 18.04 默认禁用,可忽略)。这些信息,都直接体现在hello_world_resultstdoutstderr中,Ansible 会原样输出,为排障提供第一手证据。

5. 常见问题与排查技巧实录:那些 Ansible 报错背后的真实世界

5.1 “Failed to connect to the host via ssh”:SSH 连接失败的七种可能与速查表

现象可能原因排查命令解决方案
Permission denied (publickey)公钥未正确复制到目标机~/.ssh/authorized_keysssh -v ubuntu@target-ip查看详细认证过程重新执行ssh-copy-id,或手动将公钥内容追加到目标机~/.ssh/authorized_keys
Connection timed out目标机防火墙阻止 22 端口,或网络不通ping target-iptelnet target-ip 22在目标机执行sudo ufw allow OpenSSH,或检查网络路由
No route to host目标机未开机,或 IP 地址错误`arp -agrep target-ip`
Host key verification failed目标机重装系统后 SSH 主机密钥变更ssh-keygen -R target-ip清除本地known_hosts中旧记录
Could not resolve hostnameinventory 中ansible_host是域名但 DNS 解析失败nslookup target-hostname在 inventory 中直接使用 IP 地址,或配置本地/etc/hosts
Connection refused目标机 SSH 服务未运行ssh -o ConnectTimeout=5 ubuntu@target-ip在目标机执行sudo systemctl status ssh,若为inactivesudo systemctl start ssh
Authentication failed目标机用户密码已修改,但ssh-copy-id未更新ssh -o PubkeyAuthentication=no ubuntu@target-ip临时启用密码登录,重新执行ssh-copy-id

实操心得:永远先用ssh命令手动验证连接,再运行 Ansible。Ansible 的报错信息往往不如原生命令清晰。

5.2 “The task includes an option with an undefined variable”:变量未定义的根源与修复

此错误通常出现在docker_users变量为空或未定义时。例如,在inventory.ini中忘记定义docker_users变量,或在 playbook 中误写为docker_user(少了个s)。Ansible 的变量解析是动态的,{{ docker_users }}在渲染时若找不到该变量,就会抛出此异常。修复方法有二:一是在vars区域为docker_users设置默认值docker_users: ["ubuntu"];二是在inventory.ini中为特定主机组定义变量:

[ubuntu1804_nodes:vars] docker_users = ["ubuntu", "ci"]

这样,所有属于ubuntu1804_nodes组的主机,都会继承此变量。这是 Ansible 变量作用域(inventory > playbook > role)的典型应用。

5.3 “apt module is not found”:Ansible 2.9.x 下apt模块缺失的真相

在极简 Ubuntu 18.04 镜像(如ubuntu:18.04Docker 镜像)中,apt模块可能因缺少python3-apt包而无法加载。Ansible 报错module (apt) is missing。解决方案是,在pre_tasks中增加一个raw模块任务,绕过 Python 环境直接执行 shell 命令:

- name: Install python3-apt for apt module raw: apt-get update && apt-get install -y python3-apt args: executable: /bin/bash when: ansible_facts['distribution'] == 'Ubuntu' and ansible_facts['distribution_version'] == '18.04'

raw模块不依赖目标机的 Python 环境,直接调用/bin/bash,是解决此类“鸡生蛋”问题的终极手段。

5.4 “dockerd: error while loading shared libraries: libseccomp.so.2”:Ubuntu 18.04 的libseccomp兼容性陷阱

这是 Ubuntu 18.04 用户安装新版 Docker 时最经典的坑。Docker 20.10+ 依赖libseccomp2 >= 2.3.0,而 Ubuntu 18.04 官方源中libseccomp2版本仅为2.3.3-4ubuntu0.18.04.1,看似满足,实则因 ABI 兼容性问题导致dockerd启动失败。journalctl -u docker日志中会出现error while loading shared libraries: libseccomp.so.2。解决方案是手动升级libseccomp2

- name: Upgrade libseccomp2 to fix dockerd startup apt: name: libseccomp2 state: latest deb: https://archive.ubuntu.com/ubuntu/pool/main/libs/libseccomp/libseccomp2_2.5.4-1ubuntu1~18.04.1_amd64.deb when: ansible_facts['distribution'] == 'Ubuntu' and ansible_facts['distribution_version'] == '18.04'

此任务通过deb参数直接安装来自 Ubuntu 官方 archive 的更新版.deb包,绕过apt源同步延迟,一劳永逸解决此兼容性问题。这是针对 Ubuntu 18.04 的专属补丁,其他版本无需此步骤。

5.5 “Failed to set up non-admin sandbox” 类错误的澄清:这不是 Ansible 或 Docker 的问题

网络热词中频繁出现的could not set up non-admin sandboxcould not set up agent sandbox等错误,与本方案完全无关。这些错误源自 Windows 平台的特定软件(如某些浏览器沙箱、企业级安全代理、或旧版 Visual Studio 安装程序),它们试图在非管理员权限下创建隔离环境失败。Ubuntu 18.04 是 Linux 系统,没有 Windows 的 UAC(用户账户控制)和 sandbox 机制。若你在 Ubuntu 环境中看到类似报错,大概率是误将 Windows 错误日志粘贴到了 Linux 论坛,或是混淆了不同平台的术语。请专注排查dockerd日志(journalctl -u docker -n 50)和apt安装输出,这才是 Linux 世界的真相。

6. 进阶扩展与生产就绪:从单机部署到集群管理的平滑演进

6.1 从docker-cedocker-compose:一键补齐容器编排能力

Docker 安装完成后,docker-compose是下一个刚需。它不再需要pip install docker-compose(该方式在 Python 3.6 下易出错),而是直接下载官方二进制:

- name: Download and install docker-compose get_url: url: "https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-linux-x86_64" dest: /usr/local/bin/docker-compose mode: '0755' checksum: sha256:5a5e5a5e5a5e5a5e5a5e5a5e5a5e5a5e5a5e5a5e5a5e5a5e5a5e5a5e5a5e5a5e - name: Create docker-compose symlink file: src: /usr/local/bin/docker-compose dest: /usr/bin/docker-compose state: link

checksum参数是关键,它确保下载的二进制文件未被篡改。get_url模块会自动校验 SHA256 值,不匹配则任务失败,这是安全交付的最后防线。

6.2 镜像加速:为 Docker 配置国内镜像源,告别pull超时

国内用户常因docker pull缓慢而放弃。在daemon.json中添加registry-mirrors即可:

- name: Configure Docker registry mirrors lineinfile: path: /etc/docker/daemon.json line: ' "registry-mirrors": ["https://<your-mirror>.mirror.aliyuncs.com"],' create: yes backup: yes insertbefore: EOF notify: Restart docker daemon

<your-mirror>替换为阿里云、腾讯云或中科大的镜像地址(如https://mirrors.aliyun.com/docker-ce)。注意:registry-mirrors是数组,若需配置多个,需用blockinfile模块整体写入 JSON 数组,而非lineinfile逐行添加,否则 JSON 格式会损坏。

6.3 安全加固:禁用dockerd的 TCP Socket,只保留 Unix Socket

dockerd默认只监听 Unix Socket/var/run/docker.sock,这是安全的。但若有人误配置DOCKER_OPTS="-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock",就会暴露 TCP 端口,导致未授权访问。本方案在daemon.json不配置hosts字段,确保dockerd仅绑定 Unix Socket。若需远程管理,应使用 SSH 隧道:ssh -L 2375:/var/run/docker.sock user@host,这是零信任架构下的最佳实践。

6.4 持续集成:将 playbook 集成到 GitHub Actions,实现代码即部署

创建.github/workflows/docker-deploy.yml

name: Deploy Docker to Ubuntu 18.04 on: push: branches: [main] paths: [docker-setup.yml, inventory.ini] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.6' - name: Install Ansible run: pip install ansible==2.9.27 - name: Run Docker Setup Playbook run: ansible-playbook -i inventory.ini docker-setup.yml env: ANSIBLE_HOST_KEY_CHECKING
http://www.jsqmd.com/news/1110803/

相关文章:

  • Anthropic Claude‘归零层’技术解析:语义校验环的架构级移除
  • 最佳work模型sonnet5来了,直接就能用!
  • CentOS 6 上用 Ruby 1.8.7 编写 Nagios 插件实战指南
  • GPT-4的‘2%激活‘真相:MoE稀疏推理原理与工程实践
  • 定量粗Baum–Connes猜想在自由积群上的稳定性研究
  • 如何轻松解锁加密音乐文件:浏览器中的终极音乐格式转换工具
  • 4步搭建个人音乐API服务:网易云音乐接口的终极解决方案
  • Claude语义压缩层蒸发:从可控推理到结果验证的范式迁移
  • 如何在Mac上免费获得完美的桌面歌词体验?LyricsX 2.0深度解析
  • 用Leaflet自研一套地图系统
  • 深度解析ExifToolGUI:图像元数据编辑的终极可视化解决方案
  • 从理论到实践:openeuler/seccom-tee安全模型训练完整教程
  • 性价比之王:专业芯片编程烧录座深度优选
  • Destiny 2单人模式终极指南:彻底解决匹配屏蔽失效问题
  • Windows系统文件AuthFWGP.dll丢失找不到问题解决
  • 电商系统SQL注入防御实战:从参数化查询到纵深安全架构
  • Claude Code 引发 AI coding 变革:代码质量恶化,组织管理与职场生态面临重塑!
  • VS Code Git集成原理与工程实践指南
  • Git实战:多账户配置与高频命令
  • Docker+DDEV搭建Drupal 9本地开发环境实战指南
  • “肥料袋选盛军塑业?工业包装的这些门道你该知道“
  • 如何一键下载国家中小学智慧教育平台电子课本:tchMaterial-parser终极指南
  • Nginx server块与location匹配机制深度解析
  • 七月向阳,初心不忘|数图与您一同致敬那一百零五年的荣光
  • Node.js 自动重启工具 nodemon 原理与工程化实践
  • Ubuntu 20.04 MySQL生产级安装与配置实战指南
  • Ubuntu 18.04下Django+React客户管理系统实战部署
  • 校易淘实时私信聊天完整前后端代码实现
  • 携程业绩增速放缓、监管调查叠加AI威胁,梁建章如何带领穿越周期?
  • 2003-2024年地级市互联网综合发展指数+stata代码