部署 Fedora 带有 Terraform 的 CoreOS 服务器

[ad_1]

Fedora CoreOS 是一种轻量级、安全的操作系统,针对运行容器化工作负载进行了优化。 你只需要一个 YAML 文档来描述你想在一个机器上运行的工作负载 Fedora CoreOS 服务器。

这对于单个服务器来说很棒,但是您如何描述一组合作 Fedora CoreOS 服务器? 例如,如果您想要一组服务器运行负载均衡器,其他服务器运行数据库集群,其他服务器运行 Web 应用程序,该怎么办? 如何让它们全部配置和配置? 您如何配置它们以相互通信? 本文着眼于 Terraform 如何解决这个问题。

入门

在开始之前,先决定是否需要复习基础知识 Fedora 核心操作系统。 看看之前的这篇文章 Fedora 杂志:

开始使用 Fedora 核心操作系统

地形 是一个用于定义和配置基础设施的开源工具。 Terraform 将基础设施定义为文件中的代码。 它通过计算代码中的期望状态与观察到的状态之间的差异并应用更改来消除差异来提供基础设施。

创建和维护 Terraform 的公司 HashiCorp 提供了一个 RPM 存储库来安装 Terraform。

sudo dnf config-manager --add-repo 
  https://rpm.releases.hashicorp.com/fedora/hashicorp.repo
sudo dnf install terraform

要熟悉这些工具,请从一个简单的示例开始。 你将创建一个 Fedora AWS 中的 CoreOS 服务器。 要继续,您需要安装 awscli 并拥有一个 AWS 帐户。 awscli 可以从 Fedora 存储库并使用 aws configure 命令进行配置

sudo dnf install -y awscli
aws configure

请注意, AWS 是一项付费服务​​。 如果执行正确,参与者的费用应该低于 1 美元,但错误可能会导致意外费用。

配置地形

在新目录中,创建一个名为 config.yaml 的文件。 该文件将保存您的 Fedore CoreOS 配置的内容。 该配置只是为核心用户添加一个 SSH 密钥。 修改 authorized_ssh_key 部分使用您自己的。

variant: fcos
version: 1.2.0
passwd:
  users:
  - name: core
    ssh_authorized_keys:
    - "ssh-ed25519 AAAAC3....... [email protected]"

接下来,创建一个文件 main.tf 以包含您的 Terraform 规范。 逐节查看内容。 它以一个块开始,用于指定提供程序的版本。

terraform {
  required_providers {
    ct = {
      source  = "poseidon/ct"
      version = "0.7.1"
    }
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

Terraform 使用提供程序来控制基础设施。 在这里,它使用 AWS 提供商来配置 EC2 服务器,但它可以配置任何类型的 AWS 基础设施。 这 ct提供者波塞冬实验室 代表配置转译器。 该供应商将 转译 Fedora CoreOS 配置转换为 Ignition 配置。 因此,您不需要使用 fcct 转换您的配置。 现在您的提供程序版本已指定,请初始化它们。

provider "aws" {
  region = "us-west-2"
}

provider "ct" {}

AWS 区域设置为 us-west-2 并且 ct 提供程序不需要配置。 配置了提供程序后,您就可以定义一些基础设施了。 用一个 数据源 块读取配置。

data "ct_config" "config" {
  content = file("config.yaml")
  strict = true
}

定义此数据块后,您现在可以将转换后的 Ignition 输出作为 data.ct_config.config.rendered 访问。 要创建 EC2 服务器,请使用 资源 块,并将 Ignition 输出作为 user_data 属性传递。

resource "aws_instance" "server" {
  ami           = "ami-0699a4456969d8650"
  instance_type = "t3.micro"
  user_data     = data.ct_config.config.rendered
}

此配置将虚拟机映像 (AMI) 硬编码为最新的稳定映像 Fedora 撰写本文时,位于 us-west-2 区域的 CoreOS。 如果您想使用不同的区域或流,您可以在 Fedora CoreOS 下载页面.

最后,您想知道服务器创建后的公共 IP 地址。 使用 输出 块来定义 Terraform 完成其供应后要显示的输出。

output "instance_ip_addr" {
  value = aws_instance.server.public_ip
}

好吧! 您已准备好创建一些基础架构。 要部署服务器,只需运行:

terraform init   # Installs the provider dependencies
terraform apply  # Displays the proposed changes and applies them

完成后,Terraform 会打印服务器的公共 IP 地址,您可以通过运行 ssh [email protected]{public ip here} SSH 到服务器。 恭喜 – 你已经配置了你的第一个 Fedora 使用 Terraform 的 CoreOS 服务器!

更新和不变性

此时你可以随意修改 config.yaml 中的配置。 要部署您的更改,只需再次运行 terraform apply。 请注意,每次更改配置时,当您运行 terraform apply 时,它都会破坏服务器并创建一个新服务器。 这与 Fedora CoreOS 理念:配置只能发生一次。 想要更改该配置? 创建一个新服务器。 如果您习惯于一次性配置服务器并使用诸如 Ansible, 木偶 或者 厨师.

始终创建新服务器的好处是可以更轻松地测试新配置的服务器是否按预期运行。 考虑到所有可能的方式更新到位系统可能会中断可能要困难得多。 遵循这一理念的工具通常属于不可变基础设施的标题。 这种基础设施方法与函数式编程技术具有一些相同的好处,即可变状态通常是错误的来源。

使用变量

您可以使用地形 输入变量 参数化您的基础设施。 在前面的示例中,您可能希望参数化 AWS 区域或实例类型。 这将允许您部署具有不同参数的相同配置的多个实例。 如果你想参数化 Fedora CoreOS 配置? 这样做使用 模板文件 功能。

例如,尝试参数化用户的用户名。 为此,请在 main.tf 文件中添加一个用户名变量:

variable "username" {
  type        = string
  description = "Fedora CoreOS user"
  default     = "core"
}

接下来,修改 config.yaml 文件以将其转换为模板。 渲染时,${username} 将被替换。

variant: fcos
version: 1.2.0
passwd:
  users:
  - name: ${username}
    ssh_authorized_keys:
    - "ssh-ed25519 AAAAC3....... [email protected]"

最后,使用 templatefile 函数修改数据块以呈现模板。

data "ct_config" "config" {
  content = templatefile(
    "config.yaml",
    { username = var.username }
  )
  strict = true
}

要使用设置为 jane 的用户名进行部署,请运行 terraform apply -var=”username=jane”。 要验证,请尝试使用 ssh [email protected]{public ip address} SSH 到服务器。

利用依赖图

将变量从 Terraform 传递到 Fedora CoreOS 配置非常有用。 但是您可以更进一步,将基础设施数据传递到服务器配置中。 这就是 Terraform 和 Fedora CoreOS 开始真正闪耀。

Terraform 创建了一个 依赖图 对基础设施的状态进行建模并规划更新。 如果一个资源的输出(例如服务器的公共 IP 地址)作为另一服务的输入(例如防火墙规则中的目标)传递,Terraform 理解前者的变化需要重新创建或修改后者。 如果您将基础设施数据传递到 Fedora CoreOS 配置,它将参与依赖关系图。 对输入的更新将触发使用新配置创建新服务器。

以一个包含一个负载均衡器和三个 Web 服务器的系统为例。

目标是使用每个 Web 服务器的 IP 地址配置负载平衡器,以便它可以将流量转发给它们。

网络服务器配置

首先,创建一个文件 web.yaml 并添加一个带有模板化消息的简单 Nginx 配置。

variant: fcos
version: 1.2.0
systemd:
  units:
  - name: nginx.service
    enabled: true
    contents: |
      [Unit]
      Description=Nginx Web Server
      After=network-online.target
      Wants=network-online.target
      [Service]
      ExecStartPre=-/bin/podman kill nginx
      ExecStartPre=-/bin/podman rm nginx
      ExecStartPre=/bin/podman pull nginx
      ExecStart=/bin/podman run --name nginx -p 80:80 -v /etc/nginx/index.html:/usr/share/nginx/html/index.html:z nginx
      [Install]
      WantedBy=multi-user.target
storage:
  directories:
  - path: /etc/nginx
  files:
  - path: /etc/nginx/index.html
    mode: 0444
    contents:
      inline: |
        <html>
          <h1>Hello from Server ${count}</h1>
        </html>

在 main.tf 中,您可以使用此模板和以下块创建三个 Web 服务器:

data "ct_config" "web" {
  count   = 3
  content = templatefile(
    "web.yaml",
    { count = count.index }
  )
  strict = true
}

resource "aws_instance" "web" {
  count         = 3
  ami           = "ami-0699a4456969d8650"
  instance_type = "t3.micro"
  user_data     = data.ct_config.web[count.index].rendered
}

注意 count = 3 和 count.index 变量的使用。 您可以使用 数数 制作资源的多个副本。 在这里,它创建了三个配置和三个 Web 服务器。 count.index 变量用于将第一个配置传递给第一个 Web 服务器,依此类推。

负载均衡器配置

负载均衡器将是一个基本的 HAProxy 负载均衡器 转发到每个服务器。 将配置放在名为 lb.yaml 的文件中:

variant: fcos
version: 1.2.0
systemd:
  units:
  - name: haproxy.service
    enabled: true
    contents: |
      [Unit]
      Description=Haproxy Load Balancer
      After=network-online.target
      Wants=network-online.target
      [Service]
      ExecStartPre=-/bin/podman kill haproxy
      ExecStartPre=-/bin/podman rm haproxy
      ExecStartPre=/bin/podman pull haproxy
      ExecStart=/bin/podman run --name haproxy -p 80:8080 -v /etc/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro haproxy
      [Install]
      WantedBy=multi-user.target
storage:
  directories:
  - path: /etc/haproxy
  files:
  - path: /etc/haproxy/haproxy.cfg
    mode: 0444
    contents:
      inline: |
        global
          log    stdout format raw local0
        defaults
          mode   tcp
          log    global
          option tcplog
        frontend http
          bind            *:8080
          default_backend http
        backend http
          balance roundrobin
%{ for name, addr in servers ~}
          server  ${name} ${addr}:80 check
%{ endfor ~}

该模板需要一个 地图 以服务器名称作为键,IP 地址作为值。 您可以使用 拉链图 功能。 使用 Web 服务器的 ID 作为键,使用公共 IP 地址作为值。

data "ct_config" "lb" {
  content = templatefile(
    "lb.yaml",
    { 
      servers = zipmap(
        aws_instance.web.*.id,
        aws_instance.web.*.public_ip
      )
    }
  )
  strict = true
}

resource "aws_instance" "lb" {
  ami           = "ami-0699a4456969d8650"
  instance_type = "t3.micro
  user_data     = data.ct_config.lb.rendered
}

最后,添加一个输出块以显示负载均衡器的 IP 地址。

output "load_balancer_ip" {
  value = aws_instance.lb.public_ip
}

好的! 运行 terraform apply 并在完成时显示负载均衡器的 IP 地址。 您应该能够向负载平衡器发出请求并从每个 Web 服务器获得响应。

$ export LB={{load balancer IP here}}
$ curl $LB
<html>
  <h1>Hello from Server 0</h1>
</html>
$ curl $LB
<html>
  <h1>Hello from Server 1</h1>
</html>
$ curl $LB
<html>
  <h1>Hello from Server 2</h1>
</html>

现在您可以修改 Web 服务器或负载平衡器的配置。 任何更改都可以通过再次运行 terraform apply 来实现。 请特别注意,对 Web 服务器 IP 地址的任何更改都会导致 Terraform 重新创建负载均衡器(将计数从 3 更改为 4 是一个简单的测试)。 希望这强调负载均衡器配置确实是 Terraform 依赖关系图的一部分。

清理

您可以使用 terraform destroy 命令销毁所有基础设施。 只需导航到您创建 main.tf 的文件夹并运行 terraform destroy。

接下来在哪里?

本教程的代码可以在 这个 GitHub 存储库. 如果您发现一些您想与世界分享的东西,请随意使用示例并做出更多贡献。 了解更多关于所有令人惊奇的事情 Fedora CoreOS 能做的,潜入 文档 或来聊天 社区. 要了解有关 Terraform 的更多信息,您可以翻阅 文档, 结帐 #terraform on 自由节点,或贡献于 GitHub.

[ad_2]

Related Posts