🤖

Ansible を使って Promtail のインストールを楽にする

2022/11/09に公開

Grafana Cloud (Loki) に Promtail を使って journal メッセージを飛ばしてみた では手作業で Promtail をセットアップしていたが、毎回 Linux サーバーを立てる度に手でやっても仕方ないので Ansible で自動化してみた。

GitHub - patrickjahns/ansible-role-promtail: 🔧 Ansible role for deploying promtail にあるフルセット状態のプレイブックも参考にしながら、自分用の最小限の設定だけに絞っている。

ディレクトリ構成

Ansible の Best Practice にも従いつつ必要なところだけ用意。

imksoo@ansible:~/playbooks$ find .
./roles
./roles/promtail
./roles/promtail/tasks
./roles/promtail/tasks/main.yml
./roles/promtail/handlers
./roles/promtail/handlers/main.yml
./roles/promtail/templates
./roles/promtail/templates/rsyslog-promtail.conf.j2
./roles/promtail/templates/promtail.service.j2
./roles/promtail/templates/promtail-config.yaml.j2
./roles/promtail/templates/etc-default-promtail.j2
./hosts
./site.yml

Tasks 定義

roles/promtail/tasks/main.yml
- name: Create directories
  file:
    path: "{{ item }}"
    state: directory
    owner: root
    group: root
    recurse: yes
  with_items:
    - "/opt/promtail"
    - "/opt/promtail/bin"
    - "/opt/promtail/conf"

- name: Install Unzip package
  apt:
    pkg:
      - unzip

- name: Download Promtail module
  get_url:
    url: https://github.com/grafana/loki/releases/download/v2.6.1/promtail-linux-amd64.zip
    dest: "/tmp/promtail-linux-amd64.zip"

- name: Unzip promtail binary
  unarchive:
    src: "/tmp/promtail-linux-amd64.zip"
    dest: "/opt/promtail/bin"
    remote_src: yes

- name: Create symlink to binary
  file:
    src: /opt/promtail/bin/promtail-linux-amd64
    dest: /opt/promtail/bin/promtail
    state: link

- name: write promtail vars
  template:
    src: etc-default-promtail.j2
    dest: /etc/default/promtail
  notify:
    - Restart Promtail

- name: write promtail config
  template:
    src: promtail-config.yaml.j2
    dest: /opt/promtail/conf/config.yaml
  notify:
    - Restart Promtail

- name: Write rsyslog config
  template:
    src: rsyslog-promtail.conf.j2
    dest: /etc/rsyslog.d/10-promtail.conf
  notify:
    - Restart rsyslog

- name: Write service unit file
  template:
    src: promtail.service.j2
    dest: /etc/systemd/system/promtail.service
  notify:
    - Restart Promtail

- name: Enable service
  service:
    name: promtail.service
    enabled: yes
    state: started

Templates 定義

rsyslog 経由でもメッセージを受け取るために送信先を追加している。

roles/promtail/templates/rsyslog-promtail.conf.j2
*.* @@(o)127.0.0.1:1514;RSYSLOG_SyslogProtocol23Format

Loki への接続用文字列はサービスの環境変数の中に押し込めてある。

roles/promtail/templates/etc-default-promtail.j2
LOKI_URL="https://318839:!!YOUR TOKEN!!@logs-prod3.grafana.net/loki/api/v1/push"

Systemd 経由で Promtail サービスを起動するためのユニットファイル。
/etc/default/promtail ファイルの中身を環境変数として読み取るようにしているのと、config.expand-env=trueオプションでコンフィグファイルの中で環境変数を展開する設定を追加している。

roles/promtail/templates/promtail.service.j2
[Unit]
Description=Promtail Agent

[Service]
EnvironmentFile=/etc/default/promtail
ExecStart=/opt/promtail/bin/promtail -config.file=/opt/promtail/conf/config.yaml -config.expand-env=true

[Install]
WantedBy=multi-user.target

Promtail のコンフィグファイル。
LOKI_URL 環境変数を使って送信先を選べるようにしている。

roles/promtail/templates/promtail-config.yaml.j2
server:
  http_listen_port: 0
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

client:
  url: ${LOKI_URL}

scrape_configs:
- job_name: journal
  journal:
    path: /var/log/journal
    labels:
      job: "journal"
  relabel_configs:
    - source_labels: [__journal_systemd_unit]
      regex: ^session-\d+.scope$
      action: drop
    - source_labels: ['__journal_priority_keyword']
      target_label: 'level'
    - source_labels: ['__journal__hostname']
      target_label: 'host'
    - source_labels: ['__journal__systemd_unit']
      target_label: 'unit'
- job_name: syslog
  syslog:
    listen_address: 0.0.0.0:1514
    idle_timeout: 60s
    label_structured_data: yes
    labels:
      job: "syslog"
  relabel_configs:
    - source_labels: ['__syslog_message_hostname']
      target_label: 'host'

Handlers 定義

コンフィグファイルを更新したときに、サービスを再起動するための設定。

roles/promtail/handlers/main.yml
- name: Restart rsyslog
  become: true
  systemd:
    name: rsyslog.service
    state: restarted
    daemon_reload: true

- name: Restart Promtail
  become: true
  systemd:
    name: promtail.service
    state: restarted
    daemon_reload: true

全体設定

site.yml
- hosts: all
  become: true
  roles:
    - promtail
hosts
[ansible]
192.168.1.199

[k8smaster]
192.168.1.111

実行例

$ ansible-playbook -i hosts site.yml -K

Discussion