GCE エフェメラルIPを定期的に変える方法 (クローリング,キャプチャ対策)


直近関わった案件でGCP環境で
特定Webサイトに対して定期的にクローリングする際にキャプチャ回避策として、グローバルIP定期的に変更するやり方をしたので、一般化して備忘する。


## 構成イメージ

<img width="634" alt="crawl.png" src="https://qiita-image-store.s3.amazonaws.com/0/51734/5f394cb6-dda7-2327-efd3-2b912416fe60.png">

クローラーインスタンスとは別のインスタンスからGCEインスタンスからcronでgcloudコマンドのIP変更するコマンドを叩く形としたOK。gcloudの実行ユーザはサービスユーザを利用した。

## crontabで実行させるシェル

```$HOME/scripts/change-crawler-global-ip.sh
#!/bin/sh

logDir=/var/tmp/change-ip-log/`date +"%Y%m%d"`
logFile=${logDir}/`date +"%Y%m%d_%H%M%S"`.log
mkdir -p $logDir

PROJECT="<GCP-PROJECT-ID>"
ZONE="<ZONE>" # 例: asia-northeast1-b

INSTANCE="<INSTANCE-NAME>" # 例: instance-1
NETWORK_INTERFACE="External NAT" # デフォルトではこの名前だった。

# STEP1: 変更前にインスタンス構成情報を出力
echo -e "----- BEFORE -----\n" >> $logFile
gcloud compute instances describe --project="$PROJECT" --zone="$ZONE" "$INSTANCE" >> $logFile

# STEP2: ネットワークインターフェースを削除する。
gcloud compute instances delete-access-config  --project="$PROJECT" --zone="$ZONE" $INSTANCE --access-config-name="$NETWORK_INTERFACE" >> $logFile

# STEP3: ネットワークインターフェースを新規作成する。
gcloud compute instances add-access-config   --project="$PROJECT" --zone="$ZONE" "$INSTANCE" --access-config-name="$NETWORK_INTERFACE" >> $logFile

echo -e "----- AFTER -----\n" >> $logFile
# STEP4: 変更前にインスタンス構成情報を出力
gcloud compute instances describe --project="$PROJECT" --zone="$ZONE" "$INSTANCE" >> $logFile
```

STEP2のネットワークインターフェース削除処理の実行中〜STEP3の新規ネットワーク・インターフェースの追加処理完了までは
該当インスタンスはネットに繋がらないので注意。

## crontab例

```
$ crontab -l
# 15分おきにIPを変更 (cron処理時間と被らないように要調整)
3-58/5 * * * * sh $HOME/scripts/change-crawler-global-ip.sh
```

## 実行ログ例

```
$ less /var/tmp/change-ip-log/20190124/20190124_115201.log 
canIpForward: false
cpuPlatform: Intel Broadwell
creationTimestamp: '2019-01-18T05:51:59.021-08:00'
deletionProtection: false
description: ''
disks:
- autoDelete: true
  boot: true
  deviceName: instance-1
  index: 0
  interface: SCSI
  kind: compute#attachedDisk
  licenses:
  - https://www.googleapis.com/compute/v1/projects/centos-cloud/global/licenses/centos-7
  mode: READ_WRITE
  source: https://www.googleapis.com/compute/v1/projects/...
er1
  type: PERSISTENT
id: 'xxx'
kind: compute#instance
labelFingerprint: xxx
machineType: https://www.googleapis.com/compute/v1/projects/...
metadata:
  fingerprint: xxx
  kind: compute#metadata
name: instance-1
networkInterfaces:
- accessConfigs:
  - kind: compute#accessConfig
    name: External NAT
    natIP: 34.85.25.113
    networkTier: PREMIUM
    type: ONE_TO_ONE_NAT
  fingerprint: xxx

(略)
----- AFTER -----

canIpForward: false
cpuPlatform: Intel Broadwell
creationTimestamp: '2019-01-18T05:51:59.021-08:00'
deletionProtection: false
description: ''
disks:
- autoDelete: true
  boot: true
  deviceName: instance-1
  index: 0
  interface: SCSI
  kind: compute#attachedDisk
  licenses:
  - https://www.googleapis.com/compute/v1/projects/centos-cloud/global/licenses/centos-7
  mode: READ_WRITE
  source: https://www.googleapis.com/compute/v1/projects/...
  type: PERSISTENT
id: 'xxx'
kind: compute#instance
labelFingerprint: xxx
machineType: https://www.googleapis.com/compute/v1/projects/...
metadata:
  fingerprint: xxx
  kind: compute#metadata
name: instance-1
networkInterfaces:
- accessConfigs:
  - kind: compute#accessConfig
    name: External NAT
    natIP: 34.85.46.233
    networkTier: PREMIUM
    type: ONE_TO_ONE_NAT
  fingerprint: xxx
(略)
```

`34.85.25.113` から `34.85.46.233` に変わったことがわかる。

## 参考

- サービスアカウント関連
  - [GitLab CIでGoogle App Engineプロジェクトを自動デプロイ](https://qiita.com/otuhs_d/items/bbf1699c53d24d2c0625)
- 公式ドキュメント
  - [インスタンスの IP アドレスの設定](https://cloud.google.com/compute/docs/configure-instance-ip-addresses?hl=ja)