Terraformを小さく初めてみよう
そもそもTerraformって?
AWSやCGPやAzureなどなどに対応したマルチクラウドなIaaS構築をコード化できるもの
Terraformをいじってみる
Terraform歴はざっと2日のペーペーですが、本番で小さく始められそうなのでその備忘禄。
環境
・Terraform v0.6.9
・CentOS6.6
※インストールはいたるところで書かれているので割愛します。簡単です。
安定のClassmethodさんブログ参考にしました↓
AWSでTerraformに入門 | Developers.IO
ここら辺で使ってみる
うちは小さいサービスが次々生まれるので、都度VPC作ってSubnetをAZごとに作ってRouteTable作って監視サーバーいるVPCとPeering張ってそこからの通信をSecurityGroupで開けたりとか・・
この辺いつも同じ構成なわけで、もうやりたかない。。
が、手でポチポチやってたので人に引き継ぎやすいジョブにしないと、、
マネコンのキャプチャ取って手順書くとかないし、やはりAWSだしCloudFormationか?でも実行時しかエラー判断できないしjsonだしコメント入れられないから適当にやっといてと言いづらい・・
こんな感じを作る↓
AnsibleとSpinnakerは試してみた
Ansibleは既に使ってたので、AnsibleのAWSモジュールでなんとか出来たらいいなぁと思ってました(これで済めば1番やっといてと言いやすいw)。ただ半年くらい前はPeering作れなかったり、R53のプライベートゾーンにVPCアタッチできなかったり(これはAnsible2.0で出来るみたい)なので片手落ちなものが出来るのでやめときました。
http://docs.ansible.com/ansible/route53_module.html
次はNetflixがSpinnakerというOSSを出したので試しました。UIはリッチでマルチクラウドで良さそうでしたが結構重い、、キャッシュにクセがありメンバーもはまるかなぁってのと裏でCassandraを使っているらしくCassandraにトラウマがあったのでやめました;
遠回りしましたが、じゃあTerraformでも試すべかと。
いい感じに熟してきてると思います。情報も多く改善もされまくってますね。
よいなぁ~と思った点
- terraform plan xxx.tfでドライラン出来るので慣れてない人にも優しい
- HCL(Hashicorp Configuration Language)が可読性高く慣れてなくても読める
- AnsibleよりCloudリソース多い(そりゃそうだよね)
- 依存関係は自動でよろしくやってくれる(depends_onで明示的にもできる)
- かる~い
- terraform graph | dot -Tpng > ./graph.pngでグラフが作れる。こんな感じ↓ リソースの量が増えればカオスなマップになるでしょうねきっと^^;
※実際に下の方に張ったテンプレートの実行結果をグラフ化しました。
※事前にsudo yum install -y graphviz graphviz-gdしておく
- crash.logが出る。1回クラッシュしたけどこんな感じ出てくれた↓
[root@tfsvr defaultvpc]# tail crash.log 2016/01/11 21:44:13 [DEBUG] vertex provider.aws (close), got dep: aws_route.r_default2 2016/01/11 21:44:13 [DEBUG] vertex provider.aws (close), got dep: aws_route.r_default3 2016/01/11 21:44:13 [DEBUG] vertex root, got dep: provider.aws (close) 2016/01/11 21:44:13 [DEBUG] vertex root, got dep: provisioner.local-exec 2016/01/11 21:44:13 [DEBUG] vertex root, got dep: provisioner.remote-exec 2016/01/11 21:44:13 [DEBUG] waiting for all plugin processes to complete... 2016/01/11 21:44:13 [DEBUG] /usr/local/src/terraform_0.6.9/terraform-provisioner-remote-exec: plugin process exited 2016/01/11 21:44:13 [DEBUG] /usr/local/src/terraform_0.6.9/terraform-provisioner-local-exec: plugin process exited 2016/01/11 21:44:13 [DEBUG] /usr/local/src/terraform_0.6.9/terraform-provisioner-chef: plugin process exited 2016/01/11 21:44:13 [DEBUG] /usr/local/src/terraform_0.6.9/terraform-provisioner-file: plugin process exited
むむむって思った点
- 既存環境にはテンプレート当てれない(多分)。
ステート持つのでステートをファイルにエクスポートしてからテンプレート起こすみたなことが出来そうな気がしないでもないですが今後に期待 - 冪等性はない!?のかな
冪等性があるとも謳ってないけど。
そもそもイケてないテンプレートの書き方をしたのですが、ルーティングテーブルを作成する"aws_route_table"でルートAを追加し、ルーティングテーブルエントリを作成する"aws_route"で同じルートテーブルIDに対してルートBを追加した場合
・まずドライランは成功します。
・1回目はaws_route_tableで追加されるルートAとaws_routeのルートBが両方追加されたルートテーブルができます。
・2回目はaws_routeに書かれたルートBがaws_route_tableにはないので削除されました。(毎回aws_route_tableの後にaws_routeが読まれればいいのですが違うのかな?)
・3回目は1回目と同じく全てのルートAもルートBも追加されます。あとは繰り返しですが何度やっても同じ構成に収束はしないですね;
※結局はaws_route_tableにルートAもルートBも書くべきってだけの話ですが、できれば標準のTerraformリソース使ってる範囲ではエラーで怒られたい
まずは小さく始めよう^^
とりあえずは、冒頭に戻って最初の想いを忘れずに、使い切りでいいので"AWSあるある構成"を誰がやっっても同じになる。そして確認も簡単にできればOK。
以下のようなテンプレートを作りました。
・VPC 1
・Subnet 2(AZごと)
・SecurityGroup 2(EC2用、ELB用)
・ELB 1
・EC2 2(MultiAZ、ELB追加済)
・InternetGateWay 1
・RouteTable 1
・VPCPeering 1
・既存RouteTableにルート追加
・既存SecurityGroupにルール追加
・既存R53にVPCアタッチ
※鍵は鍵を配置したOSをAMIにしてしまってるのでTerraformでは作ってません。ただ作れます。
変数はファイルで外出しし、変数だけ変えて汎用的に使えるようにしました(引数で渡したり環境変数に持たせたりもできます)。-var-fileで変数ファイルを食わせます。
applyで実行ですがテンプレートファイルとなるxxx.tfファイルを指定しないとカレントディレクトリのxxx.tfファイルを勝手に読み込みます。テンプレートファイルは分割もOKです。
用途別にディレクトリを分けるのがいいかと思います。
[root@tfsvr defaultvpc]# pwd /usr/local/src/terraform/defaultvpc [root@tfsvr defaultvpc]# terraform apply default.tf -var-file /root/terraform.tfvars
"xxxx"でマスクしているところはご自身の環境に合わせた値を入れて、"example"を"サービス名"に置換してもらえば使えるかと。多分・・
作成も削除もだいたい3分弱でできました
SGとかEC2のオプションやIPは一例ですので、それぞれポリシーに合わせて適宜変えてもらえればと
何かあればコメントください><
[root@tfsvr defaultvpc]# cat /root/terraform.tfvars ## ## よくあるAWS構成Template ## 1vpc,2subnet(multiaz),igw,routetable,peering*2,securitygroup*2,ec2*2,elb ## ## usage: ## exampleをサービス名に変更 ## (例:service1のInternetGatewayならexamplegw ==> service1gw) ## IPアドレスをサービスに割り当てたものに変更 ## (例:service1のVPCならネットワークアドレスを172.1.0.0/16 == > 172.2.0.0/16) ## ## access_key = "xxxxxxxxxxx" secret_key = "xxxxxxxxxxx" ### AWS region_oregon = "us-west-2" az_oregon1 = "us-west-2a" az_oregon2 = "us-west-2b" ##region_tokyo = "ap-northeast-1" ##az_tokyo1 = "ap-northeast-1a" ##az_tokyo2 = "ap-northeast-1c" awsid_example = "xxxxxxxxxxx" ### IGW igw_example = "example" ### VPC vpc_example = "example" ciderblock_example = "172.1.0.0/16" dhcpoptions_example = "dopt-xxxxxxxxxxx" vpc_kanshi ="vpc-xxxxxxxxxxx" vpcpeering_example1 = "kanshi--example" ### Subnet subnet_example1 = "example-2a" subnet_example2 = "example-2b" ciderblock_example1 = "172.1.0.0/24" ciderblock_example2 = "172.1.1.0/24" ### RouteTable rt_example = "example" ciderblock_any = "0.0.0.0/0" ciderblock_kanshi = "xxxxxxxxxxx/16" rt_kanshi ="rtb-xxxxxxxxxxx" ### SG sg_example1 = "example-web" sg_example2 = "example-lb" ciderblock_office1 = "xxxxxxxxxxx/32" sg_zabbix = "sg-xxxxxxxxxxx" ### EC2 instancetype_example = "t2.micro" ec2_example1 = "example-web01" ec2_example2 = "example-web02" ### ELB elb_example = "example-weblb" ### R53 route53_privatezone = "xxxxxxxxxxx"
[root@tfsvr defaultvpc]# cat default.tf variable "access_key" {} variable "secret_key" {} #variable "region_tokyo" {} variable "region_oregon" {} variable "igw_example" {} variable "vpc_example" {} variable "subnet_example1" {} variable "subnet_example2" {} variable "instancetype_example" {} variable "ciderblock_example" {} variable "ciderblock_example1" {} variable "ciderblock_example2" {} variable "rt_example" {} #variable "az_tokyo1" {} #variable "az_tokyo2" {} variable "az_oregon1" {} variable "az_oregon2" {} variable "ciderblock_any" {} variable "elb_example" {} variable "ec2_example1" {} variable "ec2_example2" {} variable "dhcpoptions_example" {} variable "vpc_kanshi" {} variable "vpcpeering_example1" {} variable "vpcpeering_example2" {} variable "awsid_example" {} variable "ciderblock_kanshi" {} variable "rt_kanshi" {} variable "sg_example1" {} variable "sg_example2" {} variable "sg_kanshizabbix" {} variable "ciderblock_office1" {} variable "route53_privatezone" {} variable "images" { default = { us-east-1 = "" us-west-2 = "ami-xxxxxxxx" us-west-1 = "" eu-west-1 = "" eu-central-1 = "" ap-southeast-1 = "" ap-southeast-2 = "" ap-northeast-1 = "" } } provider "aws" { access_key = "${var.access_key}" secret_key = "${var.secret_key}" region = "${var.region_oregon}" } ### IGW resource "aws_internet_gateway" "defaultgw" { vpc_id = "${aws_vpc.defaultvpc.id}" tags { Name = "${var.igw_example}" } } ### VPC resource "aws_vpc" "defaultvpc" { cidr_block = "${var.ciderblock_example}" enable_dns_hostnames = true tags { Name = "${var.vpc_example}" } } ### DHCP Option resource "aws_vpc_dhcp_options_association" "defaultdns" { vpc_id = "${aws_vpc.defaultvpc.id}" dhcp_options_id = "${var.dhcpoptions_example}" } ### R53 VPC Add resource "aws_route53_zone_association" "private" { zone_id = "${var.route53_privatezone}" vpc_id = "${aws_vpc.defaultvpc.id}" } ### Subnet resource "aws_subnet" "defaultsubnet1" { vpc_id = "${aws_vpc.defaultvpc.id}" cidr_block = "${var.ciderblock_example1}" availability_zone = "${var.az_oregon1}" tags { Name = "${var.subnet_example1}" } } resource "aws_subnet" "defaultsubnet2" { vpc_id = "${aws_vpc.defaultvpc.id}" cidr_block = "${var.ciderblock_example2}" availability_zone = "${var.az_oregon2}" tags { Name = "${var.subnet_example2}" } } ### Route resource "aws_route" "r_kanshi" { route_table_id = "${var.rt_kanshi}" destination_cidr_block = "${var.ciderblock_example}" vpc_peering_connection_id = "${aws_vpc_peering_connection.kanshipeering.id}" } ### RouteMainTable association resource "aws_main_route_table_association" "a" { vpc_id = "${aws_vpc.defaultvpc.id}" route_table_id = "${aws_route_table.r.id}" } ### RouteTable resource "aws_route_table" "r" { vpc_id = "${aws_vpc.defaultvpc.id}" route { cidr_block = "${var.ciderblock_any}" gateway_id = "${aws_internet_gateway.defaultgw.id}" } route { cidr_block = "${var.ciderblock_kanshi}" vpc_peering_connection_id = "${aws_vpc_peering_connection.kanshipeering.id}" } tags { Name = "${var.rt_example}" } } ### VPC Peering resource "aws_vpc_peering_connection" "kanshipeering" { peer_owner_id = "${var.awsid_example}" peer_vpc_id = "${aws_vpc.defaultvpc.id}" vpc_id = "${var.vpc_kanshi}" auto_accept = true tags { Name = "${var.vpcpeering_example1}" } } ### Instance resource "aws_instance" "defaultinstance1" { ami = "${var.images.us-west-2}" availability_zone = "${var.az_oregon1}" instance_type = "${var.instancetype_example}" subnet_id = "${aws_subnet.defaultsubnet1.id}" security_groups = ["${aws_security_group.defaultec2sg.id}"] associate_public_ip_address = "true" root_block_device = { volume_type = "gp2" volume_size = "20" } tags { Name = "${var.ec2_example1}" } } resource "aws_instance" "defaultinstance2" { ami = "${var.images.us-west-2}" availability_zone = "${var.az_oregon2}" instance_type = "${var.instancetype_example}" subnet_id = "${aws_subnet.defaultsubnet2.id}" security_groups = ["${aws_security_group.defaultec2sg.id}"] associate_public_ip_address = "true" root_block_device = { volume_type = "gp2" volume_size = "20" } tags { Name = "${var.ec2_example2}" } } ### SecurityGroup resource "aws_security_group" "defaultec2sg" { name = "exampleec2sg" description = "Used in the terraform" vpc_id = "${aws_vpc.defaultvpc.id}" # kanshi access from anywhere ingress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["${var.ciderblock_kanshi}"] } # office access from anywhere ingress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["${var.ciderblock_office1}"] } # elb HTTP access from anywhere ingress { from_port = 80 to_port = 80 protocol = "tcp" security_groups = ["${aws_security_group.defaultelbsg.id}"] } tags { Name = "${var.sg_example1}" } } resource "aws_security_group" "defaultelbsg" { name = "exampleelbsg" description = "Used in the terraform" vpc_id = "${aws_vpc.defaultvpc.id}" # office HTTP access from anywhere ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["${var.ciderblock_office1}"] } tags { Name = "${var.sg_example2}" } } resource "aws_security_group_rule" "kanshizabbixsg" { type = "ingress" from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["${var.ciderblock_example}"] security_group_id = "${var.sg_kanshizabbix}" } ### ELB resource "aws_elb" "defaultelb" { name = "${var.elb_example}" listener { instance_port = 80 instance_protocol = "http" lb_port = 80 lb_protocol = "http" } health_check { healthy_threshold = 2 unhealthy_threshold = 2 timeout = 5 target = "HTTP:80/" interval = 10 } # The instance is registered automatically instances = ["${aws_instance.defaultinstance1.id}","${aws_instance.defaultinstance2.id}"] subnets = ["${aws_subnet.defaultsubnet1.id}","${aws_subnet.defaultsubnet2.id}"] security_groups = ["${aws_security_group.defaultelbsg.id}"] cross_zone_load_balancing = true }
所感
なにやるにもTerraformでやるようになってしまった。もうぽちぽちする気が起きなくなった。
NETFLIXのSpinnakerをさわってみた備忘禄
マルチクラウドのインフラアプリデリバリの自動化と管理ツールがNETFLIXから11/17にオープンソースで公開されたのでさわって見た。
NETFLIXがGoogle,Microsoft,Pivotalと共同開発したそうです。
名前は「Spinnaker」(スピネーカー)、意味は"三角形の帆"ですが由来は不明です。
- NETFLIXブログ
Netflix、マルチクラウド対応の継続的デリバリを実現する「Spinnaker」をオープンソースで公開 - Publickey
- Pivotalブログ
Cloud Native Continuous Delivery With Netflix Spinnaker | Pivotal P.O.V.
- 本家
The Netflix Tech Blog: Global Continuous Delivery with Spinnaker
Spinnaker: Global Continuous Delivery
- git
GCPのインスタンスに入れてみる
GCPのSDKまわりの設定をしておく
・CloudSDKの認証
Cloud SDK>gcloud auth login
・projectidセット
Cloud SDK>gcloud config set project xxxxx-xxxxxxx-xxx
・確認
Cloud SDK>gcloud config list project [core] project = xxxxx-xxxxxxx-xxx
インスタンス作成
"spinnaker-test"という名前でインスタンスを作ります。マシンタイプは適当に。
Cloud SDK>gcloud compute instances create spinnaker-test --image ubuntu-14-04 --machine-type n1-standard-2 --scopes compute-rw Created [https://www.googleapis.com/compute/v1/projects/xxxx-xxx-xxxxxx/zones/asia-east1-a/instances/spinnaker-test]. NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS spinnaker-test asia-east1-a n1-standard-2 xx.xx.xx.xx yy.yy.yy.yy RUNNING
"Spinnaker"テスト済OSは以下ということで、Ubuntuにしました。GCPには14.04 LTSがあるのでそれで。
Ubuntu 14.04 LTS
Mac OS X 10.11
サーバーログイン
作ったサーバーにログイン。
手っ取り早く以下のコマンドでログインする。
Cloud SDK>gcloud compute ssh spinnaker-test
GCPのGUIからでもターミナルからでもログインはOK牧場。
Spinnakerインストール
インストールシェルが用意されてるのでcurlで叩き、Cloud(今回google)とかRegion(今回asia-east1)とかを入力する。
Cassandra,Redis,Gradleなどがパッケージされてるようです。
ore@spinnaker-test:~$ sudo su - root@spinnaker-test:~# bash <(curl --silent https://spinnaker.bintray.com/scripts/InstallSpinnaker.sh) Determined that you are running on google infrastructure. Specify a cloud provider (aws|google|none|both): google Specify default google region: asia-east1 Specify default google zone: asia-east1-a gpg: keyring `/tmp/tmpvn7suf44/secring.gpg' created gpg: keyring `/tmp/tmpvn7suf44/pubring.gpg' created gpg: requesting key C7917B12 from hkp server keyserver.ubuntu.com gpg: /tmp/tmpvn7suf44/trustdb.gpg: trustdb created gpg: key C7917B12: public key "Launchpad chrislea" imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1) : : : Setting up spinnaker-igor (1.4.0-3) ... Setting up spinnaker-orca (1.21.0-3) ... Setting up spinnaker-rosco (0.12.0-3) ... Setting up spinnaker-rush (1.21.0-3) ... Setting up ssl-cert (1.0.33) ... Processing triggers for ureadahead (0.100.0-16) ... Processing triggers for ufw (0.34~rc-0ubuntu2) ... Setting up spinnaker-deck (2.435.0-3) ... Setting up spinnaker (0.11.0-3) ... Rewriting deck settings in "/var/www/settings.js". * Restarting web server apache2 [ OK ] Processing triggers for libc-bin (2.19-0ubuntu6.6) ... spinnaker start/running To stop all spinnaker subsystems: sudo stop spinnaker To start all spinnaker subsystems: sudo start spinnaker To modify the available cloud providers: Edit: /etc/default/spinnaker And/Or: /opt/spinnaker/config/spinnaker-local.yml Then restart clouddriver and rosco with: sudo service clouddriver restart sudo service rosco restart
conf類はこの辺です。
root@spinnaker-test:/opt/spinnaker# ls bin cassandra config install pylib scripts
Spinnakerの停止、起動、確認
root@spinnaker-test:~# stop spinnaker spinnaker stop/waiting root@spinnaker-test:~# status spinnaker spinnaker stop/waiting root@spinnaker-test:~# start spinnaker spinnaker start/running root@spinnaker-test:~# status spinnaker spinnaker start/running
ポートフォワード
SpinnakerはGCPの場合localhostの9000番で起動するようです。 ですので自端末からはポートフォワードして繋ぎます。ポートフォワードはどのやり方でもいいのですがgcloud使ってみました。 --ssh-flagでsshのオプションを渡すのですが、Windowsからgcloudコマンドでやる場合は以下のようにsshに渡すオプションを細かく切ってあげないとエラーする。
エラー
Cloud SDK>gcloud compute ssh spinnaker-test --ssh-flag="-L 8084:localhost:8084" --ssh-flag="-L 9000:localhost:9000" --ssh-flag="-L 8087:localhost:8087" ssh: unknown option "-L 8084:localhost:8084" ssh: unknown option "-L 9000:localhost:9000" ssh: unknown option "-L 8087:localhost:8087"
OK
Cloud SDK>gcloud compute ssh spinnaker-test --ssh-flag="-L" --ssh-flag="8084:localhost:8084" --ssh-flag="-L" --ssh-flag=" 9000:localhost:9000" --ssh-flag="-L" --ssh-flag="8087:localhost:8087"
ブラウザ表示
トップページはこんな感じ。まだ何もない。ちなみにFirefox、IEではなぜか開かないのでChromeで!
公式ガイドにある"Getting Start"してみる
Bake & Deployでイメージからサーバー立ててLBに配置する。
Create Application
右上のActionから"CreateApplication"し、必要な項目を画面のように入れCreateする。
Createされた。
Create Security Group
"Security Group"タブをクリックして、右上の"Create Security Group"をクリックし、必要な項目を画面のように入れNext。
ここでは、ソースはAny(0.0.0.0/0)からポートは80番ポートでCreateする。
Createされた。
Create Loadbalancer
"LOAD BALANCERS"タブをクリックして、右上の"Create Loadbalancer"をクリックし、画面の項目を入力する。
項目を入れて行く。
Createされた。
GCP側から見ても出来てる。
Create a deployment pipeline
PIPELINESタブいって、右上の"Configure"して"Create New"をクリック。
Typeを"Pipeline"
Pipeline Nameを"Bake & Deploy To Test"として"Create"
Createされた。
"Add Stage"をクリックし、TypeをBakeを選ぶ。
※Bake:Bakes an image in the specified region
Packageに"redis-server"と入力 ※Redisではないけど;
"Save Change"をクリック。
このStageのTypeでJenkinsのジョブ実行したり、Canary的なテストをしたり、Script実行したりとできるぽいです。
"Add Stage"をクリックし2つめのステージをAdd
Typeに"Deploy"を選択。
"Add Server Group"をクリック。
Template selectionで"Continue without a template"をクリック。
アカウント、リージョン、ゾーン、名前(Stack)を入力する。
※キャプチャではゾーン入れてないですが入れてないとこけました。
作ったLoadBalancerを選ぶ。
作ったSecurityGroupを選ぶ。
マシンタイプと台数を選ぶ。
"save change"する。
実行してみる
"Bake & Deploy To Test"の右端の"Start Manual Execution"をクリックする。
"Run"
実行される。
デプロイ正常終了。
LB配下にサーバーが作られてますね。GCP側からも確認できます。
80番でリッスンしてないので赤ですが
git連携とかやってないんであれですが、、近々やったら更新します。
使えそうなAPI
curl -X POST localhost:7002/config-refresh
curl localhost:7002/credentials
curl localhost:8084/securityGroups
AWSもやるべ
ほとんどは以下の"AWS Setup"の手順通りでいけると思います。
VPC、subnet作成。 (例、defaultvpc、defaultvpc.internal.ap-northeast-1a) IAM作成 キーペア作成し/home/spinnaker/.aws/credentialsに chmod 400 で配置 ユーザー作成とそのCredentials(アクセスキーとシークレットキーのやつ)をSpinnakerサーバーの/home/spinnaker/.aws/credentialsに配置
細かい点はオフィシャルの手順を確認してもらえたらと。
手順にない部分で数点
/etc/default/spinnaker
以下ファイルでAWS有効にしたり、デフォルトのリージョン入れる
# Spinnaker system defaults ## Amazon # If you plan on using Amazon AWS set this to true SPINNAKER_AWS_ENABLED=true #SPINNAKER_AWS_ENABLED=false # Default region you desire to operate in SPINNAKER_AWS_DEFAULT_REGION=ap-northeast-1
subnetの命名規則
命名規則に沿ってないとsubnetとが出て来ません。こんな感じで↓
命名規則がこれです。 {purpose}.{vpcName}.{availabilityZone}
clouddriver/AmazonSubnetProvider.groovy at master · spinnaker/clouddriver · GitHub
じゃあpurposeってなんだってなるのですが、以下のように調べられます。
root@spinnaker-test:/opt/spinnaker/config# curl localhost:8084/subnets [{"id":"subnet-xxxxxx","state":"available","vpcId":"vpc-xxxxxxx","cidrBlock":"10.101.1.0/24","availableIpAddressCount":250,"account":"my-aws-account","region":"ap-northeast-1","availabilityZone":"ap-northeast-1a","purpose":"internal (defaultvpc)",
なのでsubnet名は以下のようになります
internal.defaultvpc.ap-northeast-1a
それでもsubnetが出ない
UIのリフレッシュが必要なようです。
画面のようにApplicationの"config"タブをクリックし、画面下部にある"Refresh all caches"をクリックします。
そしたらプルダウンで出てくるようになりました;
GCPと同じ感じでデプロイしてみる
ELB作成
SecurityGroup作成
あとは全て同じ流れとなります(・∀・)
やりたかなかろうAerospikeバージョンアップした話
あまりやりたかないAerospikeのバージョン上げた話
かれこれAerospike検証時期を含めると2013年11月から使ってるのでもうすぐ丸2年になります。
日本の導入企業では長いほうなんじゃないかな
ただ、普段ほとんど触りませんが(~o~)
構成
マスタークラスタ5台、スレーブクラスタ5台でXDRを使ってクラスタ間で同期しています。
クラスタ単位の容量は、メモリ 1TBくらい、SSD 15TBくらい
育ちました
あ、Aerospikeは"SSD & MEM"モードですのでフルでリソース使えないです。HighWaterMarkとかいろいろ事情がありまして。
バージョンは3.3.8
バージョンアップ
v3.3.8 => v3.6.3 (2015/10/28時点最新)
追加された設定値を精査すると結構あるな・・
Configuration Reference | Reference Manual | Aerospike
追加が26個
非推奨が17個
気になったパラメータとか
①. transaction-repeatable-read (非推奨)
これは使ってたのですが非推奨になりました。
Consistency Level的な設定で、Trueだと全てのレプリカを読んで最新を返しますが、Falseにするとマスタとなるデータを読んでそれを返します(他のレプリ側が新しいデータである可能性もあるんで、データ一貫性取るか速度取るかという感じです)。
②. read-consistency-level-override (v3.3.26から)
①のtransaction-repeatable-readの代わりとなるパラメータです。off,one,allがあります。それぞれ
off: client policy read.replicaを優先する。上書かない one: マスタから取得する all: 全てのレプリカノードから、最新(最大のgeneration)を取得する
consistencyについてはこの辺に書かれてます
Per-Transaction Consistency Guarantees | Clients | Aerospike
③. set-delete (v3.6.1から)
setが消せるようになったようです。以前は消せなかったってのがそもそもアレですが;
④. allow-nonxdr-writes、allow-nxdr-writes (3.5.12から)
こちらはまだ試せていませんが、両方ともfalseにすることでxdr以外による書き込みを禁止、xdrによる書き込みを禁止できるそうです。
今まではノードをクラスタインすると同時にReadもWriteも始まってしまうので、このオプションで一息付けるかもしれません。
なにより仕様によるXDRの転送漏れをこれで防げるかも!?
XDRはasdにある書き込みを転送します。過去分は送れません。xdrの起動プロセス上asdのプロセスがいることを一定間隔で確認してから起動します。なのでその一定間隔の間にasdにあった書き込みを送れないという事案
xdrプロセスの停止起動が発生する場合、事前にallow-nonxdr-writesをfalseにしておくことで書き込み制御します。これにより書き込みを止めた状態でxdrを起動出来、転送漏れがなくなるかもです
⑤. mesh-address,mesh-port (非推奨)
mesh-seed-address-portで設定するようです。AWSでAerospikeしてる人はマルチキャストがあれなんで使ってるはずですね。
⑥. enable-osync (3.3.21から)
RAWデバイスへのフラッシュ時のデバイスを指定できるとあるのですが、指定する分オーバーヘッドありそうだし、指定することのメリットがちょっとわからない。さらにどう確認するんだろ。ベンチかけるしかないのか
アプデ
もちろんスレーブクラスタ側。こういう時スレーブがあるって素敵☆
プロセス止めて、アップデートしてコンフィグをごちょごちょして、起動し直して
台数分実施です。当時とインストール方法が変わってたのでAnsibleのPlaybook書き直しました。
最大のネックはマイグレーションを待つ時間が15時間以上かかってたことですね。マイグレーション用のスレッドを5に上げて気長にやりました><
バックアップオプション
バックアップオプションの-bがなくなってて定期バックアップジョブがこけてた(・ω・)
デフォルトがbase64 encoded stringになった模様
asadmというコマンド
管理ツールが複数あったのですがasadmに統一していく感じでしょうか、どんどん見やすくなってもらいたいです
[root@aeroserver1 ~]# asadm Aerospike Interactive Shell, version 0.0.13 Found 5 nodes Online: xxxxxx:3000, yyyyyyy:3000, zzzzzzz:3000,aaaaaa:3000, bbbbbb:3000 Admin> help Aerospike Admin - !: "shell" is used to run shell commands on the local node. - asinfo: "asinfo" provides raw access to the info protocol. Options: -v <command> - The command to execute -p <port> - The port to use. NOTE: currently restricted to 3000 or 3004 -l - Replace semicolons ";" with newlines. Modifiers: like, with Default: Executes an info command. - clinfo: "asinfo" provides raw access to the info protocol. Options: -v <command> - The command to execute -p <port> - The port to use. NOTE: currently restricted to 3000 or 3004 -l - Replace semicolons ";" with newlines. Modifiers: like, with Default: Executes an info command. - cluster: Modifiers: with - dun: - undun: - collectinfo: "collectinfo" is used to collect system stats on the local node. - exit: Terminate session - help: Returns documentation related to a command for example, to retrieve documentation for the "info" command use "help info". - info: The "info" command provides summary tables for various aspects of Aerospike functionality. Modifiers: with Default: Displays service, network, namespace, and xdr summary information. - namespace: Displays summary information for each namespace. - network: Displays network information for Aerospike, the main purpose of this information is to link node ids to fqdn/ip addresses. - service: Displays summary information for the Aerospike service. - sindex: Displays summary information for Seconday Indexes (SIndex). - xdr: Displays summary information for Cross Datacenter Replication (XDR). - shell: "shell" is used to run shell commands on the local node. - show: "show" is used to display Aerospike Statistics and configuration. - config: "show config" is used to display Aerospike configuration settings Modifiers: diff, like, with Default: Displays service, network, namespace, and xdr configuration - namespace: Displays namespace configuration - network: Displays network configuration - service: Displays service configuration - xdr: Displays XDR configuration - distribution: "distribution" is used to show the distribution of object sizes and time to live for node and a namespace. Modifiers: like, with Default: Shows the distributions of Time to Live and Object Size - eviction: Shows the distribution of Eviction TTLs for namespaces - object_size: Shows the distribution of Object sizes for namespaces - time_to_live: Shows the distribution of TTLs for namespaces - latency: Modifiers: like, with Default: Displays latency information for Aerospike cluster. - statistics: Displays statistics for Aerospike components. Modifiers: like, with Default: Displays bin, set, service, namespace, and xdr statistics - bins: Displays bin statistics - namespace: Displays namespace statistics - service: Displays service statistics - sets: Displays set statistics - xdr: Displays xdr statistics - watch: "watch" Runs a command for a specified pause and iterations. Usage: watch [pause] [iterations] [--no-diff] command] pause: the duration between executions. [default: 2 seconds] iterations: Number of iterations to execute command. [default: until keyboard interrupt] --no-diff: Do not do diff highlighting Example 1: Show "info network" 3 times with 1 second pause watch 1 3 info network Example 2: Show "info namespace" with 5 second pause until interrupted watch 5 info namespace
[root@aeroserver1 ~]# asadm -e "show distribution" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~fox - TTL Distribution in Seconds~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Percentage of records having ttl less than or equal to value measured in Seconds Node 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% aeroserver1 272151 574541 846692 1149082 1481711 1814340 2146969 2449359 2751749 3023900 aeroserver2 272160 574560 846720 1149120 1481760 1814400 2147040 2449440 2751840 3024000 aeroserver3 272160 574560 846720 1149120 1481760 1814400 2147040 2449440 2751840 3024000 aeroserver4 272151 574541 846692 1149082 1481711 1814340 2146969 2449359 2751749 3023900 aeroserver5 272151 574541 846692 1149082 1481711 1814340 2146969 2449359 2751749 3023900 Number of rows: 5 ~~~~~~~~~~~~fox - Object Size Distribution in Record Blocks~~~~~~~~~~~~~ Percentage of records having objsz less than or equal to value measured in Record Blocks Node 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% aeroserver1 3 3 4 4 6 6 6 6 9 100 aeroserver2 3 3 4 4 6 6 6 6 9 100 aeroserver3 3 3 4 4 6 6 6 6 9 100 aeroserver4 3 3 4 4 6 6 6 6 9 100 aeroserver5 3 3 4 4 6 6 6 6 9 100 Number of rows: 5
2つめのクラスタ構築
そういや絶賛構築中です( ^o^)ノ
ではさいなら~
BIG-IPをATS対応(バージョンあげ)
バージョンアップ
先日、個人的に数年ぶりにF5のロードバランサBIG-IPのバージョンアップをやった
結論、やり方は数年前と変わってなかった。えがった。その備忘録的な。
もちろんサービスインしている筐体で行う作業で、失敗したらリアルガチの百列肉球を食らうだろうが、成功したら「フムご苦労」で終わる悲しくも切ない作業である
うちのTMOS(BIG-IPのOS)はバージョンは11.xx.xx。そんな古くない。
ではなぜアプデするかというと、AppleのiOS9のATS対応です。
こちら↓
AppleがiOS9から要求するCipherSuiteに対応しないといけない、つまりSSL終端する機器でSSLのハンドシェイク時の暗号化方式をATS準拠しましょうという作業である。
Apple豪腕だが、こういう企業が押し進めないと進まないこともあるので、ある意味尊敬してしまう。
ちなみにAWSのロードバランサ(ELB)は既に対応されておりました。
フルマネージドと言うAWSの中のあんな人やこんな人ががんばるシステムの素晴らしさをあらめて感じた(・∀・)
調べたところ、BIG-IPはv11.5以降でATSの一部Cihper対応していて、v11.6以降でほぼ全て対応とのこと。(どのバージョンもまぁまぁ最近やないか・・)
v11.6.0はかなり最近だったのと、うちの使い方だと特に必要なアプデはなさそうだったので
https://support.f5.com/kb/en-us/products/big-ip_ltm/releasenotes/product/relnote-ltm-11-6-0.html
って、あれ!?9/18の昨日12.0.0が出てますね(´Д`)
とりあえず、v11.5系の最新11.5.3をターゲットとしました。
対応できてない状態はこちら↓
[root@lb01:Active:In Sync] config # tmm --clientciphers 'DEFAULT:!SSLLv3:ECDHE:ECDHE_ECDSA' ID SUITE BITS PROT METHOD CIPHER MAC KEYX 0: 5 RC4-SHA 128 TLS1 Native RC4 SHA RSA 1: 5 RC4-SHA 128 TLS1.1 Native RC4 SHA RSA 2: 5 RC4-SHA 128 TLS1.2 Native RC4 SHA RSA 3: 47 AES128-SHA 128 TLS1 Native AES SHA RSA 4: 47 AES128-SHA 128 TLS1.1 Native AES SHA RSA 5: 47 AES128-SHA 128 TLS1.2 Native AES SHA RSA 6: 47 AES128-SHA 128 DTLS1 Native AES SHA RSA 7: 53 AES256-SHA 256 TLS1 Native AES SHA RSA 8: 53 AES256-SHA 256 TLS1.1 Native AES SHA RSA 9: 53 AES256-SHA 256 TLS1.2 Native AES SHA RSA 10: 53 AES256-SHA 256 DTLS1 Native AES SHA RSA 11: 10 DES-CBC3-SHA 192 TLS1 Native DES SHA RSA 12: 10 DES-CBC3-SHA 192 TLS1.1 Native DES SHA RSA 13: 10 DES-CBC3-SHA 192 TLS1.2 Native DES SHA RSA 14: 10 DES-CBC3-SHA 192 DTLS1 Native DES SHA RSA 15: 60 AES128-SHA256 128 TLS1.2 Native AES SHA256 RSA 16: 61 AES256-SHA256 256 TLS1.2 Native AES SHA256 RSA</span>
作業開始
念のためコンフィグバックアップ
まずは何事もバックアップ。
BIG-IPのバックアップファイルのUCSファイル取得しておきます。
system->archive->"Create"ボタンで作成したファイルをダウンロード
リアクティベート
リアクティベートを必ずしておく
新しいバージョンのOSよりライセンスの日付が古いと起動時に怒られ、リアクティベートが求められます。
ちなみにアップデート後にやるのは、ややめんどいのと、リアクティベート中オフラインにしておかないとなぜかステータスがアクティブになるという恐怖が起ることがあります(´Д`)
リアクティベートは事前にやっておきましょう!
必要ファイル取得
対象のOSをダウンロードします。
scpでBIG-IPに転送し、md5checkもしっかりやりましょう
起動OSの確認
Currentが現在のOSで、Defaultが起動時に選ばれるOS、Availableは内包してるその他OS。
[root@lb01:Active:In Sync] config # switchboot -l Current boot image: HD1.2 - title BIG-IP 11.x.x Build xxx.0 Default boot image: HD1.2 - title BIG-IP 11.x.x Build xxx.0 Available boot image(s): HD1.1 - title BIG-IP 11.y.y Build yyy.0 HD1.2 - title BIG-IP 11.x.x Build xxx.0
スロット設定をインストール先スロットに引き継ぐBIGのDB設定確認
全てEnableにしておくと新しいOSでの起動時に設定を引き継いでくれます。
[root@lb01:Active:In Sync] config # tmsh list sys db liveinstall.moveconfig sys db liveinstall.moveconfig { value "enable" } [root@lb01:Active:In Sync] config # tmsh list sys db liveinstall.movelicense sys db liveinstall.movelicense { value "enable" } [root@lb01:Active:In Sync] config # tmsh list sys db liveinstall.saveconfig sys db liveinstall.saveconfig { value "enable" } [root@lb01:Active:In Sync] config # tmsh list sys db liveinstall.savelicense sys db liveinstall.savelicense { value "enable" }
新規ボリューム作成とインスト
新しいディスクHD1.3作ってそこにインストールします。
[root@lb01:Active:In Sync] images # tmsh install sys software image BIGIP-11.5.3.0.0.163.iso volume HD1.3 create-volume [root@lb01:Active:In Sync] images # tmsh show sys software status --------------------------------------------------------------- Sys::Software Status Volume Product Version Build Active Status --------------------------------------------------------------- HD1.1 BIG-IP 11.y.y yyy.0 yes complete HD1.2 BIG-IP 11.x.x xxx.0 no complete HD1.3 BIG-IP 11.5.3 0.0.163 no installing 6.000 pct
スタンバイから実施していく
上記を2台のBIG-IPで実施したら、ここからがいよいよサービス影響が出る作業です。
スタンバイ側の起動デバイスを変更
事前にオフラインモードにしておくのがいいと思います。
新しいOSが入ったデバイスのHD1.3をデフォルト起動デバイスにします。
switchboot -b HD1.3
リブートします。
sync;sync;sync;reboot
問題なければオンラインモードに戻して、アクトスタンバイを切替えてもう一台も実施。
ふぅ
「ふぅ、、」と一息つきましょう
対応できた。ECDHEのCihperSuiteが入ってますね。
[root@lb01:Active:In Sync] config # tmm --clientciphers 'DEFAULT:!SSLLv3:ECDHE:ECDHE_ECDSA' ID SUITE BITS PROT METHOD CIPHER MAC KEYX 0: 61 AES256-SHA256 256 TLS1.2 Native AES SHA256 RSA 1: 53 AES256-SHA 256 TLS1 Native AES SHA RSA 2: 53 AES256-SHA 256 TLS1.1 Native AES SHA RSA 3: 53 AES256-SHA 256 TLS1.2 Native AES SHA RSA 4: 53 AES256-SHA 256 DTLS1 Native AES SHA RSA 5: 60 AES128-SHA256 128 TLS1.2 Native AES SHA256 RSA 6: 47 AES128-SHA 128 TLS1 Native AES SHA RSA 7: 47 AES128-SHA 128 TLS1.1 Native AES SHA RSA 8: 47 AES128-SHA 128 TLS1.2 Native AES SHA RSA 9: 47 AES128-SHA 128 DTLS1 Native AES SHA RSA 10: 10 DES-CBC3-SHA 192 TLS1 Native DES SHA RSA 11: 10 DES-CBC3-SHA 192 TLS1.1 Native DES SHA RSA 12: 10 DES-CBC3-SHA 192 TLS1.2 Native DES SHA RSA 13: 10 DES-CBC3-SHA 192 DTLS1 Native DES SHA RSA 14: 5 RC4-SHA 128 TLS1 Native RC4 SHA RSA 15: 5 RC4-SHA 128 TLS1.1 Native RC4 SHA RSA 16: 5 RC4-SHA 128 TLS1.2 Native RC4 SHA RSA 17: 49192 ECDHE-RSA-AES256-SHA384 256 TLS1.2 Native AES SHA384 ECDHE_RSA 18: 49172 ECDHE-RSA-AES256-CBC-SHA 256 TLS1 Native AES SHA ECDHE_RSA 19: 49172 ECDHE-RSA-AES256-CBC-SHA 256 TLS1.1 Native AES SHA ECDHE_RSA 20: 49172 ECDHE-RSA-AES256-CBC-SHA 256 TLS1.2 Native AES SHA ECDHE_RSA 21: 49191 ECDHE-RSA-AES128-SHA256 128 TLS1.2 Native AES SHA256 ECDHE_RSA 22: 49171 ECDHE-RSA-AES128-CBC-SHA 128 TLS1 Native AES SHA ECDHE_RSA 23: 49171 ECDHE-RSA-AES128-CBC-SHA 128 TLS1.1 Native AES SHA ECDHE_RSA 24: 49171 ECDHE-RSA-AES128-CBC-SHA 128 TLS1.2 Native AES SHA ECDHE_RSA 25: 49170 ECDHE-RSA-DES-CBC3-SHA 192 TLS1 Native DES SHA ECDHE_RSA 26: 49170 ECDHE-RSA-DES-CBC3-SHA 192 TLS1.1 Native DES SHA ECDHE_RSA 27: 49170 ECDHE-RSA-DES-CBC3-SHA 192 TLS1.2 Native DES SHA ECDHE_RSA 28: 49200 ECDHE-RSA-AES256-GCM-SHA384 256 TLS1.2 Native AES-GCM SHA384 ECDHE_RSA 29: 49199 ECDHE-RSA-AES128-GCM-SHA256 128 TLS1.2 Native AES-GCM SHA256 ECDHE_RSA 30: 49196 ECDHE-ECDSA-AES256-GCM-SHA384 256 TLS1.2 Native AES-GCM SHA384 ECDHE_ECDSA 31: 49188 ECDHE-ECDSA-AES256-SHA384 256 TLS1.2 Native AES SHA384 ECDHE_ECDSA 32: 49162 ECDHE-ECDSA-AES256-SHA 256 TLS1 Native AES SHA ECDHE_ECDSA 33: 49162 ECDHE-ECDSA-AES256-SHA 256 TLS1.1 Native AES SHA ECDHE_ECDSA 34: 49162 ECDHE-ECDSA-AES256-SHA 256 TLS1.2 Native AES SHA ECDHE_ECDSA 35: 49160 ECDHE-ECDSA-DES-CBC3-SHA 192 TLS1 Native DES SHA ECDHE_ECDSA 36: 49160 ECDHE-ECDSA-DES-CBC3-SHA 192 TLS1.1 Native DES SHA ECDHE_ECDSA 37: 49160 ECDHE-ECDSA-DES-CBC3-SHA 192 TLS1.2 Native DES SHA ECDHE_ECDSA 38: 49195 ECDHE-ECDSA-AES128-GCM-SHA256 128 TLS1.2 Native AES-GCM SHA256 ECDHE_ECDSA 39: 49187 ECDHE-ECDSA-AES128-SHA256 128 TLS1.2 Native AES SHA256 ECDHE_ECDSA 40: 49161 ECDHE-ECDSA-AES128-SHA 128 TLS1 Native AES SHA ECDHE_ECDSA 41: 49161 ECDHE-ECDSA-AES128-SHA 128 TLS1.1 Native AES SHA ECDHE_ECDSA 42: 49161 ECDHE-ECDSA-AES128-SHA 128 TLS1.2 Native AES SHA ECDHE_ECDSA
ちなみに、バージョン上げたらアイコンがちょっとかわいくなった?
動作確認
もちろん動確を忘れずに インフラレイヤをやりつつ、アプリ側にも協力を仰ぎます。HipChatやSlackやChatworkで「確認よろ!」と投げて、 「確認完了。乙!」とか来たら完了ですね。
所感
ちなみに、「フムご苦労」で終わると思ってたけど、思いのほか労を労ってもらった。いい職場やないかぁ^^
CyberZがDirect Connect 始めたってよ
CyberZではオンプレとAWSを使ってます。
つ、つ、ついにオンプレとAWSが繋がりました。
※最近は大阪からも繋がるようで、西日本企業さんも低レイテンシで Meet me できるんですね^^
http://cloud.watch.impress.co.jp/docs/news/20150817_716493.html
構成はこんな感じ
まぁ至ってシンプルです。あまり説明しないです;
AWSに全部寄せてない理由としては、ioDriveさんがいたりリアルタイム処理してる部分があったりとかクラウドにいけないあるあるです><
BGPのメトリクスは出力/入力トラフィック制御を"Local Preference"と"AS-Path"で重み付けしてます(オンプレルーター間に渡りがないのでLPは厳密にはいらないですね。。VRRPで制御されるし)。
回線は主系副系に分けて、異なるキャリアを使って異経路冗長してます。品質高い方を主系で使っています。
オンプレ側ルーターとAWS接続ルーター間は、iBGPは使わずにスタティックで渡しています。外側(AWS側)のポート障害はインタフェーストラッキングすることでHSRPを切替えてます。
あとは、AWSと繋ぐルーターがVLAN追加するとリロード必要というイケてない仕様により、、VLANを事前に作れるだけ作っておきました。VPC増えたらそこから払い出すという設計で乗り切ることに・・
あとは、AWS側でRoute Table追加やSecurityGroupをよしなに変更してあげて、
良好に繋がっております。レイテンシはだいたい3ms前後くらい?
あと知らなかったのですが、ルーターをダウンした場合、メディアコンにてリンクダウンがAWS側ルータにも伝達され、BGPセッションが切断されます。AWSルーターはリンクダウンを検出した時点でBGPセッションを切断するようです。その場合BGPもHoldtimeより短い時間で切り替わってた・・(ここは最初謎だった・・)
ちなみに、事前にAWSの”DX体験ハンズラボ”に参加しました。とても充実していてDX導入のハードルを一気に下げてくれます(DXなんてめったにやらな から試せんし^^;)。CiscoとJuniperでトラフィックエンジニアリングまでやってくれてw、久々にJuniper触れて楽しかった。講師の熱い想いを感じられるカリキュラムになっとります!w
https://aws.amazon.com/jp/dx_labo/
とりあえず直近の案件で使いますが、今後利用が増えて行くんじゃねかなと思っとります。
結局、専用線を引くのでそれ相応の時間かかりました。工事だけで短くても1.5ヶ月とか、APN業者の選定も時間かかりますし。ご利用は計画的に。(6 ̄  ̄)
※ちなみにお値段は1Gbps専用線2本で30数万円くらいです。安くないですか!?
※こちらBlack Belt参考にしました
http://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-tech-aws-direct-connect