Cloud SQL Proxy (TCP Socket)を systemd で起動させる

# あらまし
Google Cloud SQL Second Generation が日本時間2016/08/17未明に beta から GA となった。
あわせてこれまで beta 扱いであった Cloud SQL Proxy も GA となった。
Cloud SQL Proxy は Cloud SQL の疎通制限をGCEのVM毎に開放する必要がなくなり
大変便利な機能ではあるのだが、TCP Socketで利用する場合、cloud_sql_proxyプロセスの管理・監視をする必要がある。
systemd化することでプロセスの永続化、管理、自動起動などが実現できる為、以前に検証した内容を共有する。

# 検証環境
今回検証で使用した環境は以下のとおりである。
## GCP
project id: **myproject-id**

## Cloud SQL
以降出てくる設定・コマンドのinstance名は各々の環境に合わせてください。
instance名: **mycloudsql**
region: **asia-east1**
Second Generation (第2世代)で構築。

## VM (GCE)
instance名: host
VM作成時に `https://www.googleapis.com/auth/sqlservice.admin` を有効にしておく。
また、mysql client および cloud_sql_proxy を install しておく。

### mysql clientのinstall
```
sudo apt-get update
sudo apt-get install mysql-client
```

### cloud_sql_proxyのinstall

```
wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64
mv cloud_sql_proxy.linux.amd64 cloud_sql_proxy
chmod +x cloud_sql_proxy
chown root:root cloud_sql_proxy
sudo mv cloud_sql_proxy /usr/bin
```

# 検証内容
## cloud_sql_proxyをsystemd化する設定
複数のCloud SQL インスタンスで利用できるように
**汎用systemd設定ファイル** と **インスタンス特化設定ファイル（環境変数）**に分けた。

###汎用systemd設定ファイル
ファイル名は `/etc/systemd/system/cloud_sql_proxy@.service`
1VMに1ファイル配置します。

```
user@host:~$ sudo cat /etc/systemd/system/cloud_sql_proxy\@.service
[Unit]
Description = CloudSQL Proxy %i
After = network.target

[Service]
EnvironmentFile = /srv/cloud_sql_proxy/%i.conf
ExecStart = /usr/bin/cloud_sql_proxy -instances=${PROJECT_ID}:${REGION}:${INSTANCE_NAME}=tcp:${PORT}
ExecStop = /bin/kill ${MAINPID}
ExecReload = /bin/kill -HUP ${MAINPID}
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target
```

### Max open files設定
cloud_sql_proxy processのMax open filesを65535に設定しておきます。
デフォルトはulimit -fなどで設定された値が使用され、デフォルト値は総じて低め(1024など)な為。

```
usre@host:$ sudo mkdir /etc/systemd/system/cloud_sql_proxy\@.service.d
usre@host:$ sudo cat /etc/systemd/system/cloud_sql_proxy\@.service.d/limits.conf
[Service]
LimitNOFILE=65536
```

### インスタンス特化設定ファイル

ファイル名は `/srv/cloud_sql_proxy/*instance_name*.conf`
VMから接続したいCloud SQL毎に作成する必要があります。

```
user@host:~$ sudo cat /srv/cloud_sql_proxy/mycloudsql.conf
PROJECT_ID="myproject-id"
REGION="asia-east1"
INSTANCE_NAME="mycloudsql"
PORT="3306"
```

## cloud_sql_proxyの起動
sudo systemctl start cloud_sql_proxy@*instance_name*.service の形で起動する。
(ここで言うinstance_nameはCloudSQLのinstance_nameであり、systemd用語のinstanceとは異なる。)

```
# 起動コマンド
user@host:~$ sudo systemctl start cloud_sql_proxy@mycloudsql.service

# status確認
user@host:~$ sudo systemctl status cloud_sql_proxy@mycloudsql.service
● cloud_sql_proxy@mycloudsql.service - CloudSQL Proxy mycloudsql
   Loaded: loaded (/etc/systemd/system/cloud_sql_proxy@.service; disabled)
   Active: active (running) since Thu 2016-06-30 09:35:30 UTC; 6s ago
 Main PID: 634 (cloud_sql_proxy)
   CGroup: /system.slice/system-cloud_sql_proxy.slice/cloud_sql_proxy@mycloudsql.service
           └─634 /usr/bin/cloud_sql_proxy -instances=myproject-id:asia-east1:mycloudsql=tcp:3306

Jun 30 09:35:30 mycloudsql systemd[1]: Starting CloudSQL Proxy mycloudsql...
Jun 30 09:35:30 mycloudsql systemd[1]: Started CloudSQL Proxy mycloudsql.
Jun 30 09:35:30 mycloudsql cloud_sql_proxy[634]: 2016/06/30 09:35:30 Listening on 127.0.0.1:3306 for myprojet-id...-0627
Jun 30 09:35:30 mycloudsql cloud_sql_proxy[634]: 2016/06/30 09:35:30 Ready for new connections
Hint: Some lines were ellipsized, use -l to show in full.

# process確認
user@host:~$ ps -ef | grep cloud_sql | grep -v grep
root       634     1  0 09:35 ?        00:00:00 /usr/bin/cloud_sql_proxy -instances=myproject-id:asia-east1:mycloudsql=tcp:3306

# CloudSQL疎通確認
user@host:~$ mysql -uroot -h127.0.0.1
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2843
Server version: 5.6.29-google (Google)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> exit
Bye
```

## cloud_sql_proxyの停止
sudo systemctl stop cloud_sql_proxy@*instance_name*.service の形で停止する。

```
# 停止コマンド
user@host:~$ sudo systemctl stop cloud_sql_proxy@mycloudsql.service

# status確認
user@host:~$ sudo systemctl status cloud_sql_proxy@mycloudsql.service
● cloud_sql_proxy@mycloudsql.service - CloudSQL Proxy mycloudsql
   Loaded: loaded (/etc/systemd/system/cloud_sql_proxy@.service; disabled)
   Active: inactive (dead) since Thu 2016-06-30 09:41:09 UTC; 8s ago
  Process: 661 ExecStop=/bin/kill ${MAINPID} (code=exited, status=0/SUCCESS)
 Main PID: 634 (code=killed, signal=TERM)

Jun 30 09:35:30 mycloudsql systemd[1]: Starting CloudSQL Proxy mycloudsql...
Jun 30 09:35:30 mycloudsql systemd[1]: Started CloudSQL Proxy mycloudsql.
Jun 30 09:35:30 mycloudsql cloud_sql_proxy[634]: 2016/06/30 09:35:30 Listening on 127.0.0.1:3306 for myprojet-id...-0627
Jun 30 09:35:30 mycloudsql cloud_sql_proxy[634]: 2016/06/30 09:35:30 Ready for new connections
Jun 30 09:41:09 mycloudsql systemd[1]: Stopping CloudSQL Proxy mycloudsql...
Jun 30 09:41:09 mycloudsql systemd[1]: Stopped CloudSQL Proxy mycloudsql.
Hint: Some lines were ellipsized, use -l to show in full.

# process確認
user@host:~$ ps -ef | grep cloud_sql | grep -v grep
```

## 自動起動が有効なのを確認
VM障害時のOS自動再起動に対応すべく、OS再起動時にcloud_sql_proxyが自動で起動することを確認した。

```
# 自動起動有効コマンド
user@host:~$ sudo systemctl enable cloud_sql_proxy@mycloudsql.service
Created symlink from /etc/systemd/system/multi-user.target.wants/cloud_sql_proxy@mycloudsql.service to /etc/systemd/system/cloud_sql_proxy@.service.

# status確認
user@host:~$ sudo systemctl status cloud_sql_proxy@mycloudsql.service
● cloud_sql_proxy@mycloudsql.service - CloudSQL Proxy mycloudsql
   Loaded: loaded (/etc/systemd/system/cloud_sql_proxy@.service; enabled) <== 自動起動有効
   Active: inactive (dead) since Thu 2016-06-30 09:41:09 UTC; 2min 29s ago
  Process: 661 ExecStop=/bin/kill ${MAINPID} (code=exited, status=0/SUCCESS)
 Main PID: 634 (code=killed, signal=TERM)

Jun 30 09:35:30 mycloudsql systemd[1]: Starting CloudSQL Proxy mycloudsql...
Jun 30 09:35:30 mycloudsql systemd[1]: Started CloudSQL Proxy mycloudsql.
Jun 30 09:35:30 mycloudsql cloud_sql_proxy[634]: 2016/06/30 09:35:30 Listening on 127.0.0.1:3306 for myprojet-id...-0627
Jun 30 09:35:30 mycloudsql cloud_sql_proxy[634]: 2016/06/30 09:35:30 Ready for new connections
Jun 30 09:41:09 mycloudsql systemd[1]: Stopping CloudSQL Proxy mycloudsql...
Jun 30 09:41:09 mycloudsql systemd[1]: Stopped CloudSQL Proxy mycloudsql.
Hint: Some lines were ellipsized, use -l to show in full.

# OS再起動
user@host:~$ sudo reboot

# OS再起動後に自動起動することを確認
user@host:~$ sudo systemctl status cloud_sql_proxy@mycloudsql.service
● cloud_sql_proxy@mycloudsql.service - CloudSQL Proxy mycloudsql
   Loaded: loaded (/etc/systemd/system/cloud_sql_proxy@.service; enabled)
   Active: active (running) since Thu 2016-06-30 09:44:11 UTC; 1min 35s ago
 Main PID: 357 (cloud_sql_proxy)
   CGroup: /system.slice/system-cloud_sql_proxy.slice/cloud_sql_proxy@mycloudsql.service
           └─357 /usr/bin/cloud_sql_proxy -instances=myproject-id:asia-east1:mycloudsql=tcp:3306

Jun 30 09:44:11 mycloudsql systemd[1]: Started CloudSQL Proxy mycloudsql.
Jun 30 09:44:11 mycloudsql cloud_sql_proxy[357]: 2016/06/30 09:44:11 Listening on 127.0.0.1:3306 for myprojet-id...-0627
Jun 30 09:44:11 mycloudsql cloud_sql_proxy[357]: 2016/06/30 09:44:11 Ready for new connections
Jun 30 09:44:14 mycloudsql cloud_sql_proxy[357]: 2016/06/30 09:44:14 New connection for "myproject-id:asia-east1...0627"
Hint: Some lines were ellipsized, use -l to show in full.
```

# まとめ
今までbeta版だった為に、イマイチ使いどころが難しかった Cloud SQL および Cloud SQL Proxy も GA リリースとなり、ようやく利用シーンも増えそうだな、と感じています。

Cloud SQL Proxy 経由でパフォーマンスって劣化しないの？という疑問点はあるのですが、それはまた別の機会に。