二度忘れた事を三度忘れないようにする

しがないフリーランスIT系エンジニア

Lambda + GolangでEC2インスタンス起動時にRoute53へレコード登録する

github.com

ありそうでそれっぽいものがなかったので、なら作ろう、ということで勉強中のGolangを使い、こちらの記事を参考にGolangでEC2インスタンスが起動したらRoute53へレコード登録するモノを作ったので、その際にハマったポイントをメモ。

CloudWatch eventsを使ってEC2起動時にTagチェックをし必須TagがなければTerminateするLambdaサンプル - Qiita

最重要事項:ドキュメントをよく読む。

Lambda 関数ハンドラ (Go) - AWS Lambda

今回はCloudWatchEventを使ってLambdaをキックするだけ。流れは、

  1. CloudWatchEventでキックされたLambdaは例にしたがってlambda.startする
  2. lambda.startで指定したハンドラの第2引数はgithub.com/aws/aws-lambda-go/eventsのCloudWatchEvent
  3. CloudWatchEventからインスタンスの情報を取得
  4. 3で取得した情報を基にRoute53へレコード登録

と簡単なモノ。既にレコードがある場合はエラーになります。更新とか出来るけど、意図せず変わってしまうのも危険なので割り切って新規登録だけに。

真っ先に参考にさせてもらったサイト。

AWS LambdaにGoサポートが入ったので使ってみた | ブログ :: Web notes.log


流れの2では第2引数でCloudWatchEventが取れるということすらわからず1、2時間さまよった結果どこかで見たのだけど、メモするのを忘れた。。。

func Handler(ctx context.Context, event events.CloudWatchEvent) () {
...
}

とりあえず色々なイベントがあらかじめ定義されていて引数に取れるようです。参考サイトの情報から、もしかしたら、という予想でやってみたらうまく行った、という流れの可能性もあったかもしれないけど、どこか参考ページと思われるところがあれば紹介してもらえると助かります。


流れの3ではこちらの記事を参考にインスタンスの情報を取ることに成功。

AWS SDK for Go でEC2インスタンス情報取得 - Qiita

コピペしただけでは意味がないのでドキュメントも読み、理解を深める。ただ、2でインスタンスのIDが取れているので、全インスタンスの情報を取得するのはよろしくない、ということでインスタンスIDを基に情報を取得した。(絞り込み出来てるはず・・・

ec2 - Amazon Web Services - Go SDK


流れの4はひたすらドキュメントを読み解き、最終的にドキュメントにサンプルコードがあり、それを参考にすることでレコード登録が出来た。

route53 - Amazon Web Services - Go SDK

Readmeとか英語にしないと!と思ったけど意味通じなくなるので、開き直って日本語で書きました。

はてなブログの投稿をTwitter連携した

はてなブログのアカウント設定から外部アカウント連携しただけで、その投稿テストなので内容は無い!

ちなみに、予約投稿でないとTwitterに投稿ツイートしてくれないのね。。。

AmazonLinuxでRailsを動かす(2018年4月版)

毎回nokogiriにしてやられるのでメモ。不要なものもありそうだけど、とりあえず。あと、ちょっとバージョン変わったり、ubuntuとかAmazonLinux2、CentOS7等の別Linuxでも似たようなモノ入れれば大体いけるはず。

今回使ったモノ

$ yum install -y ruby24 ruby24-devel mysql57-devel gcc-c++ glibc-headers libyaml-devel zlib-devel libxml2-devel libxslt-devel
$ alternatives --config ruby # ruby2.4に切り替え
$ gem install --no-ri --no-doc nokogiri -- --use-system-libraries
$ gem install --no-ri --no-doc rails
$ rails new test-project -d mysql -B
$ cd test-project
$ vi Gemfile
   追記> gem 'json'
   追記> gem 'mini_racer'
$ bundle install
$ rails s

これでほぼバニラ状態であれば動くはず。DBは好きなモノに変えちゃって良い。 mini_racerの代わりにnode入れてもいいし、そもそもそのへん使わないという場合はコメントアウトしてしまおう。

API-Gatewayのリクエスト検証をServerlessで設定する

Webコンソールからはぺろっと出来る設定ですが、Serverlessで設定しようとしたところ、あんまり情報がなかったのでメモ。

Webコンソールにある2つのチェックルールはデフォルトでは定義されておらず、aws cliで確認しても情報は出てこない。
一度選択して設定してやると新規で定義されてaws cliでも出て来るようになる。なので、Serverlessではチェックルールを定義するところからしてやる必要がある。
あとあるあるパターンで英語のAWSドキュメントじゃないとMethodに与えるプロパティ「RequestValidatorId」が載ってなくてハマってた。

resources:
  Resources:
     TekiTouVal:
       Type: AWS::ApiGateway::RequestValidator
       Properties:
         Name: TekiTouValidator
         RestApiId:
           Ref: ApiGatewayRestApi
         ValidateRequestParameters: true
     TekitouMethod:
       Type: AWS::ApiGateway::Method
        略
        RequestValidatorId:
          Ref: TekiTouVal
        略

参考

AWS::ApiGateway::RequestValidator - AWS CloudFormation

Docker + Rancher + Portainer 開発環境構築編

前回で初期設定が完了したので、それっぽい開発環境を作っていきます。
Docker + Rancher + Portainer 導入〜初期設定編 - 二度忘れた事を三度忘れないようにする

1.Rancherにアクセスし「Add Stack」を押してStackを作成する。 (今回はデフォルトの環境を利用
f:id:knhko:20170730165608p:plain
ここで、オプションで普段利用しているdocker composeファイルを指定したり、Rancher用のcomposerファイルを作成して指定することが出来ます。

2.作成したStackに「Add Service」を押してServiceを登録する。
f:id:knhko:20170730171126p:plain
1つ目のブロックでコンテナをいくつ起動するかをここで設定できますが、今回は開発用なので1つにします。
Side Kick Containerというものがありますが、今回は利用しません。というか詳細を理解出来てません。。。恐らくメインとなるサービスに対して依存関係のあるモノ(DB等)を関連付けて一緒に動かすモノだと思うのですが。。。
2つ目のブロックでサービスの名前、説明、利用イメージを指定します。「Port Map」でホストOSで待ち受けるポートとコンテナで待ち受けるポートのマッピングを行えます。「Service Links」は既に作成しているサービスにアクセスする際はここで指定します。

f:id:knhko:20170730173816p:plain
次にDockerの詳細設定が出来るので必要に応じて入力します。コンソールの種類もココで設定出来るので、開発では便利なオプション「-i -t」を指定します。

f:id:knhko:20170730180700p:plain
Volumesタブの「Volumes」でホストOSのディレクトリをコンテナから参照出来る様にします。例のとおり「ホストのボリュームまたはディレクトリパス:コンテナのマウントポイント:権限」という順番で記述します。

他にもIPアドレスドメイン、セキュリティ、CPU・メモリリソースのリミット等をGUIで簡単に設定できます。
なお、通常のdockerコマンドと同様にコンテナを作成するとコンテナ数、名前、ServiceLinksしか変更出来なくなります。

3.起動したコンテナの整備をする。
色々な手法で構築済みコンテナを準備出来ます。今回はRancherのWebコンソールを使ってnginxとphp-fpmを入れました。
f:id:knhko:20170730191200p:plain

4.同様の手順でMySQLのコンテナを準備する。
明示的に設定していなければ同じStack内のサービスであればServiceLinkすることなく疎通可能なはず。。。設定しておくとStackトップページでLink図が綺麗になるくらい、なはず。。。

5.LBを作成する。 Stackトップページの「Add Service」右にある記号をクリックすると、Service以外も作成出来るので、LBを作成します。
f:id:knhko:20170730192606p:plain
ぱっと見ただけでもAWSのELB/ALBと同等からそれ以上のLBを導入出来るのがわかりますね。
1つ目のブロックはLBもコンテナベースで動くようなのでサービス同様コンテナの数を指定出来ます。
2つ目のブロックはLBの振り分けルールを一括で設定する箇所になります。

Access - Dockerクラスタ外部から通信を受け付ける場合はPublic、それ以外はInternalで良いはず。
Protocol - HTTP/S,SNI,TCP,TLSと幅広く対応しており、選択プロトコルによって以降の選択項目が変化します。今回はHTTP/Sで進めます。
Request Host - ドメインレベルの分散ルールが書けるのです。AWSにはない地味だけど便利な機能です。これを使うとローカル開発環境ではすごく助かったりします。
Port, Path - 待ち受けポートとリクエストパスで、この辺はAWSのソレと変わりないかと思います。
Service - 分散先をService単位で設定します。AWSでいうTargetGroupかな。
Port - Serviceで待ち受けているポートを指定します。これは各コンテナで待ち受けているポートで良いのでWebサーバであれば80,443となります。
※Selector Ruleは未検証なのでどういったものか詳しい方教えてください。。。

3つ目のブロックでSSLやStickyの設定、haproxyのコンフィグを直接書くといったことが出来ます。

6.完成。のはず

以上、アプリ周りは端折りましたが、ローカル開発環境レベルであれば実用に耐えられるかと思います。

GrafanaでMySQLのSlowQueryログを表示する

別途綺麗にまとめる予定なのでメモ。

AWSのRDSを利用していたり、MySQLのSlowLogをテーブルに保存している場合、ブラウザ経由で手軽に見られるようにする。
別記事で書く予定だが、今回はGrafanaを使って実現する。

1.DataSourceでMySQLを登録。Databaseを指定するところがあるので、mysqlを登録する。
2.ダッシュボードにテーブルタイプのパネルを追加する。
3.MetricsのDataSourceをMySQLにすると、SQL文を直書き出来るので、次にようなSQL文を記述。
select start_time, query_time, CAST(sql_text AS CHAR(200) CHARACTER SET utf8) AS sql_text from slow_log
4.Column Stylesでstart_timeカラムのDateFormatを定義すると綺麗になる。

ミソはmediumtext型のカラムをCASTしてやるところ。そのまま表示させようとするとBLOB型と判別されてエラーとなる。

Docker + Rancher + Portainer 導入〜初期設定編

Dockerを使って開発環境を構築する機会があり、Dockerのバージョンもそうだけど折角なので新しいモノを利用して構築した際のメモ。
※Rancherの勉強会を見つけたけど既に満員だった。。。

利用バージョン
CentOS
・Docker v1.12.06
・Rancher v1.6.2
・Portainer v1.13.4

この記事が参考になるケース
・開発者のインフラスキルが乏しいチーム
・遠隔地に開発用サーバがあり、そこに各個人の環境を準備する必要があるチーム

1.Dockerのインストー
以前使っていたバージョンより大分新しくなっていたので、特に気にせずyum install

$ yum install docker nginx
$ service docker start または systemctl start docker

2.Rancherの導入
Quick Start Guide に従ってRancherコンテナを導入。

$ docker run -d --restart=unless-stopped -p 8080:8080 rancher/server:stable

3.Portainerの導入
PortainerもホストOSに入れて動かす、というタイプではなくそれすらもコンテナで動かすスタイルのようなので、郷(マニュアル)に従う。

$ docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer

4.nginxの設定
同一LANにDockerホストがあるとあまり気にすることはないが、企業等では遠隔地にあったりポート制限により通信が通らない事が多いので、nginxでリバプロすることで快適なアクセスを実現。

# 例
upstream rancher {
    server localhost:8080;
}

map $http_upgrade $connection_upgrade {
    default Upgrade;
    ''      close;
}

server {
    listen 80;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://rancher;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_read_timeout 900s;
    }
}

5.Rancher初期設定(とりあえず版)
オーケストレーションツールをオリジナル、k8s、Swarmと選べるようですが、今回は一番GUI的に力の入っているオリジナルのものを利用。本番で使う場合は考慮する必要があると思いますが、k8sもSwarmも勉強不足ということもありつつ、LBの設定が個人的に気に入っているのもあります。

ブラウザでアクセスすると初期画面になるのでナビゲーションにある「Add a Host」をクリックして管理対象のDockerホストを登録する。
f:id:knhko:20170717135822p:plain

Rancherへ接続するためのIPまたはドメインを設定する。
f:id:knhko:20170717141507p:plain

今回はDockerを登録するのでカスタムを選択して手順に沿って進めていき、Rancherに登録するDockerホストのIPを入力すると、一番下にコピペ用のコマンドが出来上がるので、対象Dockerホストにコピペ実行。
f:id:knhko:20170717143726p:plain

1分程で登録が完了するのでページ上部のメニュー「infrastructure」→「hosts」を選択すると先ほどのDockerホストが表示されて、色々なコンテナが動いて入ればOK。
f:id:knhko:20170717144751p:plain

とりあえずRancherの初期設定は以上。簡単ですね。

6.Portainerへ接続
初回はパスワード設定を求められるので設定してログイン。
f:id:knhko:20170717150528p:plain

初回ログイン時に管理対象を登録する画面が出て、ローカルを対象とする場合は上、リモートを対象とする場合は下にチェックを入れる。
f:id:knhko:20170717182429p:plain

管理対象と通信が出来ればダッシュボードが表示され、既にコンテナやRancherを導入していれば画像の様に色々動いている事がわかる。
f:id:knhko:20170717183443p:plain

以上で導入からとりあえず動くところまでが完了かな。