如今软件开发对基础设施的管理有了更严格的要求:产品要适应市场做出调整,需要基础设施有更快的响应速度。持续交付和DevOps的推行更是要求产品团队对部署和运维要有更高的自主性。技术的快速进步和演化,也使得基础设施的配置频繁的发生变化。在这种快速变化的过程中,要求基础设施既要灵活、安全,也要可靠。
基础设施即代码带来的核心便利: IaC旨在利用系统配置来缓解最常见的痛点,特别是以前配置一个新环境通常需要花费大量的时间。每一个环境都需要单独配置,且如果某处出现错误,通常需重新进行整个过程。IaC消除了这些痛点,并向开发者和运维人员提供了以下额外的便利:
1.重新使用常见的脚本变得相对简单了。
2.整个供应过程可实现自动化,连供应硬件都可以作为持续交付过程的一部分。
3.版本控制,可以根据需要测试和回滚较新的配置。
4.同行审查和脚本强化。不需手动地从文档或内存中配置,就可以对脚本进行审查、更新和持续改进。
5.文档是自动的,因为本质上它就是脚本本身。
6.过程可以被测试。
用代码定义服务器配置意味着在服务器间有绝对的一致性。手动调整配置往往会存在一些微妙的差异,经常会导致出现问题并且难以调试。这个问题在有不一致的监控时更早,所以一样用代码保证监控也是一致的。最重要的是用配置代码保证变更更安全,在升级应用和系统软件时承担更小的风险。问题可以被定位并且可以得到更快的修复,最差的情况下也可以回滚到上一次的工作配置,将基础设施像版本控制一样管理有利于兼容性和审查,每一行你对配置的变更都会被记录,这样不容易出问题。
产品团队在实施持续交付的过程中,必须考虑将基础设施的维护纳入进来,作为支持产品运行的一部分。以下是产品团队的持续交付流水线全景图。
上图可以看出,产品团队除了管理项目本身代码之外,还要管理环境定义脚本。环境定义脚本可以由基础设施自动化工具执行,动态创建、销毁和更新产品运行所需的环境(包括服务器、负载均衡器、防火墙配置、第三方依赖等)。
基础设施即代码有四项关键原则:
再生性:环境中的任何元素都可以轻松复制。
一致性:无论何时,创建的环境各个元素的配置也是是完全相同的。
可见性:所有对环境的变更应该容易理解、可审计、受版本控制。
快速反馈:能够频繁、容易地进行变更,并快速知道变更是否正确。
基础设施即代码的目标:
标准化: 以代码来定义环境,实现开发环境、测试环境、生产环境的标准化。
自动化: 用自动化工具来驱动代码准备环境。包括创建环境、更新环境以及销毁环境。
可视化: 靠监控来可视化环境信息。环境当前状态可视、环境变更历史可视、可追溯。
在实施基础设施即代码时,要遵守以下内容:
一、使用DSL描述环境
Ansible、Chef、SaltStack等基础设施自动化工具都有各自的描述性语言来实现对基础设施的定义。使用DSL更容易通过描述性的语言定义基础设施,也有助于代码重用。团队成员能建立起共同理解,从而维护脚本。 以下是Ansible的一个playbook示例。
- hosts: all
tasks:
- name: stat /mnt/scriprtsh
stat: path=/mnt/script.sh
register: token_stat
- name: add execute to script
file:
path: /mnt/script.sh
mode: '0777'
when: token_stat.stat.exists
- name: run token to create results.txt
shell: /mnt/script.sh
when: token_stat.stat.exists
- name: stat if exists results.txt
stat: path=/mnt/results.txt
register: result_stat
- name: scp results.txt to master
fetch:
src: /mnt/results.txt
dest: /mnt/{{ ansible_hostname }}-results.txt
flat: yes
when: result_stat.stat.exists
二、自测试系统
在编写环境代码的配置时,也要编写对环境的测试。确保所有服务器都进行了正确的配置,遵守了所有的安全规则,也对网络连通性等进行了验证。我们一般提倡将测试代码和配置代码放在一起维护。这样配置代码更新时,能保证测试代码也被及时更新。 一些典型的基础设施自动化测试工具有ServerSpec、Testinfra等。以下是一个Testinfra的示例。
def test_passwd_file(host):
passwd = host.file("/etc/passwd")
assert passwd.contains("root")
assert passwd.user == "root"
assert passwd.group == "root"
assert passwd.mode == 0o644
def test_nginx_is_installed(host):
nginx = host.package("nginx")
assert nginx.is_installed
assert nginx.version.startswith("1.2")
def test_nginx_running_and_enabled(host):
nginx = host.service("nginx")
assert nginx.is_running
assert nginx.is_enabled
三、一切进行版本化
一旦采用了环境定义脚本实现对环境的控制后,需要将环境定义脚本纳入到版本管理中。并且之后所有的环境变更都应该先修改环境定义脚本,由环境定义脚本触发对环境的变更。登录到服务器执行一些临时性命令是被坚决禁止的。因为这极有可能会破坏环境的一致性。重建服务器时,也不能保证能应用所有需要的变更。
※部分文章来源于网络,如有侵权请联系删除;更多文章和资料|点击后方文字直达 ↓↓↓ 100GPython自学资料包 阿里云K8s实战手册 [阿里云CDN排坑指南]CDN ECS运维指南 DevOps实践手册 Hadoop大数据实战手册 Knative云原生应用开发指南 OSS 运维实战手册 云原生架构白皮书 Zabbix企业级分布式监控系统源码文档 10G大厂面试题戳领