Amazon Web Services ブログ
Fluentd を使用して Amazon EKS Windows ポッドから Amazon CloudWatch Logs にログをストリーミングする
コンテナはオペレーティングシステム仮想化の方法の 1 つで、リソース隔離処理でアプリケーションとその依存関係を実行できるようにするものです。コンテナを使用することで、アプリケーションのコード、設定、依存関係を使いやすいビルディングブロックに簡単にパッケージ化でき、環境の一貫性、運用効率、開発者の生産性を高め、バージョン管理を行うことができます。
Windows コンテナを使うと、前に述べた利点をすべて享受できるだけでなく、Windows Server 2003、2008、2008 R2 などのサポートされていない運用システムで実行しているレガシーアプリ (現在では、環境全体をセキュリティの脅威にさらし、セキュリティルールのコンプライアンスに準拠していない恐れがあります) を移行することも可能です。
AWS でコンテナを実行する場合、2 つの選択肢があります。1 つ目は、サーバーを管理するかどうかです。コンテナ用のサーバーレスコンピューティングが必要な場合は AWS Fargate を選択し、コンピューティング環境のインストール、設定、管理を制御する必要がある場合は Amazon EC2 を選択します。2 つ目は、Amazon Elastic Container Service (ECS) または Amazon Elastic Kubernetes Service (EKS) のどちらかのコンテナオーケストレーターを選択して使用します。コンテナの詳細については、こちらをご参照ください。
同時に、新しいプラットフォームに移行するには、適切な作業に適切なツールが必要です。このブログ投稿では、ログを一元化する方法として、Windows ポッドで作成した IIS ログを Amazon CloudWatch Logs にストリーミングする方法について解説します。
では、これをどのように実現するかをご説明しましょう。
前提条件および仮定:
- Amazon EKS クラスター (1.14 以降) が実行中である。ステップバイステップの説明。
- Amazon EKS Windows ワーカーノードをリリース起動している。ステップバイステップの説明。
- Amazon EKS Windows ワーカーノードが Windows Server 2019 で実行している。
- ワーカーノードと同じ AMI を使用して Docker コンテナイメージを構築するための EC2 Windows インスタンス。
- 作成済み Amazon Elastic Container Registry (ECR)。ステップバイステップの説明。
- AWS CLI (少なくともバージョン 1.18.17、eksctl、kubectl) を適切にインストールおよび設定している。
このブログでは、次のタスクを実行します。
- Windows ワーカーノードが実行中であることを確認する。
- OIDC プロバイダーを Amazon EKS クラスターに関連付ける。
- サービスアカウントで使用する IAM ポリシー、ロール、Kubernetes 名前空間を作成する。
- IIS と LogMonitor を含む Windows コンテナイメージを作成する。
- Fluentd を含む Windows コンテナイメージを作成する。
- Fluentd をデーモンセットとして含む Windows コンテナイメージをデプロイする。
- IIS と LogMonitor を含む Windows コンテナイメージをデプロイする。
- IIS ポッドにアクセスして、ログを作成する。(オプション)
- Amazon CloudWatch Logs でログを確認する。
1.Windows ワーカーノードが実行中であることを確認する。
1.1 Windows ワーカーノードが準備完了として返されるかどうかを確認します。次のコマンドを実行します。
1.2 EKS Windowsクラスターにポッド vpc-admission-webhook と vpc-resource-controller が実行中として返されることを確認する必要があります。 次のコマンドを実行します。
2.OIDC プロバイダーを Amazon EKS クラスターに関連付ける。
2.1 Amazon EKS でサービスアカウントの IAM ロールを設定するには、OIDC を Amazon EKS クラスターに関連付ける必要があります。Amazon EKS クラスター がOIDC をサポートしているかどうかを確認し、次のコマンドを実行します。
cluster_name を Amazon EKS クラスター名に置き換えます。
region-id を Amazon EKS クラスター名に置き換えます。
出力:
2.2 OIDC との関連付けを作成する必要がある場合は、次のコマンドを実行します。
- cluster_name を Amazon EKS クラスター名に置き換えます。
- region-id を Amazon EKS クラスターを起動したリージョンに置き換えます。
3.サービスアカウントで使用する IAM ポリシー、ロール、Kubernetes 名前空間を作成する。
IAM サービスアカウントには、Amazon CloudWatch アクセス許可を含む添付ポリシーが必要です。これにより、Amazon EKS クラスターがログイベントを作成、記述し、ログストリームに配置できるようになります。
3.1 IAM ポリシーとして使用する次のアクセス許可を含む JSON ファイルを作成します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EKSFluentdCW",
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"logs:CreateLogGroup",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
3.2 IAM ポリシーを作成し、次のコマンドを実行します。
- MyPolicy を目的のポリシー名に置き換えます。
- File Path をポリシーの JSON ファイルパスに置き換えます。
3.3 Kubernetes 名前空間は名前の範囲を提供し、クラスター内のワークロードを整理します。リソースの名前は名前空間内で一意である必要がありますが、名前空間全体で一意である必要はありません。Kubernetes のすべてのリソースは、1 つの名前空間にのみ存在できます。このブログ投稿では、上記の YAML ファイルを使用して amazon-cloudwatch という名前空間を作成します。:
3.4 IAM サービスアカウントを作成し、すでに作成したポリシーを添付します。次のコマンドを実行します。
- cluster_name を Amazon EKS クラスター名に置き換えます。
- PolicyARN をポリシー ARN に置き換えます。
- region-id を Amazon EKS クラスターを起動したリージョンに置き換えます。
- 上記のコマンドは、以前にeksctl を使用して Amazon EKS クラスターを作成した場合にのみ機能します。次のメッセージ (クラスターは eksctl で作成されていません) が表示された場合、AWS マネジメントコンソールまたは AWS CLI のタブにある手順に従ってください。また、amazon-cloudwatch 名前空間に Kubernetes サービスアカウントが既に作成されている必要があります。サービスアカウントを作成するには、次のコマンドを実行します。
4. LogMonitor を含む Windows コンテナイメージを作成する。
4.1 このブログで説明している機能をテストするには、IIS と LogMonitor を含む Windows コンテナイメージを作成します。LogMonitor の使用方法の詳細については、公式の GitHub リポジトリにアクセスしてください。
次の例は、IIS と LogMonitor を含む Windows コンテナイメージを構築する Dockerfile です。
LogMonitorConfig.json
このサンプル LogMonitorConfig 設定では、IIS アクセスログを含む、C:\inetpub\logs およびサブディレクトリに保存された拡張子 .log を持つすべてのログファイルを取得します。
{
"LogConfig": {
"sources": [
{
"type": "EventLog",
"startAtOldestRecord": true,
"eventFormatMultiLine": false,
"channels": [
{
"name": "system",
"level": "Error"
}
]
},
{
"type": "File",
"directory": "c:\\inetpub\\logs",
"filter": "*.log",
"includeSubdirectories": true
},
{
"type": "ETW",
"providers": [
{
"providerName": "IIS: WWW Server",
"ProviderGuid": "3A2A4E84-4C21-4981-AE10-3FDA0D9B0F83",
"level": "Information"
},
{
"providerName": "Microsoft-Windows-IIS-Logging",
"ProviderGuid": "7E8AD27F-B271-4EA2-A783-A47BDE29143B",
"level": "Information",
"keywords": "0xFF"
}
]
}
]
}
}
構築が完了したら、ECR レジストリに イメージをプッシュします。
5.Fluentd を含む Windows コンテナイメージを作成する。
5.1 Kubernetes ポッドからのログ (具体的には Docker ログ) を集約するには、Windows ServerCore をベースイメージとして使用して、Fluentd RubyGems でログを解析および書き換えて、aws-sdk-cloudwatchlogs RubyGems for Amazon CloudWatch Log で認証と AWS サービスとの通信を行います。 Dockerfile のダウンロードは、AWS GitHub リポジトリから行うことができます。
Dockerfile はすべての要件を含むコンテナイメージを構築します。 この Dockerfile はマルチステージビルドと呼ばれる Docker の機能を使用して、最終的にコンテナサイズを約 600MB に縮小します。
構築が完了したら、ECR レジストリに イメージをプッシュします。構築処理中にフリーズした場合は、構築サーバーで次のコマンドを実行し、構築フェーズ中の Docker リアルタイムモニタリングを無効にします。
5.2 Fluentd を設定するには、ファイル fluent.conf と containers.conf をコンテナに挿入する必要があります。Kubernetes を使用しているので、ConfigMap と呼ばれるオブジェクトを使用して、設定ファイルをポッド内に直接マウントします。ConfigMaps を使用すると、アプリケーション設定をアプリケーションコードから疎結合できます。コンテナイメージを再構築することなく、設定を変更できます。
---
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-windows
namespace: amazon-cloudwatch
labels:
k8s-app: fluentd-windows
data:
AWS_REGION: region-id
CLUSTER_NAME: cluster_name
fluent.conf: |
<match fluent.**>
@type null
</match>
@include containers.conf
containers.conf: |
<source>
@type tail
@id in_tail_container_logs
path /var/log/containers/*.log
exclude_path ["/var/log/containers/fluentd*"]
pos_file /var/log/fluentd-containers.log.pos
tag k8s.*
read_from_head true
<parse>
@type "json"
time_format %Y-%m-%dT%H:%M:%S.%NZ
</parse>
</source>
<filter **>
@type record_transformer
@id filter_containers_stream_transformer
<record>
stream_name ${tag_parts[4]}
</record>
</filter>
<match k8s.**>
@type cloudwatch_logs
@id out_cloudwatch_logs_containers
region "#{ENV.fetch('AWS_REGION')}"
log_group_name "/EKS/#{ENV.fetch('CLUSTER_NAME')}/Windows"
log_stream_name_key stream_name
remove_log_stream_name_key true
auto_create_stream true
<buffer>
flush_interval 5
chunk_limit_size 2m
queued_chunks_limit_size 32
retry_forever true
</buffer>
</match>
- region-id 値を Amazon EKS クラスターを起動したリージョンに置き換えます。
- cluster_name 値を Amazon EKS クラスター名に置き換えます。
6. Fluentd をデーモンセットとして含む Windows コンテナイメージをデプロイする。
デーモンセットは、すべて (または一部) のノードがポッドのコピーを実行することを保証するものです。ノードがクラスターに追加されると、ポッドもそのクラスターに追加されます。すべての Windows ワーカーノードに Windows Fluentd ポッドのコピーがあることを確認するために、次で説明するデプロイファイルを使用してデーモンセットをデプロイします。
6.1 次のコンテンツを使用して、デプロイファイルを作成します。
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: fluentd-windows
namespace: amazon-cloudwatch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: fluentd-windows
namespace: amazon-cloudwatch
rules:
- apiGroups:
- ""
resources:
- pods
- namespaces
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: fluentd-windows
roleRef:
kind: ClusterRole
name: fluentd-windows
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: fluentd-windows
namespace: amazon-cloudwatch
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-windows
namespace: amazon-cloudwatch
labels:
k8s-app: fluentd-windows
spec:
selector:
matchLabels:
name: fluentd-windows
template:
metadata:
labels:
name: fluentd-windows
spec:
serviceAccount: fluentd-windows
serviceAccountName: fluentd-windows
# Because the fluentd requires to write on /etc/fluentd/ but we
# mount the config using a configmap which is read-only,
# this initContainer needs to be used to copy
# from Read Only folder to Read Write folder.
initContainers:
- name: copy-fluentd-config
image: mcr.microsoft.com/windows/servercore:ltsc2019
command: ['powershell', '-command', 'cp /etc/temp/*.conf /etc/fluent/']
volumeMounts:
- name: fluentdconftemp
mountPath: /etc/temp/
- name: fluentdconf
mountPath: /etc/fluent
containers:
- name: fluentd-windows
image: Fluentd-ECRrepository/tag
env:
- name: AWS_REGION
valueFrom:
configMapKeyRef:
name: fluentd-windows
key: AWS_REGION
- name: CLUSTER_NAME
valueFrom:
configMapKeyRef:
name: fluentd-windows
key: CLUSTER_NAME
resources:
limits:
memory: 2Gi
requests:
cpu: 100m
memory: 1Gi
volumeMounts:
- name: fluentdconftemp
mountPath: /etc/temp/
- name: fluentdconf
mountPath: /etc/fluent
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: C:\ProgramData\Docker\containers
readOnly: true
nodeSelector:
beta.kubernetes.io/os: windows
terminationGracePeriodSeconds: 30
volumes:
- name: fluentdconftemp
configMap:
name: fluentd-windows
- name: varlog
hostPath:
path: C:\var\log
- name: varlibdockercontainers
hostPath:
path: C:\ProgramData\Docker\containers
- name: fluentdconf
emptyDir: {}
- Fluentd-ECRrepository/tag イメージを、ステップ 5.1 で作成した ECR アドレスとタグに置き換えます。
6.2 次のコマンドでポッドをデプロイします。
次のステップに進む前に、Fluentd ポッドが実行中として返されることを確認する必要があります。
- ポッドが実行中の状態になるには、コンテナのサイズにもよりますが、7 分程度かかります。次のコマンドでステータスを確認できます。
7. IIS と LogMonitor を含む Windows コンテナイメージをデプロイする。
デプロイを行うと、nodeSelector 属性「beta.kubernetes.io/os: windows」に基づいて、必要なレプリカ (ポッド) の数 (今回の場合は 2) が Windows ワーカーノードで実行されます。 サービスは Kubernetes 内に仮想 IP を作成し、ポッド間のトラフィックの負荷を分散します。
7.1 次のコンテンツを使用して、デプロイファイルを作成します。
- IIS-ECRrepository/tag イメージを、ステップ 4.1 で作成した ECR アドレスとタグに置き換えます。
7.2 次のコマンドでポッドをデプロイします。
7. IIS ポッドにアクセスして、ログを作成する (オプション)
7.1 こちらのステップは、オプションです。元のトラフィックがコンテナに到達するのを待つこともできますし、すぐに結果を確認することもできます。コンテナに直接ログを作成するには、次のコマンドを実行します。
7.2 コンテナ内から、次のコマンドを実行します。
8.Amazon CloudWatch Logs でログを確認する。
8.1 ログがログストリームに正常にストリーミングされたかどうかを確認します。Amazon CloudWatch コンソールにアクセスし、ロググループ /EKS/cluster_name/Windows と、ポッドにマッピングされている目的のログストリームをクリックします。
8.2 ご覧のとおり、IIS ログがログストリームにストリーミングされています。
まとめ
Amazon CloudWatch Logs を使用することですべての Windows ポッドログを一元化し、管理者がアプリケーションの問題をすばやく特定できるだけでなく、ビジネスの運用が可視化され、洞察を得ることができます。