ElixirライブラリをHexに公開してみた② Paidy編
Elixirのライブラリ公開シリーズ第2弾
Paidyとは
事前登録不要・クレジットカード不要・早い・安心・支払いが便利なカンタン決済サービスです。
ドキュメント
JavaScriptのドキュメントで一部必須項目が間違っていたので注意。
どこだか忘れてしまった笑。
ソースコード
公開
#!/bin/sh ENV=dev # get dependencies MIX_ENV=$ENV mix deps.get # build MIX_ENV=$ENV mix compile # publish hex MIX_ENV=$ENV mix hex.publish
無事Hexに公開されました。
ElixirライブラリをHexに公開してみた① PAY.JP編
Elixirのライブラリ公開シリーズ第1弾
Hex
Hex は Elixir, Erlang 向けのパッケージ管理ツールです。
ruby で言うところの rubygems、node.js で言うところの npm です。
Hexの使い方は省きます。
PAY.JPとは
pay.jp
クレカの決済代行サービスです。
業務上決済機能を実装することになったので、そのタイミングで公開しました。
ドキュメント
大変読みやすく、まったく詰まることなく実装できました。
ありがたや。
ソースコード
GitHubのソースコードはこちら
GitHub - yuki-toida/ex_payjp
公開
#!/bin/sh ENV=dev # get dependencies MIX_ENV=$ENV mix deps.get # build MIX_ENV=$ENV mix compile # publish hex MIX_ENV=$ENV mix hex.publish
無事Hexに公開されました。
hex.pm
GCEとCloudSQLとDockerでmetabase
- metabaseってなんぞ?
- GCE(Container-Optimized OS)作成
- ユーザー定義bridgeネットワーク作成
- CloudSQLへのプロキシコンテナ作成
- metabase コンテナ作成
- PINGで疎通確認
- おまけ
metabaseってなんぞ?
データ可視化OSSです OSSのデータ可視化ツール「Metabase」が超使いやすい ちょっとつかってみた感じ、すこぶる良いです データ分析は全部こいつにぶん投げるのがとてもよさそう
GCE(Container-Optimized OS)作成
インスタンスの作成と設定 | Container-Optimized OS | Google Cloud
* コンソールのブートディスクからContainer-Optimized OSを選択する
* CloudSQLに接続可能なサービスアカウントCloudSQLClient
を作成し設定する(詳細省略)
* HTTP/HTTPSを開ける
ユーザー定義bridgeネットワーク作成
metanet
というbridgeネットワークを作成し各コンテナの起動時に指定する
これで同一ネットワーク内でコンテナを起動できる
docker network create -d bridge metanet
CloudSQLへのプロキシコンテナ作成
Cloud SQL Proxy Docker イメージを使用して MySQL クライアントを接続する | Cloud SQL for MySQL | Google Cloud
docker pull gcr.io/cloudsql-docker/gce-proxy:1.11
docker run --name cloud_sql_proxy --net=metanet -d \ -v /mnt/stateful_partition/cloudsql:/cloudsql \ -p 3306:3306 \ gcr.io/cloudsql-docker/gce-proxy:1.11 /cloud_sql_proxy \ -instances=planet-pluto-dev:asia-northeast1:mysql-dev=tcp:0.0.0.0:3306
ここでのポイントはポートをホストのローカル127.0.0.1
でバインドする必要がないこと
metanet
経由のコンテナ間通信を行い、ポート3306でCloudSQLにプロキシ接続する
あとは--net=metanet
を指定するのを忘れないこと
metabase コンテナ作成
docker run -d -p 80:3000 --name metabase --net=metanet metabase/metabase
同じように--net=metanet
を指定する
PINGで疎通確認
これで、metanet
内ではコンテナ名で名前解決可能になる
コンテナ内からPINGで疎通確認
docker exec -it metabase /bin/bash
ping cloud_sql_proxy
疎通できていたらmetabaseからMySQLをDBに設定
HOST : cloud_sql_proxy PORT : 3306
で接続できるはず
おまけ
ちなみに最初は docker-compose を使って接続していた
ただContainer-Optimized OSにdocker-compose をインストールするのが手間なので、オススメしない
Running Docker Compose with Docker | Google Cloud Platform Community | Google Cloud
一応そのときのdocker-compose.yml
を貼っとく
version: '2' services: cloud_sql_proxy: image: gcr.io/cloudsql-docker/gce-proxy:1.11 container_name: cloud_sql_proxy command: - "/cloud_sql_proxy" - "-instances=planet-pluto-dev:asia-northeast1:mysql-dev=tcp:0.0.0.0:3306" volumes: - /mnt/stateful_partition/cloudsql:/cloudsql ports: - "3306:3306" metabase: image: metabase/metabase container_name: metabase volumes: - /mnt/stateful_partition/tmp:/tmp environment: - "MB_DB_FILE=/mnt/stateful_partition/metabase.db" ports: - "80:3000"
GKE で Let's Encrypt (ワイルドカード編)
まえがき
cert-manager は使わないです。
理由は、kube-lego で時間を無駄にしてしまったから。
これから kubernetes がどう変わっていくかわからないのと、
シンプルでプリミティブなシステムが好きなので、公式の方法で行いました。
なので、 3ヶ月に1回手動対応
です。
certbot インストール
brew install certbot
certbot 実行
sudo certbot certonly --manual \ --preferred-challenges dns-01 \ --server https://acme-v02.api.letsencrypt.org/directory \ -m hoge@fuga.com \ -d sample.com \ -d *.sample.com
こんな感じで、メインドメインとワイルドカード付サブドメインを引数に渡し実行。
DNSにTXTレコード追加
------------------------------------------------------------------------------- Please deploy a DNS TXT record under the name _acme-challenge.sample.com with the following value: lgfkjaldfjlasdkgjjakdflasjflaslasdjf Before continuing, verify the record is deployed. -------------------------------------------------------------------------------
↑の値をTXTレコードに追加します。
DNS名:_acme-challenge.sample.com 値:lgfkjaldfjlasdkgjjakdflasjflaslasdjf
追加したら、Enter
を押す。
登録前に押すとこけます。
あと、DNSにメインドメイン以外のAレコードがあるとこけました(ちょっとハマった)
tls用の Secret 作成
↑で作成された証明書を元にSecret作成
sudo kubectl create secret tls tls-certs \ --key /etc/letsencrypt/live/sample.com/privkey.pem \ --cert /etc/letsencrypt/live/sample.com/fullchain.pem
IngressでSecretを参照
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ing-dev spec: tls: - secretName: tls-certs backend: serviceName: svc-dev servicePort: 80
↑みたいに tls-certs
を追加する。
Ingress デプロイ後、2,3分間 経過すると反映されてます。
サブドメインをDNSに登録しワイルドカードが聞いているか確認してみましょう。
まとめ
公式のやり方でサクッと対応できました。
3ヶ月に1回の更新もシェルスクリプトで対応できそうです。
cert-manager
に対応して、破壊的変更リスクとバグリスクを抱えるより、
3ヶ月に1回の更新コストをとったという感じです。
Container-Optimized OS で Redisをホストする
GCE(Container-Optimized OS)作成
インスタンスの作成と設定 | Container-Optimized OS | Google Cloud
コンソールのブートディスクからContainer-Optimized OSを選択する
後は、任意でポチポチやるだけ
Redis コンテナ起動
コンテナ名を redis-master
コンテナイメージを redis:4-alpine
ポートを 6379
永続化(AOF)フォルダを /home/redis/data
とすると、下記コマンドでRedisコンテナ起動
docker run --name redis-master -p 6379:6379 -v /home/redis/data:/data -d redis:4-alpine redis-server --appendonly yes
GCE の startup script 設定
再起動時に redis-master
コンテナを起動するようにする
インスタンス名 redis-master-dev
とすると、下記コマンドで設定完了
sh
gcloud compute instances add-metadata redis-master-dev --metadata startup-script='#! /bin/bash
docker start redis-master'
コンテナ環境前提でGCEを使う場合 Container-Optimized OS
入れとけばおkです
コンテナ最高すぎる
GKE LBで、Ingressを使ってTLS/SSL対応する
追記
kube-legoがオワコンになったのでこの記事もオワコンになりました
GitHub - jetstack/kube-lego: Automatically request certificates for Kubernetes Ingress resources from Let's Encrypt
kube-legoのセットアップ
Kubernetes Ingress リソースを使って GCP上にHTTPSロードバランサを構築する
kube-legoを使う
github.com
コンテナクラスタは作成されている前提で進める
yuki-toida.hatenablog.com
kube-lego をクローンする
git clone https://github.com/jetstack/kube-lego.git
lego 作業フォルダに移動
cd kube-lego/examples/gce/lego/
configmap.yaml
を編集して、lego.email
を適切に設定する
kube-legoのリソースを作成する
kube-lego/examples/gce/lego/
配下にあるリソースを作成する
kubectl create -f ./ namespace "kube-lego" created configmap "kube-lego" created deployment "kube-lego" created
kube-lego
namespace に作成されているか確認する
kubectl get deployment,replicaset,pod,configmap --namespace kube-lego
Ingressリソースを作成する
DeploymentやServiceは作成されているものとする
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-dev annotations: kubernetes.io/ingress.global-static-ip-name: "ingress-dev-ip" kubernetes.io/ingress.class: "gce" kubernetes.io/tls-acme: "true" spec: tls: - hosts: - sample.com - sub.sample.com secretName: ingress-dev-tls rules: - host: sample.com http: paths: - path: backend: serviceName: service-dev servicePort: 80 - host: sub.sample.com http: paths: - path: backend: serviceName: service-dev servicePort: 80
ここで注意することは、
kubernetes.io/ingress.allow-http: "false"
のアノテーションを入れないこと、HTTPで認証を行っているので失敗する
作成後、ロードバランサーの疎通と認証が通るまで15分くらい時間かかる
kube-legoのログをみながら認証が通ったか確認する
kubectl logs -f --namespace kube-lego $(kubectl get pod --namespace kube-lego -l app=kube-lego -o name)
認証が通ったらhttps://ドメイン
で疎通確認
GCEインスタンスの自動起動停止をスケジューリングする
- 適切なサービスアカウントを作成する
- ターミナルサーバ(GCE)作成
- gcloudでGCEインスタンスを起動停止するスクリプト
- cron で定時にスクリプトが実行されるようにする
- Cloud SQL の起動停止も追加する
適切なサービスアカウントを作成する
インスタンスのサービス アカウントの作成と有効化 | Compute Engine ドキュメント | Google Cloud
GCEインスタンスをマネジメントするだけならCompute Admin
のみでおk
今回はCloudSQLも管理したいので、Cloud SQL 管理者
も追加する
Terminal Client
サービスアカウントを作成する
ターミナルサーバ(GCE)作成
cronを動かすだけなので、f1-micro(vCPU x 1、メモリ 0.6 GB)でおk
サービスアカウントに先程作ったTerminal Client
を設定する
作ったインスタンスにログインしZONEを設定する
gcloud compute ssh terminal-dev
sudo gcloud config set compute/zone asia-northeast1-a
最後に gcloud の config を確認する
gcloud config list
gcloudでGCEインスタンスを起動停止するスクリプト
redis-dev インスタンスを起動するスクリプト
terminal-cron-start.sh
として保存
gcloud compute instances start redis-dev
redis-dev インスタンスを停止するスクリプト
terminal-cron-stop.sh
として保存
gcloud compute instances stop redis-dev
cron で定時にスクリプトが実行されるようにする
crontab を設定する
sudo crontab -e
editorに何を使うか選ぶ
3の vim を選んだ(nano使えないので)
下記2行を追加、UTCタイムであることに注意
10:00(JST)に起動し、19:00(JST)に停止する
0 1 * * 1-5 sh /home/terminal-cron-start.sh 0 10 * * 1-5 sh /home/terminal-cron-stop.sh
Cloud SQL の起動停止も追加する
terminal-cron-start.sh
とterminal-cron-stop.sh
にそれぞれ以下を追加する
Cloud SQL起動スクリプト
gcloud sql instances patch db-$ENV --activation-policy ALWAYS
gcloud sql instances patch db-$ENV --activation-policy NEVER