Spring Cloud Kubernetesのガイド

1. 概要

マイクロサービスソリューションを構築する場合、https://www.baeldung.com/spring-cloud-tutorial [Spring Cloud]とlink:/kubernetes[Kubernetes]の両方がコンポーネントを提供するため、最適なソリューションです最も一般的な課題を解決するため。 ただし、Kubernetesをソリューションのメインコンテナーマネージャーおよび展開プラットフォームとして選択する場合、主にhttps://cloud.spring.io/spring-cloud-static/spring-cloudを介してSpring Cloudの興味深い機能を引き続き使用できます。 -kubernetes / 2.1.0.RC1 / single / spring-cloud-kubernetes.html [Spring Cloud Kubernetes]プロジェクト。
この比較的新しいプロジェクトは、https://www.baeldung.com/spring-boot-start [Spring Boot]アプリケーション用にKubernetesと簡単に統合できることは間違いありません。 開始する前に、ローカルのKubernetes環境であるlink:/spring-boot-minikube[Minikubeのスプリングブートアプリケーション]を展開する方法を確認すると役立つ場合があります__.__
このチュートリアルでは、次のことを行います。
  • ローカルマシンにMinikubeをインストールする

  • 2つの独立したマイクロサービスアーキテクチャの例を開発する
    RESTを介して通信するSpring Bootアプリケーション

  • Minikubeを使用して1ノードクラスターでアプリケーションをセットアップする

  • _YAML_構成ファイルを使用してアプリケーションをデプロイします

2. シナリオ

この例では、旅行代理店が随時旅行代理店サービスを照会するクライアントにさまざまな取引を提供する旅行代理店のシナリオを使用しています。 これを使用してデモンストレーションします:
  • Spring Cloud Kubernetesによる*サービスの発見*

  • *構成管理*およびKubernetes ConfigMapの注入と
    Spring Cloud Kubernetes Configを使用したアプリケーションポッドの秘密

  • * Spring Cloud Kubernetesリボンを使用した*負荷分散*

3. 環境設定

何よりもまず、ローカルマシンにhttps://kubernetes.io/docs/setup/minikube/[Minikube]*をインストールする必要があり、できればhttps://www.virtualbox.org/[VirtualBox ]。 この環境設定を行う前に、https://kubernetes.io/ [Kubernetes]とその主な機能を確認することもお勧めします。
ローカルの単一ノードKubernetesクラスターを開始しましょう。
minikube start --vm-driver=virtualbox
このコマンドは、VirtualBoxドライバーを使用してMinikubeクラスターを実行する仮想マシンを作成します。 _kubectl_のデフォルトのコンテキストは_minikube_になります。 ただし、コンテキストを切り替えることができるようにするには、次を使用します。
kubectl config use-context minikube
Minikubeを起動したら、Kubernetesダッシュボードに接続してログにアクセスし、サービス、ポッド、ConfigMap、およびシークレットを簡単に監視できます。
minikube dashboard

3.1. 展開

まず、https://github.com/eugenp/tutorials/tree/master/spring-cloud/spring-cloud-kubernetes [GitHub]から例を取得しましょう。
この時点で、親フォルダーから「deployment-travel-client.sh」スクリプトを実行するか、各命令を1つずつ実行して手順を十分に把握できます。
### build the repository
mvn clean install

### set docker env
eval $(minikube docker-env)

### build the docker images on minikube
cd travel-agency-service
docker build -t travel-agency-service .
cd ../client-service
docker build -t client-service .
cd ..

### secret and mongodb
kubectl delete -f travel-agency-service/secret.yaml
kubectl delete -f travel-agency-service/mongo-deployment.yaml

kubectl create -f travel-agency-service/secret.yaml
kubectl create -f travel-agency-service/mongo-deployment.yaml

### travel-agency-service
kubectl delete -f travel-agency-service/travel-agency-deployment.yaml
kubectl create -f travel-agency-service/travel-agency-deployment.yaml

### client-service
kubectl delete configmap client-service
kubectl delete -f client-service/client-service-deployment.yaml

kubectl create -f client-service/client-config.yaml
kubectl create -f client-service/client-service-deployment.yaml

# Check that the pods are running
kubectl get pods

4. サービス発見

このプロジェクトは、Kubernetesの_ServiceDiscovery_インターフェイスの実装を提供します。 マイクロサービス環境では、通常、同じサービスを実行する複数のポッドがあります。 * Kubernetesは、同じKubernetesクラスター内のポッドで実行されているSpring Bootアプリケーション内から取得して到達できるエンドポイントのコレクションとしてサービスを公開します。
たとえば、この例では、旅行代理店サービスの複数のレプリカがあり、_http:// travel-agency-service:8080_としてクライアントサービスからアクセスされます。 ただし、これは内部的に_travel-agency-service-7c9cfff655-4hxnp_などのさまざまなポッドにアクセスすることになります。
  • Spring Cloud Kubernetes Ribbonはこの機能を使用して、サービスの異なるエンドポイント間の負荷分散を行います。*

    https://search.maven.org/search?q=g:org.springframework.cloud%20a:spring-cloud-starter-kubernetes[spring-cloud-starter-kubernetes]依存関係を追加することにより、Service Discoveryを簡単に使用できます。クライアントアプリケーションで:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-kubernetes</artifactId>
</dependency>
また、クラスで_ @ Autowired_を使用して、_ @ EnableDiscoveryClient_を追加し、_DiscoveryClient_を_ClientController_に挿入する必要があります。
@SpringBootApplication
@EnableDiscoveryClient
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
@RestController
public class ClientController {
    @Autowired
    private DiscoveryClient discoveryClient;
}

5. ConfigMaps

通常、*マイクロサービスには何らかの構成管理*が必要です。 たとえば、Spring Cloudアプリケーションでは、Spring Cloud Config Serverを使用します。
ただし、Kubernetesが提供するhttps://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/[ConfigMaps]を使用することでこれを実現できます。ただし、機密性の高い暗号化されていない情報のみ。 または、共有する情報が機密情報である場合は、代わりにhttps://kubernetes.io/docs/concepts/configuration/secret/[Secrets]を使用することを選択する必要があります。
この例では、_client-service_ Spring BootアプリケーションでConfigMapsを使用しています。 __client-config .__ yamlファイルを作成して、_client-service_のConfigMapを定義しましょう。
apiVersion: v1 by d
kind: ConfigMap
metadata:
  name: client-service
data:
  application.properties: |-
    bean.message=Testing reload! Message from backend is: %s <br/> Services : %s
  • ConfigMapの名前は、「application.properties」ファイルで指定されているアプリケーションの名前と一致することが重要です。 この場合、それは_client-service_です。 次に、Kubernetesで_client-service_のConfigMapを作成する必要があります。

kubectl create -f client-config.yaml
それでは、構成クラス_ClientConfig_を_ @ Configuration_と_ @ ConfigurationProperties_で作成し、_ClientController_に注入しましょう。
@Configuration
@ConfigurationProperties(prefix = "bean")
public class ClientConfig {

    private String message = "Message from backend is: %s <br/> Services : %s";

    // getters and setters
}
@RestController
public class ClientController {

    @Autowired
    private ClientConfig config;

    @GetMapping
    public String load() {
        return String.format(config.getMessage(), "", "");
    }
}
ConfigMapを指定しない場合は、クラスに設定されているデフォルトのメッセージが表示されるはずです。 ただし、ConfigMapを作成すると、このデフォルトメッセージはそのプロパティによってオーバーライドされます。
さらに、ConfigMapの更新を決定するたびに、それに応じてページ上のメッセージが変更されます。
kubectl edit configmap client-service

6. 秘密

この例のMongoDB接続設定の仕様を見て、https://kubernetes.io/docs/concepts/configuration/secret/ [Secrets]の仕組みを見てみましょう。 Kubernetesで環境変数を作成し、Spring Bootアプリケーションに注入します。

6.1. シークレットを作成する

最初のステップは、_username_と_password_を_Base 64_にエンコードする_secret.yaml_ファイルを作成することです。
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
data:
  username: dXNlcg==
  password: cDQ1NXcwcmQ=
Kubernetesクラスターにシークレット構成を適用しましょう。
kubectl apply -f secret.yaml

6.2. MongoDBサービスを作成する

ここで、MongoDBサービスとデプロイメント_travel-agency-deployment.yaml_ファイルを作成する必要があります。 特に、展開の部分では、以前に定義したSecret _username_と_password_を使用します。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: mongo
spec:
  replicas: 1
  template:
    metadata:
      labels:
        service: mongo
      name: mongodb-service
    spec:
      containers:
      - args:
        - mongod
        - --smallfiles
        image: mongo:latest
        name: mongo
        env:
          - name: MONGO_INITDB_ROOT_USERNAME
            valueFrom:
              secretKeyRef:
                name: db-secret
                key: username
          - name: MONGO_INITDB_ROOT_PASSWORD
            valueFrom:
              secretKeyRef:
                name: db-secret
                key: password
デフォルトでは、_mongo:latest_イメージは、_admin._というデータベースに_username_および_password_を持つユーザーを作成します。

6.3. 旅行代理店サービスでのMongoDBのセットアップ

データベースに関連する情報を追加するには、アプリケーションのプロパティを更新することが重要です。 データベース名_admin_は自由に指定できますが、ここでは_username_や_password_などの最も機密性の高い情報を非表示にしています:
spring.cloud.kubernetes.reload.enabled=true
spring.cloud.kubernetes.secrets.name=db-secret
spring.data.mongodb.host=mongodb-service
spring.data.mongodb.port=27017
spring.data.mongodb.database=admin
spring.data.mongodb.username=${MONGO_USERNAME}
spring.data.mongodb.password=${MONGO_PASSWORD}
ここで、_travel-agency-deployment_プロパティファイルを見て、_mongodb-service_への接続に必要なユーザー名とパスワード情報でサービスとデプロイメントを更新してみましょう。
以下は、MongoDB接続に関連する部分を含む、ファイルの関連セクションです。
env:
  - name: MONGO_USERNAME
    valueFrom:
      secretKeyRef:
        name: db-secret
        key: username
  - name: MONGO_PASSWORD
    valueFrom:
      secretKeyRef:
        name: db-secret
        key: password

7. リボンとのコミュニケーション

マイクロサービス環境では、通常、ロードバランシングを実行するために、サービスが複製されるポッドのリストが必要です。 これは、Spring Cloud Kubernetes Ribbonが提供するメカニズムを使用して実現されます。 このメカニズムは、特定のサービスのすべてのエンドポイントを自動的に検出して到達することができ、その後、リボン_ServerList_にエンドポイントに関する情報を入力します。
_https://search.maven.org/search?q = g:org.springframework.cloud%20a:spring-cloud-starter-kubernetes-ribbon [spring-cloud-starter-kubernetes-ribbon] _を追加することから始めましょう_client-service_ pom.xmlファイルへの依存関係:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
</dependency>
次のステップは、注釈_ @ RibbonClient_を_client-service_アプリケーションに追加することです。
@RibbonClient(name = "travel-agency-service")
エンドポイントのリストが入力されると、Kubernetesクライアントは、_ @ RibbonClient_アノテーションを使用して定義されたサービス名に一致する現在のネームスペース/プロジェクトに存在する登録済みエンドポイントを検索します。
また、アプリケーションプロパティでリボンクライアントを有効にする必要があります。
ribbon.http.client.enabled=true

8. 追加機能

8.1. ヒステリック

link:/introduction-to-hystrix[*Hystrix*] *フォールトトレラントで復元力のあるアプリケーションの構築を支援します。*主な目的は、高速で迅速な復旧の失敗です。
特に、この例では、Hystrixを使用して、Spring Bootアプリケーションクラスに_ @ EnableCircuitBreaker_の注釈を付けて、_client-server_にサーキットブレーカーパターンを実装しています。
さらに、メソッド_TravelAgencyService.getDeals()_に_ @ HystrixCommand()_を注釈することで、フォールバック機能を使用しています。 これは、フォールバックの場合、_getFallBackName()_が呼び出され、「Fallback」メッセージが返されることを意味します。
@HystrixCommand(fallbackMethod = "getFallbackName", commandProperties = {
    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000") })
public String getDeals() {
    return this.restTemplate.getForObject("http://travel-agency-service:8080/deals", String.class);
}

private String getFallbackName() {
    return "Fallback";
}

8.2. ポッドヘルスインジケーター

Spring Boot _HealthIndicator_およびlink:/spring-boot-actuators[Spring Boot Actuator]を利用して、健康関連の情報をユーザーに公開できます。
特に、Kubernetesヘルスインジケータは以下を提供します。
  • ポッド名

  • IPアドレス

  • 名前空間

  • サービスアカウント

  • ノード名

  • Spring Bootアプリケーションが内部かどうかを示すフラグ
    またはKubernetesの外部

9. 結論

この記事では、Spring Cloud Kubernetesプロジェクトの完全な概要を提供します。
では、なぜそれを使用する必要があるのでしょうか? マイクロサービスプラットフォームとしてKubernetesに根ざしたものの、Spring Cloudの機能に感謝している場合、Spring Cloud Kubernetesは両方の長所を提供します。
サンプルの完全なソースコードは、https://github.com/eugenp/tutorials/tree/master/spring-cloud/spring-cloud-kubernetes [GitHubで]から入手できます。