kubernetesのログをfluentdでCloudwatchに送ろうとしたら、UndefinedConversionErrorで死んだ

# ٩(๑`^´๑)۶
エラーの原因究明に3時間くらいかかってつらかったので、書きました。

# 目的
`kubernetes`の`pod`のログをいちいち見に行くのが面倒なので、`fluentd`で`Cloudwatch`で集約したい。

# やったこと
[こちらの方の手順](https://qiita.com/ishigero/items/5b32ebe2a81f493b7a6e)を参考に`yml`を作成し、`apply`した。
- 使用した`manifest`：[fluentd-kubernetes-daemonset/fluentd-daemonset-cloudwatch-rbac.yaml](https://github.com/fluent/fluentd-kubernetes-daemonset/blob/master/fluentd-daemonset-cloudwatch-rbac.yaml)

# 起きたエラー：`UndefinedConversionError`
```
2019-03-26 08:21:06 +0000 [warn]: temporarily failed to flush the buffer. next_retry=2019-03-26 08:21:08 +0000 error_class="Encoding::UndefinedConversionError" error="\"\\xE3\" from ASCII-8BIT to UTF-8" plugin_id="out_cloudwatch_logs"
```

# 公式さん曰く
このエラーは、文字列エンコーディングがASCII-8BITに設定されているが実際のコンテンツがUTF-8の場合に発生するらしい。

-  [[FAQ] i-got-enconding-error-inside-plugin.-how-to-fix-it?](https://docs.fluentd.org/v1.0/articles/faq#i-got-enconding-error-inside-plugin.-how-to-fix-it?)

> I got enconding error inside plugin. How to fix it?
 You may hit `"\xC3" from ASCII-8BIT` to UTF-8" like `UndefinedConversionError` in the plugin. This error 
happens when string encoding is set to `ASCII-8BIT` but actual content is `UTF-8`. Fluentd and almost plugins treat the logs as a `ASCII-8BIT` by default but some libraries assume the log encoding is `UTF-8`. This is why this error happens.

> There are several approaches to avoid this problem.

> Set encoding correctly.
`tail` input has encoding related parameters to change the log encoding
Use `record_modifier` filter to change the encoding. See fluent-plugin-record-modifier README
Use `yajl` instead of `json` when error happens inside `JSON.parse/JSON.dump`

# `fluent-plugin-record-modifier`入れて`<filter pattern>`設定すれば行けそう
- 以下のように、`fluentd.conf`を指定するとエンコード方式を変更できるらしい。
  - [fluent-plugin-record-modifier](https://github.com/repeatedly/fluent-plugin-record-modifier#char_encoding)

```conf:fluentd.conf
<filter pattern>
  @type record_modifier

  # set UTF-8 encoding information to string.
  char_encoding utf-8

  # change char encoding from 'UTF-8' to 'EUC-JP'
  char_encoding utf-8:euc-jp
</filter>
```

# 確認したら最新版の`fluentd.conf`と差分があった


```conf:デフォルトのやつ
# AUTOMATICALLY GENERATED
# DO NOT EDIT THIS FILE DIRECTLY, USE /templates/conf/fluent.conf.erb

@include kubernetes.conf

<match **>
  @type cloudwatch_logs
  @id out_cloudwatch_logs
  log_group_name "#{ENV['LOG_GROUP_NAME']}"
  auto_create_stream true
  use_tag_as_stream true
</match>
```

```conf:最新のやつ
# AUTOMATICALLY GENERATED
# DO NOT EDIT THIS FILE DIRECTLY, USE /templates/conf/fluent.conf.erb

@include "#{ENV['FLUENTD_SYSTEMD_CONF'] || 'systemd'}.conf"
@include kubernetes.conf
@include conf.d/*.conf

<match **>
  @type cloudwatch_logs
  @id out_cloudwatch_logs
  log_group_name "#{ENV['LOG_GROUP_NAME']}"
  auto_create_stream true
  use_tag_as_stream true
  json_handler yajl # To avoid UndefinedConversionError
  log_rejected_request "#{ENV['LOG_REJECTED_REQUEST']}" # Log rejected request for missing parts
</match>
```

**・・・ん！？**
**なんか治ってるらしい。**
`json_handler yajl # To avoid UndefinedConversionError`


# いろいろあったけど結論
`manifest`の`image`の`tag`を最新のタグに書き換える。以上。

ここを

```yaml:fluentd-daemonset-cloudwatch-rbac.yaml
image: fluent/fluentd-kubernetes-daemonset:cloudwatch
```
こうする

```yaml:fluentd-daemonset-cloudwatch-rbac.yaml
image: fluent/fluentd-kubernetes-daemonset:v1.3-debian-cloudwatch-1
```
`:cloudwatch`タグでとってきてたやつが最新じゃなかったみたいです。