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)と使用制限の詳しい説明

推薦する

Dockerデータストレージの概要

この記事を読む前に、ボリューム、バインドマウント、tmpfs マウントの基本を理解しておいてください...

Web 開発の面接と筆記試験に必須の知識(必読)

HTML のインライン要素とブロックレベル要素の違い:標準的なドキュメント フローでは、ブロック ...

tomcat9.exeをクリックするとクラッシュする問題を解決する方法

ある読者から連絡があり、ダウンロードが終了し、操作がまだ開始されていないのに、なぜ Tomcat の...

js で 0ms 遅延タイマーを実装するいくつかの方法

目次キューマイクロタスク非同期/待機メッセージチャネルやっと付録ここ二日間、「タイムリーな setT...

フレームセットを使用して複雑なページレイアウトを実装するためのテクニックの概要

コードをコピーコードは次のとおりです。 <html> <!--混合フレームレイアウ...

Docker 経由で CentOS コンテナを作成する手順

目次序文コンテナ間の通信を容易にするためのブリッジネットワークを作成するCentOS7イメージを使用...

WindowsシステムでMySQLデータベースを完全にアンインストールして、MySQLを再インストールします

1. コントロールパネルで、MySQLのすべてのコンポーネントをアンインストールします。コントロール...

MySQLデータベース移行におけるデータ文字化けの問題を解決する

リーダーの指示のもと、Java プロジェクトを引き継ぎ、リファクタリングを行う必要がありました。同時...

CSSアニメーション属性キーフレームの詳細な説明

コラムを更新してからどれくらい経ったでしょうか?半年ですか?今年の後半は、まさに離陸、つまり文字通り...

LinuxにMySQLをインストールし、外部ネットワークアクセスを構成する例

設定手順1. DNSが設定されているかどうかを確認するDNSが設定されていない場合は、前の記事を参照...

SQL インジェクション脆弱性プロセスの例と解決策

コード例: パブリッククラスJDBCDemo3 { パブリック静的voiddemo3_1(){ bo...

マインドマップを使って4つの側面からWeb標準の価値を議論する

このアイデアを改善し、より良い意見を得られることを期待して、議論を刺激するためにいくつかの値を大まか...

VMware15 仮想マシン ブリッジ モードでインターネットにアクセスできない問題の解決方法

説明 ソリューションVMware 15 仮想マシン ブリッジ モードではインターネットにアクセスでき...

Vueデータ双方向バインディング実装方法

目次1. はじめに2. コードの実装2.1 目的分析2.2 実装プロセス2.2.1 エントリーコード...