地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【Ruby】Capistranoを使ってみる

github.com

背景

Capistranoってなんやねんレベルでコマンドだけ打って便利さを感じつつも何も理解してなかったので調べた際のメモ。「JenkinsとかGitHub Actionsででシェルスクリプトでデプロイじゃー!」ぐらいしかやったことレベル感で書いてます。(jenkinsだとDSLあった気がするけど使ったことない)

capistranorb.com

Capistranoとは

Capistranoは、デプロイスクリプトを使用してアプリケーションをデプロイするためのツール。デプロイを実行するには、事前定義されたタスクを使用するか、カスタム Rake タスクを準備する必要がある。複数のサーバー上でスクリプトを実行するためのオープンソースのツールでありイメージ的には「大量にsshしてサーバ上でなんかする」みたいなことをタスクとして定義しておいて使いまわせるよねってイメージ。

ja.wikipedia.org

wikipediaも存在していた。ただのssh便利ツールではなさそうという印象を持った。

Capistranoはおおまかに以下の3要素から構成されています。

  • capコマンド
  • Capistranoのライブラリ
  • デフォルトのデプロイタスク

Capistranoのライブラリやデフォルトのタスクを利用して設定ファイルを記述して、それをcapコマンドで実行する。そうするとCapistranoがもろもろの操作を自動的に行なってくれるという仕組み。

使ってみる

ざっくりとした流れは以下の感じです。事前にrubyでの開発環境のセットアップが前提となっている点がちょっと注意が必要ですね。

  • Capistranoのインストール
  • 設定ファイルのひな形をつくる
  • 設定ファイルのカスタマイズ
  • capコマンドを実行する

ここから下が具体的な手順となる。

source 'https://rubygems.org'
gem 'capistrano', '~> 3.16.0'

bundlerを使ってインストールする

$ bundle install --path vendor/bundle
$ bundle exec cap install

実行することで以下のようにCapfile(capistrano設定ファイル)が生成されます。全体の設定ファイルはconfig配下に生成されます。

require "capistrano/setup"
require "capistrano/deploy"

require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git

# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }

config/deploy.rbが全体の設定ファイル。(Capistranoにはデフォルトで「deploy」というタスクと、それが呼び出す複数の「deploy:サブタスク」が定義される)。Capistranoデフォルトの枠組みの中でデプロイを行う場合は、「deploy:サブタスク」を再定義するだけでよいので便利

# config valid for current version and patch releases of Capistrano
lock "~> 3.16.0"

set :application, "my_app_name"
set :repo_url, "git@example.com:me/my_repo.git"

# Default branch is :master
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp

# Default deploy_to directory is /var/www/my_app_name
# set :deploy_to, "/var/www/my_app_name"

# Default value for :format is :airbrussh.
# set :format, :airbrussh

# You can configure the Airbrussh format using :format_options.
# These are the defaults.
# set :format_options, command_output: true, log_file: "log/capistrano.log", color: :auto, truncate: :auto

# Default value for :pty is false
# set :pty, true

# Default value for :linked_files is []
# append :linked_files, "config/database.yml"

# Default value for linked_dirs is []
# append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system"

# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }

# Default value for local_user is ENV['USER']
# set :local_user, -> { `git config user.name`.chomp }

# Default value for keep_releases is 5
# set :keep_releases, 5

# Uncomment the following to require manually verifying the host key before first deploy.
# set :ssh_options, verify_host_key: :secure
  • config/deploy/任意のステージ名.rb

任意のステージ名.rb」は本番環境・テスト環境・開発環境などの環境ごとに異なる設定やタスクを書きます。これは実行時に指定しておくことでステージ毎に実行したいソースを指定することができるといった仕組みです。

実行

$ bundle exec cap [production|staging] deploy

とかやることで定義されているタスクを実行することができます。

ssh keyのforwarding設定

git cloneするための秘密鍵を、デプロイ先のサーバーに設置せず、capistranoサーバーに設置してforwardingする方法。鍵を作成する手順は以下です。(結構忘れがちなやつで最近ハマりました。。)

$ ssh-keygen -t rsa

この鍵の公開鍵をGitに登録する。また、capistranoサーバーの~/.ssh/秘密鍵を設置する。capistranoを打つサーバーでssh-addする必要があります。

$ eval `ssh-agent`
$ ssh-add ~/.ssh/id_rsa

並列実行

Parallel execution
Deploying to a fleet of app servers? Capistrano can run each deployment task concurrently across those servers and uses connection pooling for speed.

並列実行もサポートしているらしい。

感想

今回書いた内容だと正直シェルスクリプトの方が簡単でメンテもしやすそうなレベル感でしたが例えば巨大なリポジトリで複雑な構成なんかになってくるとシェルスクリプトだけでメンテナンスしてくのは困難になります。そういった時にCapistranoを知っている人同士であれば、他人の書いたデプロイ設定も読みやすく、結果的に保守や引き継ぎがしやすくなりするのかなと思いました。

また再利用の観点だったりrubyのパッケージとして配置するみたいな使い方もできるのでプロジェクトを横断したデプロイが行えるのは良いなと感じました。(新メンバーの参画でデプロイスクリプトの開発環境整えるのが大変などの問題がありますがそういうのが解決されそう。)

【Consul】入門する

背景/概要

Consulを使う機会が出てきたのでメモ。「Prometheusから利用できそうだね」くらいを理解のゴールとして設ける。

この記事でやれることはconsulの入門とdnsでサーバのIPを引けるようになるまで。dnsは別で立ててますが閉じた検証にしたいのでとりあえずdnsmasqを入れて代用してます。

Consulとは

www.consul.io

インフラ上のサービス設定とサービスディスカバリのためのツール。Consul自体は複数のコンポーネントがあるが全体としてサービスディスカバリのツールって認識で良さそう。

github.com

HashiCorpが公開していて実装言語はGolangとなっている。主な機能としては以下

ざっくりアーキテクチャは以下のような感じ。

f:id:ryuichi1208:20210717211528p:plain

(Hashicorp が提供しているデータセンタ管理ツール群 ATLAS の一部で、クラスタリングと分散KVS、オーケストレーションの基礎となる機能をいくつか提供してくれるとあるがメイン機能がどれなのかとても迷いそうなアーキテクチャ図だなと感じた。。)

公式のはこっち

f:id:ryuichi1208:20210718000602p:plain

サービス・ディスカバリってなんだっけ

サービス・ディスカバリ(Service Discovery)とは、日本語では「サービスの発見」や「検出」という意味あいで使われる。サービスディスカバリの機能はConsulを通してどのサーバでどのようなサービスが動作しているかやIPやポートをリアルタイムで知ることができる機能

Consulノードはサービス状況に変化が発生すると、「Consulサーバ」に対してデータを送信します。consulサーバは受け取ったデータとkvsに保存し情報を知りたい側のクライアントがhttpやcliを使ってサーバの検出を行います。

Consul が使うポート

機能 TCP/UDP ポート 説明
Server RPC TCP 8300|Server が他の Agent からRPCのリクエストを受け付ける
Serf LAN TCP & UDP 8301 LAN用のゴシッププロトコル。全 Agent 同士が使う
Serf WAN TCP & UDP 8302 WAN用のゴシッププロトコル。Server 同士が使う
CLI RPC TCP 8400 consulコマンド実行時にローカルの Agent との通信に使われる
HTTP API TCP 8500 Client が HTTP リクエストを受け付ける
DNS TCP & UDP 8600 Agent が DNSクエリを受け付ける

障害検知

Consul node がヘルスチェックを実施する、検出済みのサービスに対する障害発生を検出する。監視間隔や対象は、ノードが主体的に対象ホスト内部から監視

HTTP または DNS インターフェース、Web UI で確認できるといった仕組み。

qiita.com

ざっくり触る

スタンドアロン構成で動かしてみます。

install

公式に方法があるのでそのままやってみます。

www.consul.io

$ sudo yum install -y yum-utils
$ sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
$ sudo yum -y install consul

[root@master ~]# consul version
Consul v1.10.1
Revision db839f18b
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)

usage

多機能が売りというだけあってhelpだけでも盛りだくさん機能が伺えます。とりあえずagentぐらいが見れれば良さそう。

[root@master etc]# consul --help
Usage: consul [--version] [--help] <command> [<args>]

Available commands are:
    acl            Interact with Consul's ACLs
    agent          Runs a Consul agent
    catalog        Interact with the catalog
    config         Interact with Consul's Centralized Configurations
    connect        Interact with Consul Connect
    debug          Records a debugging archive for operators
    event          Fire a new event
    exec           Executes a command on Consul nodes
    force-leave    Forces a member of the cluster to enter the "left" state
    info           Provides debugging information for operators.
    intention      Interact with Connect service intentions
    join           Tell Consul agent to join cluster
    keygen         Generates a new encryption key
    keyring        Manages gossip layer encryption keys
    kv             Interact with the key-value store
    leave          Gracefully leaves the Consul cluster and shuts down
    lock           Execute a command holding a lock
    login          Login to Consul using an auth method
    logout         Destroy a Consul token created with login
    maint          Controls node or service maintenance mode
    members        Lists the members of a Consul cluster
    monitor        Stream logs from a Consul agent
    operator       Provides cluster-level tools for Consul operators
    reload         Triggers the agent to reload configuration files
    rtt            Estimates network round trip time between nodes
    services       Interact with services
    snapshot       Saves, restores and inspects snapshots of Consul server state
    tls            Builtin helpers for creating CAs and certificates
    validate       Validate config files/directories
    version        Prints the Consul version
    watch          Watch for changes in Consul

起動

bindとclientあたりはよしなに。(consul は基本ローカルアドレスからのアクセスしか受け付けませんのでその辺は注意)

$ consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul --bind 192.168.1.15 --client=0.0.0.0

これで準備は完了。consulコマンドでmembersやらを打つことで自信が参加していることを確認可能となります。サーバ側の準備ができたので次はクライアントをここへ参加させます。

$ consul agent -data-dir /tmp/consul -bind <IPアドレス> -join <ConsulサーバのIPアドレス>

正常に通信ができると、自動的にクラスタが構成されます。「consul members」コマンドを実行すると、次のように複数のホスト情報が確認できます。

[root@master ~]# consul members
Node    Address             Status  Type    Build   Protocol  DC   Segment
master  192.168.1.15:8301   alive   server  1.10.1  2         dc1  <all>
slave   192.168.1.207:8301  alive   client  1.10.1  2         dc1  <default>

httpでjsonを取ることとかもできる。APIとかアプリケーションからsdしたいケースだとこっちになるんでしょうか。

curl -s http://192.168.39.5:8500/v1/kv/hello/?recurse | jq '.'
[
  {
    "Value": "b3BlbiB0aGUgbmV4dA==",
    "Flags": 0,
    "Key": "hello/key2",
    "ModifyIndex": 16,
    "CreateIndex": 16
  },
  {
    "Value": "aGVsbG8sIHdvcmxkIQ==",
    "Flags": 0,
    "Key": "hello/key",
    "ModifyIndex": 14,
    "CreateIndex": 14
  }
]

dnsで引けるようにする

consulにはDNSクエリを受け付ける機能もあるので以下のようにメンバーを引くことができる。ただポート指定したりDNSサーバを指定したりと面倒なのでdnsmasqを導入することでそのような手間を解決することもできる。

$ dig @localhost -p 8600 master.node.consul

dnsmasqをセットアップする。resolve.confも自サーバを向くように修正しておく

$ yum -y install dnsmasq
$ echo  "server=/consul/127.0.0.1#8600" >> /etc/dnsmasq.conf
$ echo  "strict-order" >> /etc/dnsmasq.conf

このように設定しておけばdnsの指定をしなくてもdigで自宅内のサーバのIPを引けるようになる。

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;slave.node.consul.     IN  A

;; ANSWER SECTION:
slave.node.consul.  0   IN  A   192.168.1.207

;; ADDITIONAL SECTION:
slave.node.consul.  0   IN  TXT "consul-network-segment="

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: 土  7月 17 09:04:12 EDT 2021
;; MSG SIZE  rcvd: 98

サービスを使ってみる

サービスを使うことでサーバをグルーピングして死活監視などを行うことができます。prometheusとかで監視する際にはこの設定は必須になりそうなやつですね。以下のように監視対象のサーバにファイルを作成します。概要としてはchecksで書いた内容を監視しつつserviceに名前を登録するという感じです。適当に80でhttp通信を可能な状態にしておきます。

{
    "service": {
        "name": "web",
        "tags": [
            "rails"
        ],
        "port": 80,
        "check": {
            "args": [
                "curl",
                "localhost"
            ],
            "interval": "10s"
        }
    }
}

上記を設定した上で以下のようにconsulを起動します。"-config-dir", "-enable-script-checks"がポイントです。

consul agent -data-dir /tmp/consul -bind 192.168.1.207 -join 192.168.1.15 -config-dir /etc/consul.d -enable-script-checks=true

こんな感じで起動することでhttp:80の通信が可能なサーバは以下のようにdnsの名前引きで引くことが可能となります。このレコードを使うことで例えばLBのバックエンドを動的に決めたりすることが可能だったりprometheusとしてはwebというサービスでグルーピングして監視が可能になったりします。とても便利!

;; ANSWER SECTION:
web.service.consul. 0   IN  A   192.168.1.15
web.service.consul. 0   IN  A   192.168.1.207

KVS機能

kvs機能もconsulは持っている。これのユースケースとしてはconsulサーバにkvを登録しておけばconsulクライアント側がこの値をみにいく。ここの値に例えばミドルウェアとかで有効な値を設定しておくことでユーザが設定値をpostするとミドルウェアが動いているサーバがその値を元にサービスを再起動したりみたいなことが可能となる。

# post
$ curl -X PUT http://localhost:8500/v1/kv/$(hostname)/test -d "test_data"
true

# get(base64でエンコードされているのでデータをみるには以下の作業が必要)
$ curl -s http://localhost:8500/v1/kv/$(hostname)/test | jq .[].Value | tr -d '"' | base64 -d
test_data

メンテナンスを試す

バックエンドのサービスのうち1台だけをメンテモードにしてLBから切り離すみたいなことも可能。(LBを経由しないラウンドロビンをクライアントで実装してるみたいな場合はきちんとレコード以外を見るみたいなことを自分で実装する必要があるっぽいのでそこは注意。memd-perlとかそのあたりは怪しい。)

[root@master tmp]# consul maint

[root@master tmp]# dig web.service.consul
;; ANSWER SECTION:
web.service.consul. 0   IN  A   192.168.1.207
web.service.consul. 0   IN  A   192.168.1.15

# この状態でmasterサーバをメンテモードに入れてみると以下のようにレコードから削除される
[root@master tmp]# consul maint -enable
Node maintenance is now enabled

[root@master tmp]# dig web.service.consul
web.service.consul. 0   IN  A   192.168.1.207

感想/これから

とりあえずしばらくはお家のサーバには全て適用してみようかなと思います。DNSの登録とかが自動でされるのはとても便利ですね〜。sd機能があるのでprometheusからも簡単に監視が導入できそうなのでそれにいずれ挑戦しようと思います。

おまけ

consul-tempateとconsul-alertsという関連サービスもあったりする。

github.com

github.com

ざっくりcousul-templateにも触れてみる

ハンズオン

# 監視対象テンプレートファイルを作成する
$ cat nginx.ctmpl

{{ key "master/test" }}

# データをconsulへ投入する
$ curl -X PUT http://localhost:8500/v1/kv/test -d "test_data3"

# この状態でconsul-templateを起動する。
# -templateは"templateファイル":コピー先のパス: "コピー後に実行したいコマンド"
$ ./consul-template -consul-addr localhost:8500 -template "./nginx.ctmpl:/etc/test.conf:pwd"

この状態でkeyを更新したりすると自動的にファイルが更新され指定したコマンドが実行される。pwdにしてるが運用ケースとかだとgraceful restartとかになるんだと思う。こりゃ便利。

【Mackerel】入門する

f:id:ryuichi1208:20210722103653p:plain

背景

Mackerelに触れ始めたので概要だけでも入門。監視ツールはZabbixとPrometheusとElasticsearch(beats)を触ったことあるのとN社の出している独自OS用の監視ツールに触れていたという経験があると言った感じ。基本的なメトリクスというよりもMackrel独自の用語だったりツール(プラグインとかいってるやつ?)がどういうものなのかを調べていく。

テックカンファレンスでよくブース出してたりCM流れてたりするのでなんとなくは知っていたしデモを触ったことはあるので

Mackrelとは

ja.mackerel.io

株式会社はてなが提供しているサーバ管理・監視ツールで以下のような特徴を持つ。

* デフォルトで様々なメトリクスが取得されており、閾値を設定して監視することができる。(CPU,Network,Disk,Memory)
* プロセスやログ監視などはサーバー上の設定ファイルに設定を追加することでとても簡単に実現できる。
* プラグインを利用することでかなりの種類のミドルウェアのメトリクス可視化が可能

気になる料金だが以下のような感じ。

ja.mackerel.io

ホストの概念は以下でこの単位での課金となるとちょっとお高いと感じてしまった。特に重要じゃないサーバに関してはここまで無料で使えるOSSに移行したくなるんだろうなというのもちょっと分かる。

* mackerel-agentがインストールされた物理サーバーまたは仮想サーバー1台につき1スタンダードホスト
* VM系インテグレーション(AWS EC2, AzureVM) 1インスタンスにつき1スタンダードホスト
* ホストメトリック数が200を超える場合、200メトリックごとに1スタンダードホスト
* サービスメトリック数が200メトリックにつき1スタンダードホスト
* 外形監視数が20項目につき1スタンダードホスト

プラグイン

Mackerelはデフォルトで取れるメトリクス以外にもpluginを利用して独自の値を取ることも可能となっている。mkr plugin installコマンドでインストールできると書いてあり独自のプラグインマネージャ的なのがいる模様。

mackerel.io

バージョン管理とかもできるっぽいのでコードとかに起こせるような仕組みになっていそうですごいなと感じました。

# Usage: mkr plugin install [--prefix <prefix>] [--upgrade] [--overwrite] <install_target>

# Install mackerelio/mackerel-plugin-sample(v0.0.1 release) to /opt/mackerel-agent/plugins/bin
$ sudo mkr plugin install mackerelio/mackerel-plugin-sample@v0.0.1

# Install mackerel-plugin-sample(latest release) defined in plugin registry to /path/to/plugin_dir/bin
$ mkr plugin install --prefix /path/to/plugin_dir mackerel-plugin-sample

GItHubから取ってくることもできるらしくきちんと使用を満たしておけば例えば会社のGHEとかプライベートリポジトリとかにおいて自前で管理していくことも可能となっている。最小構成でいつか作ってみたい。

$ mkr plugin install <owner>/<repo>[@<release_tag>]

公式で出してるプラグインだけでも結構な種類がある模様。クラウドプロパイダー毎のプラグインに加えて有名なミドルウェアは網羅してそうなイメージ。公式でこれだけ持ってるのはすごいですねぇ。

github.com

【Terraform】入門する

f:id:ryuichi1208:20210718213156p:plain

www.terraform.io

背景となぜ書いたのか

仕事で遂にTerraformを使う機会ができたのでこの気に学び直してみた記事。これまでAnsibleを使っての構成管理を行なった経験はあるがよりレイヤの低い部分の管理はGUIなりでやってきた経験しかないので結構新鮮に学んでみました。

記事概要

ざっくりTerraformがなんなのかとか基本情報とかをざっくり書いてます。込み入ったテクニックとかはこの記事ではなく別記事に書いていきたいという思いがあったりします。

Terraform概要

github.com

TerraformとはIaCを実現するツール。Terraformはオープンソースであり、HashiCorpによってGo言語で開発されている。具体的にはTerraformではインフラの構成をコードで宣言します。構造化された構成ファイルでは、手動で操作することなくインフラ構成を自動で管理できます。インフラの初期プロビジョニング、更新、破棄、いずれもTerraformではコードにより宣言し、実行します。

Terraformは、いわゆる宣言型の方法を採用しており、インフラの望ましい状態を構成ファイルで宣言します。Terraformは、インフラの望ましい状態を達成するために最小限のことだけを行います。

単語集

主要コンポーネント

ハンズオン

感想

参考リンク