王者荣耀 6无双4祸源无双和祸源哪个比较好 王者荣耀 6无双4祸源无双和祸源

使用 Ansible 高效交付 Docker 容器_服务器应用_Linux公社-Linux系统门户网站
你好,游客
使用 Ansible 高效交付 Docker 容器
来源:IBM&
作者:Xavier Bruhiere
使用 playbook、插件和 Docker 模块设置和扩展 Ansible 环境
Docker 和它的容器工作流可封装、共享和部署您的应用程序环境。Ansible 是一个与 Docker 高度兼容的自动化工具,它使用一个强大的接口来管理远程服务器上的容器。在本文中,我将探索为何和如何使用 Ansible 的可扩展设计来将 Docker 和 Ansible 的最佳功能合并在一起。
Docker 之所以如此流行,是因为它创造了一种采用方便的命令行接口 (CLI) 和 HTTP API 工具来封装、运行和维护容器的独特方式。这种简化降低了此技术的入门门槛,使得将应用程序及其运行时环境封装到一个简单 Dockerfile 中的独立镜像中变得可行。Docker 使您能够开发更复杂的项目,但您仍需要配置这些容器。在本文中,我将展示 Ansible 如何通过更清晰的语法带来配置管理器的特性。您将学习如何仅使用已安装的 Python 和 Docker 构建任何堆栈。
在介绍 Ansible 的细节之前,我首先将介绍 Ansible 的&&中提到的一些要点:
尽管容器导致一些新工作流出现,但编排和配置工具仍然非常活跃。
Ansible 和 Salt 等新参与者正在挑战现有的工具,比如 Chef 和 Puppet。
许多与 Docker 有关联的开发人员也很关心这些工具。
更确切地讲,借助 Docker,您可以在几秒内实现完全隔离的堆栈环境,或者在服务器之间复制准确的设置。但是,Docker 不包含提供端到端体验的可靠工具,无论是针对开发还是生产。Docker 团队通过新的集群工具解决了这些不断演变的挑战,尝试将 Docker 转变为一个大规模运行容器的可靠解决方案。然而,Docker 仍然需要您手动硬编码任务和重复常见的设置。所以,针对容器的编排和配置管理的关键 Docker 流程仍有待解决。在本文中,您将学习如何结合使用 Ansible 和 Docker 来帮助解决这些问题。
DevOps 的兴起
在部署到生产中之前,现代应用程序通常涉及到一个复杂的部署管道。最佳实践建议在每次小型迭代后尽早地、频繁地发布代码。任务的手动执行无法扩展,组织已开始完善介于开发人员与系统管理员之间的流程,所以 DevOps 就诞生了。从那时起,敏捷团队就开始尝试强化和自动化测试代码,以及将其交付给用户的方式。
通过实现最新的技术和方法,公司对其服务器上的代码建立了信心。然而,随着应用程序在规模和复杂性上不断增长,开发人员和系统管理员继续面临着无数挑战。现在比以往更需要为产品提供受支持的社区驱动工具。
Ansible 的可扩展设计
在此环境中,Ansible 提供了一个有趣的框架来管理基础架构。您可以获得服务器定义的控制权,比如要安装的包或要复制的文件,并将该配置扩展到数千个服务器。Ansible playbook 构成了集群的目标状态的一种安全表示。它的 YAML 语法和庞大的模块列表生成了任何开发人员都能快速理解的易读性配置文件。不同于 Chef 或 Puppet,Ansible 是无代理的,这意味着您要在远程主机上运行命令,只需一个 SSH 连接即可。可以看到,Ansible 可轻松地处理 DevOps 复杂性。
但是,Ansible 是在容器快速兴起和它们在云开发环境中带来革命之前设计的。那么 Ansible 是否仍然有用?微型服务的范式和复杂开发环境引入了新的需求:
轻量型镜像。为了容易传输或节省成本,镜像被剥离到仅剩下最低限度的依赖项。
单一用途,单一流程。如果应用程序不是非常需要 SSH 守护进程,则无需运行它。
短暂性。容器随时可能死亡、转移和复活。
在此上下文中,Ansible 的可扩展架构解决了这些问题。一个 Docker 模块在较高层面上管理主机和容器。尽管您可能会争论哪个编排工具(来自 Google 的 Kubernetes,还是来自 New Relic 的 Centurion)最适合此环境,但 Docker 模块执行效率很高,这正是我在本文中使用它的原因。但是,您还可以构建从其官方 Ansible 镜像启动的容器,然后在本地模式下从内部运行 playbook。尽管此方法非常适合 Packer,而且肯定也适合许多使用情况,但它的缺点通常极为关键。
您被锁定在一个基础镜像中,无法再利用特殊的秘诀或其他堆栈。
最终的工件已安装 Ansible 和它的依赖项,它们与实际应用程序毫无关系,这让工件变得更笨重。
尽管 Ansible 可管理数千个服务器,但它只配备(Provision)了一个容器。
此方法将容器视为小型 VM,您可以在其中使用一个特定的解决方案。幸运的是,Ansible 拥有模块化设计。模块分散在不同的存储库中,而且 Ansible 的大部分功能都可以通过插件进行扩展。
在下一节中,您将设置一个有效的环境,针对您的需求来调整 Ansible。
设置一个 Ansible 环境
假设您想要一个很容易部署的工具,它在轻量型容器中配置应用程序环境。由于与这些容器分离,您需要一个安装了 Ansible 的客户端,您将使用它来向 Docker 守护进程发送命令。此设置如 图 1 中所示。
图 1. 使用 Ansible 配备容器所需的组件
您在此配置中必须管理的依赖项,已通过从容器中运行 Ansible 来最小化。此架构将主机限制为容器与命令之间的一个通信桥梁。
可通过许多选项在您服务器上安装 Docker:
使用&&将它安装在远程主机上。
安装在本地。顺便说一下,您可能不想亲自管理一个严格基于容器的基础架构;在这种情况下,可以考虑采用外部提供程序。
依赖于外部提供程序。
使用&,这是一个在 Windows 和 Mac 上运行 Docker 容器的轻量型 Linux 发行版。
无论选择何种解决方案,请确保部署了 Docker 1.3 版或更高版本(1.3 版引入了进程注入)。您还需要运行一个 SSH 服务器来安全地处理 Ansible 命令。
以下的命令使用公钥设置了一种方便可靠的身份验证方法。
# install dependencies
sudoapt-get install -y openssh-server libssl-dev
# generate privateandpublic keys
ssh-keygen -t rsa -f ansible_id_rsa
# allow future client withthispublic key to connect to this server
cat ansible_id_rsa.pub &&~/.ssh/authorized_keys
# setup proper permissions
chmod0700~/.ssh/
chmod0600~/.ssh/authorized_keys
#make sure the daemon is running
sudo service ssh restart
配置 SSH 和安全性问题不属于本文的讨论范围。细心的读者可查阅&/etc/ssh/sshd_config&文件,进一步了解配置 SSH 的可用选项。
下一步是将公钥加载到运行 Ansible 的客户端容器上并配备构建器容器。使用一个 Dockerfile 来配备构建器。参见以下代码。
配备构建器的 Dockerfile:
FROM python:2.7
#InstallAnsiblefrom source (master)
RUN apt-get-y update && \
apt-get install -y python-httplib2 python-keyczar python-setuptools python-pkg-resources
git python-pip && \
apt-get clean &&rm-rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN pip install paramiko jinja2 PyYAML setuptools pycrypto&=2.6 six \
requests docker-py # docker inventory plugin
RUN git clone /ansible/ansible.git /opt/ansible && \
cd /opt/ansible && \
git reset --hard fbec8bfb90df1d2e8a0a4df7ac1ddde && \
git submodule update --init
ENV PATH /opt/ansible/bin:$PATH
ENV PYTHONPATH $PYTHONPATH:/opt/ansible/lib
ENV ANSIBLE_LIBRARY /opt/ansible/library
# setup ssh
RUN mkdir /root/.ssh
ADD ansible_id_rsa /root/.ssh/id_rsa
ADD ansible_id_rsa.pub /root/.ssh/id_rsa.pub
# extend Ansible
# use an inventory directory for multiple inventories support
RUN mkdir -p /etc/ansible/inventory && \
cp /opt/ansible/plugins/inventory/docker.py /etc/ansible/inventory/
ADD ansible.cfg /etc/ansible/ansible.cfg
ADD hosts /etc/ansible/inventory/hosts
这些指令改编自官方构建版本,自动化了一次来自 Ansible 主分支上的提交 fbec8bfb90df1d2e8a0a4df7ac1ddde 有效安装。
主机和 ansible.cfg 配置文件已封装。通过使用容器,可以确保您将共享同一个环境。在本示例中,Dockerfile 安装了 Python 2.7.10 版和 Ansible 2.0.0。
主机配置文件:
#thisfileis an inventory that Ansibleisusing to address remote servers.
Make sure to replace the information with your specific setup and variables
that you don't want to provide for every command.
# host properties where docker daemon is running
192.168.0.12 ansible_ssh_user=xavier
Ansible 配置文件:
# ansible.cfg
[defaults]
#use the path created from the Dockerfile
inventory =/etc/ansible/inventory
#not really secure but convenient in non-interactive environment
host_key_checking =False
# free you from typing `--private-key` parameter
priva_key_file =~/.sh/id_rsa
# tell Ansiblewhere are the plugins to load
callback_plugins =/opt/ansible-plugins/callbacks
connection_plugins =/opt/ansible-plugins/connections
在构建 Ansible 容器之前,您必须导出 DOCKER_HOST 环境变量,因为 Ansible 将使用它连接到远程 Docker 守护进程。在使用 HTTP 端点时,需要修改&/etc/default/docker:
#make docker to listen on HTTP anddefault socket
DOCKER_OPTS="-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock"
输入命令&sudo service docker restart&来重新启动 Docker 守护进程,以便让对它的配置文件的更改生效。
以下命令将会构建并验证您用来输入命令的 Ansible 容器:
# you need DOCKER_HOST variable to point to a reachable docker daemon
# pick the method that suits your installation
#for boot2docker users
eval"$(boot2docker shellinit)"
#for docker-machine users, provisioning the running VM was named "dev"
eval"$(docker-machine env dev)"
#forusers running daemon locally
export DOCKER_HOST=tcp://$(hostname -I | cut -d" " -f1):2375
#finallyusers relying on a remote daemon should provide the server's public ip
export DOCKER_HOST=tcp://1.2.3.4:2375
# build the container from Dockerfile
docker build -t article/ansible .
# provide server API version, as returned by `docker version | grep -i "server api"`
# it should be at least greater or equal than 1.8
export DOCKER_API_VERSION=1.19
# create and enter the workspace
docker run -it --name builder \
# make docker client available inside
-v /usr/bin/docker:/usr/bin/docker \
-v /var/run/docker.sock:/var/run/docker.sock \
# detect local ip
-e DOCKER_HOST=$DOCKER_HOST \
-e DEFAULT_DOCKER_API_VERSION=DOCKER_API_VERSION \
-v $PWD:/app -w /app \ # mount the working space
article/ansible bash
# challenge the setup
$ container & ansible docker -m ping
192.168.0.12 | SUCCESS =& {
"invocation": {
"module_name": "ping",
"module_args": {}
"changed": false,
"ping": "pong"
目前为止,一切顺利。您能够从容器输入命令。在下一节中,将对 Ansible 使用特定于 Docker 的扩展。
使用 playbook 和插件扩展 Ansible 环境
实质上,Ansible 通过 playbook 自动化了它的执行,这些 playbook 是指定要执行的每个任务和它们的属性的 YAML 文件。
Ansible 还使用了清单 (inventory)&来将用户提供的主机映射到基础架构中的具体端点。不同于上一节中使用的静态&hosts&文件,Ansible 也支持动态内容。内置的列表包含一个 Docker 插件,该插件可查询 Docker 守护进程并向 Ansible playbook 共享大量信息。
# provision.yml
- name: debug docker host
hosts: docker
- name: debug infrastructure
# access container data :print the state
debug:var=hostvars["builder"]["docker_state"]
# you can target individual containers by name
- name: configure the container
hosts: builder
- name: run dummy command
command:/bin/echo hello world
下面的命令查询 Docker 主机,导入事实,打印一些事实,并使用它们对构建器容器执行第二个任务(如上述所示)。
ansible-playbook provision.yml -i /etc/ansible/inventory
TASK [setup]********************************************************************
fatal:[builder]: FAILED!=&{"msg":"ERROR! SSH encountered an unknown error during the
connection. Re-run the command using -vvvv, which enables SSH debugging
output to help diagnose the issue","failed":true}
Ansible 不能连接容器,因为它没有运行 SSH 服务器。SSH 服务器是一个要管理的额外进程,它与实际应用程序完全无关。在下一节中,我们将使用一个连接插件来排除此困难。
连接插件是实现传输命令(比如 SSH 或本地执行)的类。Docker 1.3 随带了&docker exec,并能够在容器命名空间内运行任务。此外,因为您???前已学习如何连接特定的目标容器,所以您可以使用此功能来处理 playbook。
像其他插件类型一样,连接挂钩继承一个抽象类,会在您将其放到预期的目录(您在配置文件&ansible.cfg&中定义的是/opt/ansible-plugins/connections)时自动可用。
# saved as./connection_plugins/docker.py
import subprocess
from ansible.plugins.connections importConnectionBase
classConnection(ConnectionBase):
def transport(self):
""" Distinguish connection plugin. """
return'docker'
def _connect(self):
""" Connect to the container. Nothing to do """
returnself
def exec_command(self, cmd, tmp_path, sudo_user=None, sudoable=False,
executable='/bin/sh', in_data=None,su=None,
su_user=None):
""" Run a command within container namespace. """
if executable:
local_cmd =["docker","exec",self._connection_info.remote_addr, executable,'-c', cmd]
local_cmd ='%s exec "%s" %s'%("docker",self._connection_info.remote_addr, cmd)
self._display.vvv("EXEC %s"%(local_cmd), host=self._connection_info.remote_addr)
p = subprocess.Popen(local_cmd,
shell=isinstance(local_cmd, basestring),
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
return(p.returncode,'', stdout, stderr)
def put_file(self, in_path, out_path):
""" Transfer a file from local to container """
def fetch_file(self, in_path, out_path):
""" Fetch a file from container to local. """
def close(self):
""" Terminate the connection. Nothing to do for Docker"""
此代码挂钩到 Ansible 模块中,以便通过一个本地&docker exec&而不是默认的&ssh&来运行命令。您需要重新排列一些设置步骤来告诉 Ansible 使用此插件。
# modify the builder Dockerfile to upload the plugin code
whereAnsibleis expecting connection plugins
echo"ADD connection_plugins/docker.py /opt/ansible-plugins/connections/docker.py"&&Dockerfile
#then, you need to explicitly tell which connection hook to use
when executing playbooks.
# you can achieve this by inserting the 'connection'property at the top
of provision tasks in provision.yml
- name: configure the container
connection: docker
hosts: builder
# you are ready to redeploy the builder container
#(providing DOCKER_HOST and DOCKER_API_VERSION are still set like before)
# rebuild the image
docker build -t article/ansible .
# restart the builder environment
docker run -it --name builder \
#make docker client available inside
-v /usr/bin/docker:/usr/bin/docker \
-v /var/run/docker.sock:/var/run/docker.sock \
# detect localip
-e DOCKER_HOST=$DOCKER_HOST \
-e DEFAULT_DOCKER_API_VERSION=DOCKER_API_VERSION \
-v $PWD:/app -w /app \ #mount the working space
article/ansible bash
# rerun provisioning from inside
ansible-playbook -i /etc/ansible/inventory provision.yml
#...Hurrah, full green output ...
目前为止,您在容器中运行 Ansible 任务,对容器或主机没有太多需求。尽管此实现满足了初始需求,但仍有一些不严密的地方需要解决。
前面的代码在同一个节点上运行任务。一种更逼真的工作流会启动一个新基础镜像,配置它,最终提交、推送和关闭得到的工件。得益于 Ansible 中内置的 Docker 模块,这些步骤无需额外的代码即可实现。
- name: initialize provisioning
hosts: docker
- name: start up target container
image: python:2.7
pull: missing
detach:yes
command:sleep infinity
state: started
# dynamically update inventory to make it available down the playbook
- name:registernew container hostname
add_host: name=lab
- name: provision container
connection: docker
hosts: lab
- name: finalize build
hosts: docker
- name: stop container
image: python:2.7
state: stopped
前面已经提到过,自动命名和存储在成功配备后构建的镜像会很方便。不幸的是,Ansible 中的 Docker 模块没有实现方法来标记和推送镜像。您可以使用简单的 shell 命令来克服此限制。
# name the resulting artifact under a human readable image tag
docker tag lab article/lab:experimental
# push this image to the official docker hub
#make sure to replace 'article' by your own DockerHublogin(https://)
#(this step is optional and will only make the image available from any docker host.
You can skip it or even use your own registry)
docker push article/lab:experimental
我们的工具正在成形,但它仍缺少一个必要特性:层缓存。
在使用 Dockerfile 构建容器时,通常需要迭代许多次才能完成。为了显著加快该过程,成功的步骤会被缓存并在后续运行中重用。
要复制此行为,我们的工具在每次成功完成任务后提交了容器状态。如果发生构建错误,该工具会从上次的快照位置重新启动配备过程。Ansible 承诺实现幂等的任务,所以以前成功的任务不会处理两次。
借助 Ansible,您可以使用回调插件来挂住任务事件。这些类应实现了特定的回调,这些回调在 playbook 生命周期的各个步骤上触发。
# save as callback_plugins/docker-cache.py
import hashlib
import socket
#HackyFix`ImportError: cannot import name display`
# pylint: disable=unused-import
import ansible.utils
import requests
import docker
classDockerDriver(object):
""" Provide snapshot feature through 'docker commit'. """
def __init__(self, author='ansible'):
self._author = author
self._hostname = socket.gethostname()
err =self._connect()
except(requests.exceptions.ConnectionError, docker.errors.APIError), error:
ansible.utils.warning('Failed to contact docker daemon: {}'.format(error))
# deactivate the plugin on error
self.disabled =True
self._container =self.target_container()
self.disabled =Trueifself._container isNoneelseFalse
def _connect(self):
#use the same environment variable as other docker plugins
docker_host = os.getenv('DOCKER_HOST','unix:///var/run/docker.sock')
#default version is current stable docker release (10/07/2015)
#if provided, DOCKER_VERSION should match docker server api version
docker_server_version = os.getenv('DOCKER_VERSION','1.19')
self._client = docker.Client(base_url=docker_host,
version=docker_server_version)
returnself._client.ping()
def target_container(self):
""" Retrieve data on the container you want to provision. """
def _match_container(metadatas):
return metadatas['Id'][:len(self._hostname)]==self._hostname
matchs = filter(_match_container,self._client.containers())
return matchs[0]if len(matchs)==1elseNone
def snapshot(self, host, task):
tag = hashlib.md5(repr(task)).hexdigest()
feedback =self._client.commit(container=self._container['Id'],
repository='factory',
author=self._author)
except docker.errors.APIError, error:
ansible.utils.warning('Failed to commit container: {}'.format(error))
self.disabled =True
# pylint: disable=E1101
classCallbackModule(object):
"""Emulate docker cache.
Commit the current container for each task.
This plugin makes use of the following environment variables:
- DOCKER_HOST (optional): How to reach docker daemon.
Default: unix://var/run/docker.sock
- DOCKER_VERSION (optional): Docker daemon version.
Default: 1.19
- DOCKER_AUTHOR (optional): Used when committing image. Default: Ansible
- docker-py &= v0.5.3
Resources:
- http://docker-py.readthedocs.org/en/latest/api/
_current_task =None
def playbook_on_setup(self):
""" initialize client. """
self.controller =DockerDriver(self.conf.get('author','ansible'))
def playbook_on_task_start(self, name, is_conditional):
self._current_task = name
def runner_on_ok(self, host, res):
ifself._current_task isNone:
#No task performed yet, don't commit
self.controller.snapshot(host, self._current_task)
因为您已将代码上传到期望的位置,并重新构建了构建器容器,所以您可以像&docker exec&连接插件一样注册此插件。
# modify the builder Dockerfile to upload the code whereAnsibleis expecting callback plugins
echo"ADD callback_plugins/docker-cache.py /opt/ansible-plugins/callbacks/docker-cache.py"&&Dockerfile
重新构建构建器容器并重新运行 Ansible playbook 后,该模块会自动加载,您可以查看中间容器是如何创建的。
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
factory bc0fbc bbdfab2bd904 32 seconds ago 829.8 MB
factory d19d39e0f0e5c133 ec 55 seconds ago 785.2 MB
配备是一个复杂流程,您在本教程中执行的实现为未来的开发奠定了基础。代码本身已经过简化,而且一些步骤仍需人类干预。缓存实现肯定值得更多关注,例如更具体的提交命名或清理技能。
尽管如此,您创建了一个可运行 Ansible playbook 来管理容器配置的工具。借助此实现,您可以通过为基础架构的微型服务来组合、重用和设置陈述性的构建文件,充分利用 Ansible 的全部威力。此解决方案可帮助避免锁定问题。您开发的插件包装了 playbook,您可对不同的目标重用这些 playbook,而且极低的需求使得该项目能兼容大部分提供程序。
使用Ansible批量管理远程服务器&
Ansible安装配置与简单使用&
7 中安装并使用自动化工具 Ansible&
Ansible和Docker的作用和用法&
Ansible批量搭建LAMP环境
Ansible :一个配置管理和IT自动化工具&
Ansible 的详细介绍:Ansible 的下载地址:
本文永久更新链接地址:
相关资讯 & & &
& (03月26日)
& (03月24日)
& (04月20日)
& (03月26日)
& (03月06日)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款使用ansible批量管理远程服务器 - 文章 - 伯乐在线
& 使用ansible批量管理远程服务器
使用ansible批量管理远程服务器
本地需要管理远程的一批服务器,主要执行以下任务:
1) 将本地的文件复制到远端所有服务器;
2) 需要在远程服务器中执行一个个命令;
远端服务器路径并非完全一致,一般访问通过环境变量中定义的变量路径访问;
比如在.bashrc中定义$app_path=/opt/app/bin
最终选择ansible,使用这个自动化运维工具可以满足我的需求;
下面介绍下对于我这种场景需要使用的ansible的主要模块;
关于ansible是什么以及安装配置请自行百度;
使用copy模块,可以将本地文件一键复制到远程服务器;
-a后跟上参数,参数中指定本地文件和远端路径;
ansible myservers -m copy -a "src=/opt/app/bin/transfer.tar dest=~/"
ansible myservers -m copy -a "src=/opt/app/bin/transfer.tar dest=~/"
ansible通过ssh登录到远程服务器后,并不执行.bash_profile来设置用户自定义的环境变量;如果我们需要管理的目标服务器的路径不同,就不能直接写绝对路径,也不能写变量替换的路径;
比如:针对服务器A的目标复制路径为 /opt/app/user1/bin ,服务器B的目标复制路径为/opt/app/user2/ 这两个路径在各自的服务器中的路径变量都设置为$ 但在copy模块中,我们不能直接使用dest = $bin/;
路径设置一般放在.bashrc /.bash_profile文件,但ansible模块登录后并不加载这两个文件;
解决方法:
针对这种情况,可以将dest路径设置为~/,都复制到用户目录,后续再通过远程脚本处理;
远程批量命令
需要在远程执行一个个命令来管理远程服务器;
远程执行命令的模块有command、shell、scripts、以及raw模块;
command模块
command模块为ansible默认模块,不指定-m参数时,使用的就是command模块;
comand模块比较简单,常见的命令都可以使用,但其命令的执行不是通过shell执行的,所以,像这些 “”, “|”, and “&”操作都不可以,当然,也就不支持管道;
示例:显示远程路径:
ansible myservers
10.6.143.38 | success | rc=0 &&
/home/rduser
10.6.143.53 | success | rc=0 &&
/home/rduser
10.6.143.37 | success | rc=0 &&
/home/rduser
ansible myservers&&-a 'pwd'10.6.143.38 | success | rc=0 &&/home/rduser10.6.143.53 | success | rc=0 &&/home/rduser10.6.143.37 | success | rc=0 &&/home/rduser
缺点:不支持管道,就没法批量执行命令;
使用shell模块,在远程命令通过/bin/sh来执行;所以,我们在终端输入的各种命令方式,都可以使用;
但是我们自己定义在.bashrc/.bash_profile中的环境变量shell模块由于没有加载,所以无法识别;如果需要使用自定义的环境变量,就需要在最开始,执行加载自定义脚本的语句;
对shell模块的使用可以分成两块:
1) 如果待执行的语句少,可以直接写在一句话中:
ansible myservers
-a ". .bash_ps -fe |grep sa_q" -m shell
ansible myservers&&-a ". .bash_ps -fe |grep sa_q" -m shell
2) 如果在远程待执行的语句比较多,可写成一个脚本,通过copy模块传到远端,然后再执行;但这样就又涉及到两次ansible调用;对于这种需求,ansible已经为我们考虑到了,script模块就是干这事的;
scripts模块
使用scripts模块可以在本地写一个脚本,在远程服务器上执行:
ansible myservers
-m script -a "/opt/app/target.sh"
ansible myservers&&-m script -a "/opt/app/target.sh"
这里是命令模块的官方文档:
批量执行playbooks
远程批量命令执行的另外一种方式是用playbooks;
这里是playbooks的官方文档:
这里有ansible的playbooks示例:
在python中使用ansbile API
以上执行ansible模块的方式都是在命令行中直接调用,如果对返回结果需要进一步处理,可以在程序中通过API调用的方式来使用ansible模块:
比如,以上在命令行中调用scripts的模块的方式在API中调用:
import ansible.runner
results = ansible.runner.Runner(
pattern='myservers', forks=5,
module_name='script', module_args='/opt/app/target.sh',
import ansible.runnerresults = ansible.runner.Runner(pattern='myservers', forks=5,module_name='script', module_args='/opt/app/target.sh',).run()
这里是官方给出的一个详细示例,直接运行一次,将result全部打印出来,会有直观的了解:
#!/usr/bin/python
import ansible.runner
import sys
# construct the ansible runner and execute on all hosts
results = ansible.runner.Runner(
pattern='*', forks=10,
module_name='command', module_args='/usr/bin/uptime',
if results is None:
print "No hosts found"
sys.exit(1)
print "UP ***********"
for (hostname, result) in results['contacted'].items():
if not 'failed' in result:
print "%s &&& %s" % (hostname, result['stdout'])
print "FAILED *******"
for (hostname, result) in results['contacted'].items():
if 'failed' in result:
print "%s &&& %s" % (hostname, result['msg'])
print "DOWN *********"
for (hostname, result) in results['dark'].items():
print "%s &&& %s" % (hostname, result)
12345678910111213141516171819202122232425262728
#!/usr/bin/python&import ansible.runnerimport sys&# construct the ansible runner and execute on all hostsresults = ansible.runner.Runner(pattern='*', forks=10,module_name='command', module_args='/usr/bin/uptime',).run()&if results is None:&& print "No hosts found"&& sys.exit(1)&print "UP ***********"for (hostname, result) in results['contacted'].items():if not 'failed' in result:print "%s &&& %s" % (hostname, result['stdout'])&print "FAILED *******"for (hostname, result) in results['contacted'].items():if 'failed' in result:print "%s &&& %s" % (hostname, result['msg'])&print "DOWN *********"for (hostname, result) in results['dark'].items():print "%s &&& %s" % (hostname, result)
API设计详见:
可能感兴趣的话题
ansible在windows客户端上执行java命令总是报heap错误,lz是否遇到过
关于伯乐在线博客
在这个信息爆炸的时代,人们已然被大量、快速并且简短的信息所包围。然而,我们相信:过多“快餐”式的阅读只会令人“虚胖”,缺乏实质的内涵。伯乐在线内容团队正试图以我们微薄的力量,把优秀的原创文章和译文分享给读者,为“快餐”添加一些“营养”元素。
新浪微博:
推荐微信号
(加好友请注明来意)
– 好的话题、有启发的回复、值得信赖的圈子
– 分享和发现有价值的内容与观点
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 翻译传播优秀的外文文章
– 国内外的精选文章
– UI,网页,交互和用户体验
– 专注iOS技术分享
– 专注Android技术分享
– JavaScript, HTML5, CSS
– 专注Java技术分享
– 专注Python技术分享
& 2017 伯乐在线

我要回帖

更多关于 王者荣耀祸源和无双 的文章

 

随机推荐