GCEにConsulをさっとデプロイしてみる

こんにちは。grasysでSREをやっております守永です。 最近天変地異が日本を襲ってきていますが、そんな中でさっと検証しなければならない! なーんてことがあると思います。

GCEのインスタンスを立ててさっと検証用にConsulをインストールしてみましょう。

今回使用したイメージはこちら

debian-9-stretch-v20180401

前提条件として、作成したインスタンスにはNetwork Tagにconsulを付ける事ぐらいです。これは、Consul自体のService DiscoveryにGCE APIを使うためです。

手順

  1. セットアップで利用するツール類をインストール
  2. Consulインストール
  3. Consul初期化

セットアップで利用するツール類をインストール

netcatとかtmuxは趣味です・・・

Mustacheとかjqとかjoが無いと何もできない体に・・・ でも今回はjqとjoしか使ってない事に気づく。

sudo su -

apt-get update
apt-get install -y unzip jq netcat tmux jo less

# Download and install Mustache
cd /tmp && \
  curl -sSL https://git.io/get-mo -o mo && \
  chmod +x mo && \
  mv mo /usr/local/bin/

Consulインストール

バージョンは適当に変えてね!

# Download and install Consul
consul_version=1.0.7
cd /tmp && \
  curl -sLO https://releases.hashicorp.com/consul/${consul_version}/consul_${consul_version}_linux_amd64.zip && \
  unzip consul_${consul_version}_linux_amd64.zip && \
  mv consul /usr/local/bin/consul && \
  rm consul_${consul_version}_linux_amd64.zip

Consulセットアップ

今気づいたけど、DomainやらServerモードもメタデータとかに外出しすれば汎用的なイメージ作れそうですね。

Service DiscoveryはGCE API使ってるので、大きめのクラスタ作るときはGCE APIのLate Limitとか気をつけてねw

# Enable Consul completion (Require restart bash)
consul -autocomplete-install

# Consul user
useradd -r -d /var/lib/consul -s /bin/nologin consul
install -o consul -g consul -m 750 -d /var/lib/consul

# Consul config
mkdir -p /etc/consul
cat - > /etc/consul/reconfig.sh <<'EOF'
#!/bin/bash

PROJECT_ID=$(curl -s -H "Metadata-Flavor: Google" metadata/computeMetadata/v1/project/project-id)
INSTANCE_NAME=$(curl -s -H "Metadata-Flavor: Google" metadata/computeMetadata/v1/instance/name)
ZONE=$(curl -s -H "Metadata-Flavor: Google" metadata/computeMetadata/v1/instance/zone)
SERVERTYPE=$(gcloud compute instances describe ${INSTANCE_NAME} --zone ${ZONE##*/} --format json | jq -M -r .labels.servertype)
NETWORK_IF0=$(curl -s -H "Metadata-Flavor: Google" metadata/computeMetadata/v1/instance/network-interfaces/0/ip)
jo domain=vault \
  bind_addr=0.0.0.0 \
  client_addr=0.0.0.0 \
  node_meta=$(jo servertype=${SERVERTYPE}) \
  advertise_addr=${NETWORK_IF0} \
  leave_on_terminate=true \
  datacenter=${PROJECT_ID} \
  disable_remote_exec=false \
  server=true \
  node_name=${INSTANCE_NAME} \
  reconnect_timeout=8h \
  rejoin_after_leave=true \
  retry_join[]="provider=gce tag_value=consul" \
  enable_debug=false \
  enable_script_checks=true \
  enable_syslog=true \
  log_level=INFO \
  data_dir=/var/lib/consul/data/${PROJECT_ID}/${INSTANCE_NAME} \
  bootstrap_expect=3 \
  | jq . > /etc/consul/config.json
chown consul.consul /etc/consul/config.json
chmod 0600 /etc/consul/config.json
EOF
chown consul.consul /etc/consul/reconfig.sh
chmod 511 /etc/consul/reconfig.sh

# Systemd service
cat - > /etc/systemd/system/consul.service <<'EOF'
[Unit]
Description=Consul
Documentation=https://www.consul.io/docs/
After=network.target
ConditionFileNotEmpty=/etc/consul/config.json

[Service]
User=consul
Group=consul
ExecStartPre=/etc/consul/reconfig.sh
ExecStart=/usr/local/bin/consul agent -config-file=/etc/consul/config.json
ExecReload=/usr/local/bin/kill --signal HUP $MAINPID
NoNewPrivileges=yes
KillSignal=SIGINT

[Install]
WantedBy=multi-user.target
EOF
chmod 0600 /etc/systemd/system/consul.service

systemctl daemon-reload
systemctl enable consul
systemctl start consul

jq使わずにjo -pすればいいじゃん、って言う所もあるけど気にしない!