Go 開発環境構築 [glide のインストール]
前回からの続きで今回はパッケージ管理ツール
Go のパッケージ管理ツール
Go のパッケージ管理ツールは以下の通り複数ある。
今回は Star 数の多い glide について記載する。
2017/11/02 現在
ツール名 | Star |
---|---|
glide | 5611 |
dep | 5513 |
godep | 5014 |
govendor | 2615 |
gb | 2006 |
注意点
公式がパッケージ管理ツール dep を開発している。
glide の README に dep への移行を考えてくれと記載されているが、今回は glide を紹介する。
理由としては、以下の通りまだ大きな変更が入る可能性があるためである。
参考: https://github.com/golang/dep#current-status
- 取り込まれるのは Go 1.10 以降である事 (参考: ロードマップ)
- まだ厄介なバグが含まれている事
- 遅い事
glide とは
- npm, Maven, Bundler のようなGo 言語のパッケージ管理ツール
- プロジェクトに依存するパッケージを vendor ディレクトリで管理する
- プロジェクトごとに依存パッケージのバージョンを固定できる
glide のインストール
1コマンドでインストール可能
参考: https://github.com/Masterminds/glide#install
curl https://glide.sh/get | sh
glide の使い方
参考: https://github.com/Masterminds/glide#usage
glide の利用開始
$ glide create
glide.yaml
ファイルが自動生成される
glide 経由でパッケージをダウンロードする
例として echo というパッケージをダウンロードする場合
$ glide get github.com/labstack/echo
vendor
ディレクトリ配下に指定したパッケージがダウンロードされる
$ tree vendor/
vendor/
└── github.com
└── labstack
└── echo
また glide.yaml
, glide.lock
にダウンロードしたパッケージが記載される
# glide.yaml package: github.com/mmts1007/glide_sample import: - package: github.com/labstack/echo version: ^3.2.3
# glide.lock hash: d8348bf86f67e8762c036cca040e09d39a74eec9cbe7d8b4f5e6ad9148bc2495 updated: 2017-11-02T14:10:52.482634978Z imports: - name: github.com/labstack/echo version: cec7629194fe4bf83b0c72d9a02d340c7a1468ac testImports: []
glide で管理しているパッケージのアップデート
glide.yaml
に記載されているパッケージのアップデートを行う
$ glide up
依存パッケージのダウンロード
プロジェクトに glide.lock
ファイルがある場合、glide.lock
ファイルの内容を元に依存パッケージをダウンロードすることができる
$ glide install
glide の基本的な使い方は以上
Go 開発環境構築 [ワークスペースの構成]
今回はワークスペースについて
ワークスペース
参考: Goコードの書き方 - The Go Programming Language
例えば、ホームディレクトリ直下の go ディレクトリをワークスペースとした場合は以下の通り
$ tree $HOME/go
/home/vagrant/go
├── bin
├── pkg
└── src
GOPATH
ワークスペースの場所については特に指定がないため GOPATH を使ってワークスペースの場所を教えてあげる必要がある
Goコードの書き方 - The Go Programming Language にも記載されているが、Goをインストールしたパスではない ことに注意。GOPATH は Go のワークスペースがどこなのかを教えるものである
私の場合 $HOME/go
をワークスペースとしたので GOPATH は $HOME/go
になる。
また
と記載されているので環境変数は以下の通り
$ export GOPATH=$HOME/go $ export PATH=$PATH:$GOPATH/bin
プロジェクト
例えば、 GitHub で hello_world
パッケージを管理する場合は、以下のようなディレクトリ構成にする
$ tree $HOME/go /home/vagrant/go ├── bin ├── pkg └── src └── github.com └── mmts1007 # GitHub のアカウント └── hello_world # hello_world パッケージ └── main.go # Go コード
ワークスペースについては以上。次はパッケージ管理ツールについて
Go 開発環境構築 [goenv のインストール]
Go 言語を触る機会があったので、 Go 言語の開発環境構築方法をまとめておく
まずは goenv のインストールから
goenv とは
- goenv は rbenv や pyenv のような Go 言語のバージョン管理ツール
- 複数の Go 言語のバージョンをインストールできる
- プロジェクト(ディレクトリ)ごとにバージョンを簡単に切り替えることができる
goenv のインストール
Mac であれば Homebrew でインストールできる
参考: https://github.com/syndbg/goenv#homebrew-on-mac-os-x
$ brew update $ brew install goenv
Linux の場合は GitHub からクローンしてインストールする
参考: https://github.com/syndbg/goenv#installation
# GitHub からクローン $ git clone https://github.com/syndbg/goenv.git ~/.goenv # 環境変数を定義 $ echo 'export GOENV_ROOT="$HOME/.goenv"' >> ~/.bash_profile $ echo 'export PATH="$GOENV_ROOT/bin:$PATH"' >> ~/.bash_profile # goenv init を Shell に追加 $ echo 'eval "$(goenv init -)"' >> ~/.bash_profile # .bash_profile に定義した内容を読み込み $ source ~/.bash_profile
Go のインストール
goenv 経由で Go をインストールする
参考: https://github.com/syndbg/goenv/blob/master/COMMANDS.md#goenv-install
# Go 1.9.2 をインストール $ goenv install 1.9.2 # システム全体で Go 1.9.2 を使用するよう設定 $ goenv global 1.9.2 # local でディレクトリごとにバージョンを変更することも可能 # cd 先に .go-version ファイルがあれば、ファイル内に記載されているバージョンに自動的に切り替わる # (goenv local すると .go-version ファイルが自動生成される) $ goenv local 1.9.2
goenv のインストールは以上でおしまい
SSL クライアント認証を試してみる
Web サーバへのアクセス制限をするために、 SSL クライアント認証を試してみた。
その時調べた内容や、動作確認をした時の内容などをまとめてみました。
SSL クライアント認証とは
SSL クライアント証明書を利用して、クライアントを認証する方法です。
SSL クライアント証明書を持っているクライアントしか利用できないため、セキュアと言えます。
SSL クライアント証明を理解するために参考になったページ
利用方法
SSL クライアント認証を利用するには
- クライアント証明書
- Web サーバの設定
が必要です。
今回は上記内容に加えて
も利用しました。
プライベート認証局
認証局がないと証明書を発行できないため、はじめに認証局を作成します。
プライベート認証局の証明書、サーバー証明書、クライアント証明書の作成方法について | レンタルサーバー・自宅サーバー設定・構築のヒント
を参考に作成しました。
サーバ証明書、クライアント証明書
こちらも
プライベート認証局の証明書、サーバー証明書、クライアント証明書の作成方法について | レンタルサーバー・自宅サーバー設定・構築のヒント
を参考に作成しました。
Web サーバの設定
今回 Web サーバは nginx を利用しました。
以下のリンクを参考に conf ファイルを作成しました。
(conf ファイルはしっかり調べてないので、ベストな設定ではないかも・・・)
ssl.conf
server { listen 443 ssl; server_name www.example.com; ssl_certificate /etc/pki/CA/certs/www.example.com.crt; ssl_certificate_key /etc/pki/CA/private/www.example.com.key; ssl_verify_client on; ssl_client_certificate /etc/pki/CA/cacert.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; location / { root /usr/share/nginx/html; index index.html index.htm; } }
この ssl.conf を /etc/nginx/conf.d/
に配置し、 nginx を再起動
$ ls /etc/nginx/conf.d/ default.conf ssl.conf $ sudo /etc/init.d/nginx start
デモ
Web サーバにリクエストすると、サーバから証明書を求められる
適切な証明書を選択すると、 nginx の welcome ページが表示される
証明書を渡さないと、エラーページに遷移される
(基本参考のリンクばかりになってしまったw)
Docker で Rails の開発環境を構築する
Docker で Rails の開発環境を配れたら、楽できるのでは?思い、サンプルを作ったのでまとめる。
サンプルコード
Dockerfile と docker-compose.yml は以下の通り
FROM ruby:2.4.1 MAINTAINER mmts1007 ENV APP_ROOT=/usr/src/app WORKDIR $APP_ROOT EXPOSE 3000 RUN apt-get update && apt-get install -y \ nodejs \ mysql-client COPY . $APP_ROOT RUN bundle install CMD ["bundle", "exec", "rails", "s", "-b", "0.0.0.0"]
version: '3' services: db: image: mysql environment: MYSQL_ROOT_PASSWORD: root volumes: - mysql-data:/var/lib/mysql web: build: context: . dockerfile: Dockerfile.development volumes: - .:/usr/src/app ports: - "3000:3000" depends_on: - db volumes: mysql-data:
工夫した点
- 開発時は DB も必要になるため、 docker-compose を利用して 1コマンドで開発に必要がものが揃うようにした
- 修正したソースコードをすぐに反映したかったため、ソースコードは Docker コンテナにマウント
- DB に書き込んだデータは保持したかったので、 volumes を使って永続化
使い方
docker-compose build
$ pwd
/path/to/docker-rails/simple_note
$ docker-compose build
...
Successfully tagged simplenote_web:latest
docker-compose up
$ docker-compose up Starting simplenote_db_1 ... Starting simplenote_db_1 ... done Recreating simplenote_web_1 ... Recreating simplenote_web_1 ... done Attaching to simplenote_db_1, simplenote_web_1 ... web_1 | Use Ctrl-C to stop
ブラウザから http://localhost:3000 にアクセス
その他
初回起動時は DB、テーブルが存在しないため作成する
$ docker-compose run web bundle exec rake db:create $ docker-compose run web bundle exec rake db:migrate
追記
Gem ファイルの永続化
記事を公開したところ、先輩に「Gemfile 更新時に、全 Gem インストールし直しになっちゃうから Gem ファイルのインストール先も Volume にするのが良いよ」とコメントを頂きました。(ありがとうございます!)
確かに Gemfile 更新した時に毎回 build して、イメージに含めてあげないと動かない状態でした・・・
Gemfile に Kaminari を追加
gem 'kaminari'
bundle install
$ docker-compose run web bundle install ... Fetching kaminari-core 1.0.1 Installing kaminari-core 1.0.1 ... Fetching kaminari-activerecord 1.0.1 Installing kaminari-activerecord 1.0.1 Fetching kaminari-actionview 1.0.1 Installing kaminari-actionview 1.0.1 ... Fetching kaminari 1.0.1 Installing kaminari 1.0.1 ... Bundle complete! 18 Gemfile dependencies, 76 gems now installed. Bundled gems are installed into /usr/local/bundle.
もう一度 bundle install を実行すると キャッシュされて Gem は何もインストールされないことを期待していましたが・・・
$ docker-compose run web bundle install ... Fetching kaminari-core 1.0.1 Installing kaminari-core 1.0.1 ... Fetching kaminari-activerecord 1.0.1 Installing kaminari-activerecord 1.0.1 Fetching kaminari-actionview 1.0.1 Installing kaminari-actionview 1.0.1 ... Fetching kaminari 1.0.1 Installing kaminari 1.0.1 ... Bundle complete! 18 Gemfile dependencies, 76 gems now installed. Bundled gems are installed into /usr/local/bundle.
全く同じログが出ました・・・
新たに作成したコンテナに Gem をインストールし、そのコンテナは破棄されてしまうため、このような現象が起きてしまいました。
docker-compose.yml を以下のように変更し、インストールした Gem を永続化するようにしました。
iff --git a/simple_note/docker-compose.yml b/simple_note/docker-compose.yml index 18e6132..c824f93 100644 --- a/simple_note/docker-compose.yml +++ b/simple_note/docker-compose.yml @@ -12,9 +12,11 @@ services: dockerfile: Dockerfile.development volumes: - .:/usr/src/app + - gem-store:/usr/local/bundle ports: - "3000:3000" depends_on: - db volumes: mysql-data: + gem-store:
この状態であればコンテナが破棄されたとしても Gem 自体は残るので、先ほどの問題は発生しなくなりました!
参考
SAML 認証を Ruby on Rails で試してみた
SAML 認証に触れる機会があったので、 Ruby on Rails で SAML 認証するサンプルアプリを作ってみた
折角なので、SAML とは何なのか?あたりからまとめてみようと思います。
SAML とは
まずは、SAML とは何なのか
- 読み方は サムル
- Security Assertion Markup Language の略
- 異なるサービス、アプリケーション間で認証情報を交換するための仕組み
- これによりシングルサインオン(1度のログインで、複数のアプリが利用可能になること) が実現できる
登場人物
Identity Provider
- 略称は IdP
- 実際の認証処理を行う人。認証したユーザの情報(ID、 メールアドレス等)を提供してくれる
Service Provider
- 略称は SP
- 認証情報を利用する人
今回は SP のサンプルを作成しました。
認証フロー
SAML の認証フローのイメージです。
- ユーザは SP に対してログインを試みる
- SP は Idp に対して認証リクエストを送信する
- IdP はユーザにログイン画面を表示する
- ユーザはログイン情報を入力する(ex. ID / Password)
- IdP は入力情報を検証し、正しければ SP に認証結果を送信
- SP は認証結果を検証し、正しければユーザをログインさせる
SAML の説明はこのあたりにして、サンプルアプリについて説明します
構成
IdP
サンプルアプリを動かすためには IdP が必要なので、今回は IdP に Azure Active Directory を利用しました。
SP
SP は以下の技術要素で作成
- Ruby 2.3.3
- Ruby on Rails 5.0.1
また、SAML のライブラリとして ruby-saml を使用しました。
サンプルアプリ
サンプルアプリはメモ管理アプリとなっています。
Azure AD で認証したユーザのメモ一覧・登録・更新・削除ができる簡単なものです。
SAML 連携部分の実装は https://github.com/onelogin/ruby-saml のサンプル https://github.com/onelogin/ruby-saml-example をベースに
少し修正を入れたものになっています。
(SAML 部分の実装はほぼサンプルのままです)
動作確認
http://localhost:3000 にアクセス
「Azure AD で Login」をクリック
Microsoft アカウント(IdP)のログインページが表示される
ID / Password を入力
メモアプリ(SP)にログインする
まとめ
SP を作るためにはもっとゴリゴリ書く必要があるかと思っていたのですが、
https://github.com/onelogin/ruby-saml がとても使いやすく、IdP の設定情報を記述するだけで動かすことができました。サンプルもあるのも良かったです。
Grafana を使ってサーバメモリ使用率、CPU使用率を可視化する
top コマンドや free コマンドなどで確認していたサーバ負荷状況をグラフィカルに見やすできないのかと思い調べたところ、Grafana という可視化ツールがあったので試してみました。
Grafana とは
- インフラや、アプリケーションの分析データなど時系列データを可視化するためのダッシュボードツール
- デフォルトで複数のデータストアをサポートしている
- Graphite
- Elasticsearch
- Cloudwatch
- Prometheus
- InfluxDB
今回は InfluxDB を利用しました。
構成
- 負荷状況を送信するサーバ(CentOS 6.7)
- Grafana, InfluxDB サーバ(CentOS 6.7)
- 本来は Grafana と InfluxDB は別サーバにすべきだと思いますが、お試しのため同居させています。
- 負荷情報を確認したいサーバの CPU, メモリ情報を InfluxDB に送信
- InfluxDB は CPU, メモリ情報を DB に格納
- ブラウザから Grafana ダッシュボードにアクセス
- Grafana はダッシュボードを表示するために必要な情報を InfluxDB から取得し、ダッシュボードを表示する
インストール手順
Grafana のインストール
http://docs.grafana.org/installation/rpm/ を参考に Grafana をインストール
# Grafana のインストール $ sudo yum install https://grafanarel.s3.amazonaws.com/builds/grafana-4.0.2-1481203731.x86_64.rpm # Grafana を起動 $ sudo service grafana-server start
http://192.168.33.10:3000/login にブラウザからアクセスし、Grafana のログイン画面が開くことを確認
InfluxDB のインストール
https://www.influxdata.com/downloads/ に記載されている「RedHat & CentOS」のとおり実施
# influxDB をダウンロード $ wget https://dl.influxdata.com/influxdb/releases/influxdb-1.1.1.x86_64.rpm # インストール $ sudo yum localinstall -y influxdb-1.1.1.x86_64.rpm # InfluxDB 起動 $ sudo service influxdb start
InfluxDB データベースの作成
https://docs.influxdata.com/influxdb/v1.1/introduction/getting_started/ を参考にデータベースを作成します。
$ influx Visit https://enterprise.influxdata.com to register for updates, InfluxDB server management, and monitoring. Connected to http://localhost:8086 version 1.1.1 InfluxDB shell version: 1.1.1 > CREATE DATABASE grafana # DB が作成されているか確認 > SHOW DATABASES name: databases name ---- _internal grafana
Grafana のセットアップ
Grafana の管理画面から利用するデータストアや、ダッシュボードの設定します。
- http://192.168.33.10:3000/login にブラウザからアクセス(admin/admin でログイン)
左上 Grafana アイコンクリック → 「Data Sources」 をクリック
「Add Data Source」をクリック
InfluxDB の情報を入力、「Add」をクリック
負荷情報の取得方法
InfluxDB へのデータアクセス方法は、複数サポートしています。
今回は負荷情報を確認したいサーバから InfluxDB の HTTP API を利用して負荷情報を送信します。
CLI
https://docs.influxdata.com/influxdb/v1.1/tools/shell/
$ influx -execute 'SELECT * FROM "h2o_feet" LIMIT 3' -database="NOAA_water_database" -precision=rfc3339 name: h2o_feet -------------- time level description location water_level 2015-08-18T00:00:00Z below 3 feet santa_monica 2.064 2015-08-18T00:00:00Z between 6 and 9 feet coyote_creek 8.12 2015-08-18T00:06:00Z between 6 and 9 feet coyote_creek 8.005
HTTP API
https://docs.influxdata.com/influxdb/v1.1/tools/api/
$ curl -i -XPOST "http://localhost:8086/write?db=mydb&precision=s" --data-binary 'mymeas,mytag=1 myfield=90 1463683075'
クライアントライブラリ
https://docs.influxdata.com/influxdb/v1.1/tools/api_client_libraries/
実際に利用したコマンドは以下のとおり
メモリの使用率を取得するスクリプト
while true; do curl -i -s -XPOST 'http://192.168.33.10:8086/write?db=grafana' --data-binary "memory,host=serverA,region=jp_east value=`free -t | grep Total | sed 's/[\t ]\+/\t/g' | cut -f3`" sleep 5 done
CPU の使用率を取得するスクリプト
while true; do idle=`mpstat | tail -n 1 | sed 's/[\t ]\+/\t/g' | cut -f11` rate_of_cpu=`echo "100-${idle}" | bc` curl -i -s -XPOST 'http://192.168.33.10:8086/write?db=grafana' --data-binary "cup,host=serverA,region=jp_east value=${rate_of_cpu}" sleep 5 done
まとめ
ダッシュボードを作成し、以下のような値が取得できるようになりました。
過去のデータも確認することができますし、毎回サーバにログインする手間もなくなるので楽になりそうですね。
本番で運用するためには Grafana の admin ユーザのパスワード変更や、InfluxDB の パスワード設定などセキュリティの設定をする必要があります。(今回は Vagrant 上にお試しで作ったのでセキュリティ部分に関しては設定していません)