代码部署工具全解析
在软件开发和运维领域,代码部署是一个关键环节。不同的部署工具各有特点,下面将详细介绍几种常见的代码部署工具。
Puppet
Puppet是一个广泛使用的部署工具,它拥有庞大的社区和丰富的网络资源。有大量不同的模块可供使用,如果要部署的组件不是特别特殊,很可能已经存在现成的模块,可根据需求进行修改。然而,Puppet也存在一些缺点。它在客户端机器上需要依赖多个组件,有时会引发问题。例如,Puppet代理需要一个Ruby运行时,而这个Ruby版本有时需要比发行版仓库中的版本更新,企业发行版的版本更新往往滞后。此外,Puppet的配置编写和测试较为复杂。
Ansible
Ansible是一种倾向于简单性的部署解决方案。它采用无代理架构,不像Puppet那样需要在客户端运行守护进程。相反,Ansible服务器通过SSH登录到Ansible节点并发出命令来安装所需的配置。虽然Ansible的无代理架构使事情变得简单,但需要在Ansible节点上安装Python解释器。不过,Ansible对运行其代码所需的Python版本要求比Puppet对其Ruby代码的要求更宽松,因此在实践中,对Python的依赖并不是很大的麻烦。
和Puppet等工具一样,Ansible专注于幂等的配置描述符。这意味着描述符是声明性的,Ansible系统会自行确定如何将服务器带到所需的状态。可以安全地重新运行配置,而对于命令式系统来说,情况并非总是如此。
下面通过Docker方法来尝试使用Ansible:
1. 创建一个Dockerfile:
FROM williamyeh/ansible:centos7
- 构建Docker容器:
docker build .
这将下载镜像并创建一个空的Docker容器。通常会有一个更复杂的Dockerfile来添加所需的内容,但这里将以交互方式使用镜像,因此会将主机上包含Ansible文件的目录挂载到容器中,以便在主机上更改文件并轻松重新运行。
3. 运行容器:
docker run -v `pwd`/ansible:/ansible -it <hash> bash
这里的
<hash>
是上一步构建命令生成的哈希值。现在有了一个命令提示符,并且可以使用Ansible。
-v
参数的作用是使主机文件系统的部分内容对Docker容器可见,文件将在容器的
/ansible
目录中可见。
以下是一个简单的
playbook.yml
文件示例:
---
- hosts: localhost
vars:
http_port: 80
max_clients: 200
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum: name=httpd state=latest
这个剧本的功能有限,但展示了Ansible剧本的一些概念。现在可以尝试运行Ansible剧本:
cd /ansible
ansible-playbook -i inventory playbook.yml --connection=local --sudo
运行结果可能如下:
PLAY [localhost] ********************************************************
******
GATHERING FACTS *********************************************************
******
ok: [localhost]
TASK: [ensure apache is at the latest version] **************************
******
ok: [localhost]
PLAY RECAP **************************************************************
******
localhost : ok=2 changed=0 unreachable=0
failed=0
任务的运行是为了确保达到所需的状态。在这个例子中,是使用
yum
安装Apache的
httpd
并确保其为最新版本。
如果想进一步探索,例如自动启动服务,使用Docker模拟物理或虚拟主机的方法会存在一些限制。因为Docker是一种容器技术,而不是成熟的虚拟化系统。在Docker的正常使用场景中,这可能不是问题,但在这种情况下,需要一些变通方法。主要问题是
systemd
初始化系统在容器中运行需要特殊处理。以下是Red Hat的Vaclav Pavlin修改后的Docker镜像:
FROM fedora
RUN yum -y update; yum clean all
RUN yum install ansible sudo
RUN systemctl mask systemd-remount-fs.service dev-hugepages.mount sys-
fs-fuse-connections.mount systemd-logind.service getty.target console-
getty.service
RUN cp /usr/lib/systemd/system/dbus.service /etc/systemd/system/; sed
-i 's/OOMScoreAdjust=-900//' /etc/systemd/system/dbus.service
VOLUME ["/sys/fs/cgroup", "/run", "/tmp"]
ENV container=docker
CMD ["/usr/sbin/init"]
环境变量
container
用于告诉
systemd
初始化系统它在容器中运行并相应地表现。为了使
systemd
在容器中工作,
docker run
命令需要一些额外的参数:
docker run -it --rm -v /sys/fs/cgroup:/sys/fs/cgroup:ro -v `pwd`/
ansible:/ansible <hash>
容器使用
systemd
启动后,需要从另一个shell连接到正在运行的容器:
docker exec -it <hash> bash
现在可以在容器中运行一个更高级的Ansible剧本:
---
- hosts: localhost
vars:
http_port: 80
max_clients: 200
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum: name=httpd state=latest
- name: write the apache config file
template: src=/srv/httpd.j2 dest=/etc/httpd.conf
notify:
- restart apache
- name: ensure apache is running (and enable it at boot)
service: name=httpd state=started enabled=yes
handlers:
- name: restart apache
service: name=httpd state=restarted
这个例子在之前的基础上进行了扩展,展示了如何安装包、编写模板文件以及处理服务的运行状态,格式采用了简单的YML语法。
不同部署工具的执行模型对比
| 工具 | 执行模型 | 特点 |
|---|---|---|
| Puppet | 拉取模型 | Puppet代理向Puppet主服务器注册并打开通信通道以检索命令,通常每30分钟重复一次该过程。可配置更短的时间间隔。客户端必须主动检查是否有更改可用。 |
| Ansible | 推送模型 | 通过SSH在需要时推送更改。 |
| Salt | 推送模型 | 使用ZeroMQ消息服务器,客户端连接到该服务器并监听更改通知,工作方式类似Puppet,但速度更快。 |
不同的执行模型在开发者社区中存在争议。消息队列架构的支持者认为其速度更快,而普通SSH方法的支持者则认为速度足够且简单性更重要。
Vagrant
Vagrant是一个用于虚拟机的配置系统,主要用于为开发者创建虚拟机,但也可用于其他目的。它支持多种虚拟化提供商,VirtualBox是开发者常用的提供商。
在Fedora上安装Vagrant的步骤如下:
1. 安装Vagrant:
yum install 'vagrant*'
在Fedora上安装时会遇到一些问题,因为Fedora的Vagrant包使用libvirt作为虚拟机提供商而不是VirtualBox。如果想使用VirtualBox作为提供商,需要进行一些额外的步骤。
2. 添加VirtualBox仓库并安装VirtualBox:
dnf install VirtualBox
VirtualBox还需要特殊的内核模块才能工作,因为它需要仲裁对底层资源的访问。VirtualBox内核驱动不随Linux内核一起分发。可以使用
dkms
命令在一定程度上自动化编译驱动的过程,或者使用发行版为内核编译的内核模块。如果发行版提供了内核模块,它应该会自动加载,否则可以尝试
modprobe vboxdrv
,对于某些发行版,还可以通过调用init.d脚本来编译驱动:
sudo /etc/init.d/vboxdrv setup
安装好Vagrant的依赖项后,可以启动一个Vagrant虚拟机:
1. 创建Vagrant配置文件:
vagrant init hashicorp/precise32
- 启动虚拟机:
vagrant up
如果一切顺利,应该会有一个Vagrant虚拟机实例在运行,但由于是无头模式,不会看到任何界面。
可以使用以下命令连接到之前启动的无头Vagrant实例:
vagrant ssh
Vagrant还提供了一个配置系统,使得可以使用Vagrant机器描述符从源代码重新创建一个完全配置好的虚拟机。以下是一个简单的Vagrantfile示例:
Vagrant.configure(2) do |config|
config.vm.box = "hashicorp/precise32"
config.vm.provision :shell, path: "bootstrap.sh"
end
bootstrap.sh
脚本如下:
#!/usr/bin/env bash
apt-get update
apt-get install -y apache2
这将在Vagrant管理的虚拟机中安装一个Apache Web服务器。
从DevOps的角度来看,Vagrant是一种方便管理基于VirtualBox的虚拟机配置的方式,非常适合测试。但其配置方法不太适合扩展到集群,不过一些配置系统如Ansible支持Vagrant,因此在测试配置代码时Vagrant非常有用。
Docker部署
Docker是一种新兴的部署替代方案,具有许多有趣的特性。即使使用Puppet或Ansible等工具来部署产品,也可以利用Docker的特性进行测试自动化。Docker创建可重用容器的模型非常有吸引力,这些容器可用于开发机器、测试环境和生产环境。
目前,Docker开始对大型企业产生影响,但Puppet等解决方案仍然占据主导地位。虽然如何构建大型Puppet或Ansible服务器农场已经广为人知,但如何构建大型基于Docker的服务器集群还不是很清楚。目前有一些新兴的解决方案:
- Docker Swarm:与Docker Compose兼容,由Docker社区维护。
- Kubernetes:模仿Google的Borg集群软件,这是一个经过良好测试的模型,但Kubernetes与Borg并不相同,其扩展能力是否与Borg相同尚不清楚。
综上所述,不同的部署工具各有优缺点,在选择时需要根据具体的需求和场景进行综合考虑。
代码部署工具全解析
PalletOps
PalletOps是一个高级部署系统,它将Lisp的声明式能力与轻量级的服务器配置相结合。PalletOps进一步发展了Ansible的无代理理念,与其他工具不同,它不需要在待配置的节点上安装Ruby或Python解释器,只需要安装ssh和bash即可。这种简单的要求使得它可以在非常小型和简单的服务器上使用,甚至可以在手机上使用。
不过,PalletOps也存在一定的局限性。虽然有一些名为crates的支持模块,但与Puppet或Ansible相比,其数量较少。
Chef部署
Chef是Opscode开发的基于Ruby的部署系统。在Docker容器中尝试使用Chef可以避免对主机环境造成污染,具体步骤如下:
1. 启动一个Ubuntu的Docker容器:
docker run -it ubuntu
- 安装curl命令以用于下载Chef安装程序:
apt-get -y install curl
- 下载并安装Chef:
curl -L https://www.opscode.com/chef/install.sh | bash
Chef安装程序是使用Chef团队的omnibus工具构建的。这里我们要尝试使用的是名为chef - solo的工具,可通过以下命令验证其是否安装成功:
chef-solo -v
如果安装成功,会输出类似如下信息:
Chef: 12.5.1
chef - solo的优势在于可以在不依赖完整配置系统基础设施(如客户端/服务器设置)的情况下运行配置脚本。在开发要部署的配置时,这种测试环境非常有用,因为在使所有组件正常工作可能会很困难。
Chef对文件结构有一定要求,可以从GitHub获取预定义的文件结构,步骤如下:
1. 下载并解压文件结构:
curl -L http://github.com/opscode/chef-repo/tarball/master -o master.tgz
tar -zxf master.tgz
mv chef-chef-repo* chef-repo
rm master.tgz
- 配置Chef的cookbook路径:
mkdir .chef
echo "cookbook_path [ '/root/chef-repo/cookbooks' ]" > .chef/knife.rb
- 使用knife工具创建配置模板:
knife cookbook create phpapp
SaltStack部署
SaltStack是基于Python的部署解决方案。Jackson Cage提供了一个方便的Docker化测试环境,启动该环境的命令如下:
docker run -i -t --name=saltdocker_master_1 -h master -p 4505 -p 4506 \
-p 8080 -p 8081 -e SALT_NAME=master -e SALT_USE=master \
-v `pwd`/srv/salt:/srv/salt:rw jacksoncage/salt
这将创建一个包含Salt主服务器和Salt从服务器的单个容器。可以通过以下命令在容器内创建一个shell进行进一步探索:
docker exec -i -t saltdocker_master_1 bash
SaltStack使用.yml文件进行配置,它将配置称为“状态”或Salt状态。例如,要安装一个Apache服务器,可以使用以下简单的Salt状态:
top.sls
文件内容:
base:
'*':
- webserver
webserver.sls
文件内容:
apache2: # ID声明
pkg: # 状态声明
- installed # 函数声明
top.sls
文件声明所有匹配的节点都应该是webserver类型,
webserver.sls
文件声明应该安装apache2包。需要注意的是,这会依赖于具体的发行版,这里使用的Salt Docker测试镜像基于Ubuntu,在Ubuntu中Apache Web服务器包名为apache2,而在Fedora中则名为httpd。
可以通过以下命令让Salt读取并应用Salt状态:
salt-call --local state.highstate -l debug
第一次运行时会非常详细,尤其是启用了调试标志的情况下。再次运行该命令时,会看到类似如下输出:
local:
----------
ID: apache2
Function: pkg.installed
Result: True
Comment: Package apache2 is already installed.
Started: 22:55:36.937634
Duration: 2267.167 ms
Changes:
Summary
------------
Succeeded: 1
Failed: 0
------------
Total states run: 1
退出容器并重新启动后,之前安装的Apache实例会被清除。此时可以使用消息队列方法应用相同的状态:
salt-call state.highstate
各工具的综合对比与选择建议
| 工具名称 | 编程语言 | 主要特点 | 适用场景 | 复杂度 |
|---|---|---|---|---|
| Puppet | Ruby | 社区庞大,模块丰富,但客户端依赖多,配置复杂 | 大型企业级部署,对模块复用性要求高 | 高 |
| Ansible | Python | 无代理架构,简单易用,幂等性配置 | 中小型项目,对简单性和灵活性要求高 | 低 |
| PalletOps | Lisp | 无代理,要求低,但支持模块少 | 小型设备或简单服务器部署 | 中 |
| Chef | Ruby | 基于Ruby,适合测试环境,有特定文件结构要求 | 开发测试阶段,对配置脚本独立运行有需求 | 中 |
| SaltStack | Python | 基于Python,使用ZeroMQ消息服务器,速度快 | 对部署速度有较高要求的场景 | 中 |
| Vagrant | 多种语言支持 | 用于虚拟机配置,适合测试 | 开发测试阶段,对虚拟机配置管理有需求 | 低 |
| Docker | 多种语言支持 | 容器化部署,可用于多环境 | 开发、测试、生产全流程,对环境一致性要求高 | 中 |
在选择部署工具时,需要综合考虑项目的规模、复杂度、团队技术栈、对环境一致性的要求等因素。例如,如果是小型项目且追求简单性,Ansible或Vagrant可能是不错的选择;如果是大型企业级项目且有丰富的模块需求,Puppet可能更合适;而对于容器化部署和环境一致性要求高的场景,Docker及其相关解决方案则值得考虑。
总之,不同的代码部署工具都有其独特的优势和适用场景,开发团队应根据实际情况做出明智的选择,以提高代码部署的效率和质量。
超级会员免费看

被折叠的 条评论
为什么被折叠?



