菜单
开源 RSS

在 AWS EC2 上运行 Promtail 客户端

在本教程中,我们将设置 Promtail 在 AWS EC2 实例上运行,并将其配置为将其所有日志发送到 Grafana Loki 实例。

注意

Promtail 已被弃用,并将通过长期支持 (LTS) 持续到 2026 年 2 月 28 日。Promtail 将于 2026 年 3 月 2 日到达生命周期结束 (EOL)。您可以在此处找到迁移资源。

要求

开始之前,您需要

  • 一个 AWS 账户(包含 AWS_ACCESS_KEYAWS_SECRET_KEY
  • 一个可从互联网路由的 VPC。(如果您需要创建一个,请按照这些说明进行操作)
  • 一个 SSH 公钥。(如果您需要一个新的,请按照这些说明进行操作)
  • 已配置的 AWS CLI(运行 aws configure)。
  • 一个已配置 Loki 数据源的 Grafana 实例,您可以使用 GrafanaCloud 免费试用。

为了简单起见,我们将使用 Grafana Cloud Loki 和 Grafana 实例,您可以在 [Grafana Cloud] 获取免费账户以完成本教程,但如果您运行自己的开源版本 Loki 和 Grafana 实例,所有步骤都是相同的。

为了便于学习,以下所有说明都是手动的,但在实际设置中,我们建议您使用 TerraformCloudFormationAnsibleChef 等配置工具。

创建 EC2 实例

第一步,我们将 SSH 密钥导入到 AWS,以便我们可以 SSH 连接到未来的 EC2 实例,让我们运行第一个命令

bash
aws ec2 import-key-pair --key-name "promtail-ec2" --public-key-material fileb://~/.ssh/id_rsa.pub

接下来我们将创建一个安全组,务必记下组 ID,后续命令需要用到它

bash
aws ec2 create-security-group --group-name promtail-ec2  --description "promtail on ec2" --vpc-id vpc-668d120f
{
    "GroupId": "sg-02c489bbdeffdca1d"
}

现在让我们授权 SSH 和 Promtail 服务器的入站访问

bash
aws ec2 authorize-security-group-ingress --group-id sg-02c489bbdeffdca1d --protocol tcp --port 22 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id sg-02c489bbdeffdca1d --protocol tcp --port 3100 --cidr 0.0.0.0/0

注意

您无需像上面所示那样向所有 IP 开放这些端口,您可以使用自己的 IP 范围。

我们将创建一个 Amazon Linux 2 实例,因为它是最流行的之一,但您也可以随意使用您选择的 AMI。

使用以下命令创建实例,务必记下实例 ID

bash
aws ec2 run-instances --image-id ami-016b213e65284e9c9 --count 1 --instance-type t2.micro --key-name promtail-ec2 --security-groups promtail-ec2

为了以后更有趣,让我们给实例打上标签(Name=promtail-demo

bash
aws ec2 create-tags --resources i-041b0be05c2d5cfad --tags Key=Name,Value=promtail-demo

注意

标签允许您以不同方式分类您的 AWS 资源,例如按用途、所有者或环境。当您有许多同类资源时,这会很有用——您可以根据您分配的标签快速识别特定资源。您稍后会看到,Promtail 可以将这些标签转换为 Loki 标签

最后让我们获取实例的公有 DNS

bash
aws ec2 describe-instances --filters "Name=tag:Name,Values=promtail-demo" --query "Reservations[].Instances[].NetworkInterfaces[].Association.PublicDnsName"

并启动 SSH 会话

bash
ssh ec2-user@ec2-13-59-62-37.us-east-2.compute.amazonaws.com

设置 Promtail

首先,通过使用 sudo -s 确保我们以 root 身份运行。接下来我们将下载、安装 Promtail 并赋予其可执行权限。

bash
mkdir /opt/promtail && cd /opt/promtail
curl -O -L "https://github.com/grafana/loki/releases/download/v2.0.0/promtail-linux-amd64.zip"
unzip "promtail-linux-amd64.zip"
chmod a+x "promtail-linux-amd64"

现在我们将下载下面的 Promtail 配置文件并进行编辑,不用担心,我们会解释这些配置的含义。该文件也作为 gist 可在 cyriltovena/promtail-ec2.yaml 获取。

bash
curl https://raw.githubusercontent.com/grafana/loki/main/docs/sources/send-data/promtail/cloud/ec2/promtail-ec2.yaml > ec2-promtail.yaml
vi ec2-promtail.yaml
yaml
server:
  http_listen_port: 3100
  grpc_listen_port: 0

clients:
  - url: https://<user id>:<api secret>@logs-prod-us-central1.grafana.net/loki/api/v1/push

positions:
  filename: /opt/promtail/positions.yaml

scrape_configs:
  - job_name: ec2-logs
    ec2_sd_configs:
      - region: us-east-2
        access_key: REDACTED
        secret_key: REDACTED
    relabel_configs:
      - source_labels: [__meta_ec2_tag_Name]
        target_label: name
        action: replace
      - source_labels: [__meta_ec2_instance_id]
        target_label: instance
        action: replace
      - source_labels: [__meta_ec2_availability_zone]
        target_label: zone
        action: replace
      - action: replace
        replacement: /var/log/**.log
        target_label: __path__
      - source_labels: [__meta_ec2_private_dns_name]
        regex: "(.*)"
        target_label: __host__

server 部分指示 Promtail 将其 HTTP 服务器绑定到 3100 端口。Promtail 提供 HTTP 页面用于服务发现和目标的故障排除

clients 部分允许您指定 Loki 实例。如果您使用 GrafanaCloud,只需将 <user id><api secret> 替换为您的凭据。否则,只需将整个 URL 替换为您自定义的 Loki 实例。(例如 http://my-loki-instance.my-org.com/loki/api/v1/push

Promtail 使用与 Prometheus 相同的 scrape_configs。这意味着如果您已经拥有 Prometheus 实例,配置将非常相似且易于理解。

由于我们在 AWS EC2 上运行,我们希望使用 EC2 服务发现,这将允许我们抓取当前实例的元数据(甚至您的自定义标签)并将其附加到我们的日志中。这样一来,管理和查询日志将变得容易得多。

务必相应地替换您当前的 regionaccess_keysecret_key,或者您也可以使用 AWS IAM Role ARN。有关更多信息,请参阅 ec2_sd_config 的文档。

最后,relabeling_configs 部分有三个作用

  1. 选择您希望附加到目标上的发现的标签。在本例中,我们将 instance_id 作为 instance,将标签 Name 作为 name,以及实例的 zone。务必查阅 Prometheus ec2_sd_config 文档以获取可用标签的完整列表。

  2. 选择 Promtail 应该从哪里找到日志文件进行尾部追踪。在我们的示例中,我们希望使用 glob /var/log/**.log 来包含 /var/log 中存在的所有日志文件。如果您需要使用多个 glob,只需在您的 scrape_configs 中添加另一个 job 即可。

  3. 确保发现的目标仅是 Promtail 当前运行的机器。这通过使用传入的元数据 __meta_ec2_private_dns_name 添加标签 __host__ 来实现。如果它与当前的 HOSTNAME 环境变量不匹配,该目标将被丢弃。如果 __meta_ec2_private_dns_name 与您的实例主机名不匹配(例如在 EC2 Windows 实例上,它是 IP 地址而不是主机名),您可以在此阶段硬编码主机名,或检查实例的任何标签是否包含主机名(__meta_ec2_tag_<tagkey>:实例的每个标签值)

好的,我们应该准备好启动 Promtail 了,我们将使用 --dry-run 标志运行它。这非常适合确保一切正常,尤其是在您还在调整配置时。不用担心,使用此模式时,Promtail 不会发送任何日志,也不会记住任何文件位置。

bash
 ./promtail-linux-amd64 -config.file=./ec2-promtail.yaml --dry-run

如果一切顺利,Promtail 应该会打印出带有发现的标签的日志行,而不是将它们发送到 Loki,如下所示

bash
2020-07-08T14:51:38-0700	{filename="/var/log/cloud-init.log", instance="i-041b0be05c2d5cfad", name="promtail-demo", zone="us-east-2c"}	Jul 07 21:37:24 cloud-init[3035]: util.py[DEBUG]: loaded blob returned None, returning default.

请随时编辑您的配置文件并再次启动 Promtail 来尝试您的配置。

如果您想查看现有目标和可用标签,可以使用分配给您实例的公有 DNS 访问 Promtail 服务器

bash
open http://ec2-13-59-62-37.us-east-2.compute.amazonaws.com:3100/

例如,下面的页面是服务发现页面。它显示了所有发现的目标,以及它们各自可用的标签以及被丢弃的原因(如果被丢弃的话)。

Service discovery page

此页面对于了解哪些标签可以通过 relabeling 配置进行转发以及为什么 Promtail 没有抓取您的目标非常有帮助。

将 Promtail 配置为服务

现在我们已经正确配置了 Promtail。我们通常希望确保它作为 systemd 服务运行,这样它就可以在失败或实例重启时自动重新启动。

让我们使用 vim /etc/systemd/system/promtail.service 创建一个新的服务,并复制下面的服务定义

systemd
[Unit]
Description=Promtail

[Service]
User=root
WorkingDirectory=/opt/promtail/
ExecStartPre=/bin/sleep 30
ExecStart=/opt/promtail/promtail-linux-amd64 --config.file=./ec2-promtail.yaml
SuccessExitStatus=143
TimeoutStopSec=10
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

让我们重新加载 systemd,然后启用并启动 Promtail 服务

bash
systemctl daemon-reload
systemctl enable promtail.service
systemctl start promtail.service

您可以使用以下命令验证服务是否正常运行

bash
systemctl status promtail.service -l

● promtail.service - Promtail
   Loaded: loaded (/etc/systemd/system/promtail.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2020-07-08 15:48:57 UTC; 4s ago
 Main PID: 2732 (promtail-linux-)
   CGroup: /system.slice/promtail.service
           └─2732 /opt/promtail/promtail-linux-amd64 --config.file=./ec2-promtail.yaml

Jul 08 15:48:57 ip-172-31-45-69.us-east-2.compute.internal systemd[1]: Started Promtail.
Jul 08 15:48:57 ip-172-31-45-69.us-east-2.compute.internal systemd[1]: Starting Promtail...
Jul 08 15:48:57 ip-172-31-45-69.us-east-2.compute.internal promtail-linux-amd64[2732]: level=warn ts=2020-07-08T15:48:57.559085451Z caller=filetargetmanager.go:98 msg="WARNING!!! entry_parser config is deprecated, please change to pipeline_stages"
Jul 08 15:48:57 ip-172-31-45-69.us-east-2.compute.internal promtail-linux-amd64[2732]: level=info ts=2020-07-08T15:48:57.559869071Z caller=server.go:179 http=[::]:3100 grpc=[::]:35127 msg="server listening on addresses"
Jul 08 15:48:57 ip-172-31-45-69.us-east-2.compute.internal promtail-linux-amd64[2732]: level=info ts=2020-07-08T15:48:57.56029474Z caller=main.go:67 msg="Starting Promtail" version="(version=1.6.0, branch=HEAD, revision=12c7eab8)"

您现在可以在 Grafana 中使用 LogQL 查询 {zone="us-east-2"} 来验证 Loki 是否已正确接收到您的实例日志。

Grafana Loki logs

发送 systemd 日志

就像我们对 Promtail 所做的那样,您很可能会使用 systemd 管理您的应用程序,systemd 通常将应用程序日志存储在 journald 中。Promtail 实际上支持从 journald 抓取日志,所以让我们配置它。

我们将编辑之前的配置(vi ec2-promtail.yaml)并在 scrape_configs 部分添加以下块。

yaml
  - job_name: journal
    journal:
      json: false
      max_age: 12h
      path: /var/log/journal
      labels:
        job: systemd-journal
    relabel_configs:
      - source_labels: ['__journal__systemd_unit']
        target_label: 'unit'

请注意,您可以使用 relabeling 将 systemd 标签转换为您想要的格式。最后确保 journald 日志路径正确,在某些系统上可能会有所不同。

注意

您可以从我们的 [GitHub 仓库][final config] 下载最终配置示例。

就这样,保存配置,您可以重启机器(或只需重启服务 systemctl restart promtail.service)。

让我们回到 Grafana,并在 Explore 中使用 LogQL 查询 {unit="promtail.service"} 验证您的 Promtail 日志是否在 Grafana 中可用。最后务必查看live tailing,以查看日志在被摄入 Loki 时实时显示。