从 Ansible 游戏管理 Docker 容器 [英] Managing Docker containers from Ansible plays
问题描述
我正在编写我的第一本 Ansible 剧本,需要一些指导.我有一个由 3 个虚拟机组成的简单网络:
I am in the process of writing my first ever Ansible playbook and am in need of a bit of steering. I have a simple network that consists of 3 VMs:
ansible01
- 我的 Ansible 服务器 (Ubuntu)db01
- 一个数据库(同样是 Ubuntu)myapp01
- 一个托管 Java 应用程序的 Ubuntu VM
ansible01
- my Ansible server (Ubuntu)db01
- a DB (again, Ubuntu)myapp01
- an Ubuntu VM hosting a Java app
我已经像这样配置了我的 /etc/ansible/hosts
文件:
I have configured my /etc/ansible/hosts
file like so:
[databases]
db01.example.com
[app_servers]
myapp01.example.com
myapp02.example.com
我已经正确配置了 SSH,我可以运行 ansible all ping -m
并且 Ansible 能够 ping 数据库和应用服务器节点.到目前为止一切顺利.
I have configured SSH correctly, and I can run ansible all ping -m
and Ansible is able to ping the DB and app server nodes. So far so good.
我正在尝试编写三 (3) 本与 Docker 相关的剧本,以实现以下目标:
I’m trying to write three (3) Docker-related playbooks that will accomplish the following:
- 确保 Docker 在所有
[databases]
节点以及所有 [app_servers]
节点上运行;如果未安装并运行,则安装 Docker 引擎并开始运行它.如果已安装但未运行,请重新启动它. - 停止/启动/重启为特定类型节点(角色"?!?)运行的所有容器.例如,我想告诉 Ansible 我想重启所有容器在所有
[app_servers]
节点上运行. - 停止/启动/重启在任意节点上运行的任意容器.例如,也许
myapp01
上运行了 2 个容器,fizz
和buzz
.我希望能够告诉 Ansible(特别是)myapp01
的fizz
容器,但不是它的buzz
容器,也不是任何myapp02
容器.
- Ensure that Docker is running on all
[databases]
nodes as well as all [app_servers]
nodes; if it is not installed and running, then install Docker engine and start running it. If it is installed but not running, restart it. - Stop/start/restart all containers running for a specific type of node ("role"?!?). For instance, I’d like to tell Ansible that I want to restart all containers running on all
[app_servers]
nodes. - Stop/start/restart an arbitrary container running on an arbitrary node. For instance, perhaps
myapp01
has 2 containers running on it,fizz
andbuzz
. I’d like to be able to tell Ansible to restart (specifically)myapp01
’sfizz
container, but not itsbuzz
container, nor anymyapp02
containers.
我相信这些属于三个独立的剧本(如果我错了或者有更好的方法,请纠正我).我刺伤了他们.第一个是setup_docker.yml
:
I believe these belong in three separate playbooks (correct me if I’m wrong or if there’s a better way). I took a stab at them. The first is setup_docker.yml
:
- name: ensure docker engine is installed and running
docker:
name: *
state: started
然后重新启动所有[databases]
,在restart_app_servers.yml
:
Then for restarting all [databases]
, in restart_app_servers.yml
:
- name: restart app servers
docker:
name: app_servers
state: restarted
以及在单个节点上重启任意容器(restart_container.yml
):
And for restarting an arbitrary container on a single node (restart_container.yml
):
- name: restart a specific container
docker:
name: %name_of_container_and node%
state: restarted
但是这里有几个问题:
- 在
setup_docker.yml
中,如何指定所有节点类型([databases]
和[app_servers]
)都应该受到影响?我知道星号(*")不正确. - 在
restart_app_servers.yml
中,name
字段的正确值是多少?我如何实际告诉 Ansible 重新启动所有app_server
节点? - 在
restart_container.yml
中,我如何注入"(作为参数/变量传入)节点和容器的名称?理想情况下,我希望针对任何节点和任何容器运行此剧本. - 还有什么让你觉得不对劲的吗?
- In
setup_docker.yml
, how do I specify that all node types ([databases]
and[app_servers]
) should be affected? I know that asterisk ("*") isn’t correct. - In
restart_app_servers.yml
, what is the proper value for thename
field? How do I actually tell Ansible to restart allapp_server
nodes? - In
restart_container.yml
, how do I "inject" (pass in as arguments/variables) the node's and container’s names? Ideally I’d like to run this playbook against any node and any container. - Anything else jumping out at you as wrong?
提前致谢!
推荐答案
我认为您在这里将 Plays 和 Playbooks 的含义混淆了.您在上面指定的三件事 setup_docker.yml、restart_app_servers.yml 和 restart_container.yml 似乎是 Plays.我建议创建一个 Docker 角色,其中包含您在此处详述的任务.
I think you have Plays and Playbooks mixed up in meaning here. The three things you have specified above, setup_docker.yml, restart_app_servers.yml, and restart_container.yml appear to be Plays. I recommend creating a Docker role which contains the tasks you have detailed here.
解决您的问题:
- 在 setup_docker.yml 中,如何指定所有节点类型([databases] 和 [app_servers])都应该受到影响?我知道星号(*")不正确.
这是在 Playbook 级别完成的.您可以指定要受哪些任务影响的主机,例如:
This is done at the Playbook level. You can specify which hosts you want to be effected by which tasks, e.g:
#docker.yml
- hosts: all
user: {{ privileged_user }}
gather_facts: false
roles:
- install_docker
然后在您的 install_docker 角色中,您将拥有以下内容:
Then in your install_docker role, you would have something along the lines of:
- name: Add docker apt keys
apt_key: keyserver=keyserver.ubuntu.com id=36A1D7869245C8950F966E92D8576A8BA88D21E9
- name: update apt
apt_repository: repo='deb https://get.docker.com/ubuntu docker main' state=present
- name: Install docker
apt: pkg=lxc-docker update_cache=yes
- 在 restart_app_servers.yml 中,名称字段的正确值是多少?我如何实际告诉 Ansible 重新启动所有 app_server 节点?
我假设您的意思是您希望重新启动属于 app-server 组的每个节点上的所有 Docker 容器?我会为每个组保留所有容器名称的清单(因为这个例子相对简单).例如:
I'm assuming you mean you wish to restart all Docker containers on each of the nodes which belong to the app-server group? I would keep an inventory of all of the container names for each group (since this example is relatively simple). e.g:
#group_vars/app-server
all_containers: [ 'container1', 'container2', 'container3',.. 'containern' ]
从这里您可以在 Play 中使用此库存来重新启动每个容器.在您的剧本中:
From here you can use this inventory in your Play to restart each container. In your Playbook:
#restart_app_containers.yml
- hosts: app_server
user: {{ privileged_user }}
gather_facts: false
roles:
- restart_app_servers
然后在 Play 本身:
Then in the Play itself:
#restart_app_servers.yml
- name: restart app servers
docker:
name: {{ item }}
state: restarted
with_items: all_containers
- 在 restart_container.yml 中,我如何注入"(作为参数/变量传入)节点和容器的名称?理想情况下,我希望针对任何节点和任何容器运行此剧本.
对于这部分,您需要直接引用您需要对其采取行动的容器.这可以通过动态库存来完成,例如
For this portion you would need to reference your container directly which you need to act against. This can be done with Dynamic Inventory, e.g
#sample.yml
- hosts: Tag_name_{{ public_name }}
user: {{ privileged_user }}
gather_facts: false
roles:
- example
如果您在 AWS 上.主机字典因基础设施而异.然后在你列出的实际游戏中,你可以传入特定的变量.由于它是单个主机上的单个容器,因此您可以通过命令行执行此操作:
In the event you are on AWS. The hosts dictionary would vary by infrastructure. Then in your actual play you listed, you can pass in the specific variable. Since it's a single container on a single host, you could do this via the command line:
ansible-playbook -i $INVENTORY_FILE -e container_name=$CONTAINER_NAME restart_single_container_on_single_host.yml
您的 Play 看起来像这样:
Where your Play would look something like:
- name: restart a specific container
docker:
name: {{ container_name }}
state: restarted
这篇关于从 Ansible 游戏管理 Docker 容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!