ハンズオン : gcutil コマンドで Google Compute Engine のインスタンスを作成する


この記事は以下のハンズオン部分です。

googlecomputeengine - Google Compute Engine 入門 - Qiita
http://qiita.com/yuko/items/460ac35d8706e8df1290

この実践をする前に準備とGoogle Cloud SDKのハンズオンの実施が必要となりますので、これらがまだの方は上記を参照して下さい。

#gcutil

##gcutilとは
Google Compute Engine 用コマンドラインツールです。
Google Cloud Platform SDK に含まれています。

##gcutil基本

###ヘルプの見方

```bash
gcutil
```

または

```bash
gcutil help
```

と実行するとコマンドの一覧が出てきます。

次に“list”が含まれる行を絞り込んでコマンドを探してみましょう。

``` bash
gcutil | grep list
```

コマンド実行例

```bash
~ $ gcutil | grep list
  listaddresses, listdisks, listfirewalls, listforwardingrules,
  listhttphealthchecks, listimages, listinstances, listkernels,
  listmachinetypes, listnetworks, listoperations, listregions, listroutes,
  listsnapshots, listtargetinstances, listtargetpools, listzones, moveinstances,
listaddresses                List the IP addresses for a project.
listdisks                    List the disks for a project.
listfirewalls                List the firewall rules for a project.
listforwardingrules          List the forwarding rule for a project.
listhttphealthchecks         List the HTTP health checks for a project.
listimages                   List the images for a project.
listinstances                List the VM instances for a project.
listkernels                  [Deprecated] List the kernels for a project.
listmachinetypes             List the machine types for a project.
listnetworks                 List the virtual networks for a project.
listoperations               List the operations for a project.
listregions                  List the regions for a project.
listroutes                   List the routing rules for a project.
listsnapshots                List the persistent disk snapshots for a project.
listtargetinstances          List the target instances for a project.
listtargetpools              List the target pools for a project.
listzones                    List the zones for a project.
```

※ Deprecated は古くなった非推奨コマンドです。


コマンドの詳細は下記で確認します。

```bash
gcutil help コマンド
````

コマンド実行例

```bash
~ $ gcutil help listimages
Command line tool for interacting with Google Compute Engine.

Please refer to http://developers.google.com/compute/docs/gcutil/tips for more information about gcutil usage.


USAGE: gcutil [--global_flags] <command> [--command_flags] [args]


listimages                   List the images for a project.

                             Usage: gcutil [--global_flags] listimages [--command_flags]

                             Flags for listimages:
<以下略>
```

###リージョンの確認
利用できるリージョンの確認をします。

```bash
gcutil listregions

```

コマンド実行例

```bash
~ $ gcutil listregions
+--------------+--------+----------+----------------+------------------+
| name         | status | cpus     | disks-total-gb | static-addresses |
+--------------+--------+----------+----------------+------------------+
| asia-east1   | UP     | 0.0/20.0 | 0.0/5120.0     | 0.0/8.0          |
+--------------+--------+----------+----------------+------------------+
| europe-west1 | UP     | 0.0/20.0 | 0.0/5120.0     | 0.0/8.0          |
+--------------+--------+----------+----------------+------------------+
| us-central1  | UP     | 0.0/20.0 | 0.0/5120.0     | 0.0/8.0          |
+--------------+--------+----------+----------------+------------------+
```
※2014/4/15 に asiaリージョンがオープンしました！やったー！

###ゾーンの確認
リージョンの中にあるゾーンの一覧を確認します。
メンテナンススケジュールを確認することができます。

```bash
gcutil listzones

```

コマンド実行例

```bash
~ $ gcutil listzones
+----------------+--------+-------------------------------+
| name           | status | next-maintenance              |
+----------------+--------+-------------------------------+
| asia-east1-a   | UP     | None scheduled                |
+----------------+--------+-------------------------------+
| asia-east1-b   | UP     | None scheduled                |
+----------------+--------+-------------------------------+
| europe-west1-a | UP     | 2014-06-13T12:00:00.000-07:00 |
+----------------+--------+-------------------------------+
| europe-west1-b | UP     | None scheduled                |
+----------------+--------+-------------------------------+
| us-central1-a  | UP     | None scheduled                |
+----------------+--------+-------------------------------+
| us-central1-b  | UP     | None scheduled                |
+----------------+--------+-------------------------------+
```

###マシンタイプの確認
利用できる仮想マシンタイプの一覧を確認できます。

```bash
gcutil listmachinetypes

```

コマンド実行例

```bash
~ $ gcutil listmachinetypes
+-----------------+----------------+------+-----------+-------------+
| name            | zone           | cpus | memory-mb | deprecation |
+-----------------+----------------+------+-----------+-------------+
| n1-standard-1-d | us-central1-a  |    1 |      3840 | DEPRECATED  |
+-----------------+----------------+------+-----------+-------------+
| n1-standard-1   | us-central1-a  |    1 |      3840 |             |
+-----------------+----------------+------+-----------+-------------+
| f1-micro        | us-central1-a  |    1 |       614 |             |
+-----------------+----------------+------+-----------+-------------+
| g1-small        | us-central1-a  |    1 |      1740 |             |
+-----------------+----------------+------+-----------+-------------+
| n1-standard-1   | us-central1-b  |    1 |      3840 |             |
+-----------------+----------------+------+-----------+-------------+
| n1-standard-1-d | us-central1-b  |    1 |      3840 | DEPRECATED  |
+-----------------+----------------+------+-----------+-------------+
| f1-micro        | us-central1-b  |    1 |       614 |             |
+-----------------+----------------+------+-----------+-------------+
<以下略>
```
※ Deprecated は古くなった非推奨仮想マシンタイプです。

zoneを指定してリストを出力することもできます。
詳細は以下のコマンドでヘルプを確認してみましょう。

```bash
gcutil help listmachinetypes
```

###マシンイメージの確認
利用できる仮想マシンOSイメージを確認してみましょう

```bash
gcutil listimages
```

コマンド実行例

```bash
~ $ gcutil listimages
+-------------------------------------------------------------------------+-------------+--------+
| name                                                                    | deprecation | status |
+-------------------------------------------------------------------------+-------------+--------+
| projects/centos-cloud/global/images/centos-6-v20140318                  |             | READY  |
+-------------------------------------------------------------------------+-------------+--------+
| projects/debian-cloud/global/images/backports-debian-7-wheezy-v20140331 |             | READY  |
+-------------------------------------------------------------------------+-------------+--------+
| projects/debian-cloud/global/images/debian-6-squeeze-v20130926          | DEPRECATED  | READY  |
+-------------------------------------------------------------------------+-------------+--------+
| projects/debian-cloud/global/images/debian-7-wheezy-v20140318           |             | READY  |
+-------------------------------------------------------------------------+-------------+--------+
| projects/rhel-cloud/global/images/rhel-6-v20140318                      |             | READY  |
+-------------------------------------------------------------------------+-------------+--------+
| projects/suse-cloud/global/images/sles-11-sp3-v20140306                 |             | READY  |
+-------------------------------------------------------------------------+-------------+--------+
| projects/suse-cloud/global/images/sles11-sp3-v20131209                  | DEPRECATED  | READY  |
+-------------------------------------------------------------------------+-------------+--------+
```


##インスタンスの作成
ではインスタンスを作成してみましょう。

手元にプロジェクトIDを用意して下さい。
プロジェクトIDは以下で確認できます。
https://cloud.google.com/console‎

また作成するインスタンス名を決めておいて下さい。この名前がホスト名にもなります。
全て英数小文字で作成する必要があります。大文字は使えません。また頭に数字をつけることはできません。

```bash
gcutil --project=<project-id> addinstance <instance-name>
```

実行例

```bash
~ $ gcutil --project=handson addinstance test001

Select a zone:
1: asia-east1-a
2: asia-east1-b
3: europe-west1-a
4: europe-west1-b
5: us-central1-a
6: us-central1-b
>>> 5
```

最初にZoneを選択します。今回は 5: us-central1-a を選択しましょう

```bash
Select a machine type:
1: n1-standard-1	1 vCPU, 3.75 GB RAM
2: n1-standard-2	2 vCPUs, 7.5 GB RAM
3: n1-standard-4	4 vCPUs, 15 GB RAM
4: n1-standard-8	8 vCPUs, 30 GB RAM
5: n1-highcpu-2	2 vCPUs, 1.8 GB RAM
6: n1-highcpu-4	4 vCPUs, 3.6 GB RAM
7: n1-highcpu-8	8 vCPUs, 7.2 GB RAM
8: n1-highmem-2	2 vCPUs, 13 GB RAM
9: n1-highmem-4	4 vCPUs, 26 GB RAM
10: n1-highmem-8	8 vCPUs, 52 GB RAM
11: f1-micro	1 vCPU (shared physical core) and 0.6 GB RAM
12: g1-small	1 vCPU (shared physical core) and 1.7 GB RAM
>>> 1
```

次に仮想マシンタイプを選択します。1: n1-standard-1 を選択してみましょう。

```bash
Select an image:
1: projects/centos-cloud/global/images/centos-6-v20140318
2: projects/debian-cloud/global/images/backports-debian-7-wheezy-v20140331
3: projects/debian-cloud/global/images/debian-7-wheezy-v20140318
4: projects/rhel-cloud/global/images/rhel-6-v20140318
5: projects/suse-cloud/global/images/sles-11-sp3-v20140306
6: projects/debian-cloud/global/images/debian-6-squeeze-v20130926 (DEPRECATED)
7: projects/suse-cloud/global/images/sles11-sp3-v20131209 (DEPRECATED)
>>> 1
```

OSイメージを選択します。1: projects/centos-cloud/global/images/centos-6-vxxxxxx を選択してみましょう

```bash
WARNING: You don’t have an ssh key for Google Compute Engine. Creating one now...
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
```

あなたは Google Compute Engine 用のSSHキーを持っていないので作りますね…
と書かれています。

秘密鍵のパスフレーズ(passphrase)を聞かれるので、今回は "google" と入力して下さい。（これはテスト用です。実際の運用時は自分だけがわかるパスフレーズを入れてくださいね！） 

-- 注意 --
このパスフレーズは忘れないようにして下さい。パスフレーズを忘れてしまうとその鍵は二度と使えなくなってしまいます。また、この秘密鍵と関連している公開鍵を登録しているインスタンスに二度とログインできなくなる恐れが高いです。

これによりSSH公開鍵と秘密鍵が作成されます。
そして公開鍵は自動的にプロジェクトに登録され、インスタンスを作成するときに利用されます。

ここまで出来るとあとは自動的にインスタンスが作成されて起動します。

```bash
INFO: Waiting for insert of instance test001. Sleeping for 3s.
INFO: Waiting for insert of instance test001. Sleeping for 3s.
INFO: Waiting for insert of instance test001. Sleeping for 3s.
INFO: Waiting for insert of instance test001. Sleeping for 3s.
INFO: Waiting for insert of instance test001. Sleeping for 3s.

Table of resources:

+---------+---------------+-----------------+---------------+---------+
| name    | network-ip    | external-ip     | zone          | status  |
+---------+---------------+-----------------+---------------+---------+
| test001 | 10.240.180.32 | 173.255.118.xxx | us-central1-a | RUNNING |
+---------+---------------+-----------------+---------------+---------+

Table of operations:

+---------------------------------------------------------+--------+-------------------------------+----------------+
| name                                                    | status | insert-time                   | operation-type |
+---------------------------------------------------------+--------+-------------------------------+----------------+
| operation-1396733358040-4f65253a29631-127b913f-8ad60bab | DONE   | 2014-04-01T14:29:18.040-07:00 | insert         |
+---------------------------------------------------------+--------+-------------------------------+----------------+
```

### SSH秘密鍵と公開鍵
SSHの秘密鍵と公開鍵はこのような名前で ~/.ssh/ 配下に保存されています。
今後もこの鍵を使うようでしたら、後でなくならないよう、大切に保存しておいて下さい。
※このハンズオンで作ったものはパスフレーズがわかりやすすぎるので捨てて新たに作り直して下さい。

```bash
~ $ ls -l ~/.ssh/google*
-rw-------  1 hoge  staff   1.7K  4  2 06:37 /Users/hoge/.ssh/google_compute_engine
-rw-r--r--  1 hoge  staff   401B  4  2 06:37 /Users/hoge/.ssh/google_compute_engine.pub
```

### 作成したインスタンスの確認

```bash
~ $ gcutil listinstances
+---------+---------------+---------+---------------+-----------------+
| name    | zone          | status  | network-ip    | external-ip     |
+---------+---------------+---------+---------------+-----------------+
| test001 | us-central1-a | RUNNING | 10.240.180.32 | 173.255.118.xxx |
+---------+---------------+---------+---------------+-----------------+
```

external-ip が外部向けのIPアドレスです。
あとで利用するのでメモをしておいて下さい。

### 作成したインスタンスにリモートログイン

gcutilコマンドを使ってインスタンスにログインすることができます。

```bash
gcutil --project=<project-id> ssh <instance-name>
```

```bash
~$ gcutil --project= handson ssh test001

INFO: Zone for test001 detected as us-central1-a.
INFO: Running command line: ssh -o UserKnownHostsFile=/dev/null -o CheckHostIP=no -o StrictHostKeyChecking=no -i /Users/hoge/.ssh/google_compute_engine -A -p 22 hoge@173.255.118.xxx --
Warning: Permanently added '173.255.118.xxx' (RSA) to the list of known hosts.
Identity added: /Users/hoge/.ssh/google_compute_engine (/Users/hoge/.ssh/google_compute_engine)

[hoge@test001 ~]$ <- インスタンスにログインできました！
```

インスタンスのホスト名は作成したインスタンス名とおなじになります。
また、ログインユーザーは現在あなたがこのコマンドを実行しているユーザー名で自動的に作成されています。

※もし指定したユーザー名でインスタンスを作成したい場合は `gcutil addinstance --authorized_ssh_keys` で可能です。詳細はヘルプを確認してみましょう。

##Webサーバをインストール
では試しにWebサーバをインストールしてブラウザからアクセスしてみましょう。

お手軽なApacheをインストールして起動します。

```bash
sudo yum -y install httpd
sudo service httpd start

```

実行例

```bash
[hoge@test001 ~]$ sudo yum -y install httpd
Loaded plugins: downloadonly, fastestmirror, security
Loading mirror speeds from cached hostfile
 * base: mirror.teklinks.com
 * extras: mirrors.tummy.com
 * updates: mirror.fdcservers.net
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package httpd.x86_64 0:2.2.15-30.el6.centos will be installed
<中略>
[hoge@test001 ~]$ sudo service httpd start
Starting httpd:                                            [  OK  ]
```

上記まで完了できたら、先ほどメモしたインスタンスのexternal-IP にブラウザでアクセスしてみましょう。

```
http://<external-ip>
```

おそらくはこんな表示が出ているはずです。

![01.png](https://qiita-image-store.s3.amazonaws.com/0/40971/ecb95e81-9f82-a9fe-78d9-1739b73b6017.png "01.png")

そう、アクセスできません。
どんな問題があるのでしょう？

###Firewallを設定する

アクセスできなかったのには理由があります。
インスタンスは Firewall で守られていて、そのままでは外からアクセスできません。
Firewallの設定を変更して、外からアクセスできるようにしてあげましょう。

一旦インスタンスから出ます。

```bash
[hoge@test001 ~]$ exit
logout
Connection to 173.255.118.xxx closed.
```

以下のコマンドを実行して、プロジェクトの80番ポートを開放します。

``` bash
gcutil addfirewall http2 --description="Incoming http allowed." --allowed="tcp:http"
```

コマンド実行例

```bash
$ gcutil addfirewall http2 --description="Incoming http allowed." --allowed="tcp:http"

INFO: Waiting for insert of firewall http2. Sleeping for 3s.
INFO: Waiting for insert of firewall http2. Sleeping for 3s.
INFO: Waiting for insert of firewall http2. Sleeping for 3s.
INFO: Waiting for insert of firewall http2. Sleeping for 3s.
INFO: Waiting for insert of firewall http2. Sleeping for 3s.

Table of resources:

+-------+---------+
| name  | network |
+-------+---------+
| http2 | default |
+-------+---------+

Table of operations:

+---------------------------------------------------------+--------+-------------------------------+----------------+
| name                                                    | status | insert-time                   | operation-type |
+---------------------------------------------------------+--------+-------------------------------+----------------+
| operation-1396736296953-4f65302cf8eb1-d0a3b77b-12d6a6dd | DONE   | 2014-04-01T15:18:16.953-07:00 | insert         |
+---------------------------------------------------------+--------+-------------------------------+----------------+
```

Firewallの設定ができたら
再度先ほどメモしたインスタンスのexternal-IP にブラウザでアクセスしてみましょう

```
http://<external-ip>
```

こんなページが見えていたら成功です。
![02.png](https://qiita-image-store.s3.amazonaws.com/0/40971/0d3864f8-23d7-245b-716e-07d21dc5aa75.png "02.png")

##Google Developers Console で確認

以下にアクセスして、作成した内容を確認してみてください。
自分が作ったインスタンスが表示されているかな？

```
https://console.developers.google.com/project/apps~<プロジェクトID>/compute/instances
```


##削除
ここまでインスタンスを作成しましたが、このまま放おって置くと課金され続けてしまうので削除を行いましょう。
上記Developer Consoleで削除しても構いません。
ここではコマンドでの削除方法を記載します。

まず、下記コマンドを利用して現在のインスタンスとディスクの内容を確認して下さい。

```bash
gcutil listinstances
gcutil listdisks

```

コマンド実行例

```bash
~ $ gcutil listinstances
+---------+---------------+---------+---------------+-----------------+
| name    | zone          | status  | network-ip    | external-ip     |
+---------+---------------+---------+---------------+-----------------+
| test001 | us-central1-a | RUNNING | 10.240.180.32 | 173.255.118.xxx |
+---------+---------------+---------+---------------+-----------------+
~ $ gcutil listdisks
+---------+---------------+--------+---------+
| name    | zone          | status | size-gb |
+---------+---------------+--------+---------+
| test001 | us-central1-a | READY  |      10 |
+---------+---------------+--------+---------+
```

インスタンの削除は下記コマンドを利用して行います

```bash
gcutil deleteinstance --zone=<ゾーン名> <インスタンス名>
```

コマンド実行例

```bash
~ $ gcutil deleteinstance --zone=us-central1-a test001
Delete instance test001? [y/n]
>>> y
Delete persistent boot disk test001? [y/n]
>>> y
INFO: Enabling auto-delete on test001 (test001).
INFO: Waiting for setDiskAutoDelete of instance test001. Sleeping for 3s.
INFO: Waiting for delete of instance test001. Sleeping for 3s.
INFO: Waiting for delete of instance test001. Sleeping for 3s.
INFO: Waiting for delete of instance test001. Sleeping for 3s.
INFO: Waiting for delete of instance test001. Sleeping for 3s.
INFO: Waiting for delete of instance test001. Sleeping for 3s.
INFO: Waiting for delete of instance test001. Sleeping for 3s.
INFO: Waiting for delete of instance test001. Sleeping for 3s.
INFO: Waiting for delete of instance test001. Sleeping for 3s.
INFO: Waiting for delete of instance test001. Sleeping for 3s.
INFO: Waiting for delete of instance test001. Sleeping for 3s.
+---------------------------------------------------------+--------+-------------------------------+----------------+
| name                                                    | status | insert-time                   | operation-type |
+---------------------------------------------------------+--------+-------------------------------+----------------+
| operation-1397593714220-4f71aa4e05be0-4d3e7f10-d95668a3 | DONE   | 2014-04-15T13:28:34.220-07:00 | delete         |
+---------------------------------------------------------+--------+-------------------------------+----------------+
```

そして削除ができたか確認してみてください。

```bash
~ $ gcutil listinstances
+------+------+--------+------------+-------------+
| name | zone | status | network-ip | external-ip |
+------+------+--------+------------+-------------+
~ $ gcutil listdisks
+------+------+--------+---------+
| name | zone | status | size-gb |
+------+------+--------+---------+
```

上記のようにインスタンスもディスクも無くなっていれば削除できています。

残っていても課金の対象とはなりませんが、Firewallも消しておきましょう。
削除する場合は以下のようにして下さい。

コマンド実行例（http2 firewall を削除します）

```bash
~ $ gcutil listfirewalls
+------------------------+---------+
| name                   | network |
+------------------------+---------+
| default-allow-internal | default |
+------------------------+---------+
| default-ssh            | default |
+------------------------+---------+
| http2                  | default |
+------------------------+---------+
~ $ gcutil deletefirewall http2
Delete firewall http2? [y/n]
>>> y
INFO: Waiting for delete of firewall http2. Sleeping for 3s.
+---------------------------------------------------------+--------+-------------------------------+----------------+
| name                                                    | status | insert-time                   | operation-type |
+---------------------------------------------------------+--------+-------------------------------+----------------+
| operation-1397594984974-4f71af09e86b0-8123ebc6-c739d2a6 | DONE   | 2014-04-15T13:49:44.974-07:00 | delete         |
+---------------------------------------------------------+--------+-------------------------------+----------------+
~ $ gcutil listfirewalls
+------------------------+---------+
| name                   | network |
+------------------------+---------+
| default-allow-internal | default |
+------------------------+---------+
| default-ssh            | default |
+------------------------+---------+

```


#Google Developer サイト

ここまでうまく出来ましたでしょうか。
Google Cloud Platrform は日々進化し続けています。

ドキュメントなどは下記を参照して下さい。
サンプルコードも用意されています。

Developer Information & Resources - Google Cloud Platform
https://cloud.google.com/developers/?hl=ja

またGithubにもいろいろな便利ツールやSampleが掲載されていますので確認してみてください。

Google Cloud Platform
https://github.com/GoogleCloudPlatform/

Enjoy!