GCP: Compute Engine
CLI
インスタンスの作成
gcloud compute instances create <instance name>
# addressは指定しなくてもいい
gcloud compute instances create hoge \
--boot-disk-device-name=hoge-disk \
--boot-disk-size=10GB \
--boot-disk-type=pd-ssd \
--machine-type=n1-standard-2 \
--address *.*.*.*
使えるイメージのリストを取得
gcloud compute images list
インスタンスの一覧取得
gcloud compute instances list
インスタンスへの接続
インスタンスへの接続にはgcloud compute ssh
を使う。
gcloud compute ssh <instance-name> --zone <zone-name>
ローカル ⇔ インスタンス間でファイルのコピーをするにはgcloud compute scp
を使う。
# ローカルマシンからインスタンスへコピー
gcloud compute scp ~/file-1 my-instance:~/remote-destination --zone us-central1-a
# インスタンスからローカルマシンへコピー
gcloud compute scp my-instance:~/file-1 ~/local-destination --zone us-central1-a
ssh
とscp
を直接使いたいときは以下のコマンドで~/.ssh/config
を生成する。
# ~/.ssh/config を生成
gcloud compute config-ssh
# 以降、sshコマンドで直接接続できる
ssh <instance-name>.<region-name>.<project -name>
インスタンスの削除
instances delete
コマンドを使う。
gcloud compute instances delete <instance-name> --zone <zone-name>
インスタンスを削除すると自動で関連付けられている永続ディスクも削除される。
永続ディスクを削除したくない場合は--keep-disks
フラグを使う。
起動スクリプトを渡す
Ref: https://cloud.google.com/compute/docs/startupscript?hl=ja
インスタンスの起動後に ssh 接続できるようになるまで待つ
スクリプトでインスタンスの起動とインスタンスへの接続を同時に行う場合にハマるポイント。
gcloud compute instances create
の直後に gcloud compute ssh
すると Connection Refused になってしまう。
これは、create
がインスタンスが起動するまでは待ってくれるけど ssh 接続できるようになるまでは待ってくれていないために起こる。
gcloud compute instances create my-instance --zone asia-northeast1-b
# ここですぐsshするとつながらない
# gcloud compute ssh my-user@my-instance
# 22番が開くまで待つ
IP=$(gcloud compute instances list | awk '/'my-instances'/ {print $5}')
if nc -w 5 -z $IP 22; then
echo "OK! Ready for heavy metal"
else
echo "Maybe later?"
fi
# sshできる
gcloud compute ssh my-user@my-instance
ディスクを追加・マウントする
ディスクを作成する。
gcloud compute disks create <name> \
--size 30 \
--type pd-ssd \
--zone asia-northeast1-b
ディスクを VM インスタンスに割り当てる。
gcloud compute instances attach-disk <INSTANCE_NAME> \
--disk <DISK_NAME>
ディスクをフォーマットする。
# ディスクを割り当てたVM上で実行すること
# デバイスの確認。素のUbuntu18.04にディスクを1つ割り当てるとsdbという名前で認識される
sudo lsblk
# ディスクをフォーマットする
sudo mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb
マウントするディレクトリを作る。
mkdir -p /mnt/disks/dev
# マウントして全ユーザに対して書き込み権限を与える
sudo mount -o discard,defaults /dev/sdb /mnt/disks/dev
sudo chmod a+w /mnt/disks/dev
# 起動時に自動マウントする
echo UUID=`sudo blkid -s UUID -o value /dev/sdb` /mnt/disks/dev ext4 discard,defaults,nofail 0 2 | sudo tee -a /etc/fstab
Ref: https://cloud.google.com/compute/docs/disks/add-persistent-disk?hl=ja#create_disk
VM シャットダウン時に Pub/Sub で通知する
アイドル状態になったら自動シャットダウンさせる(Ubuntu)
cron_shutdown
を作る。
*/5 * * * * root /root/shutdown_auto.sh
shutdown_auto.sh
を作る。
#!/bin/bash
UPTIME_MINUTE=$(echo $(awk '{print $1}' /proc/uptime) / 60 | bc)
if [ $UPTIME_MINUTE -lt 15 ] ; then
exit 0
fi
if [ 480 -lt $UPTIME_MINUTE ] ; then
sudo shutdown -h now
exit 0
fi
sudo find /home -type f -mmin -15 | [ $(wc -c) -eq 0 ] && sudo shutdown -h now
メタデータを追加する
gcloud compute instances add-metadata KEY1=VALUE1,KEY2=VALUE2...
# 起動スクリプトとシャットダウンスクリプトを追加
gcloud compute instances add-metadata \
shutdown-script="gcloud pubsub topics publish dev-info --message 'VM powered off...'",startup-script="gcloud pubsub topics publish dev-info --message 'VM powered on!!'"
VM インスタンスのポートを外部に公開する
次の手順でポートを外部に公開できる
- 好きなタグ名でファイアウォールルールを作成する
- VM インスタンスに 1 で作成したネットワークタグを設定する
Kafka 用にポート 2181 と 9092 を公開するファイアウォール設定の例
NAME='kafka'
TAG='use-kafka'
gcloud compute firewall-rules create $NAME \
--network default \
--priority 1000 \
--direction ingress \
--action allow \
--target-tags $TAG \
--rules tcp:2181,tcp:9092
Ref: ファイアウォール ルールを作成する
ヘルスチェック
https://cloud.google.com/load-balancing/docs/health-checks?hl=ja
ヘルスチェックからのトラフィックを許可するファイアウォールの作成
以下のヘルスチェックのソース IP 範囲を指定してファイアウォールを作成する。
35.191.0.0/16
130.211.0.0/22
NAT ゲートウェイ構築
https://cloud.google.com/vpc/docs/special-configurations?hl=ja#
https://cloud.google.com/vpc/docs/special-configurations#multiple-natgateways
Tips
GPU つきの Windows サーバーを作成する
PROJECT_ID="my-project"
NAME="win-vm"
gcloud beta compute --project=$PROJECT_ID instances create $NAME \
--zone=asia-northeast1-a \
--machine-type=n1-standard-8 \
--subnet=default \
--no-restart-on-failure \
--maintenance-policy=TERMINATE \
--preemptible \
--accelerator=type=nvidia-tesla-t4,count=1 \
--image-family windows-2019 \
--image-project=windows-cloud \
--boot-disk-size=300GB \
--boot-disk-type=pd-standard \
--boot-disk-device-name=$NAME
Chrome をインストールする。
$LocalTempDir = $env:TEMP; $ChromeInstaller = "ChromeInstaller.exe"; (new-object System.Net.WebClient).DownloadFile('http://dl.google.com/chrome/install/375.126/chrome_installer.exe', "$LocalTempDir\$ChromeInstaller"); & "$LocalTempDir\$ChromeInstaller" /silent /install; $Process2Monitor = "ChromeInstaller"; Do { $ProcessesFound = Get-Process | ?{$Process2Monitor -contains $_.Name} | Select-Object -ExpandProperty Name; If ($ProcessesFound) { "Still running: $($ProcessesFound -join ', ')" | Write-Host; Start-Sleep -Seconds 2 } else { rm "$LocalTempDir\$ChromeInstaller" -ErrorAction SilentlyContinue -Verbose } } Until (!$ProcessesFound)
Ref:
https://www.snel.com/support/install-chrome-in-windows-server/
startupScript(起動スクリプト)のログを表示する
起動スクリプトのログは次のファイルに書き込まれる。
- CentOS、RHEL: /var/log/messages
- Debian: /var/log/daemon.log
- Ubuntu 14.04、16.04、16.10: /var/log/syslog
- SLES 11 および 12: /var/log/messages
Ref:
起動スクリプトの実行 | Compute Engine ドキュメント | Google Cloud
SFTP サーバ構築
startup.sh
を書く。
#!/usr/bin/env bash
set -eu
groupadd sftp_users
useradd -m -G sftp_users sftp-user
echo "sftp-user:sftp-password" | chpasswd
chown root /home/sftp-user
mkdir /home/sftp-user/upload
chown sftp-user /home/sftp-user/upload
cp /etc/ssh/sshd_config /etc/ssh/sshd_config-org
sed -i 's/\/usr\/lib\/openssh\/sftp-server/internal-sftp/' /etc/ssh/sshd_config
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
cat >> /etc/ssh/sshd_config << EOF
Match group sftp_users
ChrootDirectory %h
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
EOF
systemctl restart sshd
Terraform で構築する例:
resource "google_compute_instance" "sftp-server" {
name = "sftp-server"
machine_type = "n1-standard-1"
metadata_startup_script = "${file("startup_sftp_server.sh")}"
boot_disk {
initialize_params {
image = "gce-uefi-images/ubuntu-1804-lts"
}
}
}
sftp
コマンドで外部から接続する。
sftp sftp-user@<IP>
# password: sftp-password
sftp>