Kuma Meshes を真っ向から攻略する - 初心者向けガイド すぐに学習し始めるには、クラスターが最も重要な要素の 1 つです。次に、Kubernetes (別名 ) 内のポッドの状態を確認するコマンドも必要で、 インストールでき、最後に、いくつかの コマンドを発行できることも必要です。 Kuma k8s Kuma Kuma つまり、 の準備を整えるには、 4 つの必須コマンドをインストールする必要があるということです。これらのコマンドは次のとおりです。 Kuma - これは Docker では Kubernetes とも呼ばれます。これは、 のみで作成する機能を活用するコマンドです。 kind kubectl - すでに の操作に慣れている場合、おそらくこのリストで最も期待されるものでしょう。これは、 クラスターにコマンドを発行する方法です。 kubectl k8s k8s - Helm を使用すると、 コントロール プレーンのインストールなど、非常に便利なスクリプトを実行できます。 helm Kuma - このガイドではこのコマンドをあまり使用しませんが、その使用方法を知っておくことは重要です。 kumactl このガイドでは、 でこれを行う方法を説明します。これらはすべて システムでテストされています。Mac や 、またはお持ちのその他のオペレーティング システムにこれをインストールする方法に関するガイドにご興味がある場合は、私の YouTube チャンネル で声をかけてください。 Ubuntu Ubuntu Mac-OS Windows JESPROTECH コミュニティ I. コマンドのインストール Docker の種類 ( ) k8s kind をインストールするには、次のコマンドを発行する必要があります。 [ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.22.0/kind-linux-amd64 chmod +x ./kind sudo mv ./kind /usr/local/bin/kind コマンド にインストールされることに注意してください。これは、Linux ディストリビューション内でもシステムごとに異なる場合があります。 kind /usr/local/bin/kind 証明書と GPG キーのインストール と コマンドは両方とも、特定の キーが存在している状態でインストールする必要があります。これを Linux ディストリビューションのローカル リポジトリに追加するには、次の操作を行います。 helm kubectl GPG apt sudo apt-get install -y apt-transport-https ca-certificates curl gpg curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list sudo apt-get update kubectl 前の手順が完了すると、 のインストールは非常に簡単になります。 Kubectl sudo apt-get install -y kubelet kubeadm kubectl 、 、 コマンドは必須ではありませんが、インストールしておくことをお勧めします。 kubelet kubeadm kubectl 兜 すでにご想像のとおり、 インストールも非常に簡単になりました。 helm sudo apt-get install -y helm クマ インストールは、手動の手順が 1 つ必要となるため、少し面倒ですが、まず依存関係をダウンロードする必要があります。 Kuma cd ~ || exit; curl -L https://kuma.io/installer.sh | VERSION=2.6.1 sh - このコマンドを発行する前に、必ず フォルダに移動してください。たとえば、Kuma を削除することにした場合など、簡単にアクセスでき、簡単に見つけられる場所に をインストールしておくことが重要です。 HOME Kuma それが終わったら、PATH に フォルダを追加することも非常に重要です。 bin export PATH=~/kuma-2.6.1/bin:$PATH; この行をスタートアップ スクリプトの最後または途中に追加すると、このプロセスが簡単になります。スタートアップ スクリプトは、 、 、 のいずれかになりますが、別の形式になる可能性もあります。 .bashrc .zshrc .profile k9s インストールも他のアプリケーションとはかなり異なります。この場合、 では または 使用できます。私はこれまで で 主に使用しており、Linux ではほとんど必要ありませんでしたが、この場合は brew が非常に必要なので、まずは brew を次のようにインストールする必要があります。 k9s Linux pacman brew Mac-OS brew /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" brew のインストールが完了したら、 (" ") をインストールするだけです。 k9s kanines brew install derailed/k9s/k9s 考慮すべき重要な点の 1 つは、 をインストールして初めて実行し始めると、監視対象のクラスターが削除または追加された場合に クラッシュする点に気付くと思います。 k9s k9s II. クラスターの作成 kind create cluster --name=wlsm-mesh-zone kubectl cluster-info --context kind-wlsm-mesh-zone 最初のコマンドは、 という名前のクラスターを作成します。これは、Kuma をインストールするために使用するクラスターです。2 番目のコマンドは、クラスターのステータスを確認するために使用されます。 wlsm-mesh-zone III. ローカル Docker レジストリの作成 前に述べたように、Docker レジストリは非常に簡単に作成できます。作成するのは簡単そうに聞こえますが、これを行うためのスクリプトは一握りです。したがって、最善の方法は、Web サイトで既に利用可能なものをコピーして貼り付けることです。ここで、この ダウンロードできます。 スクリプトを #!/bin/sh # Original Source # https://creativecommons.org/licenses/by/4.0/ # https://kind.sigs.k8s.io/docs/user/local-registry/ set -o errexit # 1. Create registry container unless it already exists reg_name='kind-registry' reg_port='5001' if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then docker run \ -d --restart=always -p "127.0.0.1:${reg_port}:5000" --network bridge --name "${reg_name}" \ registry:2 fi # 2. Create kind cluster with containerd registry config dir enabled # TODO: kind will eventually enable this by default and this patch will # be unnecessary. # # See: # https://github.com/kubernetes-sigs/kind/issues/2875 # https://github.com/containerd/containerd/blob/main/docs/cri/config.md#registry-configuration # See: https://github.com/containerd/containerd/blob/main/docs/hosts.md cat <<EOF | kind create cluster --config=- kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 containerdConfigPatches: - |- [plugins."io.containerd.grpc.v1.cri".registry] config_path = "/etc/containerd/certs.d" EOF # 3. Add the registry config to the nodes # # This is necessary because localhost resolves to loopback addresses that are # network-namespace local. # In other words: localhost in the container is not localhost on the host. # # We want a consistent name that works from both ends, so we tell containerd to # alias localhost:${reg_port} to the registry container when pulling images REGISTRY_DIR="/etc/containerd/certs.d/localhost:${reg_port}" for node in $(kind get nodes); do docker exec "${node}" mkdir -p "${REGISTRY_DIR}" cat <<EOF | docker exec -i "${node}" cp /dev/stdin "${REGISTRY_DIR}/hosts.toml" [host."http://${reg_name}:5000"] EOF done # 4. Connect the registry to the cluster network if not already connected # This allows kind to bootstrap the network but ensures they're on the same network if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" = 'null' ]; then docker network connect "kind" "${reg_name}" fi # 5. Document the local registry # https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ConfigMap metadata: name: local-registry-hosting namespace: kube-public data: localRegistryHosting.v1: | host: "localhost:${reg_port}" help: "https://kind.sigs.k8s.io/docs/user/local-registry/" EOF このスクリプトは にあります。ローカル Docker レジストリをインストールするには、この bash スクリプトを実行するだけです。 プロジェクトのルート フォルダー IV. コードの作成方法 このブログ投稿の例として提供したコードについては、語るべきことがたくさんあるかもしれません。ただし、この場合は、いくつかの重要な側面に焦点を当てましょう。 から 、そして へと進みます。サービスをローカルで実行する場合、またはコンテナーを起動するために 構成を使用する場合、通常は、コンテナー名または で構成した名前として自動的に割り当てられる DNS 属性名を使用します。 リスナー サービス コレクター データベース docker-compose hostname では、ホスト名をクラスター全体で利用できるようにする一連のルールもあります。リスナーとコレクターの例を見てみましょう。 k8s リスナーの例 リスナーは、 を使用して で開発されたアプリケーションです。この方法で作成されたすべてのアプリケーションと同様に、 ファイルもあります。 Spring framework Java application.properties spring.application.name=wlsm-listener-service server.port=8080 spring.main.web-application-type=reactive spring.webflux.base-path=/app/v1/listener wslm.url.collector=http://localhost:8081/api/v1/collector これらすべてのプロパティの中で、現時点で最も注目すべきは プロパティです。 設定では、コンテナ化された環境を使用せずにこのサービスをローカルで実行できます。ただし、 クラスターでは、 にアクセスできる必要があり、そのためには、定義ファイル を含む プロファイルが必要です。 wslm.url.collector default k8s collector application-prod.properties prod wslm.url.collector=http://wlsm-collector-deployment.wlsm-namespace.svc.cluster.local:8081/api/v1/collector このプロパティは、ホスト にアクセスしようとします。このファイルは次の構成に従います。 wlsm-collector-deployment.wlsm-namespace.svc.cluster.local <Service Name>.<Namespace>.svc.cluster.local ドットで区切られた要素が 5 つあります。最後の 3 つは静的で、最初の 2 つはアクセスしようとしているマシンによって異なります。左側には、サービス名とそれに続く名前空間を配置します。これは、クラスター内でコンテナーが相互にどのように接続されているかを理解するために重要です。 注目すべきコード部分は、もちろんコントローラーとサービスです。コントローラーは次のようになります。 @RestController @RequestMapping public class ListenerController { private final ListenerService listenerService; ListenerController(ListenerService listenerService) { this.listenerService = listenerService; } @GetMapping("info") public String info() { return "Listener Service V1"; } @PostMapping("create") public Mono<AnimalLocationDto> sendAnimalLocation( @RequestBody AnimalLocationDto animalLocationDto) { return listenerService.persist(animalLocationDto); } } サービスは次のようになります。 @Service public class ListenerService { @Value("${wslm.url.collector:http://localhost:8080}") private String collectorUrl; private final WebClient client = WebClient.create(collectorUrl); HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance(); List<AnimalLocationDto> cache = hazelcastInstance.getList("data"); public Mono<AnimalLocationDto> persist(AnimalLocationDto animalLocationDto) { cache.add(animalLocationDto); return client.post() .uri(collectorUrl.concat("/animals")) .contentType(MediaType.APPLICATION_JSON) .bodyValue(animalLocationDto) .retrieve() .bodyToMono(AnimalLocationDto.class); } } すでにお気づきかもしれませんが、この最初のアプリケーションは、このリポジトリ内の を使用して実装されたすべてのアプリケーションと同様にリアクティブであり、すべて ではなく を使用します。現時点では、このコードでの の使用は無視できます。これは、このプロジェクトの後のバージョンで使用されます。 Spring Framework tomcat netty hazelcast コレクターの例 この時点では、コレクターはリスナーとまったく同じように動作します。現時点での唯一の役割は、リスナーからデータベースにデータを中継することであり、そのためには、コレクターはデータベースがどこにあるかを正確に知る必要があります。 で同じ分析を行ってみましょう。 application.properties file of this project spring.application.name=wlsm-collector-service server.port=8081 spring.main.web-application-type=reactive spring.webflux.base-path=/api/v1/collector spring.r2dbc.url=r2dbc:postgresql://localhost:5432/wlsm spring.r2dbc.username=admin spring.r2dbc.password=admin spring.data.r2dbc.repositories.naming-strategy=org.springframework.data.relational.core.mapping.BasicRelationalPersistentEntityNamingStrategy spring.data.r2dbc.repositories.naming-strategy.table=org.springframework.data.relational.core.mapping.SnakeCaseNamingStrategy spring.data.r2dbc.repositories.naming-strategy.column=org.springframework.data.relational.core.mapping.SnakeCaseNamingStrategy これらのプロパティは、サービスを開始するために最低限必要なものです。ただし、これはローカルで実行できるようにするためだけのものです。また、このサービスには プロファイル ファイルもあり、ここの で確認できます。 prod application-prod.properties spring.r2dbc.url=r2dbc:postgresql://wlsm-database-deployment.wlsm-namespace.svc.cluster.local:5432/wlsm この場合、データベース接続はデータベースのホストを参照します。 wlsm-database-deployment.wlsm-namespace.svc.cluster.local これも、以前と同じ分析に従います。左側にはサービス名が表示され、その後に名前空間が続き、最後に が追加されます。 svc.cluster.local このサービスでは、コントローラーとサービスも使用します。コントローラーは次のようになります。 @RestController @RequestMapping class CollectorController( val collectorService: CollectorService ) { @PostMapping("animals") suspend fun listenAnimalLocation(@RequestBody animalLocationDto: AnimalLocationDto): AnimalLocationDto = run { collectorService.persist(animalLocationDto) animalLocationDto } } サービスは次のようになります。 @Service class CollectorService( val applicationEventPublisher: ApplicationEventPublisher ) { fun persist(animalLocationDto: AnimalLocationDto) = applicationEventPublisher.publishEvent(AnimalLocationEvent(animalLocationDto)) } このサービスは、 と呼ばれるイベント パブリッシャーを使用します。これは、このイベント リスナーで後で処理されるイベント ストリーミング アーキテクチャに従います。リアクティブ アーキテクチャ実装パラダイムを維持するために が使用されていることがすぐにわかります。 applicationEventPublisher r2dbc @Service class EventHandlerService( val animalLocationDao: AnimalLocationDao ) { @EventListener fun processEvent(animalLocationEvent: AnimalLocationEvent){ println(animalLocationEvent) runBlocking(Dispatchers.IO) { animalLocationDao.save(animalLocationEvent.animalLocationDto.toEntity()) } } } V. スクリプトの展開 を使用したデプロイは通常非常に簡単な作業です。ただし、サービスに必要な構成を確認することも重要です。たとえば、リスナーの実装を見てみましょう。 k8s apiVersion: v1 kind: Namespace metadata: name: wlsm-namespace labels: kuma.io/sidecar-injection: enabled --- apiVersion: apps/v1 kind: Deployment metadata: name: wlsm-listener namespace: wlsm-namespace spec: replicas: 1 selector: matchLabels: app: wlsm-listener template: metadata: labels: app: wlsm-listener spec: containers: - name: wlsm-listener-service image: localhost:5001/wlsm-listener-service:latest imagePullPolicy: Always ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: wlsm-listener-deployment namespace: wlsm-namespace spec: selector: app: wlsm-listener ports: - protocol: TCP appProtocol: http port: 8080 この構成には 3 つのブロックがあります。最初のブロックは名前空間ブロックです。名前空間構成は、ポリシーを適用するために必要な Envoy サイドカーを Kuma が挿入できるようにするために重要です。定義された名前空間がないと、 これを実行できません。kuma を構成するときに注意する必要があるもう 1 つの点は、名前空間に kuma が認識する適切なラベルが含まれている必要があることです。 kuma kuma.io/sidecar-injection: enabled. 正しいラベルを持つ名前空間の定義は、Kuma を動作させるために不可欠です。2 番目のブロックには、デプロイメントの定義があります。これは、Kubernetes クラスター内でのポッドのデプロイメントがどのようになるかを定義する方法です。ここで注目すべき重要な点は、 、 、および です。image は、使用している Docker イメージの完全なタグです。 image imagePullPolicy containerPort で作成された Docker レジストリ用に設定されるポートは 5001 で、これはイメージのタグに含まれています。これはタグとして機能するだけでなく、Docker レジストリへの接続としても機能します。これにより、イメージをプルして、Kubernetes 環境で実行するコンテナーを作成できます。 kind しかし、もちろん、イメージを使用するには、イメージを作成する必要があります。そのためには、 例と 例でそれがどのように行われるかを見てみましょう。 の Docker イメージは次のように定義されています。 listener database listener FROM eclipse-temurin:21-jdk-alpine WORKDIR /root ENV LANG=C.UTF-8 COPY entrypoint.sh /root COPY build/libs/wlsm-listener-service.jar /root/wlsm-listener-service.jar ENTRYPOINT ["/root/entrypoint.sh"] これはすべて というベースイメージから始まります。その後は、プロジェクトをビルドして作成された jar をコピーし、それをイメージにコピーします。その前に、 もコンテナーにコピーし、それを使用する を定義します。 、次のように jar を呼び出すだけです。 eclipse-temurin:21-jdk-alpine entrypoint.sh ENTRYPOINT entrypoint #!/usr/bin/env sh java -jar -Dspring.profiles.active=prod wlsm-listener-service.jar サービスは、オープンソースでオンラインで利用できるいくつかのスクリプトを使用するため、かなり異なります。 database FROM postgres:15 COPY . /docker-entrypoint-initdb.d COPY ./multiple /docker-entrypoint-initdb.d/multiple ENV POSTGRES_USER=admin ENV POSTGRES_PASSWORD=admin ENV POSTGRES_MULTIPLE_DATABASES=wlsm EXPOSE 5432 このスクリプトは、次のファイルとフォルダーのコピーを docker init ディレクトリに作成します: および 。最後に、これらのスクリプトで使用される変数を定義して、データベースとユーザー名/パスワードの組み合わせを定義します。 create-multiple-postgresql-databases.sh multiple データベースは次のスキーマを使用して作成されます。 CREATE TABLE families( id uuid DEFAULT gen_random_uuid(), name VARCHAR(100), PRIMARY KEY(id) ); CREATE TABLE genuses( id uuid DEFAULT gen_random_uuid(), name VARCHAR(100), PRIMARY KEY(id) ); CREATE TABLE species( id uuid DEFAULT gen_random_uuid(), common_name VARCHAR(100), family uuid, genus uuid, PRIMARY KEY(id), CONSTRAINT fk_species FOREIGN KEY(family) REFERENCES families(id), CONSTRAINT fk_genus FOREIGN KEY(genus) REFERENCES genuses(id) ); CREATE TABLE animal ( id uuid DEFAULT gen_random_uuid(), name VARCHAR(100), species_id uuid, PRIMARY KEY(id), CONSTRAINT fk_species FOREIGN KEY(species_id) REFERENCES species(id) ); CREATE TABLE animal_location ( id uuid DEFAULT gen_random_uuid(), animal_id uuid, latitude BIGINT, longitude BIGINT, PRIMARY KEY(id), CONSTRAINT fk_animal FOREIGN KEY(animal_id) REFERENCES animal(id) ); そして、データの例として、 という名前の動物を 1 匹登録します。 Piquinho は、世界中を旅するアホウドリの名前です。このアホウドリにはセンサーが取り付けられており、センサーから送信されるデータを読み取ります。種を定義するテーブルが 2 つあります。種を定義するのは、種と属です。これらは、 と というテーブルです。 piquinho families genuses テーブル「 、動物が属する種を定義します。最後に、種と動物の名前が登録される同じ名前のテーブルに を定義します。データベースは次のようになります。 species animal ビルドしてイメージを作成し、プロジェクトを開始するには、 で使用可能な次のコマンドを実行します。 Makefile make make create-and-push-images make k8s-apply-deployment 最初の make は単なる コマンドです。2 番目のコマンドでは変数が使用されました。 gradle build MODULE_TAGS := aggregator \ collector \ listener \ management \ database 走る: docker images "*/*wlsm*" --format '{{.Repository}}' | xargs -I {} docker rmi {} @for tag in $(MODULE_TAGS); do \ export CURRENT=$(shell pwd); \ echo "Building Image $$image..."; \ cd "wlsm-"$$tag"-service"; \ docker build . --tag localhost:5001/"wlsm-"$$tag"-service"; \ docker push localhost:5001/"wlsm-"$$tag"-service"; \ cd $$CURRENT; \ done これは単純にすべてのモジュールを調べ、 で指定された値ごとに変化する標準の汎用コマンドを使用してイメージを作成し、ポート 5001 のローカル レジストリにプッシュします。同じ戦略に従って、3 番目のコマンドを使用してポッドをデプロイできます。この 3 番目のコマンドは、次のような異なるループを使用します。 MODULE_TAGS @for tag in $(MODULE_TAGS); do \ export CURRENT=$(shell pwd); \ echo "Applying File $$tag..."; \ cd "wlsm-"$$tag"-service"; \ kubectl apply -f $$tag-deployment.yaml --force; \ cd $$CURRENT; \ done この場合、すべてのデプロイメント スクリプトがすべてのサービスに適用されます。コマンド を実行すると、次の出力が表示されます。 kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-76f75df574-dmt5m 1/1 Running 0 5m21s kube-system coredns-76f75df574-jtrfr 1/1 Running 0 5m21s kube-system etcd-kind-control-plane 1/1 Running 0 5m38s kube-system kindnet-7frts 1/1 Running 0 5m21s kube-system kube-apiserver-kind-control-plane 1/1 Running 0 5m36s kube-system kube-controller-manager-kind-control-plane 1/1 Running 0 5m36s kube-system kube-proxy-njzvl 1/1 Running 0 5m21s kube-system kube-scheduler-kind-control-plane 1/1 Running 0 5m36s kuma-system kuma-control-plane-5f47fdb4c6-7sqmp 1/1 Running 0 17s local-path-storage local-path-provisioner-7577fdbbfb-5qnxr 1/1 Running 0 5m21s wlsm-namespace wlsm-aggregator-64fc4599b-hg9qw 1/1 Running 0 4m23s wlsm-namespace wlsm-collector-5d44b54dbc-swf84 1/1 Running 0 4m23s wlsm-namespace wlsm-database-666d794c87-pslzp 1/1 Running 0 4m22s wlsm-namespace wlsm-listener-7bfbcf799-f44f5 1/1 Running 0 4m23s wlsm-namespace wlsm-management-748cf7b48f-8cjh9 1/1 Running 0 4m23s この時点で注目すべきは、 、 、および独自のカスタム で実行されているすべてのサービスの存在です。クラスターは外部から分離されており、さまざまなポートにアクセスできるようにするには、アクセスするすべてのポッドに対して を作成する必要があります。そのためには、別々のタブで次のコマンドを発行します。 kuma-control-plane kube-controller-manager wlsm-namespace port-forwarding を見てもこれを確認することができます: k9s kubectl port-forward svc/wlsm-collector-deployment -n wlsm-namespace 8081:8081 kubectl port-forward svc/wlsm-listener-deployment -n wlsm-namespace 8080:8080 kubectl port-forward svc/wlsm-database-deployment -n wlsm-namespace 5432:5432 kubectl port-forward svc/kuma-control-plane -n kuma-system 5681:5681 VI. アプリケーションの実行 アプリケーションを実行するには、すべてのポートを開く必要があります。すべてのポートが開くと、画面に次のような表示がされます。 とポート を使用してデータベースに接続できます。接続文字列は です。これにアクセスするには、ユーザー名とパスワードの組み合わせ / を使用します。 localhost 5432 jdbc:postgresql://localhost:5432/wlsm admin admin テストを実行する前に最初に行う必要があるのは、 の ID を知ることです。これは、次のような Intellij データベース ツールを使用して行うことができます。 Piquinho プロジェクトのルート フォルダーには、 というファイルがあります。これは、開いているポートに対して REST リクエストを作成するためのスクラッチ ファイルです。 test-requests.http ### GET http://localhost:8080/app/v1/listener/info ### POST http://localhost:8080/app/v1/listener/create Content-Type: application/json { "animalId": "2ffc17b7-1956-4105-845f-b10a766789da", "latitude": 52505252, "longitude": 2869152 } ### POST http://localhost:8081/api/v1/collector/animals Content-Type: application/json { "animalId": "2ffc17b7-1956-4105-845f-b10a766789da", "latitude": 52505252, "longitude": 2869152 } このファイルを使用できるようにするには、ID を、この例では から に置き換えるだけです。この場合、コレクターまたはリスナーからリクエストを行うことができます。両方のリクエストが機能し、その後、リクエストごとに次のような応答が表示されます。 2ffc17b7-1956-4105-845f-b10a766789da d5ad0824-71c0-4786-a04a-ac2b9a032da4 { "animalId": "d5ad0824-71c0-4786-a04a-ac2b9a032da4", "latitude": 52505252, "longitude": 2869152 } Response file saved. > 2024-04-12T001024.200.json Response code: 200 (OK); Time: 7460ms (7 s 460 ms); Content length: 91 bytes (91 B) 両方のポートが開かれており、この時点では同じペイロード タイプを共有しているため、リスナーとコレクターに対して同じリクエストを実行できます。これら 2 つのリクエストを実行すると、テーブル に結果が表示されます。 animal_locations したがって、これはクラスターが正しく実行されていることのみを確認し、Kuma メッシュでポリシーをテストする準備が整いました。 VII. メッシュトラフィック許可 - パート I 、Kuma で選択できる機能の 1 つであり、おそらく最もよく使用される機能です。 MeshTrafficPermission しかし、まずは Kuma コントロール プレーンを少し調べてみましょう。転送がすべてオンになっているので、 にアクセスして Kuma メッシュを視覚化できます。メイン ページには、次のようなものが表示されます。 localhost:5681/gui 現時点では特に見るものはありませんが、 を適用してみましょう。 MeshTrafficPermission echo "apiVersion: kuma.io/v1alpha1 kind: MeshTrafficPermission metadata: namespace: kuma-system name: mtp spec: targetRef: kind: Mesh from: - targetRef: kind: Mesh default: action: Allow" | kubectl apply -f - これを適用すると、 のような応答が返されるはずです。 meshtrafficpermission.kuma.io/mtp created VIII. メッシュ メッシュを適用しても、クラスターのセットアップに関しては大きな変化はありません。メッシュによってトラフィック ルーティング ポリシーを設定できるようになります。 選択できるものはたくさんありますが、最も明白なものの 1 つは これは相互 TLS とも呼ばれ、簡単に言えば、当事者間の ID を確立し、暗号化されたデータ トラフィックを確立するために、証明書が相互に受け入れられ、検証されることを意味します。 mTLS. これは、次のシンプルな 構成を使用して自動的に実行できます。 Mesh echo "apiVersion: kuma.io/v1alpha1 kind: Mesh metadata: name: default spec: mtls: enabledBackend: ca-1 backends: - name: ca-1 type: builtin" | kubectl apply -f - このポリシーを適用すると、次のような警告が表示される場合があります。 Warning: resource meshes/default is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically. 今のところ、この警告は無視できます。 IX メッシュトラフィック許可 - パート II さて、ここからが楽しい部分です。まず最初に、すべてのポッド間のすべてのトラフィックを無効にします。 echo " apiVersion: kuma.io/v1alpha1 kind: MeshTrafficPermission metadata: namespace: wlsm-namespace name: mtp spec: targetRef: kind: Mesh from: - targetRef: kind: Mesh default: action: Deny" | kubectl apply -f - 確認メッセージ 後、いずれかのポート転送を使用してリクエストを送信しようとすると、次のメッセージが表示されます。 meshtrafficpermission.kuma.io/mtp configured HTTP/1.1 500 Internal Server Error Content-Type: application/json Content-Length: 133 { "timestamp": "2024-04-12T07:09:26.718+00:00", "path": "/create", "status": 500, "error": "Internal Server Error", "requestId": "720749ce-56" } Response file saved. > 2024-04-12T090926.500.json Response code: 500 (Internal Server Error); Time: 10ms (10 ms); Content length: 133 bytes (133 B) これは、ポッド間のすべてのトラフィックが拒否されていることを意味します。これで、組織内の潜在的な悪意のある行為者から保護された内部システムが得られましたが、すべてのポッド間のトラフィックもブロックされました。つまり、 は素晴らしいものですが、すべてのトラフィックをブロックするのはまったくもって素晴らしいことではありません。 mTLS これを完璧にするには、単に「すべて ルールに例外を設けるだけです。そのためには、リスナーとコレクターの間、コレクターとデータベースの間のトラフィックを許可するポリシーが必要です。まずは、コレクターとデータベースの間のトラフィックから始めましょう。 DENY echo " apiVersion: kuma.io/v1alpha1 kind: MeshTrafficPermission metadata: namespace: kuma-system name: wlsm-database spec: targetRef: kind: MeshService name: wlsm-database-deployment_wlsm-namespace_svc_5432 from: - targetRef: kind: MeshService name: wlsm-collector-deployment_wlsm-namespace_svc_8081 default: action: Allow" | kubectl apply -f - この場合、私たちが行っていることは、データ トラフィックが コレクターから データベースに流れるようにすることです。これを知らない場合は、 作成と同様に機能目的で使用される を Kuma がどのように解釈するかに注意することが重要です。 targetRef targetRef hostname name これらの を構築する一般的な方法は次のとおりです。 name <service name>_<namespace>_svc_<service port> この場合、区切り文字はアンダースコアであり、このように名前を作成すると 何が許可されているかを正確に知らせることができます。この場合、このポリシーを適用すると、 という応答を受け取った後、コレクターにリクエストを送信できるようになります。 Kuma meshtrafficpermission.kuma.io/wlsm-database created そして、それらを作成すると、応答は、場所レコードがコレクターに送信されたことを確認する になるはずです。 200 POST http://localhost:8081/api/v1/collector/animals HTTP/1.1 200 OK Content-Type: application/json Content-Length: 91 { "animalId": "a3a1bc1c-f284-4876-a84f-f75184b6998f", "latitude": 52505252, "longitude": 2869152 } Response file saved. > 2024-04-12T091754.200.json Response code: 200 (OK); Time: 1732ms (1 s 732 ms); Content length: 91 bytes (91 B) ただし、リスナーとコレクター間のトラフィックに対する例外はまだ定義されていないため、そのようにリクエストを行うと、次の結果になります。 HTTP/1.1 500 Internal Server Error Content-Type: application/json Content-Length: 133 { "timestamp": "2024-04-12T07:18:54.149+00:00", "path": "/create", "status": 500, "error": "Internal Server Error", "requestId": "e8973d33-62" } Response file saved. > 2024-04-12T091854-1.500.json Response code: 500 (Internal Server Error); Time: 10ms (10 ms); Content length: 133 bytes (133 B) これは当然予想されたことです。では、このデータ トラフィックに別のポリシーを適用してみましょう。 echo " apiVersion: kuma.io/v1alpha1 kind: MeshTrafficPermission metadata: namespace: kuma-system name: wlsm-collector spec: targetRef: kind: MeshService name: wlsm-collector-deployment_wlsm-namespace_svc_8081 from: - targetRef: kind: MeshService name: wlsm-listener-deployment_wlsm-namespace_svc_8080 default: action: Allow" | kubectl apply -f - リスナーからコレクターへのリクエストを実行できるようになりました。 POST http://localhost:8080/app/v1/listener/create HTTP/1.1 200 OK Content-Type: application/json Content-Length: 91 { "animalId": "a3a1bc1c-f284-4876-a84f-f75184b6998f", "latitude": 52505252, "longitude": 2869152 } Response file saved. > 2024-04-12T092039-2.200.json Response code: 200 (OK); Time: 14ms (14 ms); Content length: 91 bytes (91 B) X - メッシュフォールトインジェクション 最後に、別の機能を例として挙げると、 という別の機能も使用できます。これは、 でテストを実行するときに非常に便利です。たとえば、メッシュ内の潜在的な問題をシミュレートし、エラー処理が正しく行われているかどうかを確認できます。 MeshFaultInjection Kuma また、設定したサーキットブレーカーが不良な接続や高レートのリクエストにどのように反応するかなど、他のことも確認できます。 それでは試してみましょう。MeshFaultInjection 適用する 1 つの方法は次のとおりです。 MeshFaultInjection echo " apiVersion: kuma.io/v1alpha1 kind: MeshFaultInjection metadata: name: default namespace: kuma-system labels: kuma.io/mesh: default spec: targetRef: kind: MeshService name: wlsm-collector-deployment_wlsm-namespace_svc_8081 from: - targetRef: kind: MeshService name: wlsm-listener-deployment_wlsm-namespace_svc_8080 default: http: - abort: httpStatus: 500 percentage: 50" | kubectl apply -f - このポリシーでは、リスナーからの送信トラフィックとコレクターへの受信トラフィックが 50% の確率で成功するとしています。リクエストの結果は予測できないため、このポリシーを適用した後、リスナー エンドポイントへのリクエストでエラーが発生するか、リクエストが成功するかが予想されます。 POST http://localhost:8080/app/v1/listener/create HTTP/1.1 500 Internal Server Error Content-Type: application/json Content-Length: 133 { "timestamp": "2024-04-12T07:28:00.008+00:00", "path": "/create", "status": 500, "error": "Internal Server Error", "requestId": "2206f29e-78" } Response file saved. > 2024-04-12T092800.500.json Response code: 500 (Internal Server Error); Time: 8ms (8 ms); Content length: 133 bytes (133 B) POST http://localhost:8080/app/v1/listener/create HTTP/1.1 200 OK Content-Type: application/json Content-Length: 91 { "animalId": "a3a1bc1c-f284-4876-a84f-f75184b6998f", "latitude": 52505252, "longitude": 2869152 } Response file saved. > 2024-04-12T092819.200.json Response code: 200 (OK); Time: 13ms (13 ms); Content length: 91 bytes (91 B) 最後に、興味深いことに、 テーブルが現在どのようになっているかを見てみましょう。 animal_location XI - 結論 ここまでこの記事を読んでいただき、マシン上でクラスターを実行できたことを願っています。この記事を読んでいただき、Kuma について理解を深めるために時間を割いていただき、ありがとうございました。個人的には、 はネットワークと環境をより細かく構成および制御できるようになるため、非常に有効に活用でき、将来性も高いと考えています。 Kuma エンタープライズ版の はかなり完成度が高いようです。Kuma はオープンソースで、テストにもエンタープライズにも最適のようです。メッシュというテーマは非常に興味深いと思います。Kuma メッシュの仕組みを学び、ネットワーク内のデータフローをより適切に制御する方法を理解するための優れた方法を提供していると思います。 Kong-Mesh Kuma サービスのステータスを確認したい場合は、次の の場所にある コントロール プレーンに移動するだけです: : localhost Kuma http://localhost:5681/gui/meshes/default/services?page=1&size=50 Kuma コントロール プレーンでは、インストールされているポリシーを確認したり、ポッドの状態を確認したり、バックグラウンドで何が起こっているかを監視したり、一般的にメッシュで何が起こっているか、どのように構成されているかの概要を把握したりすることもできます。アプリケーションを試してみて、インストールしたポリシーの状態を確認できるかどうかを確認してください。Kuma コントロール プレーン (GUI) は、メッシュを簡単に理解して追跡できるように作られています。 XII - リソース 相互 TLS (mTLS) とは何ですか? K9s 南北交通 東西交通 Kuma サービスメッシュを使い始める Kubernetes に Kuma をデプロイする ローカルレジストリの種類 これに関するビデオも私の YouTube チャンネルで作成しました。 JESPROTECH https://youtu.be/KE3VTYtLvnI?embedable=true