2013年11月5日火曜日

オープンソースのAWS CLI vol.2

こんにちは、村田です。

11月15日に開催されます Red Hat Forum 2013 の登録はお済みでしょうか?
私も登録しまして、Red Hat Enterprise Linux 7 の動向を見てみたいと思っています。

そして、サイオステクノロジーのセッションもございますので、お時間がある方はぜひ足を運んでみてください。

(サイオスとAWSのセッションは同じ時間なので、見に行けないのが非常に残念です。しかも、あちらは既に満席でしたのでコンテンツの内容では負けてられません)

さて、本題に入りましょう。
前回の「オープンソースのAWS CLI vol.1」に続きまして、今回は実際にCLIから使うところまでをご案内したいと思います。

まずは、インスタンスの起動と停止を見てみましょう。
EC2 のインスタンスを起動するコマンドは aws ec2 start-instances となります。

使い方は help を見ればわかるので、まずは help を見てみます。

$ aws ec2 start-instances help
START-INSTANCES()                                            START-INSTANCES()



NAME
       start-instances -

DESCRIPTION
       Starts  an  instance that uses an Amazon EBS volume as its root device.
       Instances that use Amazon EBS volumes as  their  root  devices  can  be
       quickly  stopped  and started. When an instance is stopped, the compute
       resources are released and you  are  not  billed  for  hourly  instance
       usage.  However, your root partition Amazon EBS volume remains, contin-
       ues to persist your data, and you are charged  for  Amazon  EBS  volume
       usage. You can restart your instance at any time.

       NOTE:
           Performing  this  operation  on  an  instance that uses an instance
           store as its root device returns an error.

SYNOPSIS
             start-instances
           --instance-ids 
           [--additional-info ]
           [--dry-run | --no-dry-run]

OPTIONS
       --instance-ids (list)
           The list of Amazon EC2 instances to start.

       Syntax:

           "string" "string" ...

       --additional-info (string)

       --dry-run | --no-dry-run (boolean)

       Checks whether you have the required permissions for the action,  with-
       out  actually  making the request. Using this option will result in one
       of two possible errorresponses. If you have the  required  permissions,
       the error response will be DryRunOperation . Otherwise it will be Unau-
       thorizedOperation .

EXAMPLES
       To start an Amazon EC2 instance

       This example starts the specified Amazon EBS-backed instance.

       Command:

           aws ec2 start-instances --instance-ids i-1a2b3c4d

       Output:

           {
               "StartingInstances": [
                   {
                       "InstanceId": "i-1a2b3c4d",
                       "CurrentState": {
                           "Code": 0,
                           "Name": "pending"
                       },
                       "PreviousState": {
                           "Code": 80,
                           "Name": "stopped"
                       }
                   }
               ]
           }

       For more information, see Stop and Start Your Instance  in  the  Amazon
       Elastic Compute Cloud User Guide.

help を確認するとインスタンスの起動にはインスタンスのIDが必要とあります。
前回のおさらいも含めてインスタンスを確認するコマンドを入力してみましょう。

※ help は標準出力フォーマットである JSON での出力を例にしているため、前回よりアウトプットの config を JSON に戻しています。

$ aws ec2 describe-instances
{
    "Reservations": [
        {
            "OwnerId": "179966892910",
            "ReservationId": "r-3a007a3f",
            "Groups": [],
            "Instances": [
                {
                    "Monitoring": {
                        "State": "disabled"
                    },
                    "PublicDnsName": "ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com",
                    "RootDeviceType": "ebs",
                    "State": {
                        "Code": 16,
                        "Name": "running"
                    },
                    "EbsOptimized": false,
                    "LaunchTime": "2013-10-31T10:33:32.000Z",
                    "PublicIpAddress": "54.xxx.xxx.xxx",
                    "PrivateIpAddress": "172.xxx.xxx.xxx",
                    "ProductCodes": [
                        {
                            "ProductCodeId": "455dlx2t2m0noxeymztl0uc60",
                            "ProductCodeType": "marketplace"
                        }
                    ],
                    "VpcId": "vpc-4a025222",
                    "StateTransitionReason": null,
                    "InstanceId": "i-f2ceb6f7",
                    "ImageId": "ami-99fa7098",
                    "PrivateDnsName": "ip-172.xxx.xxx.xxx.ap-northeast-1.compute.internal",
                    "KeyName": "oss-div",
                    "SecurityGroups": [
                        {
                            "GroupName": "default",
                            "GroupId": "sg-9a0be8f5"
                        }
                    ],
                    "ClientToken": "dFthY1380881880084",
                    "SubnetId": "subnet-4b025223",
                    "InstanceType": "t1.micro",
                    "NetworkInterfaces": [
                        {
                            "Status": "in-use",
                            "SourceDestCheck": true,
                            "VpcId": "vpc-4a025222",
                            "Description": "Primary network interface",
                            "Association": {
                                "PublicIp": "54.xxx.xxx.xxx",
                                "PublicDnsName": "ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com",
                                "IpOwnerId": "amazon"
                            },
                            "NetworkInterfaceId": "eni-70c69618",
                            "PrivateIpAddresses": [
                                {
                                    "PrivateDnsName": "ip-172.xxx.xxx.xxx.ap-northeast-1.compute.internal",
                                    "Association": {
                                        "PublicIp": "54.xxx.xxx.xxx",
                                        "PublicDnsName": "ec2-54-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com",
                                        "IpOwnerId": "amazon"
                                    },
                                    "Primary": true,
                                    "PrivateIpAddress": "172.xxx.xxx.xxx"
                                }
                            ],
                            "PrivateDnsName": "ip-172.xxx.xxx.xxx.ap-northeast-1.compute.internal",
                            "Attachment": {
                                "Status": "attached",
                                "DeviceIndex": 0,
                                "DeleteOnTermination": true,
                                "AttachmentId": "eni-attach-ed4adee8",
                                "AttachTime": "2013-10-04T10:18:00.000Z"
                            },
                            "Groups": [
                                {
                                    "GroupName": "default",
                                    "GroupId": "sg-9a0be8f5"
                                }
                            ],
                            "SubnetId": "subnet-4b025223",
                            "OwnerId": "179966892910",
                            "PrivateIpAddress": "172.xxx.xxx.xxx"
                        }
                    ],
                    "SourceDestCheck": true,
                    "Placement": {
                        "Tenancy": "default",
                        "GroupName": null,
                        "AvailabilityZone": "ap-northeast-1a"
                    },
                    "Hypervisor": "xen",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/sda",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": false,
                                "VolumeId": "vol-cc22d69a",
                                "AttachTime": "2013-10-04T10:18:03.000Z"
                            }
                        }
                    ],
                    "Architecture": "i386",
                    "KernelId": "aki-42992843",
                    "RootDeviceName": "/dev/sda1",
                    "VirtualizationType": "paravirtual",
                    "Tags": [
                        {
                            "Value": "CentOS",
                            "Key": "Name"
                        }
                    ],
                    "AmiLaunchIndex": 0
                }
            ]
        },
    ]
}

出力される情報は少々多いのですが、"InstanceId": の項目にインスタンスID が記載されています。

ふと気付いたのですが、AWS EC2 の仮想化技術は Xen をベースにしているのは有名な話で、出力にも "Hypervisor": "xen" と出てきています。そして、"VirtualizationType": "paravirtual" とあるので、この仮想インスタンスは準仮想化で動いているのが分かったりもします。

インスタンスID が確認できたので、起動コマンドを実行してみましょう。

$ aws ec2 start-instances --instance-ids  i-f2ceb6f7
{
    "StartingInstances": [
        {
            "InstanceId": "i-f2ceb6f7",
            "CurrentState": {
                "Code": 0,
                "Name": "pending"
            },
            "PreviousState": {
                "Code": 80,
                "Name": "stopped"
            }
        }
    ]
}

インスタンスの起動確認は describe-instance-status で確認できます。
起動してしばらくすると "SystemStatus" の項目は "Status": "initializing" となります。
"Status": "ok" となればシステムは起動したことになります。

$ aws ec2 describe-instance-status
{
    "InstanceStatuses": [
        {
            "InstanceId": "i-f2ceb6f7",
            "InstanceState": {
                "Code": 16,
                "Name": "running"
            },
            "AvailabilityZone": "ap-northeast-1a",
            "SystemStatus": {
                "Status": "initializing",
                "Details": [
                    {
                        "Status": "initializing",
                        "Name": "reachability"
                    }
                ]
            },
            "InstanceStatus": {
                "Status": "initializing",
                "Details": [
                    {
                        "Status": "initializing",
                        "Name": "reachability"
                    }
                ]
            }
        }
    ]
}

ここまでは既存のインスタンスの起動でしたが、新たなインスタンスの作成もコマンドラインから行えます。

新規インスタンスの作成の場合、aws ec2 run-instances コマンドを使用します。記述例は以下のようになっています。
オプションが不明な場合は help を活用してください。

$ aws ec2 run-instances --image-id ami-xxxxxxxx --count 1 --instance-type t1.micro --key-name MyKeyPair --security-groups MySecurityGroup

では、実際に CentOS のインスタンスを新規に作成してみましょう。

$ aws ec2 run-instances --image-id ami-99fa7098 --count 1 --instance-type t1.micro --key-name  oss-div --security-groups  default
{
    "OwnerId": "179966892910",
    "ReservationId": "r-7e74c67b",
    "Groups": [],
    "Instances": [
        {
            "Monitoring": {
                "State": "disabled"
            },
            "PublicDnsName": null,
            "KernelId": "aki-42992843",
            "State": {
                "Code": 0,
                "Name": "pending"
            },
            "EbsOptimized": false,
            "LaunchTime": "2013-10-31T12:18:52.000Z",
            "PrivateIpAddress": "172.xxx.xxx.xxx",
            "ProductCodes": [
                {
                    "ProductCodeId": "455dlx2t2m0noxeymztl0uc60",
                    "ProductCodeType": "marketplace"
                }
            ],
            "VpcId": "vpc-4a025222",
            "StateTransitionReason": null,
            "InstanceId": "i-61bab763",
            "ImageId": "ami-99fa7098",
            "PrivateDnsName": "ip-172-XXX-XXX-XXX.ap-northeast-1.compute.internal",
            "KeyName": "oss-div",
            "SecurityGroups": [
                {
                    "GroupName": "default",
                    "GroupId": "sg-9a0be8f5"
                }
            ],
            "ClientToken": null,
            "SubnetId": "subnet-4c025224",
            "InstanceType": "t1.micro",
            "NetworkInterfaces": [
                {
                    "Status": "in-use",
                    "SourceDestCheck": true,
                    "VpcId": "vpc-4a025222",
                    "Description": null,
                    "NetworkInterfaceId": "eni-0cb5e04a",
                    "PrivateIpAddresses": [
                        {
                            "PrivateDnsName": "ip-172-XXX-XXX-XXX.ap-northeast-1.compute.internal",
                            "Primary": true,
                            "PrivateIpAddress": "172.xxx.xxx.xxx"
                        }
                    ],
                    "PrivateDnsName": "ip-172-XXX-XXX-XXX.ap-northeast-1.compute.internal",
                    "Attachment": {
                        "Status": "attaching",
                        "DeviceIndex": 0,
                        "DeleteOnTermination": true,
                        "AttachmentId": "eni-attach-36952333",
                        "AttachTime": "2013-10-31T12:18:52.000Z"
                    },
                    "Groups": [
                        {
                            "GroupName": "default",
                            "GroupId": "sg-9a0be8f5"
                        }
                    ],
                    "SubnetId": "subnet-4c025224",
                    "OwnerId": "179966892910",
                    "PrivateIpAddress": "172.xxx.xxx.xxx"
                }
            ],
            "SourceDestCheck": true,
            "Placement": {
                "Tenancy": "default",
                "GroupName": null,
                "AvailabilityZone": "ap-northeast-1c"
            },
            "Hypervisor": "xen",
            "BlockDeviceMappings": [],
            "Architecture": "i386",
            "StateReason": {
                "Message": "pending",
                "Code": "pending"
            },
            "RootDeviceName": "/dev/sda1",
            "VirtualizationType": "paravirtual",
            "RootDeviceType": "ebs",
            "AmiLaunchIndex": 0
        }
    ]
}

起動確認は先ほどの describe-instance-status で行ってください。
もう少し苦労するかと思いましたが、意外と簡単に AWS EC2 のインスタンスが作成できてしまいました。

起動ができましたので、次は起動したインスタンスを停止してみましょう。
インスタンスを停止するには以下の書式となります。

$ aws ec2 stop-instances --instance-ids (list)

実際に先ほど作成したインスタンスを停止するコマンドを実行します。

$ aws ec2 stop-instances --instance-ids i-61bab763
{
    "StoppingInstances": [
        {
            "InstanceId": "i-61bab763",
            "CurrentState": {
                "Code": 64,
                "Name": "stopping"
            },
            "PreviousState": {
                "Code": 16,
                "Name": "running"
            }
        }
    ]
}

※今回はAWS CLIから落としていますが、通常はOSにログインしてシャットダウンすることをお勧めします。

コマンドラインから操作が行えるということは、時間がきたらインスタンスを落としたり、起ち上げたりができるということですね。例えば crond を使えば AWS は時間課金なので検証用サーバーなどは業務時間外はインスタンスを止めておき、朝9時前には自動的に立ち上げる事もできるわけです。

$ crontab -l
45 8 * * * /home/ec2-user/aws.sh

$ cat /home/ec2-user/aws.sh
#!/bin/bash
aws ec2 start-instances --instance-ids i-61bab763

$ chmod 755 aws.sh

そして、翌朝9時に確認すると…。インスタンスが立ち上がっていません。

すっかり忘れていたことですが、EC2 Amazon Linux インスタンスはUTCを使っているため、日本時間の朝9時に date コマンドを打つと 「Fri Nov 1 00:16:01 UTC 2013」 と返ってきます。 時間をUTCに変換して時間を設定するか、OSの設定を変更する必要がありました。

UTC時間で入力して実行を待つと、ちゃんと動きました。
以下の設定で9時20分に実行されます。

$ crontab -l
20 0 * * * /home/ec2-user/aws.sh

このように Linux コマンドラインからも AWS の管理が行えるということは、これまでの Linux 運用知識を応用して、クラウド上のリソースも管理もできることになるのではないでしょうか。
リソースの自動化や耐障害性の向上やシステムのバックアップなども OSS と AWS との連携で簡単にできそうなので、次回は自動化の機能を使ってみたいと思います。

余談ですが、AWS管理用のiPhone アプリも公開されています。
iPhone からインスタンスの起動も停止も行えるので、週末に落とし忘れたインスタンスの停止や、万が一の時にインスタンスを仕込んでおけば緊急対応にも...などと考えてしまいます。
https://itunes.apple.com/jp/app/aws-console/id580990573?mt=8

0 件のコメント:

コメントを投稿