読者です 読者をやめる 読者になる 読者になる

長生村本郷Engineers'Blog

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

peco 小技シリーズ 〜多段ssh + peco, ghq + peco + atom〜

f:id:kenzo0107:20170427172718j:plain

概要

本当に小技です。
が、割と使ってみると作業時間の短縮となって便利という声を頂き
peco 関連でよく使うものを記事にしました。

peco インストール

macOS %$ brew install peco

ssh ログインする Host を検索して選択

前提条件として ~/.ssh/config で接続ホストを管理しています。

gist.github.com

上記を ~/.bashrc などに貼り付けて source ~/.bashrc すれば使えます♪

macOS %$ git clone https://gist.github.com/kenzo0107/06b3b1e202f36b70815cfe0207292a66
macOS %$ cd 06b3b1e202f36b70815cfe0207292a66
macOS %$ cat peco-sshconfig-ssh.sh >> ~/.bashrc
macOS %$ source ~/.bashrc

// sshc 実行!
macOS %$ sshc

上記の様に順調に進むと候補がリストされます。
モザイクしかなくすいません (>_<)
f:id:kenzo0107:20170427171121p:plain

ghq で管理している repository を検索して選択し atom で開く

gist.github.com

こちらも同様、

macOS %$ git clone https://gist.github.com/kenzo0107/e460e31ae2478341cc7a39859ad7fefd
macOS %$ cd e460e31ae2478341cc7a39859ad7fefd
macOS %$ cat peco-git-atom.sh >> ~/.bashrc
macOS %$ source ~/.bashrc

// opg 実行!
macOS %$ opg

f:id:kenzo0107:20170427171728p:plain

他にも様々な箇所で peco を利用させて頂いてます。
こんな peco の使い所あるよーという方、是非教えてください♪

参照

zsh ですが dotfile をまとめてます。

GitHub - kenzo0107/dotfiles: dotfile setting

docker-compose で開発環境構築 〜Nginx アクセスログ(ltsv) を fluentd + elasticsearch + kibana で可視化〜

概要

前回構築した Vagrant 環境上で docker-compose による開発環境構築をします。

kenzo0107.hatenablog.com

今回は前回の続きで Nginx のアクセスログを Elasticsearch + Fluentd + Kibana で可視化してみます。
アプリ

簡単構築手順

macOS% $ git clone https://github.com/kenzo0107/vagrant-docker
macOS% $ cd vagrant-docker
macOS% $ vagrant up
macOS% $ vagrant ssh
vagrant% $ cd /vagrant/nginx-efk

// -d デタッチモードでないのは各コンテナの起動状況がログで見える為です。
vagrant% $ docker-compose up
...
...

docker-compose 構成

Git にまとめています。
https://github.com/kenzo0107/vagrant-docker/tree/master/docker/nginx-efk

├── docker-compose.yml
├── fluentd
│   ├── conf
│   │   ├── conf.d
│   │   │   └── nginx.log.conf
│   │   └── fluent.conf
│   └── Dockerfile
└── nginx
    └── conf
        └── nginx.conf

ポイント

  • nginx のログ格納場所を volume 指定しホスト側とシンク。 それを fluentd 側でも volume 指定し tail するようにしました。

以下のようなイメージです。 f:id:kenzo0107:20170421221055p:plain

ブラウザから Nginx 起動確認

ブラウザから http://192.168.35.101/ にアクセスすると
Nginx の Welcome ページが確認できます。

f:id:kenzo0107:20170421222343p:plain

先程の docker-compose up 後に以下のようなログが見え
fluentd が Nginx アクセスログを捕まえているのがわかります。

f:id:kenzo0107:20170421222937p:plain

Kibana にアクセス

ブラウザから http://192.168.35.101:5601 にアクセスすると
Kibana ページが表示されます。

f:id:kenzo0107:20170421223008p:plain

  1. Index name or pattern

    • fluentd-* 指定
  2. Time-field name

    • @timestamp 指定
  3. Create ボタン押下

  4. レフトメニューから Discover クリック

f:id:kenzo0107:20170421223626p:plain

macOS からログ確認

当然ながら macOSvagrant とシンクしているので
macOS 上からもログが tail できます。

macOS%$ tail -f <path/to/vagrant-docker>/docker/nginx-efk/_log/nginx/access.log

以上です。 参考になれば幸いです。

AWS [Retirement Notification] 対応

f:id:kenzo0107:20170418105821p:plain

概要

とある日、AWS よりこんなメール通知が来ました。

要約すると
ホストしている基盤のハードウェアで回復不可能な障害が検知されたので 指定期限までに対応しないとインスタンスが停止する、とのこと。

今回こちらの対応をまとめました。

Dear Amazon EC2 Customer,

We have important news about your account (AWS Account ID: xxxxxxxxxxxx). EC2 has detected degradation of the underlying hardware hosting your Amazon EC2 instance (instance-ID: i-xxxxxxxx) in the ap-northeast-1 region. Due to this degradation, your instance could already be unreachable. After 2017-04-25 04:00 UTC your instance, which has an EBS volume as the root device, will be stopped.

You can see more information on your instances that are scheduled for retirement in the AWS Management Console (https://console.aws.amazon.com/ec2/v2/home?region=ap-northeast-1#Events)

* How does this affect you?
Your instance's root device is an EBS volume and the instance will be stopped after the specified retirement date. You can start it again at any time. Note that if you have EC2 instance store volumes attached to the instance, any data on these volumes will be lost when the instance is stopped or terminated as these volumes are physically attached to the host computer

* What do you need to do?
You may still be able to access the instance. We recommend that you replace the instance by creating an AMI of your instance and launch a new instance from the AMI. For more information please see Amazon Machine Images (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html) in the EC2 User Guide. In case of difficulties stopping your EBS-backed instance, please see the Instance FAQ (http://aws.amazon.com/instance-help/#ebs-stuck-stopping).

* Why retirement?
AWS may schedule instances for retirement in cases where there is an unrecoverable issue with the underlying hardware. For more information about scheduled retirement events please see the EC2 user guide (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-retirement.html). To avoid single points of failure within critical applications, please refer to our architecture center for more information on implementing fault-tolerant architectures: http://aws.amazon.com/architecture

If you have any questions or concerns, you can contact the AWS Support Team on the community forums and via AWS Premium Support at: http://aws.amazon.com/support

Sincerely,
Amazon Web Services
  • AWS Console イベントを見ると一覧で表示されている。
    f:id:kenzo0107:20170418095219p:plain

  • AWS Console 詳細を見ると Notice が出ている。
    f:id:kenzo0107:20170411215054p:plain

ToDO

ボリュームタイプによって異なります。

今回は EBS ボリューム対応について記載してます。

対応

対象インスタンスが多かったのでローカルPC (macOS) から awscli でインスタンス停止→起動するシェル作成しました。
本番環境で利用されるインスタンスも含まれていた為、1件ずつ実行することとしました。

事前準備

$ brew install awscli jq
  • 各アカウント毎のアクセスキー、シークレットキー等設定
$ aws configure --profile <profile>
$ grep 'profile' ~/.aws/config

インスタンスの停止・再起動シェル

gist.github.com

以下のように実行すると
インスタンスが起動(running)していれば
停止後、再び起動し、ステータスチェックをするようにしました。

$ sh stop_and_start_ec2_instance.sh "<profile>" "<instance id>"

イベント情報取得シェル

.aws/config で設定されている profile を全てチェックし
未対応インスタンスのみ表示する様修正しました。

gist.github.com

結果確認

大体 1インスタンス 5分程度で完了。
問題なく停止起動でき、対象イベントが一覧から消えたことを確認しました♪

所感

メンテ対象インスタンスの Region が northeast に集中していたのが気になる点でした。
このインスタンス何に使ってるんだっけ?とならない様に、インスタンスやprivate key の命名ルール必須と感じました。

以上です。

Docker コマンド早見表

f:id:kenzo0107:20170414222435p:plain

バージョン

docker --version

Docker version 17.04.0-ce, build 4845c56

コンテナ

docker ps                     # running コンテナ一覧
docker ps -a                  # 全コンテナ一覧表示
docker start <CONTAINER ID>   # コンテナ起動
docker restart <CONTAINER ID> # コンテナ再起動
docker stop <CONTAINER ID>    # コンテナ終了
docker kill <CONTAINER ID>    # コンテナ強制終了
docker attach <CONTAINER ID>  # コンテナへアタッチ
docker top <CONTAINER ID>     # コンテナプロセスを表示
docker logs -f <CONTAINER ID> # コンテナログ表示
docker inspect <CONTAINER ID> # コンテナ情報表示
docker rm <CONTAINER ID>      # コンテナID指定でコンテナ削除
dockre rm <CONTAINER NAME...> # コンテナ名(複数)指定でコンテナ削除
docker container prune        # 停止コンテナを削除

dockr run -it -h <host name> <IMAGE>[:TAG] <command>  # イメージよりコンテナ起動 command 実施

イメージ

docker pull <IMAGE NAME>[:tag]     # イメージダウンロード
docker images ls              # イメージ一覧
docker inspect <IMAGE ID>     # イメージ情報表示
docker rmi <IMAGE ID>         # イメージ削除

イメージ作成

docker build -t NAME[:TAG]
docker commit -m "<comment here>" <CONTAINER ID> <IMAGE NAME>[:TAG]

Docker Compose

docker-compose up -d    # デタッチモードでイメージよりコンテナ起動
docker-compose ps       # コンテナ一覧表示
docker-compose stop     # docker compose 管理下全てのコンテナ停止
docker-compose start    # docker compose 管理下全てのコンテナ起動
docker-compose rm       # docker compose 管理下全ての停止コンテナ削除

Docker Compose チュートリアル

前回 Vagrant (Ubuntu)で Docker, Docker Compose 環境構築しました。

kenzo0107.hatenablog.com

上記環境を元に Docker Compose チュートリアルを実行しました。

完全な備忘録です。

プロジェクトディレクトリ作成

vagrant%$ mkdir composetest && cd composetest

app.py 作成

from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
    count = redis.incr('hits')
    #return 'Hello World! I have been seen {} times.\n'.format(count)
    return 'Hello from Docker! I have been seen {} times.\n'.format(count)

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

requirements.txt 作成

pip でインストールするモジュールを列挙します。

flask
redis

Dockerfile 作成

FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

docker-compose.yml 作成

version: '2'
services:

  web:
    build: .
    ports:
     - "5000:5000"
    volumes:
     - .:/code

  redis:
    image: "redis:alpine"

Docker Compose でイメージビルド、コンテナ起動

vagrant%$ docker-compose up

Creating composetest_web_1
Creating composetest_redis_1
Attaching to composetest_redis_1, composetest_web_1
redis_1  | 1:C 13 Apr 14:25:38.483 # Warning: no config file specified, using the default config. Inorder to specify a config file use redis-server /path/to/redis.conf
redis_1  |                 _._
redis_1  |            _.-``__ ''-._
redis_1  |       _.-``    `.  `_.  ''-._           Redis 3.2.8 (00000000/0) 64 bit
redis_1  |   .-`` .-```.  ```\/    _.,_ ''-._
redis_1  |  (    '      ,       .-`  | `,    )     Running in standalone mode
redis_1  |  |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
redis_1  |  |    `-._   `._    /     _.-'    |     PID: 1
redis_1  |   `-._    `-._  `-./  _.-'    _.-'
redis_1  |  |`-._`-._    `-.__.-'    _.-'_.-'|
redis_1  |  |    `-._`-._        _.-'_.-'    |           http://redis.io
redis_1  |   `-._    `-._`-.__.-'_.-'    _.-'
redis_1  |  |`-._`-._    `-.__.-'    _.-'_.-'|
redis_1  |  |    `-._`-._        _.-'_.-'    |
redis_1  |   `-._    `-._`-.__.-'_.-'    _.-'
redis_1  |       `-._    `-.__.-'    _.-'
redis_1  |           `-._        _.-'
redis_1  |               `-.__.-'
redis_1  |
redis_1  | 1:M 13 Apr 14:25:38.486 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis_1  | 1:M 13 Apr 14:25:38.486 # Server started, Redis version 3.2.8
redis_1  | 1:M 13 Apr 14:25:38.486 # WARNING overcommit_memory is set to 0! Background save may failunder low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf andthen reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
redis_1  | 1:M 13 Apr 14:25:38.486 * The server is now ready to accept connections on port 6379
web_1    |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
web_1    |  * Restarting with stat
web_1    |  * Debugger is active!
web_1    |  * Debugger PIN: 135-466-976
web_1    | 192.168.35.1 - - [13/Apr/2017 14:25:53] "GET / HTTP/1.1" 200 -
web_1    | 192.168.35.1 - - [13/Apr/2017 14:25:53] "GET /favicon.ico HTTP/1.1" 404 -

ブラウザにアクセスしてみる。

f:id:kenzo0107:20170413233236p:plain

表示されました!

リロードする度に以下数字部分がインクリメントされるのが確認できます。

Hello from Docker! I have been seen 1 times.

便利♪

WEB+DB PRESS Vol.98

WEB+DB PRESS Vol.98

Vagrant (Ubuntu) に Docker, Docker Compose インストール

f:id:kenzo0107:20170413222957p:plain

概要

開発環境構築用に作成した、
Vagrant (Ubuntu) に Docker と Docker Compose をインストールする手順をまとめました。

Vagrantfile 作成

かなりシンプルにしてます。

  • Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.network "private_network", ip: "192.168.35.101"
end

vagrant provision で docker compose をインストールすることも可能ですが
vagrant ならではの provision だと他環境で利用できない為、OS上でインストールする方針です。

VM 起動

MacOS%$ vagrant up
...
しばし待つ
...

MacOS%$ vagrant ssh

// ssh ログイン成功
vagrant%$ 

Vagrant Ubuntu 環境情報確認

vagrant%$ lsb_release -a

No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.5 LTS
Release:        14.04
Codename:       trusty

カーネルバージョン確認

vagrant%$ uname -r
3.13.0-116-generic

カーネルバージョンが 3.10 より低いとバグを引き起こす危険性があるので NG。
別のカーネルバージョンの高い box を使用しましょう。

古いバージョンをアンインストール

vagrant%$ sudo apt-get remove docker docker-engine

extra パッケージインストール

Docker に aufs ストレージを使用許可する為です。

vagrant%$ sudo apt-get update
vagrant%$ sudo apt-get -y install \
    wget \
    linux-image-extra-$(uname -r) \
    linux-image-extra-virtual

Docker インストール

// Docker インストール
vagrant%$ wget -qO- https://get.docker.com/ | sh

// Docker バージョン確認
vagrant%$ docker --version
Docker version 17.04.0-ce, build 4845c56

// vagrant ユーザを docker グループに追加 (一旦ログアウトしログインし直すと有効になることを確認できます)
vagrant%$ sudo usermod -aG docker vagrant

Docker Compose インストール

vagrant%$ curl -L "https://github.com/docker/compose/releases/download/1.12.0/docker-compose-$(uname -s)-$(uname -m)" >  ~/docker-compose

// 実行権限付与
vagrant%$ chmod +x ~/docker-compose

// 実行パス移動
vagrant%$ sudo mv docker-compose /usr/bin/

// Docker Compose バージョン確認
vagrant%$ docker-compose --version
docker-compose version 1.12.0, build b31ff33

一度ログアウトし再度ログイン

vagrant%$ exit
MacOS%$ vagrant ssh
vagrant%$ 

メモリとスワップ利用量の調整

Docker を使用していない時にメモリのオーバーヘッドとパフォーマンス劣化を低減させる様、
GRUB (GRand Unified Bootloader: グラブ or ジーラブ) に設定する必要があります。

vagrant%$ sudo vi /etc/default/grub

# GRUB_CMDLINE_LINUX=""
GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"
  • GRUB (GRand Unified Bootloader: グラブ or ジーラブ) 更新
vagrant%$ sudo update-grub

// 念の為、再起動
vagrant%$ sudo reboot

以上で準備完了です♪

早速試してみる

簡単なチュートリアルとして nginx コンテナを立ててみます。

vagrant%$ docker run --rm -p 80:80 nginx:mainline-alpine

Unable to find image 'nginx:mainline-alpine' locally
mainline-alpine: Pulling from library/nginx
709515475419: Already exists
4b21d71b440a: Pull complete
c92260fe6357: Pull complete
ed383a1b82df: Pull complete
Digest: sha256:5aadb68304a38a8e2719605e4e180413f390cd6647602bee9bdedd59753c3590
Status: Downloaded newer image for nginx:mainline-alpine

ブラウザアクセス

ローカルの Mac からブラウザでアクセス

http://192.168.35.101

※192.168.35.101 … Vagrant で指定した private ip

f:id:kenzo0107:20170413224153p:plain

問題なく Welcome ページが表示されました。

先程のログに以下のようにアクセスログが出力されるのがわかります。

192.168.35.1 - - [13/Apr/2017:10:45:46 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36" "-"

MacOSVagrant → Docker
とアクセスできるようになりました♪

追記

今回作成した Box を Vagrant Cloud に置きました。

https://atlas.hashicorp.com/kenzo0107/boxes/ubuntu14.04.5LTS-docker-dockercompose/

こちら設定を元にこれから様々な環境構築を記載していきたいと思います♪

参照

Terraform でキーペア登録し起動した EC2 に SSH接続

f:id:kenzo0107:20170327212027p:plain

今回やること

  • Mac ローカルで公開鍵、秘密鍵を生成
  • Terraform でEC2起動、セキュリティグループで SSH (ポート22)許可、key-pair 登録

Terraform の Hello World 的なチュートリアルと思っていただけたら幸いです。

環境

  • Mac OS 10.12.3 (Sierra)
  • Terraform 0.9.1

公開鍵、秘密鍵生成

RSAフォーマットで鍵を生成します。

$ ssh-keygen -t rsa

Enter file in which to save the key (/Users/kenzo_tanaka/.ssh/id_rsa): /Users/kenzo_tanaka/.ssh/terraform-test
Enter passphrase (empty for no passphrase): (空のままEnter)
Enter same passphrase again: (空のままEnter)
...
...

// 生成されたか確認
$ ls ~/.ssh/terraform-test*

/Users/kenzo_tanaka/.ssh/terraform-test      # 秘密鍵
/Users/kenzo_tanaka/.ssh/terraform-test.pub # 公開鍵

公開鍵を起動したEC2インスタンスに登録し
秘密鍵でアクセスします。

以下のように利用する予定です。

$ ssh -i ~/.ssh/terraform-test <ec2 user>@<ec2 public ip>

Terraform 設定ファイル

  • Point !

    • resource "aws_key_pair" で使用する公開鍵設定をしています。
    • resource "aws_security_group"SSH(ポート22)を開いてます。
    • resource "aws_instance" で使用しているセキュリティグループの指定は vpc_security_group_ids を利用
      • セキュリティグループの条件追加・削除する場合にインスタンスを一度削除し作り直すことをしたくない場合に vpc_security_group_ids を利用すると良いです。
  • main.tf

provider "aws" {
  access_key = "${var.access_key}"
  secret_key = "${var.secret_key}"
  region     = "${var.region}"
}

resource "aws_instance" "example" {
  ami           = "${lookup(var.amis, var.region)}"
  instance_type = "t2.nano"
  key_name      = "${aws_key_pair.auth.id}"
  vpc_security_group_ids = ["${aws_security_group.default.id}"]
}

resource "aws_key_pair" "auth" {
  key_name   = "${var.key_name}"
  public_key = "${file(var.public_key_path)}"
}

resource "aws_security_group" "default" {
  name        = "terraform_security_group"
  description = "Used in the terraform"

  # SSH access from anywhere
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
  • variables.tf
variable "access_key" {}
variable "secret_key" {}
variable "region" {
  default = "ap-northeast-1"
}

variable "amis" {
  type = "map"
  default = {
    us-east-1 = "ami-13be557e"
    us-west-2 = "ami-21f78e11"
    ap-northeast-1 = "ami-1bfdb67c"
  }
}

variable "key_name" {
  description = "Desired name of AWS key pair"
}

variable "public_key_path" {
  description = <<DESCRIPTION
Path to the SSH public key to be used for authentication.
Ensure this keypair is added to your local SSH agent so provisioners can
connect.

Example: ~/.ssh/terraform.pub
DESCRIPTION
}
  • terraform.tfvars
access_key = "A******************Q"
secret_key = "q**************************************Z"

key_name = "terraform-test"
public_key_path = "~/.ssh/terraform-test.pub"

いざ実行

  • 実行計画確認
$ terraform plan
  • 実行
$ terraform apply

確認

  • AWS コンソール上で起動確認

    • キーペアに terraform-test が指定されています。
    • vpc, subnet も自動的にアタッチされてます。

f:id:kenzo0107:20170327214009p:plain

  • キーペア
    一応キーペアを見てみると登録されているのがわかります。
    f:id:kenzo0107:20170327214404p:plain

  • セキュリティグループ確認
    f:id:kenzo0107:20170327214628p:plain

  • SSH ログイン確認

$ ssh -i ~/.ssh/terraform-test ubuntu@ec2-54-65-244-25.ap-northeast-1.compute.amazonaws.com

f:id:kenzo0107:20170327214837p:plain

無事SSHログインできました!

所感

Terraform by HashiCorp を見ながら各パラメータの利用意図を確認しながら
設定してみましたが
パラメータの説明自体はざっくりで利用方法まではわからないです。

Teffaform のチュートリアルに始まり
その他 Stack Overflow
適宜パターンを蓄積していく学習が程よいと思います。

DevOpsを支えるHashiCorpツール大全 ThinkIT Books

DevOpsを支えるHashiCorpツール大全 ThinkIT Books

参考

Terraformで立てたEC2に後からSGを追加しようとするとEC2が再作成される - tjinjin's blog