AlibabaCloud上に本番サービスをデプロイした話

[NAVITIME JAPAN Advent Calendar 2019](https://qiita.com/advent-calendar/2019/navitime_japan)の20日目です。

## はじめに
先日おこなわれたAlibaba Cloud Internet Champion Day(秋)にて発表した、「[ナビタイムジャパンのクラウド活用事例　～2週間でAlibaba Cloud上に本番サービスをデプロイした話～](https://www.slideshare.net/NavitimeJapan/2alibaba-cloud)」について、ログ転送周りを詳しく紹介します。

通常、AlibabaCloudではLogServiceを用いてログの管理/集約をおこなうと思いますが、敢えてfluentdを用いてOSSに転送をおこないました。
他のパブリッククラウドでは基本的にfluentdを用いてログ転送をおこなうことが多いため、同じ構成でできないかと思いこの構成にしました。


## 今回登場するサービス
* Container Service
    * コンテナ管理
* Elastic Compute Service (ECS)
    * インスタンス管理
* Object Storage Service (OSS)
    * オブジェクトの保存等
* Resource Access Management (RAM)
    * 権限管理

![構成図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/006b440f-c021-0981-6fe7-c32332ab4a63.png)


## 事前準備1 〜OSS〜
ログを保存するOSSバケットを作成しましょう
(略)

```OSSUtilSample.
$ ossutil mb oss://BucketName
```

## 事前準備2 〜RAM〜
AlibabaCloudにはRAMと呼ばれる権限管理のサービスがあります。
RAMロールをECSインスタンスに付与することで、インスタンス内から許可したAlibabaCloudのサービスを操作することが可能です。

ただし、fluentdの転送時にはこのRAMロールが使えないため、アクセスキーを発行するしかありません。

#### アクセスキー用のユーザーを発行 
1. RAMを選択
2. ユーザーを選択
3. ユーザーの作成
4. ログイン名と表示名(ログイン名と同じでOK)を入力し、「プログラムによるアクセス」にチェックを入れOK
5. 次の画面で、AccessKeyIdとAccessKeySecretをコピーしておく（この画面を閉じると二度と表示されない）

```AliyunCLI.sample
$ aliyun ram CreateUser --UserName test --DisplayName test
$ aliyun ram CreateAccessKey --UserName test
```

#### 権限の追加
* すでに作られている権限をそのまま追加すると、過剰に権限を付与することになるため、ポリシーは基本的に自作します

1. RAM上でポリシーを選択
2. 「ポリシーの作成」
3. 設定モードをスクリプトにし、以下のポリシーを設定
4. このポリシーをユーザーにアタッチする

```
{
    "Statement": [
        {
            "Action": [
                "oss:PutObject",
                "oss:GetObject",
                "oss:List*"
            ],
            "Effect": "Allow",
            "Resource": [
                "acs:oss:*:*:BucketName",
                "acs:oss:*:*:BucketName/*"
            ]
        }
    ],
    "Version": "1"
}
```

```AliyunCLISample.
aliyun ram CreatePolicy --PolicyName PutLogOSS --PolicyDocument "{\"Statement\": [{\"Action\": [\"oss:PutObject\",\"oss:GetObject\",\"oss:List*\"],\"Effect\": \"Allow\",\"Resource\": [\"acs:oss:*:*:BucketName\",\"acs:oss:*:*:BucketName/*\"]}],\"Version\": \"1\"}"
```



## fluentdコンテナの設定
fluentdの設定ファイルのサンプルです。
サンプルなので適宜お使いの環境に合わせて修正してください。

```fluent.conf
<source>
  @type tail
  @label @access-log
  format none
  path /var/log/apache/access_log
  pos_file "/fluentd/log/REPLACE_WITH_INSTANCE_ID.access_log.pos"
  tag raw.log
</source>

<label @access-log>
  <match raw.log>
    @type record_modifier
    tag "access_log.REPLACE_WITH_INSTANCE_ID"
  </match>

  <match apache.access_log.**>
    @type oss
    endpoint oss-cn-hongkong-internal.aliyuncs.com
    bucket 作ったバケット名
    access_key_id 作ったアクセスキー
    access_key_secret 作ったシークレットアクセスキー
    path "%Y%m%d/REPLACE_WITH_INSTANCE_ID/"
    auto_create_bucket false
    key_format %{path}accesslog_%{time_slice}.%{file_extension}
    store_as gzip
    <buffer tag,time>
      @type file
      path "/fluentd/log/REPLACE_WITH_INSTANCE_ID.access_log.buf"
      timekey 10s
      timekey_wait 0
    </buffer>
    <format>
      @type out_file
    </format>
  </match>
</label>
```

これでfluentdコンテナを起動すれば指定したファイルがOSSに転送されると思います。


## OSSへログ転送ができたら・・・
OSSへログを転送できたら、ログの可視化したいですよね？
AlibabaCloudでは独身の日などでも使われるData-Vで可視化することが多いです。

ただし、Data-Vはあくまでも可視化ツールなので事前のETL処理が必要です。
OSSのファイルを参照するにはjson形式で集計したものを適切な形式で配置する必要があります。

サンプル

![Data-V Sample](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/7daa47cb-68a7-39cd-ae49-7ca1087a655e.gif)


上記のダッシュボードでは以下の要素を使っています
* Carousel List II
* Flat Map with 3D Effects
* Ticker Board
* Carousel Pie Chart
* Basic Line Chart

以下にJSONのサンプルを記載しました。Key値についてはマッピングが可能なので必ずしもこの名前でなくてOKです

### Carousel List II
* レスポンスタイムとそのパスを表示しています

```JSON形式.
[{"response_time": "123","request_path": "/hoge"},{"response_time": "124","request_path": "/fuga"}]
```

### Flat Map with 3D Effects
* どこからアクセスがあるかを表示しています
* idには ISO 3166-1 alpha-3 の国コードを指定する必要があります

```JSON形式.
[{"id": "JPN","value": 1,"name": "Japan"},{"id": "CHN","value": 2,"name": "China"}]
```
### Ticker Board
* 直近のエラー件数を表示しています

```JSON形式.
[{"name": "", "value": 0}]]
```

### Carousel Pie Chart
* エラーコード別リクエスト割合を表示しています

```JSON形式.
[{"x": "200","y": 100},{"x": "404","y": 20}]
```

### Basic Line Chart
* リクエスト数の推移を表示しています

```JSON形式.
[{"x": "2019/10/01 00:00:00","y": 100},{"x": "2019/10/01 01:00:00","y": 50}]
```


## さいごに
アジア市場でシェア1位を誇るAlibabaCloudですが、まだまだ日本では発展途上かと思います。
特にドキュメントの整備がされていない、サンプルなどが少ないという状況なので、ここの改善がされるのを期待しています。
いい意味でAWSライクなので、AWS利用者は使いやすいと思います！

それでは、よいAlibabaライフを！