Kong Meshは、サービスメッシュの管理を簡素化するためのプラットフォームで、マイクロサービス間の通信を安全かつ効率的に管理します。セキュリティ、可観測性、トラフィック制御といった機能を提供し、サイドカーアーキテクチャを利用して、各サービス間の通信をプロキシします。KubernetesやVMに対応し、異なる環境間でも統一したネットワーク管理を実現します。これにより、開発者はアプリケーションに集中でき、運用の複雑さを軽減できます。
この記事は、Kong Meshのデプロイ方法と、ポリシーの使い方をメモします。
K8s 環境の準備#
標準のk8s環境であればどれでも大丈夫ですが、今回自分はk3sを使います。
1
2
  | 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みたいのを入れればインストールするバージョンを指定できますが、省略する場合は最新のバージョンになります。
1
2
3
  | 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を省略したら最新のバージョンがインストールされます。
1
2
3
4
  | 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と同じライセンスファイルのパスをセットします。
1
2
  | kumactl install control-plane \
    --license-path=/home/ubuntu/license | kubectl apply -f -
  | 
デプロイが終わると、kong-mesh-control-plane-xxxxxのPodがRunning状態になり、defaultのmeshesがデプロイされています。
1
2
3
4
5
6
7
  | 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します。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
  | 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へのアクセス#
上記で公開したサービスにアクセスすると、以下のような内容が出力されます。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
  |   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の情報を追加します。
1
2
3
4
5
  | 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の設定状況を確認できる。
1
2
3
  | 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のサービスはカウンターを保存する簡単なアプリです。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
  | 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ファイルを使ってデモ用リソースを追加します。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
  | 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)を確認することができます。
1
2
3
4
5
  | 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#
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
  | 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#
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
  | 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にアクセスすることができます。
1
2
3
4
5
6
  | 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が無効になっています。
1
2
3
  | kumactl get meshes
NAME      mTLS   METRICS   LOGGING   TRACING   LOCALITY   ZONEEGRESS   AGE
default   off    off       off       off       off        off          9h
  | 
Kong Mesh内部にbuilt-inのCAがあるため、以下で簡単に有効することができます。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
  | # 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内の全てのトラフィックが正常のままになっています。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
  | 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への許可を設定します。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
  | 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への許可を設定します。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
  | 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を使用してセキュアで効率的なサービスメッシュを構築し、ポリシーを活用してトラフィックを管理する方法を学びます。