Spring Cloud Kubernetes 構成ウォッチャー

ただし、アプリケーションを再起動しない限り、Spring Boot はこれらの変更を自動的にリフレッシュしません。Spring Cloud は、アクチュエーターエンドポイント /refresh をヒットするか、Spring Cloud Bus を使用して RefreshRemoteApplicationEvent をパブリッシュすることにより、アプリケーションを再起動せずにアプリケーションコンテキストをリフレッシュする機能を提供します。

Kubernetes 上で実行されている Spring Cloud アプリの構成をリフレッシュするには、Spring Cloud Kubernetes Configuration Watcher コントローラーを Kubernetes クラスターにデプロイします。

アプリケーションはコンテナーとして公開され、Docker Hub (英語) で利用できます。ただし、構成ウォッチャーの動作をカスタマイズする必要がある場合、またはイメージを自分で構築したい場合は、GitHub のソースコード (英語) から独自のイメージを簡単に構築し、それを使用できます。

これを設定するもう 1 つのオプションは、構成ウォッチャーをデプロイするために使用される デプロイ .yaml にいくつかの環境変数を提供することです。重要なものをいくつか示します。

env:
  - name: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES_CONFIGURATION_WATCHER
    value: DEBUG
  - name: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES_CLIENT_CONFIG_RELOAD
    value: DEBUG
  - name: LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_CLOUD_KUBERNETES_COMMONS_CONFIG_RELOAD
    value: DEBUG

これらは、構成ウォッチャーでのデバッグログ記録を有効にし、潜在的な構成ミスを診断できるようにするために、初期セットアップで特に役立ちます。

env:
  - name: SPRING_CLOUD_KUBERNETES_RELOAD_NAMESPACES_0
    value: "namespace-a"

これにより、ウォッチャーはシークレットと構成マップを検索する場所を認識できます。ここでは、選択的な名前空間 (上記の設定) と名前空間の解決によって選択された名前空間 (これがデフォルトのオプション) の 2 つのオプションがあります。これらすべてのオプションには適切な RBAC ルールが必要であることに注意してください。

configmaps/secrets からの変更は、その特定の変更がラベル spring.cloud.kubernetes.config=true または spring.cloud.kubernetes.secret=true を持つソースから発生した場合にのみ、構成ウォッチャーから発生するイベントをトリガーします。

さらに簡単に言うと、上記のラベルを持たない configmap (またはシークレット) を変更すると、構成ウォッチャーはそのイベントの発生をスキップします (デバッグログを有効にしている場合は、これがログに表示されます)。

デフォルトでは、構成ウォッチャーは構成された名前空間内のすべての構成マップ / シークレットを監視します。特定のソースのみを監視するようにフィルタリングする場合は、次のように設定します。

SPRING_CLOUD_KUBERNETES_CONFIG_INFORMER_ENABLED=TRUE

これにより、ウォッチャーはラベル spring.cloud.kubernetes.config.informer.enabled=true を持つソースのみを監視するように指示されます。

特にボリュームとしてマウントされる configmaps とシークレット (spring.cloud.kubernetes.config.paths/spring.cloud.kubernetes.secrets.paths 経由、または spring.config.import を使用) の場合、もう 1 つ重要な構成は次のとおりです。

- name: SPRING_CLOUD_KUBERNETES_CONFIGURATION_WATCHER_REFRESHDELAY
  value: "10000"

これは、構成ウォッチャーからイベントを発行する前に何ミリ秒待つ必要があるかを示します。Kubernetes のドキュメントには次のように記載されているため、これは重要です。

ボリュームで現在使用されている ConfigMap が更新されると、射影されたキーも最終的に更新されます。

この最終部分をクラスター上のミリ秒単位の値に「一致」させる必要があります。

Spring Cloud Kubernetes Configuration Watcher は、2 つの方法でリフレッシュ通知をアプリケーションに送信できます。

  1. HTTP 経由の場合、通知を受けるアプリケーションは、/refresh アクチュエーターエンドポイントを公開し、クラスタ内からアクセスできるようにする必要があります。

  2. Spring Cloud Bus を使用する場合、アプリケーションが使用するメッセージブローカーをクラスターにデプロイする必要があります。

デプロイ YAML

以下は、Kubernetes Configuration Watcher を Kubernetes にデプロイするために使用できるサンプルデプロイ YAML です。

---
apiVersion: v1
kind: List
items:
  - apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: spring-cloud-kubernetes-configuration-watcher
      name: spring-cloud-kubernetes-configuration-watcher
    spec:
      ports:
        - name: http
          port: 8888
          targetPort: 8888
      selector:
        app: spring-cloud-kubernetes-configuration-watcher
      type: ClusterIP
  - apiVersion: v1
    kind: ServiceAccount
    metadata:
      labels:
        app: spring-cloud-kubernetes-configuration-watcher
      name: spring-cloud-kubernetes-configuration-watcher
  - apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      labels:
        app: spring-cloud-kubernetes-configuration-watcher
      name: spring-cloud-kubernetes-configuration-watcher:view
    roleRef:
      kind: Role
      apiGroup: rbac.authorization.k8s.io
      name: namespace-reader
    subjects:
      - kind: ServiceAccount
        name: spring-cloud-kubernetes-configuration-watcher
  - apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: default
      name: namespace-reader
    rules:
      - apiGroups: ["", "extensions", "apps"]
        resources: ["configmaps", "pods", "services", "endpoints", "secrets"]
        verbs: ["get", "list", "watch"]
  - apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: spring-cloud-kubernetes-configuration-watcher-deployment
    spec:
      selector:
        matchLabels:
          app: spring-cloud-kubernetes-configuration-watcher
      template:
        metadata:
          labels:
            app: spring-cloud-kubernetes-configuration-watcher
        spec:
          serviceAccount: spring-cloud-kubernetes-configuration-watcher
          containers:
          - name: spring-cloud-kubernetes-configuration-watcher
            image: springcloud/spring-cloud-kubernetes-configuration-watcher:3.1.2
            imagePullPolicy: IfNotPresent
            readinessProbe:
              httpGet:
                port: 8888
                path: /actuator/health/readiness
            livenessProbe:
              httpGet:
                port: 8888
                path: /actuator/health/liveness
            ports:
            - containerPort: 8888

サービスアカウントと関連するロールバインディングは、Spring Cloud Kubernetes 構成が適切に動作するために重要です。コントローラーは、Kubernetes クラスター内の ConfigMaps、Pods、サービス、エンドポイント、シークレットに関するデータを読み取るためにアクセスする必要があります。

ConfigMaps とシークレットの監視

有効なラベルを持つ ConfigMap または Secret に変更が加えられた場合 (上記で詳述)、Spring Cloud Kubernetes 構成ウォッチャーは ConfigMap または Secret の名前を取得し、その名前でアプリケーションに通知を送信します。ただし、これはユースケースには十分ではない可能性があります。たとえば、次のことが必要になる場合があります。

  • 構成マップを複数のアプリケーションにバインドして、単一の構成マップ内の変更が多くのサービスのリフレッシュをトリガーするようにします。

  • プロファイルベースのソースがアプリケーションのイベントをトリガーするようにする

そのため、指定できる追加のアノテーションがあります。

spring.cloud.kubernetes.configmap.apps または spring.cloud.kubernetes.secret.apps。これは、コンマで区切られたアプリの文字列を受け取り、このシークレット / 構成マップで変更が発生したときに通知を受け取るアプリケーションの名前を指定します。

例:

kind: ConfigMap
apiVersion: v1
metadata:
  name: example-configmap
  labels:
    spring.cloud.kubernetes.config: "true"
  annotations:
    spring.cloud.kubernetes.configmap.apps: "app-a, app-b"

HTTP の実装

The HTTP implementation is what is used by default. When this implementation is used, Spring Cloud Kubernetes Configuration Watcher and a change to a ConfigMap or Secret occurs then the HTTP implementation will use the Spring Cloud Kubernetes Discovery Client to fetch all instances of the application which match the name of the ConfigMap or Secret and send an HTTP POST request to the application’s actuator /refresh endpoint. By default, it will send the post request to /actuator/refresh using the port registered in the discovery client.

デフォルト以外の管理ポートとアクチュエーターのパス

アプリケーションがデフォルト以外のアクチュエーターパスを使用している場合、または管理エンドポイントに別のポートを使用している場合、アプリケーションの Kubernetes サービスは boot.spring.io/actuator というアノテーションを追加し、その値をアプリケーションが使用するパスとポートに設定できます。たとえば

apiVersion: v1
kind: Service
metadata:
  labels:
    app: config-map-demo
  name: config-map-demo
  annotations:
    boot.spring.io/actuator: http://:9090/myactuator/home
spec:
  ports:
    - name: http
      port: 8080
      targetPort: 8080
  selector:
    app: config-map-demo

アクチュエーターパスや管理ポートの設定を選択できるもう 1 つの方法は、spring.cloud.kubernetes.configuration.watcher.actuatorPath および spring.cloud.kubernetes.configuration.watcher.actuatorPort を設定することです。

メッセージングの実装

Spring Cloud Kubernetes Configuration Watcher アプリケーションが Kubernetes にデプロイされるときに、プロファイルを bus-amqp (RabbitMQ) または bus-kafka (Kafka) に設定することで、メッセージングの実装を有効にできます。

RabbitMQ の構成

bus-amqp プロファイルが有効になっている場合は、使用する RabbitMQ インスタンスの場所と認証に必要な資格情報を指すように Spring RabbitMQ を構成する必要があります。これは、標準の Spring RabbitMQ プロパティを設定することで実行できます。たとえば

spring:
  rabbitmq:
    username: user
    password: password
    host: rabbitmq

Kafka の構成

bus-kafka プロファイルが有効になっている場合は、使用する Kafka ブローカーインスタンスの場所を指すように Spring Kafka を構成する必要があります。これは、標準の Spring Kafka プロパティを設定することで実行できます。たとえば

spring:
  kafka:
    producer:
      bootstrap-servers: localhost:9092