nginx-ingress-controller ログ永続化ソリューションのソリューション

nginx-ingress-controller ログ永続化ソリューションのソリューション

最近、nginx-ingress-controller のアプリケーションについて説明した公開アカウントの記事を見ました。ログを永続化する方法について、以下にコメントした人がいました。仕事でこの問題に遭遇したので、参考までに解決策をまとめました。

nginx-ingress-controller ログ

nginx-ingress-controller のログには、次の 3 つの部分が含まれます。

  • コントローラー ログ: stdout に出力します。起動パラメータの --log_dir を使用して、ファイルへの出力を設定できます。ファイルにリダイレクトすると、自動的にローテーションされますが、自動的にクリーンアップされることはありません。
  • accesslog: stdout に出力します。出力ファイルは、nginx-configuration のフィールドを通じて設定できます。ファイルへの出力は自動的に回転またはクリーンアップされません
  • errorlog: stderr に出力します。設定方法は accesslog と同様です。

コントローラのログをディスクに書き込む

  • nginx-ingress-controllerにホストパスを指定します: /data/log/nginx_ingress_controller/はコンテナ内の/var/log/nginx_ingress_controller/にマップされます。
  • ログを /var/log/nginx_ingress_controller/ にリダイレクトするには、nginx-ingress-controller の log-dir および logtostderr パラメータを設定します。

コントローラーのログは定期的にクリーンアップする必要があります。コントローラーのログは klog (k8s.io/klog) を通じて出力されるため、ログはロールオーバーされ、スクリプトを使用して特定の時間前にログ ファイルを定期的にクリーンアップすることができます。

nginx ログをディスクに書き込む

configmap: nginx-configuration を変更します。デフォルトの stdout と stderr を置き換えるために、accesslog と errorlog の出力パスを構成します。出力パスはコントローラーと一致させることができるため、簡単に検索できます。

accesslog と errorlog には、ログ ファイルが 1 つだけあります。logrotate を使用してログをローテーションし、ホスト マシンに出力されるログをローテーションしてクリーンアップすることができます。次のような構成:

$ cat /etc/logrotate.d/nginx.log
/data/log/nginx_ingress_controller/access.log {
  su ルートリスト
  7回転
  毎日
  最大サイズ 50M
  コピー切り捨て
  行方不明
  0644 www-data ルートを作成
}

公式テンプレートでは、nginx-ingress-controller はデフォルトでユーザー 33 としてログインしてコンテナを起動するため、hostpath パスをマウントするときに権限の問題が発生します。マシン上で chown -R 33:33 /data/log/nginx_ingress_controller を手動で実行する必要があります。

自動化オペレーション

nginx ログがディスクに書き込まれる場合、ポイント 2 と 3 は手動での操作とメンテナンスが必要です。解決策はありますか?

問題の鍵は、nginx-ingress-controller コンテナが起動される前にフックを追加して、ホスト マシンの指定されたディレクトリを chown する方法があるかどうかです。

initContainer を使用できます。コンテナー内のコンテナーが実行される前に、initcontainer が完了まで実行され、正常に終了する必要があります。この k8s 機能を使用して、次のスクリプトのみを実行する Docker イメージを開発します。

#!/bin/bash
ログディレクトリ=$LOG_DIR
ユーザーID=$USER_ID
echo "dir: $logdir のグループを $userID として設定してみてください"
chown -R $userID:$userID $logdir

スクリプトはいくつかの環境変数を読み取り、どのディレクトリを変更する必要があるか、どのユーザー グループに変更するかを決定します。

スクリプトを Docker イメージにパッケージ化し、nginx-ingress-controller のデプロイ yaml に initcontainers として配置します。 initcontainer の環境変数と volumeMount を設定する必要があることに注意してください。

2 点目については、nginx-ingress-controller のベースイメージに logrotate が付属していることに気づいたので、問題は簡単です。記述した logrotate 設定ファイルを configmap の形式でコンテナにマウントするだけです。

デプロイ yaml は次のとおりです。

---
APIバージョン: v1
種類: サービス
メタデータ:
 名前: ingress-nginx
 名前空間: kube-system
仕様:
 タイプ: ClusterIP
 ポート:
 - 名前: http
  ポート: 80
  ターゲットポート: 80
  プロトコル: TCP
 - 名前: https
  ポート: 443
  ターゲットポート: 443
  プロトコル: TCP
 セレクタ:
  アプリ: ingress-nginx
---
APIバージョン: v1
種類: サービス
メタデータ:
 名前: default-http-backend
 名前空間: kube-system
 ラベル:
  アプリ: デフォルトのhttpバックエンド
仕様:
 ポート:
 - ポート: 80
  ターゲットポート: 8080
 セレクタ:
  アプリ: デフォルトのhttpバックエンド
---
apiバージョン: extensions/v1beta1
種類: イングレス
メタデータ:
 名前: デフォルト
 名前空間: kube-system
仕様:
 バックエンド:
  サービス名: default-http-backend
  サービスポート: 80
---
種類: ConfigMap
APIバージョン: v1
メタデータ:
 名前: nginx-configuration
 名前空間: kube-system
 ラベル:
  アプリ: ingress-nginx
データ:
 転送ヘッダーを使用する: "true"
 # ここで nginx ログのリダイレクト先を設定します access-log-path: /var/log/nginx_ingress_controller/access.log
 エラーログパス: /var/log/nginx_ingress_controller/error.log

---

# コンテナ内の nginx ログのログ ファイル apiVersion: v1 に対応する nginx ログのローテーション戦略を構成するための configmap を作成します。
データ:
 nginx.log: |
  {{ user_nginx_log.host_path }}/access.log {
    {{ user_nginx_log.rotate_count }} を回転させる
    毎日
    最大サイズ {{ user_nginx_log.rotate_size }}
    最小サイズ 10M
    コピー切り捨て
    行方不明
    0644 ルート ルートを作成
  }
  {{ user_nginx_log.host_path }}/error.log {
    {{ user_nginx_log.rotate_count }} を回転させる
    毎日
    最大サイズ {{ user_nginx_log.rotate_size }}
    最小サイズ 10M
    コピー切り捨て
    行方不明
    0644 ルート ルートを作成
  }
種類: ConfigMap
メタデータ:
 名前: nginx-ingress-logrotate
 名前空間: kube-system
---

種類: ConfigMap
APIバージョン: v1
メタデータ:
 名前: tcp-services
 名前空間: kube-system
---
種類: ConfigMap
APIバージョン: v1
メタデータ:
 名前: udp-services
 名前空間: kube-system
---
APIバージョン: v1
種類: サービスアカウント
メタデータ:
 名前: nginx-ingress-serviceaccount
 名前空間: kube-system
---
APIバージョン: rbac.authorization.k8s.io/v1beta1
種類: ClusterRole
メタデータ:
 名前: nginx-ingress-clusterrole
ルール:
 -apiグループ:
   - 「」
  リソース:
   - 構成マップ
   - エンドポイント
   - ノード
   - ポッド
   - 秘密
  動詞:
   - リスト
   - 時計
 -apiグループ:
   - 「」
  リソース:
   - ノード
  動詞:
   - 得る
 -apiグループ:
   - 「」
  リソース:
   - サービス
  動詞:
   - 得る
   - リスト
   - 時計
 -apiグループ:
   - 「拡張機能」
  リソース:
   - 入口
  動詞:
   - 得る
   - リスト
   - 時計
 -apiグループ:
   - 「」
  リソース:
    - イベント
  動詞:
    - 作成する
    -パッチ
 -apiグループ:
   - 「拡張機能」
  リソース:
   - 入力/ステータス
  動詞:
   - アップデート
---
APIバージョン: rbac.authorization.k8s.io/v1beta1
種類: 役割
メタデータ:
 名前: nginx-ingress-role
 名前空間: kube-system
ルール:
 -apiグループ:
   - 「」
  リソース:
   - 構成マップ
   - ポッド
   - 秘密
   - 名前空間
  動詞:
   - 得る
 -apiグループ:
   - 「」
  リソース:
   - 構成マップ
  リソース名:
   # デフォルトは「<election-id>-<ingress-class>」
   # ここでは: "<ingress-controller-leader>-<nginx>"
   # いずれかのパラメータを変更する場合はこれを調整する必要があります
   # nginx-ingress-controller を起動するとき。
   - 「イングレス コントローラー リーダー nginx」
  動詞:
   - 得る
   - アップデート
 -apiグループ:
   - 「」
  リソース:
   - 構成マップ
  動詞:
   - 作成する
 -apiグループ:
   - 「」
  リソース:
   - エンドポイント
  動詞:
   - 得る
---
APIバージョン: rbac.authorization.k8s.io/v1beta1
種類: RoleBinding
メタデータ:
 名前: nginx-ingress-role-nisa-binding
 名前空間: kube-system
ロールリファレンス:
 apiグループ: rbac.authorization.k8s.io
 種類: 役割
 名前: nginx-ingress-role
科目:
 - 種類: サービスアカウント
  名前: nginx-ingress-serviceaccount
  名前空間: kube-system
---
APIバージョン: rbac.authorization.k8s.io/v1beta1
種類: ClusterRoleBinding
メタデータ:
 名前: nginx-ingress-clusterrole-nisa-binding
ロールリファレンス:
 apiグループ: rbac.authorization.k8s.io
 種類: ClusterRole
 名前: nginx-ingress-clusterrole
科目:
 - 種類: サービスアカウント
  名前: nginx-ingress-serviceaccount
  名前空間: kube-system
---
APIバージョン: アプリ/v1
種類: DaemonSet
メタデータ:
 名前: ingress-nginx
 名前空間: kube-system
仕様:
 セレクタ:
  一致ラベル:
   アプリ: ingress-nginx
 テンプレート:
  メタデータ:
   ラベル:
    アプリ: ingress-nginx
   注釈:
    prometheus.io/ポート: '10254'
    prometheus.io/scrape: 'true'
  仕様:
   サービスアカウント名: nginx-ingress-serviceaccount
   許容範囲:
   - キー: 専用
    値: ingress-nginx
    効果: NoSchedule
   親和性:
    ノードアフィニティ:
     スケジュール中は必須、実行中は無視:
      ノードセレクタ用語:
      - 一致する表現:
       - キー: "system/ingress"
        演算子:
        値:
        - "真実"
   dnsポリシー: ClusterFirstWithHostNet
   ホストネットワーク: true
   # nginx-ingress-controller コンテナが起動される前に、ログ ディレクトリの権限が設定されていることを確認するために initcontainer を設定します。initContainers:
   - 名前: adddirperm
    イメージ: "{{ image_registry.addr }}/{{ image.adddirperm }}"
    環境:
    - 名前: LOG_DIR
     値: /var/log/nginx_ingress_controller
    - 名前: USER_ID
      値: "33"
    ボリュームマウント:
    - 名前: logdir
     マウントパス: /var/log/nginx_ingress_controller
   コンテナ:
   - 名前: nginx-ingress-controller
    イメージ: "{{ image_registry.addr }}/{{ image.ingress }}"
    イメージプルポリシー: IfNotPresent
    引数:
    - /nginx-イングレスコントローラー
    - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
    - --configmap=$(POD_NAMESPACE)/nginx-configuration
    - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
    - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
    - --publish-service=$(POD_NAMESPACE)/ingress-nginx
    - --annotations-prefix=nginx.ingress.kubernetes.io
    
    # コントローラーログの出力パスと方法を設定します - --log_dir=/var/log/nginx_ingress_controller
    - --logtostderr=false
    セキュリティコンテキスト:
     機能:
       落とす:
       - 全て
       追加:
       -NET_BIND_SERVICE
     # wwwデータ -> 33
     実行ユーザー: 33
    環境:
     - 名前: POD_NAME
      値:
       フィールド参照:
        フィールドパス: metadata.name
     - 名前: POD_NAMESPACE
      値:
       フィールド参照:
        フィールドパス: metadata.namespace
    ポート:
    - 名前: http
     コンテナポート: 80
    - 名前: https
     コンテナポート: 443
    リソース:
     リクエスト:
      CPU: 100m
      メモリ: 256Mi
    ライブネスプローブ:
     失敗しきい値: 3
     httpGet:
      パス: /healthz
      ポート: 10254
      スキーム: HTTP
     初期遅延秒数: 10
     期間秒数: 10
     成功しきい値: 1
     タイムアウト秒数: 1
    準備プローブ:
     失敗しきい値: 3
     httpGet:
      パス: /healthz
      ポート: 10254
      スキーム: HTTP
     期間秒数: 10
     成功しきい値: 1
     タイムアウト秒数: 1
    ボリュームマウント:
    #マウントされたコンテナ内のコントローラコンポーネントとnginxのログ出力パスを設定します - name: logdir
     マウントパス: /var/log/nginx_ingress_controller
    #nginx ログの logrotate 構成マウント パスを設定します - 名前: logrotateconf
     マウントパス: /etc/logrotate.d/nginx.log
     サブパス: nginx.log
   ボリューム:
   # コントローラコンポーネントとnginxのログ出力パスはホストマシンのホストパスです
   - 名前: logdir
    ホストパス:
     パス: {{ user_nginx_log.host_path }}
     タイプ: ""
   # nginxログのローテーション設定ファイルはconfigmapから取得されます
   - 名前: logrotateconf
    構成マップ:
     名前: nginx-ingress-logrotate
     アイテム:
     - キー: nginx.log
      パス: nginx.log
---

APIバージョン: アプリ/v1
種類: DaemonSet
メタデータ:
 名前: default-http-backend
 名前空間: kube-system
 ラベル:
  アプリ: デフォルトのhttpバックエンド
仕様:
 セレクタ:
  一致ラベル:
   アプリ: デフォルトのhttpバックエンド
 テンプレート:
  メタデータ:
   ラベル:
    アプリ: デフォルトのhttpバックエンド
  仕様:
   終了猶予期間秒数: 60
   許容範囲:
   - キー: 専用
    値: ingress-nginx
    効果: スケジュールなし
   親和性:
    ノードアフィニティ:
     スケジュール中は必須、実行中は無視:
      ノードセレクタ用語:
      - 一致する表現:
       - キー: "system/ingress"
        演算子:
        値:
        - "真実"
   コンテナ:
   - 名前: default-http-backend
    # 以下の条件を満たす限り、どのような画像でも許可されます:
    # 1. 404ページが / に表示されます
    # 2. /healthzエンドポイントで200を提供します
    イメージ: "{{ image_registry.addr }}/{{ image.http_backend }}"
    イメージプルポリシー: IfNotPresent
    ライブネスプローブ:
     httpGet:
      パス: /healthz
      ポート: 8080
      スキーム: HTTP
     初期遅延秒数: 30
     タイムアウト秒数: 5
    ポート:
    - コンテナポート: 8080
    リソース:
     制限:
      CPU: 10m
      メモリ: 20マイル
     リクエスト:
      CPU: 10m
      メモリ: 20マイル
---

最後に、initcontainer を削除し、元の nginx-ingress-controller イメージに基づいてレイヤーを追加し、このレイヤーでパス権限を構成するスクリプトを実行することを提案する人もいました。 個人的には、この方法は美しくも便利でもないと思います。唯一の利点は、deploy yaml が依然として簡潔であることです (ただし、volumeMount などの構成は不可欠です)。しかし、それは個人の経験に依存します〜

nginx-ingress-controller ログ永続化ソリューションに関するこの記事はこれで終わりです。nginx ingress controller ログ永続化の詳細については、123WORDPRESS.COM で以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • アーチファクト!最高の Nginx ログ分析ツール GoAccess
  • Dockerでnginxログをローリングするアイデアの詳細な説明
  • goaccess を使用して nginx ログを分析する詳細な方法

<<:  JavaScript の navigator.userAgent がブラウザ情報を取得するケースの説明

>>:  MySQLにおけるビューの作成(CREATE VIEW)と使用制限の詳しい説明

推薦する

Websocket に基づくシンプルなチャットルームダイアログの実装

この記事では、WebSocketを使用して簡単なチャットルームの会話を実装するための具体的なコードを...

DockerはClickHouseをインストールし、データテストを初期化します

クリックハウスの紹介ClickHouse は、SQL クエリを使用して分析データ レポートをリアルタ...

HTML の順序付きリスト、順序なしリスト、定義リストに関する簡単な説明

順序付きリストXML/HTML コードコンテンツをクリップボードにコピー<オルタイプ= &qu...

Docker クリーニングの一般的な方法と問題点

大規模な開発に Docker を使用する場合でも、クリーンアップ戦略がなければ、ディスクがすぐにいっ...

JavaScript BOMの構成と一般的なイベントの詳細な説明

目次1. 部品2. BOMの構成2. ウィンドウオブジェクトの共通イベント1. ウィンドウ読み込みイ...

Vue でデータコレクターを設計する

目次シナリオ中核問題ステータス監視状態監視の利点国家監視の欠点復興実行のアイデア依存関係の収集要約す...

DockerはMysql、.Net6、Sqlserverなどのコンテナをデプロイします

目次CentOS 8にDockerをインストールする1. yumを更新する2. containerd...

uniAppエディタWeChatスライド問題について

ユニアプリアプレットはWeChatでも同様のドロップダウン問題を抱えることになる解決策は、app.v...

選択ドロップダウンメニューのテキストを左右にスクロールするように設定する

marquee タグを使用してフォントのスクロールを設定したいです。コードは次のように記述しましたが...

フロントエンドの面接の質問の最も包括的なコレクション

HTML+CSS 1. WEB 標準と W3C の理解と知識<br /> タグを閉じ、小...

HTMLフォームのいくつかの送信方法の概要

最も一般的で、最もよく使用され、最も一般的な方法は、submit タイプを使用することです。コードを...

HTML と CSS を書くための 6 つの最も効果的な方法

この記事では、効率を向上させ、時間を節約することを願って、最も効果的な 6 つの方法を紹介します。 ...

MySQL での一時テーブルの使用例

ここ2日間ちょっと忙しくて、公式アカウントも数日更新が止まってしまいました。その結果、何人かの読者か...

Vue のフィルターの適用シナリオの詳細な説明

filterは通常、特定の値をフィルターするために使用されます。たとえば、フィールドが空だが、フロン...

4 つの主要な SQL ランキング関数 ROW_NUMBER、RANK、DENSE_RANK、NTILE の使用方法の紹介

1. ROW_NUMBER()定義: ROW_NUMBER() 関数は、select によってクエリ...