長生村本郷Engineers'Blog

千葉県長生村本郷育ちのエンジニアが書いているブログ

ecs-cli バージョン指定してインストール

完全な備忘録です。

経緯

6月に入って数日、
ecs-cli の latest をインストールすると latest が 1.6.0 となり
ecs-cli compose ... を実行すると以下のようなエラーが出るようになりました。

level=error msg="Unable to open ECS Compose Project" error="Volume driver is not supported"

1.4.0 では問題なかったタスク定義でしたが
1.6.0 では Volume driver is not supported となったそうで処理がこけるようになりました。

その対応として 1.4.0 にバージョン固定した設定です。

結論

latest の部分を <version> に変更することで指定のバージョンでインストールが可能です。

curl -s https://s3.amazonaws.com/amazon-ecs-cli/ecs-cli-linux-amd64-v1.4.0 -o /usr/bin/ecs-cli && chmod +x /usr/bin/ecs-cli

AWS Documentation では

最新の ecs-cli のみの説明の為、若干ハマりました。

docs.aws.amazon.com

GitHub には Download specific version とあるのでこちらの情報を追っておくと良かったです。

github.com

以上 本当に備忘録でした。

AWSによるサーバーレスアーキテクチャ

AWSによるサーバーレスアーキテクチャ

Rails × Redis でスレッドセーフなアクセス数ランキング実装

f:id:kenzo0107:20180606115540j:plain

概要

メディアサイトで記事ページへアクセス数ランキングを実装しました。

  • Rails 5.1
  • Redis (AWS ElastiCache 3.2.10)

その際にマルチスレッド環境を考慮してスレッドセーフな実装を心がけました。

スレッドセーフとは

スレッドセーフとは複数のスレッドが同時並行的に実行しても問題が発生しないことを意味します。 スレッドセーフでない場合は、あるスレッドで変更した共有データが、他のスレッドによって上書きされてしまう可能性があります。

Webサーバーやデータベースなどのサーバー用ソフトウェアは、マルチスレッド(マルチプロセス)で動作しているので、サーバー向けアプリケーションを開発するときは、マルチスレッドで動作するように実装することが望ましいです。

参照

スレッドセーフ - Wikipedia

JavaのThreadLocalとスレッドセーフについて

仕様

メディアサイトで記事詳細ページへアクセスした際に その記事 ID に対して閲覧数を +1 インクリメントします。

そして、 その閲覧数 TOP 10 のランキングを表示する、 というものです。

その際の Rails, Redis の設定についてまとめました。

実装方法検討

config/initializers/redis.rb*1 で Redis の初期設定の実装方法を検討しました。

global 変数として設定

require 'redis'

REDIS = Redis.new(host: host, port: port)

上記の場合、 グローバルで Redis クライアントを持っており マルチスレッド環境では、複数のスレッドが上書きされる可能性があります。

Thread.current

require 'redis'

def redis
  Thread.current[:redis] ||= Redis.new(host: host, port: port)
end

現在実行中のスレッドを取得しスレッド毎のデータを担保します。

が、以下 2 点の問題があります。

  1. 他人が上書いてしまう
  2. 構造化されていない

ActiveSupport::PerThreadRegistry

require 'redis'

class RedisRegistry
  extend ActiveSupport::PerThreadRegistry
  attr_accessor :redis, :current_permissions
end

def redis
  RedisRegistry.redis ||= Redis.new(host: host, port: port)
end

redis をスレッドローカル変数として定義し、そのアクセスをカプセル化し上書きされるのを防止しています。

ですが、 Rails 5.2 で deprecated となっておりました (TへT)

thread_mattr_accessor

以下を見てみると thread_mattr_accessor の挙動が Fix していました。 Fix thread_mattr_accessor share variable superclass with subclass

thread_mattr_accessor を利用して書き換えます。

  • config/initializers/redis.rb
require 'redis'

class RedisRegistry
  thread_mattr_accessor :redis
end

def redis
  RedisRegistry.redis ||= Redis.new(host: host, port: port)
end

アクセス数インクリメント

rescue 設定は Redis に接続できなくなった場合でもサイト自体が落ちることはなく、ランキングだけが表示されなくなる様にする為に設定しました。

    def increment_access_count(id)
      redis.zincrby "entries/daily/#{Time.zone.today}", 1, id
    rescue SocketError => e
      logger.error e
    end

アクセスランキング取得

Redis の zrevrangebyscore によりスコアの大きい順に 10 個、ID を取得します。 もし取得できなかった場合、 [] を返します。 decorate で体良く整形して View に渡します。 *2

    def access_ranking
      limit = 10
      ids = redis.zrevrangebyscore "entries/daily/#{Time.zone.today}", '+inf', 0, limit: [0, limit]
      if ids.any?
        where(id: ids).order(['field(id, ?)', ids]).limit(limit).decorate
      else
        []
      end
    rescue SocketError => e
      logger.error e
      []
    end

以上です。

Redis入門 インメモリKVSによる高速データ管理

Redis入門 インメモリKVSによる高速データ管理

*1:host, port は secrets.yml なり ENV で設定してください

*2:decorate のコードは省略してます

AWS ECS prefix 指定してまとめてタスク登録解除

概要

awscli でタスク定義のまとめて登録解除がなかったので簡単に Shell 化しました

gist.github.com

実行

sh deregister_all_tasks_filtered_by_family_prefix.sh <profile> <task definition family prefix>

サクッと削除

Docker入門

Docker入門

AWS Vault で複数アカウントにMFA認証通過

f:id:kenzo0107:20180514221849j:plain

AWS Vault とは?

AWS Vault は IAMの認証情報 (Access Key Id, Secret Access Key) を安全に OS のキーストアに保存しアクセスできる仕組みを提供するツールです。

Vault = 金庫 というだけあって PC 落としても秘匿情報が漏れにくい仕組みにしてくれます。

今回の目的

AWS Vault で複数アカウントのコンソールログインを簡単にしたいと思います。
AWS IAM を頂く際に MFA 設定をしているかと思います。

バイス認証することでセキュアなアカウントを管理をする為です。

その際に、以下の様なアプリをインストールし
1分置きに更新される 6桁 の数字で認証する仕組みにします。

MFA 自体は
その会社の開発ポリシーにも依りますが、入れておいて損なしの仕組みです。

ただ、毎回 6桁の数字をコピぺするのは面倒です。

それを簡易的に認証通過する様にしました。

aws-vault インストール

macOS%$ brew cask install aws-vault

profile 設定

aws-vault add <profile>
Enter Access Key ID: <Access Key ID 入力>
Enter Secret Access Key: <Secret Access Key 入力>

事前準備

brew tap peco/peco
brew install peco

bash 設定

ご利用の .bashrc, .zshrc 等に設定してください。

function peco-login-aws-account() {
    local account=$(aws-vault ls | awk 'NR>2 {if ($2 != "-") print $2}' | peco)
    aws-vault login $account
}

function peco-aws-exec() {
    local account=$(aws-vault ls | awk 'NR>2 {if ($2 != "-") print $2}' | peco)
    echo -e "aws-vault exec \"$account\" -- \\" | pbcopy
}

alias avl='peco-login-aws-account'
alias ave='peco-aws-exec'

使い方

  • 設定した profile を選択して Login
avl
  • 設定した profile を選択してコマンド実行
ave

実際のコマンドを rec して出すのは憚れる内容でしたので貼り付けられず汗

是非一度利用し使用感を試してみてください♪

毎回パスワード入力というのも辛いところではありますが
MFA の手間に比べれば数段楽です。

AWS Vault は本来はそういう意図ではないと思いますが
楽になるならば良し♪

続 ECR にログイン(aws ecr get-login)無しでプッシュする

概要

前回 ECR への Docker イメージをプッシュする際の認証コマンドを実行せずにプッシュできる様にしました。

kenzo0107.hatenablog.com

ですが、 設定が手間というのがあり、CircleCI, AWS CodeBuild 等でワンライナーでささっと書きたいときには不便です。

解決

awscli profile で設定した profile を利用し ecs-cli を利用することで認証をよろしくやってくれます。

ecs-cli push <image> --aws-profile <profile> --region <region>

設定 Step

aws configure set --profile hogehoge aws_access_key_id $ACCESS_KEY_ID
aws configure set --profile hogehoge aws_secret_access_key $SECRET_ACCESS_KEY
aws configure set --profile hogehoge region ap-northeast-1
ecs-cli push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/stg-mogemoge-rails:latest \
    --aws-profile hogehoge \
    --region ap-northeast-1

以上で aws ecr get-login を使用せず、ECR へプッシュができる様になりました♪

WEB+DB PRESS総集編[Vol.1~102] (WEB+DB PRESS plusシリーズ)

WEB+DB PRESS総集編[Vol.1~102] (WEB+DB PRESS plusシリーズ)

docker build 時に Text file busy で shell が実行できない対策

f:id:kenzo0107:20180418215217j:plain

概要

Dockerfile 内に以下のように shell の実行を記述していました。

RUN chmod +x hoge.sh \
  && hoge.sh

上記記述のある状態で docker build 実行した所、以下のようなエラーに遭遇しました。

/bin/sh: hoge.sh: Text file busy

What is Text file busy ?

書き込みのために現在開いている手続きのみの (共用テキスト) ファイルを実行しようとした場合や、実行中の手続きのみのファイルを書き込みのために開こうとしたり、削除しようとしたりする場合に発生します。

上記鑑みると chmod +x hoge.sh 実行中に hoge.sh を実行しようとしたが為に発生しているということ?? と推測。

環境情報

  • Ubuntu 14.04.5 LTS \n \l
  • Docker version 17.05.0-ce, build 89658be
  • Base Image: ruby:2.5-alpine

対策

以下 sync 処理を追加し無事問題解決できました。

RUN chmod +x hoge.sh \
  && sync \
  && hoge.sh

What is sync command ?

sync - システム管理コマンドの説明 - Linux コマンド集 一覧表

参考

github.com

qiita.com

curl で FTPS (File Transfer Protocol over SSL/TLS) 接続確認

f:id:kenzo0107:20180418082402p:plain

以下コマンドで FTPS 接続確認ができます。

curl -u <user> --ftp-ssl -k ftp://<ftp domain>/

概要

備忘録記事です。

社外向けに FTPS で接続許可をする必要があり設定しました。

単純に作成・更新した user, password で認証をパスできるか、 の確認だけができれば良いので、その確認方法を模索している時に 程よいコマンドがありました。

その接続確認を FileZilla, Cyberduck でしましたが どうもうまくいかず。。

改めて、 lftp とか色々 ftp だけでもコマンドは多々あるんだなと実感しました。