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

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

【Rundeck】入門する

f:id:ryuichi1208:20210721234436p:plain

背景

Rundeckを使う機会というか調べる機会があったので記事としてまとめる。Jenkinsのジョブ機能の対抗馬として前に調べたことある程度でがっつり使ったことはない。

OSSのジョブスケジューラなのでGitHubでソースが読める。現在もめちゃめちゃ草が生えてて開発は活発な印象。最新版は6日前にリリースされていたりする。(3.4.1-20210715になっているがバージョニングに日付が入るのか)

github.com

一応無償版と有償版というのがあって今回対象にしてるのは無償版の話です。有償のエンタープライズ版の「Rundeck Enterprise」ではサポート体制に加えてパラレル実行とかリアルタイム可視化やユーザーインターフェイスの改良など機能面でも差があるらしいです。

www.rundeck.com

最新は3系っぽいので3系だけとりあえずみていく。

docs.rundeck.com

Rundeckとは

Webアプリ上で操作できるJava製のスケジューラ。

特徴としては以下。いろいろなブログ見た感じの羅列だけど他にもたくさん機能はあるっぽい。エージェントレスSSH接続できればジョブを実行できるのも特徴の一つ。

* 処理の実行ログが保存されリアルタイムで閲覧できる
* 処理の実行履歴を閲覧できる
* 直近の実行予定時刻がわかる
* 処理の再実行
* 処理の開始・終了に対して通知設定できる

ジョブAが正常に終わらないとジョブBを実行したくないと言った所謂、依存関係を設定できたりとジョブスケジューラとしての機能は思いつく限りは実装されていそうでした。cronと全く同じ記述が可能だったりと学習コストが低そうという印象も持ちました。

www.slideshare.net

Jenkinsとの比較

Jenkinsは4年くらい利用経験があるがRundeckは数十分触った程度での比較です。

Jenkinsは継続的インテグレーションツールであって、ジョブ管理ツールではないと言った意見はちらほら見られるがJenkins自体をリッチなcronくらいで長く使っていたためその手の視点で何か見えることはなかった。依存関係を書けたりシェルスクリプトで書けば複数サーバで実行を制御したりすることもできた。ただシェルスクリプトで若干メンテナンスがしづらい点もあった。その辺はうまくRundeckが吸収して

  • どのサーバで動いているか
  • 同一時刻にどんな処理が動いてるか
  • どのジョブとどのジョブが関連しているか

あたりは綺麗に書けそうかなと言った印象を持った。(実際やったことないからあくまでも感想)。あとはJenkinsだとpluginとか管理が大変な印象もあったりしたがRundeckはデフォルトで結構機能があってメンテ自体は楽そうな感じもしました。

使ってみる

hub.docker.com

$ docker run -p 4440:4440 -e SERVER_URL=http://localhost:4440 --name rundeck -t jordan/rundeck:latest

とかやってlocalhost:4440に繋げば使える。第一印象としてはすごい直感的でわかりやすいと言った感じ。

strategyとか

docs.rundeck.com

ワークフローの実行は、ステップの失敗の処理をstragegyとかで処理することができる。ジョブが失敗した場合に何かしらの処理を入れるだったり先へ進めて復旧処理を書くなりとと言ったことができる。

【HAProxy】入門する

f:id:ryuichi1208:20210720195534p:plain

背景

HAProxyに触れる機会が出てきそうなので調べたメモ的な記事。業務で使ってたことはあるけど実は要件書通りのパラメータで構築してそれっぽいテストしただけで実はどんな機能があってどのような特徴があるとかは何も分かってないレベル。要件定義とかも見てすらないので何もわからなんので復習も兼ねて書いた。

(ちなみによくわからないけど2年くらい運用してトラブル起きたこと1回くらいしかないからソフトウェア的にはすごく安定してそう(小並感))

HAProxyとは

多機能なプロキシサーバです。ソフトウェアロードバランサの一種。(L4だけかと思ってたけど全然違うらしいというのを初めて知った。)高パフォーマンスと安定性のあるTCP通信やHTTP通信の負荷分散や、Proxyサーバ機能が有名。C言語で実装されている。比較対象ってなるとLVSとかNginxのplus版とかになるんでしょうか。

github.com

haproxy + keepalived で構成することにより、冗長化構成のロードバランサーとして機能する。最新版は2021年5月14日:HAProxy2.4.0とのことで最近でも開発が続いているのが伺える。

HAProxyの機能

ja.wikipedia.org

↑あたりから抜粋。単純な負荷分散だけでなくSSLの終端やらgRPCサポートとかサーキットブレーカの役目もこなすらしい。

* Layer 4(TCP)およびLayer 7(HTTP)でのロードバランス
* URLのrewrite
* レート制限
* SSL/TLS termination
* Gzip圧縮
* Proxy Protocolのサポート
* ヘルスチェック
* コネクションとHTTPメッセージのログ
* HTTP/2
* Hitless Reloads
* gRPCのサポート
* LuaおよびSPOEのサポート
* APIのサポート
* Layer 4でのリトライ
* 簡易的なサーキットブレーカー

MySQLとかRedisの手前においてL4のリトライをここでやってもらうみたいなのもありなのかなーとか考えたりしました。オンプレでやるならDBへの接続過多とかで過負荷になるみたいなのを防ぐとかもありなのかなぁと。

スケジューリングアルゴリズム

対応しているのは下記。/etc/haproxy/haproxy.cfg辺りのファイルのbackend セクションにある balance パラメーターで編集できるとのこと。RDP Cookieだけ不思議な機能でTCPレイヤでも動作しそうな感じだけどどういう仕組みなのかはよくわからなかった。

* Round-Robin
* 静的ラウンドロビン
* 最小接続 
* ソース
* URI
* URL パラメーター
* ヘッダー名
* RDP Cookie

詳しい設定例は以下に載っていた。server_timeoutとかmaxconとかの数値はチューニング可能な数値となっている。

access.redhat.com

docs.aws.amazon.com

configファイル自体はこんな感じで書いていく

HAProxy全体に関連する設定を記述する
global
  <設定項目1> <設定値1>
  <設定項目2> <設定値2>

各セクションにおけるパラメータのデフォルト値を記述する
defaults
  <設定項目1> <設定値1>
  <設定項目2> <設定値2>

プロクシの動作に関連する設定
<listen/frontend/backendセクション1> <名前>
  <設定項目1> <設定値1>
  <設定項目2> <設定値2>

イベント駆動型モデルの話

HAProxyでもNginxとかNode.jsで使われているようなイベント駆動型のモデルで作られているらしい。preforkとかでやるとどうしてもc10k問題とかが絡んでくるためだと思われる。マルチスレッドを使用したCPUのコアを活かした上げ方も可能らしい。

www.haproxy.com

性能の話だと最近書かれている記事で2 Million HTTP Requests per Secondとか言っている。桁が違いすぎてよくわからない。言及している内容がL2キャッシュとかL3キャッシュとかCPUとかの低レイヤの話であったりIRQアフィニティが出てきたりと知見が全然ないのでなんかすごいしかわからない。

www.haproxy.com

イベント駆動あたりはソースを眺める限りはシステムコール呼び出ししている感じだったのでエンジンごと独自実装になっていそう。

github.com

【Consul】ノードへのmeta_data付与

www.consul.io

Consul 0.7.3以降で利用可能な機能らしい。任意のメタデータのキーと値のペアをローカルノードに関連付けることができ、特定のカタログエンドポイントからの結果をフィルタリングするために使用したりできる。以下は公式にあるサンプル。

{
  "node_meta": {
    "instance_type": "t2.medium"
  }
}

任意のkey,valueを付けれるのでcurl --get <path> --data-urlencode 'filter="<filter expression>"'みたいにやっていくことでノードを絞り込んで特定ができる。jq芸とかやらなくても良くなるので便利そう。

【Ruby】Gemfile入門

背景

ruby経験0だけどbundlerとか打って環境構築した気になってるの良くない気がしたので調べてまとめてみた記事。gemってなんやねんって状態だけど雰囲気で実行しているマンです。

gemってなんだ

Rubyのライブラリのこと

www.ruby-lang.org

Ruby のライブラリは主に RubyGems.org に gem として置かれている。cpanとかpipとかその手のイメージで良さそう。gem search -rとかでライブラリを探したりすることもできる。Rubyのパッケージとしてのgemとパッケージ管理システムとしてのgemがあるらしくその辺はコンテキストから察するしかないみたい。

ちなみにRubyGemsを使ってgemを管理する機会は少なく、「bundler」というパッケージ管理ツールを使うのが主流らしい。perlでいうcpan使わないでcartonとかcpanm使うとかそのイメージでしょうか。

Gemfileって?

Bundler用の設定ファイル。BundlerはGemfileの記述にしたがって、gemの依存関係を示したGemfile.lockを生成する。これだけでも他の言語にもある仕組みだしなんとなく分かるけど細かく追ってみる。ちなみにbundler自体もgemの一種らしい。(gem install bundlerとかしないと使えない)

rubygems.org

bundlerって?

『bundler』は依存関係にあるgemの依存関係やバージョンを管理してくれるgem。依存関係にあるgemもあわせてインストールする必要があったりする場合によしなにやってくれるやつ。

Usage

bundler --help
Bundler commands:
  bundler add GEM VERSION         # Add gem to Gemfile and run bundle install
  bundler binstubs GEM [OPTIONS]  # Install the binstubs of the listed gem
  bundler check [OPTIONS]         # Checks if the dependencies listed in Gemfile are satisfied by currently installed gems
  bundler config NAME [VALUE]     # Retrieve or set a configuration value
  bundler console [GROUP]         # Opens an IRB session with the bundle pre-loaded
  bundler doctor [OPTIONS]        # Checks the bundle for common problems
  bundler env                     # Print information about the environment Bundler is running under
  bundler exec [OPTIONS]          # Run the command in context of the bundle
  bundler gem NAME [OPTIONS]      # Creates a skeleton for creating a rubygem
  bundler help [COMMAND]          # Describe available commands or one specific command
  bundler info GEM [OPTIONS]      # Show information for the given gem
  bundler init [OPTIONS]          # Generates a Gemfile into the current working directory
  bundler install [OPTIONS]       # Install the current environment to the system
  bundler issue                   # Learn how to report an issue in Bundler
  bundler licenses                # Prints the license of all gems in the bundle
  bundler lock                    # Creates a lockfile without installing
  bundler open GEM                # Opens the source directory of the given bundled gem
  bundler outdated GEM [OPTIONS]  # List installed gems with newer versions available
  bundler package [OPTIONS]       # Locks and then caches all of the gems into vendor/cache
  bundler platform [OPTIONS]      # Displays platform compatibility information
  bundler plugin                  # Manage the bundler plugins
  bundler plugin help [COMMAND]   # Describe subcommands or one specific subcommand
  bundler plugin install PLUGINS  # Install the plugin from the source
  bundler pristine [GEMS...]      # Restores installed gems to pristine condition
  bundler remove [GEM [GEM ...]]  # Removes gems from the Gemfile
  bundler show GEM [OPTIONS]      # Shows all gems that are part of the bundle, or the path to a given gem
  bundler update [OPTIONS]        # Update the current environment
  bundler version                 # Prints the bundler's version information

Options:
      [--no-color]                 # Disable colorization in output
  -r, [--retry=NUM]                # Specify the number of times you wish to attempt network commands
  -V, [--verbose], [--no-verbose]  # Enable verbose output mode

checkでGemfile内の依存性を現在インストールされているGemが満たしているか確認したり、

Gemfile入門

バージョン管理の基本

バージョン管理
Bundlerはただのgemインストーラではなくバージョン管理ツール*5なので、このgemコマンドは第2引数にバージョンを取れる。

gem "rails"                 # 最新版を入れる
gem "rails", "3.0.0"   # 3.0.0で固定
gem "rails",  ">=3.0" # 3.0以降のバージョンに制限
gem "rails",  "~>1.1"  # 3.0以降4.0以前のバージョンに制限

他言語にないようなやつだと以下みたいな書き方。「3.5.2 以上,3.6.0 未満」という意味の指定になるらしい。MINORバージョンまで指定しているときは同じMAJORバージョンの中で最新の物を扱うのは確かに便利。

gem "hoge", "~> 3.5.2"

特定ブランチを使いたいとか,ローカルでちょっと変更して試したいときのGemfileの変更方法を以下に記載。

source

下記のように、:sourceオプションを利用してgemを検索してくるサイトを指定することもできる。

gem "some_internal_gem", :source => "https://gems.example.com"

git

github上のものを使う場合は以下。sshとかで認証をしておけばprivateリポジトリとかGHE上のものとかもこうやって書ける。

git "https://github.com/rails/rails.git" do
  gem "test1"
  gem "test2"
end

satoryu.hatenablog.com

group

groupコマンドではgemをインストールする環境を指定できる。

group :development, :test do
  gem "rspec-rails"
  gem "cucumber"
end

bundle install --without testみたいに実行することでproductionなら使わないgemを除いて環境セットアップとかが可能になる。

ローカルにあるgem

閉じたネットワークなのか古のモジュールを自分で管理してるのかみたいなケースで使えそう。

gem 'hogeee', :path => '/Users/hogeee'

Gemfile.lockとは

Gemfile.lockには依存関係にあるgemも含め、bundlerによってインストールされた全てのgemとそのgemのバージョンが記載される。lockファイルと現環境に差分があるみたいなのはどの言語でもあるあるな話なんですかね記事がありました。

qiita.com

--path vendor/bundleを付ける必要性は本当にあるのかの話

qiita.com

これ読んで面白いなーと思った。pythonならvenvは必須で使っていたけど言われてみると確かにという思いが出てきた。システムにコマンドを提供する系のgemを入れなきゃいけないケースとか以外はなるべく付けない方が良さそうなんだろうな。

Gemfile.lockをコミットするのか

stackoverflow.com