Kong Meshは、サービスメッシュの管理を簡素化するためのプラットフォームで、マイクロサービス間の通信を安全かつ効率的に管理します。セキュリティ、可観測性、トラフィック制御といった機能を提供し、サイドカーアーキテクチャを利用して、各サービス間の通信をプロキシします。KubernetesやVMに対応し、異なる環境間でも統一したネットワーク管理を実現します。これにより、開発者はアプリケーションに集中でき、運用の複雑さを軽減できます。
この記事は、Kong Meshのデプロイ方法と、ポリシーの使い方をメモします。
K8s 環境の準備
標準のk8s環境であればどれでも大丈夫ですが、今回自分はk3sを使います。
export INSTALL_K3S_EXEC="--tls-san <ip address> --write-kubeconfig ~/.kube/config --write-kubeconfig-mode 644"
curl -sfL https://get.k3s.io | sh -
shの前に INSTALL_K3S_CHANNEL=v1.24.4+k3s1
みたいのを入れればインストールするバージョンを指定できますが、省略する場合は最新のバージョンになります。
kubectl get node
NAME STATUS ROLES AGE VERSION
wenhan-demo Ready control-plane,master 5m56s v1.30.4+k3s1
Kong Meshのデプロイメント
今回はまずシンプルなSingle Zone構成をデプロイします。
Kumactl
kumactlは、Kong MeshやKumaの管理用CLIツールで、サービスメッシュの設定やリソースの操作を簡単に行えます。CLIコマンドで、メッシュのデプロイ、ポリシー設定、監視が可能です。
以下の手順でkumactl
を展開し、PATH
にも追加します。
こちらも同じく、VERSIONを省略したら最新のバージョンがインストールされます。
curl -L https://docs.konghq.com/mesh/installer.sh | VERSION=2.8.2 sh -
cd kong-mesh-2.8.2/bin
export PATH=$(pwd):$PATH
Kong Mesh Control Plane
以下のコマンドでKong Mesh Control Planeをk8s上にデプロイします。
ここで初めてkumactlを使います。インストールに必要なCRDなどが生成してくれます。
--license-path
には、Kong Gatewayと同じライセンスファイルのパスをセットします。
kumactl install control-plane \
--license-path=/home/ubuntu/license | kubectl apply -f -
デプロイが終わると、kong-mesh-control-plane-xxxxx
のPodがRunning状態になり、default
のmeshes
がデプロイされています。
kubectl get pods -n kong-mesh-system
NAME READY STATUS RESTARTS AGE
kong-mesh-control-plane-5d5cb5f55c-h59wb 1/1 Running 0 24s
kubectl get meshes
NAME AGE
default 2m20s
Kong Mesh Control planeをアクセスするには、CLIとGUIの方法があります。
まずはkong-mesh-control-plane
サービスを公開します。方法はなんでもありですが、今回はまずシンプルにNodePort
でexposeします。
kubectl expose deployment kong-mesh-control-plane \
-n kong-mesh-system \
--type=NodePort \
--name=kongmesh-cp \
--port 5681
service/kongmesh-cp exposed
kubectl patch service kongmesh-cp \
--namespace=kong-mesh-system \
--type='json' \
--patch='[{"op": "replace", "path": "/spec/ports/0/nodePort", "value":30001}]'
service/kongmesh-cp patched
serviceへのアクセス
上記で公開したサービスにアクセスすると、以下のような内容が出力されます。
curl -sX GET http://<IP address>:30001 | jq
{
"hostname": "kong-mesh-control-plane-5d5cb5f55c-h59wb",
"tagline": "Kong Mesh",
"product": "Kong Mesh",
"version": "2.8.2",
"instanceId": "kong-mesh-control-plane-5d5cb5f55c-h59wb-2875",
"clusterId": "ed1a75f5-caf5-4749-943b-0ad7c6c7a49d",
"gui": "/gui",
"basedOnKuma": "2.8.2"
}
GUIでのアクセス
公開したサービスの後ろに、/gui
を追加すると、GUI画面が表示されています。
kumactlからのアクセス
kumactl
コマンドからでもKong Mesh Control Planeを確認することもできます。
まずは、kumactlコマンドに上記のControl Planeの情報を追加します。
kumactl config control-planes add \
--name=kongmesh-cp \
--address=http://18.178.66.113:30001 --overwrite
added Control Plane "kongmesh-cp"
switched active Control Plane to "kongmesh-cp"
kumactl get meshes
から、現在のMeshの設定状況を確認できる。
kumactl get meshes
NAME mTLS METRICS LOGGING TRACING LOCALITY ZONEEGRESS AGE
default off off off off off off 9h
Kong MeshにAppを追加
リソースのmetadata.labels
にkuma.io/sidecar-injection: enabled
を付与すれば、Kong Meshにそのリソースに含まれているものが追加されます。以下の例では、Namespaceにラベルを付与したので、このNamespace内の全てのPodにsidecar(DP)を追加し、Kong Meshで管理することになります。
Appのデプロイ
以下のdemo用のYAMLファイルを保存します。Front Endのサービスはページ表示、Redisのサービスはカウンターを保存する簡単なアプリです。
apiVersion: v1
kind: Namespace
metadata:
name: kuma-demo
labels:
kuma.io/sidecar-injection: enabled
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: kuma-demo
spec:
selector:
matchLabels:
app: redis
replicas: 1
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: "redis"
ports:
- name: tcp
containerPort: 6379
lifecycle:
postStart:
exec:
command: ["/usr/local/bin/redis-cli", "set", "zone", "local"]
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: kuma-demo
spec:
selector:
app: redis
ports:
- protocol: TCP
port: 6379
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
namespace: kuma-demo
spec:
selector:
matchLabels:
app: demo-app
replicas: 1
template:
metadata:
labels:
app: demo-app
version: v1
spec:
containers:
- name: demo-app
image: "thefosk/kuma-demo"
env:
- name: REDIS_HOST
value: "redis.kuma-demo.svc.cluster.local"
- name: REDIS_PORT
value: "6379"
- name: APP_VERSION
value: "1.0"
- name: APP_COLOR
value: "#efefef"
ports:
- name: http
containerPort: 5000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app-v2
namespace: kuma-demo
spec:
selector:
matchLabels:
app: demo-app
replicas: 1
template:
metadata:
labels:
app: demo-app
version: v2
spec:
containers:
- name: demo-app
image: "thefosk/kuma-demo"
env:
- name: REDIS_HOST
value: "redis.kuma-demo.svc.cluster.local"
- name: REDIS_PORT
value: "6379"
- name: APP_VERSION
value: "2.0"
- name: APP_COLOR
value: "#5da36f"
ports:
- name: http
containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
name: demo-app
namespace: kuma-demo
annotations:
5000.service.kuma.io/protocol: http
ingress.kubernetes.io/service-upstream: "true"
spec:
selector:
app: demo-app
ports:
- protocol: TCP
port: 5000
保存したYAMLファイルを使ってデモ用リソースを追加します。
kubectl apply -f counterapp.yaml
namespace/kuma-demo created
deployment.apps/redis created
service/redis created
deployment.apps/demo-app created
deployment.apps/demo-app-v2 created
service/demo-app created
kubectl get pod -n kuma-demo
NAME READY STATUS RESTARTS AGE
demo-app-5db8dc7c7c-5lxv4 2/2 Running 0 31s
demo-app-v2-977f89977-szv4p 2/2 Running 0 31s
redis-b95455698-hk7sm 2/2 Running 0 31s
各Podにcontainerが二つあることから、Sidecarが追加されたことはわかります。
GUIのData Plane Proxies
を開いたら確認できます。
kumactlコマンドからでも、現在管理中のSidecar(dataplane)を確認することができます。
kumactl inspect dataplanes
MESH NAME TAGS STATUS LAST CONNECTED AGO LAST UPDATED AGO TOTAL UPDATES TOTAL ERRORS CERT REGENERATED AGO CERT EXPIRATION CERT REGENERATIONS CERT BACKEND SUPPORTED CERT BACKENDS KUMA-DP VERSION ENVOY VERSION DEPENDENCIES VERSIONS NOTES
default demo-app-5db8dc7c7c-5lxv4.kuma-demo app=demo-app k8s.kuma.io/namespace=kuma-demo k8s.kuma.io/service-name=demo-app k8s.kuma.io/service-port=5000 kubernetes.io/hostname=wenhan-demo kuma.io/protocol=http kuma.io/service=demo-app_kuma-demo_svc_5000 kuma.io/zone=default pod-template-hash=5db8dc7c7c version=v1 Online 1m 51s 9 0 never - 0 - 2.8.2 1.30.4 -
default demo-app-v2-977f89977-szv4p.kuma-demo app=demo-app k8s.kuma.io/namespace=kuma-demo k8s.kuma.io/service-name=demo-app k8s.kuma.io/service-port=5000 kubernetes.io/hostname=wenhan-demo kuma.io/protocol=http kuma.io/service=demo-app_kuma-demo_svc_5000 kuma.io/zone=default pod-template-hash=977f89977 version=v2 Online 1m 51s 9 0 never - 0 - 2.8.2 1.30.4 -
default redis-b95455698-hk7sm.kuma-demo app=redis k8s.kuma.io/namespace=kuma-demo k8s.kuma.io/service-name=redis k8s.kuma.io/service-port=6379 kubernetes.io/hostname=wenhan-demo kuma.io/protocol=tcp kuma.io/service=redis_kuma-demo_svc_6379 kuma.io/zone=default pod-template-hash=b95455698 Online 1m 50s 9 0 never - 0 - 2.8.2 1.30.4 -
Appの公開
このアプリにアクセスしてみましょう。やり方は複数ありますが、ここではGateway + Ingressの方法で公開します。
Install gateway
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml
customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io created
echo "
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: kong
annotations:
konghq.com/gatewayclass-unmanaged: 'true'
spec:
controllerName: konghq.com/kic-gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: kong
spec:
gatewayClassName: kong
listeners:
- name: proxy
port: 80
protocol: HTTP
" | kubectl apply -f -
gatewayclass.gateway.networking.k8s.io/kong created
gateway.gateway.networking.k8s.io/kong created
Install Kong KIC and Ingress
kubectl create ns kong
kubectl label ns kong kuma.io/sidecar-injection='enabled'
helm install kong kong/ingress -n kong
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: /home/ubuntu/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: /home/ubuntu/.kube/config
NAME: kong
LAST DEPLOYED: Mon Sep 2 10:02:13 2024
NAMESPACE: kong
STATUS: deployed
REVISION: 1
TEST SUITE: None
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: counterapp
namespace: kuma-demo
annotations:
kubernetes.io/ingress.class: kong
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo-app
port:
number: 5000
EOF
これでKong-gateway-proxyを使って、デプロイしたAPPにアクセスすることができます。
kubectl get svc -n kong
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kong-controller-validation-webhook ClusterIP 10.43.225.243 <none> 443/TCP 3m10s
kong-gateway-admin ClusterIP None <none> 8444/TCP 3m10s
kong-gateway-manager NodePort 10.43.69.48 <none> 8002:32047/TCP,8445:31615/TCP 3m10s
kong-gateway-proxy LoadBalancer 10.43.97.252 <pending> 80:32333/TCP,443:31081/TCP 3m10s
32333
portにアクセスすれば、デモAPPにアクセスすることができます。
適当にIncrementをクリックしたら、全てが正常に動作しているはずです。
Kong Meshのポリシーを活用
ここからはKong Meshの本領を発揮するところです。Kong Meshのポリシーは、サービスメッシュ環境でセキュリティやアクセス管理、トラフィック制御を実現するためのルール設定をサポートするものです。これらのポリシーには、主に以下の要素が含まれます。
- セキュリティポリシー: 通信の暗号化(mTLS)や認証・認可を通じて、マイクロサービス間のセキュリティを強化します。トラフィックが安全に通信されることを保証します
- トラフィックポリシー: サービス間の通信ルールを定義します。リトライやタイムアウト設定、トラフィックシェーピング、ロードバランシングなどを管理することが可能です
- 認可ポリシー: RBAC(Role-Based Access Control)に基づき、どのサービスやユーザーがどのリソースにアクセスできるかを制御します
- 監査ポリシー: システム全体のアクティビティを記録し、監査ログを生成します。これにより、異常やセキュリティインシデントの早期検知が可能です
Kong Meshのポリシーは、これらの機能を通じて、分散システム全体のセキュリティ、パフォーマンス、信頼性を向上させることを目的としています。
https://docs.konghq.com/mesh/latest/policies/introduction/
ここでは、以下の二つのポリシーを適用して、Zero Trust networkを構築する方法を説明します。
https://docs.konghq.com/mesh/latest/policies/meshpassthrough/
https://docs.konghq.com/mesh/latest/policies/meshtrafficpermission/
Zero-trust Networkの構築
mTLSの有効化
デフォルトでは、mTLSが無効になっています。
kumactl get meshes
NAME mTLS METRICS LOGGING TRACING LOCALITY ZONEEGRESS AGE
default off off off off off off 9h
Kong Mesh内部にbuilt-inのCAがあるため、以下で簡単に有効することができます。
# config mesh to enable mtls
cat <<EOF | kubectl apply -f -
apiVersion: kuma.io/v1alpha1
kind: Mesh
metadata:
name: default
spec:
mtls:
enabledBackend: ca-1
backends:
- name: ca-1
type: builtin
EOF
kumactl get meshes
NAME mTLS METRICS LOGGING TRACING LOCALITY ZONEEGRESS AGE
default builtin/ca-1 off off off off off 9h
mTLSを有効化すれば、これで全てのトラフィックに、meshtrafficpermission
が必要になっています。現在はまだ作っていないため、APPへのアクセスが失敗になるはずです。
Kong Meshのバージョンによって失敗にならないケースもありますが、それはデフォルトにallow-all
のmeshtrafficpermission
が存在しているからです。
マイクロサービス間のアクセスを許可
例えば、以下のようにallow-all
のPermissionを作ったら、Mesh内の全てのトラフィックが正常のままになっています。
cat <<EOF | kubectl apply -f -
apiVersion: kuma.io/v1alpha1
kind: MeshTrafficPermission
metadata:
name: allow-all
namespace: kong-mesh-system
labels:
kuma.io/mesh: default
spec:
targetRef:
kind: Mesh
from:
- targetRef:
kind: Mesh
default:
action: Allow
EOF
もう少しコントロールしたいので、許可をマイクロベースレベルで設定してみます。
まずはFront EndのKong GatewayのサービスからAPPへの許可を設定します。
cat <<EOF | kubectl apply -f -
apiVersion: kuma.io/v1alpha1
kind: MeshTrafficPermission
metadata:
name: kong2frontend
namespace: kong-mesh-system
labels:
kuma.io/mesh: default
spec:
targetRef:
kind: MeshService
name: demo-app_kuma-demo_svc_5000
from:
- targetRef:
kind: MeshSubset
tags:
kuma.io/service: kong-gateway-admin_kong_svc_8444
default:
action: Allow
EOF
meshtrafficpermission.kuma.io/kong2frontend created
次に、APPからRedisへの許可を設定します。
cat <<EOF | kubectl apply -f -
apiVersion: kuma.io/v1alpha1
kind: MeshTrafficPermission
metadata:
name: frontend2backend
namespace: kong-mesh-system
labels:
kuma.io/mesh: default
spec:
targetRef:
kind: MeshService
name: redis_kuma-demo_svc_6379
from:
- targetRef:
kind: MeshSubset
tags:
kuma.io/service: demo-app_kuma-demo_svc_5000
default:
action: Allow
EOF
ここまでで、マイクロサービスレベルのアクセス許可を設定し、アプリケーションの動きが正常になるはずです。
まとめ
Kong Meshは、サービスメッシュの管理を簡素化するプラットフォームで、マイクロサービス間の通信を安全かつ効率的に管理します。この記事では、Kong Meshのデプロイ方法とポリシーの使い方を説明しています。
-
K8s環境の準備: k3sを使用してKubernetes環境をセットアップします。
-
Kong Meshのデプロイ:
-
kumactl
を使用してKong Mesh Control Planeをデプロイします。 -
NodePort
を使用してControl Planeを公開し、CLIやGUIでアクセスします。
-
-
アプリケーションのデプロイ:
-
kuma.io/sidecar-injection: enabled
ラベルを使用して、Namespace内のPodにサイドカーを追加します。 - Redisとデモアプリをデプロイし、Kong Meshで管理します。
-
-
アプリケーションの公開:
- GatewayとIngressを使用してアプリケーションを公開します。
-
Kong Meshのポリシー活用:
- mTLSを有効化し、Zero Trust Networkを構築します。
-
MeshTrafficPermission
を設定して、マイクロサービス間のアクセスを制御します。
このプロセスにより、Kong Meshを使用してセキュアで効率的なサービスメッシュを構築し、ポリシーを活用してトラフィックを管理する方法を学びます。