1. 概要

マイクロサービスソリューションを構築する場合、 SpringCloudKubernetesはどちらも、最も一般的な課題を解決するためのコンポーネントを提供するため、最適なソリューションです。 ただし、ソリューションのメインのコンテナマネージャーおよびデプロイプラットフォームとしてKubernetesを選択する場合でも、主に Spring CloudKubernetesプロジェクトを通じてSpringCloudの興味深い機能を使用できます。

この比較的新しいプロジェクトは、間違いなく SpringBootアプリケーションのKubernetesとの簡単な統合を提供します。 開始する前に、ローカルのKubernetes環境であるMinikubeSpringBootアプリケーションをデプロイする方法を確認すると役立つ場合があります。

このチュートリアルでは、次のことを行います。

  • Minikubeをローカルマシンにインストールします
  • RESTを介して通信する2つの独立したSpringBootアプリケーションを使用してマイクロサービスアーキテクチャの例を開発する
  • Minikubeを使用して1ノードクラスターでアプリケーションをセットアップします
  • YAML構成ファイルを使用してアプリケーションをデプロイします

2. シナリオ

この例では、旅行代理店が時々旅行代理店サービスに問い合わせるクライアントにさまざまな取引を提供するシナリオを使用しています。 これを使用して、次のことを示します。

  • SpringCloudKubernetesを介したサービスディスカバリ
  • 構成管理およびSpringCloudKubernetesConfigを使用したアプリケーションポッドへのKubernetesConfigMapsとシークレットの挿入
  • 負荷分散SpringCloudKubernetesリボンを使用

3. 環境設定

何よりもまず、Minikubeをローカルマシンインストールする必要があります。できればVirtualBoxなどのVMドライバーをインストールする必要があります。 この環境設定に従う前に、Kubernetesとその主な機能を確認することもお勧めします。

ローカルのシングルノードKubernetesクラスターを起動してみましょう。

minikube start --vm-driver=virtualbox

このコマンドは、VirtualBoxドライバーを使用してMinikubeクラスターを実行する仮想マシンを作成します。 kubectlのデフォルトコンテキストはminikubeになります。 ただし、コンテキストを切り替えることができるようにするには、次を使用します。

kubectl config use-context minikube

Minikubeを起動すると、 Kubernetesダッシュボードに接続してログにアクセスし、サービス、ポッド、ConfigMap、シークレットを簡単に監視できます。

minikube dashboard

3.1. 展開

まず、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クラスター内のポッドで実行されているSpringBootアプリケーション内からフェッチして到達できるエンドポイントのコレクションとしてサービスを公開します。

たとえば、この例では、旅行代理店サービスの複数のレプリカがあり、クライアントサービスから http:// travel-agency-service:8080としてアクセスされます。 ただし、これは内部的にはtravel-agency-service-7c9cfff655-4hxnpなどのさまざまなポッドへのアクセスに変換されます。

Spring Cloud Kubernetesリボンは、この機能を使用して、サービスのさまざまなエンドポイント間の負荷分散を行います。

クライアントアプリケーションにspring-cloud-starter-kubernetes依存関係を追加することで、サービスディスカバリを簡単に使用できます。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-kubernetes</artifactId>
</dependency>

また、 @EnableDiscoveryClient を追加し、クラスで @Autowired を使用して、DiscoveryClientClientControllerに挿入する必要があります。

@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 CloudConfigServerを使用します。

ただし、これは、Kubernetesが提供する ConfigMaps を使用することで実現できます。ただし、機密性の低い、暗号化されていない情報にのみ使用する場合に限ります。 または、共有したい情報が機密情報である場合は、代わりにSecretsを使用することを選択する必要があります。

この例では、 client-serviceSpring 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

次に、@Configuration@ConfigurationPropertiesを使用して構成クラスClientConfigを作成し、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接続設定の仕様を見て、Secretsがどのように機能するかを見てみましょう。 Kubernetesで環境変数を作成し、それをSpring Bootアプリケーションに挿入します。

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

最初のステップは、 secret.yaml ファイルを作成し、ユーザー名パスワード Base64にエンコードすることです。

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ファイルを作成する必要があります。 特に、展開の部分では、前に定義したシークレットユーザー名パスワードを使用します。

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。という名前のデータベースにusernamepasswordのユーザーを作成します。

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

アプリケーションのプロパティを更新して、データベース関連の情報を追加することが重要です。 データベース名adminは自由に指定できますが、ここではユーザー名パスワードなどの最も機密性の高い情報を非表示にしています。

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. リボンとのコミュニケーション

マイクロサービス環境では、通常、負荷分散を実行するために、サービスが複製されるポッドのリストが必要です。 これは、SpringCloudKubernetesリボンが提供するメカニズムを使用して実現されます。 このメカニズムは、特定のサービスのすべてのエンドポイントを自動的に検出して到達し、その後、リボンServerListにエンドポイントに関する情報を入力します。

spring-cloud-starter-kubernetes-ribbon依存関係をclient-servicepom.xmlファイルに追加することから始めましょう。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
</dependency>

次のステップは、注釈@RibbonClientclient-serviceアプリケーションに追加することです。

@RibbonClient(name = "travel-agency-service")

エンドポイントのリストが入力されると、Kubernetesクライアントは、@RibbonClientアノテーションを使用して定義されたサービス名に一致する現在の名前空間/プロジェクトに存在する登録済みエンドポイントを検索します。

また、アプリケーションのプロパティでリボンクライアントを有効にする必要があります。

ribbon.http.client.enabled=true

8. 追加機能

8.1. ヤマアラシ

Hystrix は、フォールトトレラントで復元力のあるアプリケーションの構築に役立ちます。その主な目的は、フェイルファストと迅速なリカバリです。

特に、この例では、Hystrixを使用して、Spring Bootアプリケーションクラスに @EnableCircuitBreaker の注釈を付けることにより、クライアントサーバーにサーキットブレーカーパターンを実装しています。

さらに、メソッド TravelAgencyService.getDeals() @HystrixCommand()のアノテーションを付けることで、フォールバック機能を使用しています。 これは、フォールバックの場合、 getFallBackName()が呼び出され、「フォールバック」メッセージが返されることを意味します。

@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およびSpringBoot Actuator を利用して、健康関連の情報をユーザーに公開できます。

特に、Kubernetesヘルスインジケーターは次の機能を提供します。

  • ポッド名
  • IPアドレス
  • 名前空間
  • サービスアカウント
  • ノード名
  • SpringBootアプリケーションがKubernetesの内部か外部かを示すフラグ

9. 結論

この記事では、SpringCloudKubernetesプロジェクトの概要を説明します。

では、なぜそれを使用する必要があるのでしょうか。 マイクロサービスプラットフォームとしてKubernetesを支持しているにもかかわらず、Spring Cloudの機能を高く評価している場合、SpringCloudKubernetesは両方の長所を提供します。

この例の完全なソースコードは、GitHubから入手できます。