0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

istio入門

Posted at

はじめに

istioの挙動の確認をする。

実施環境について

  • Mac M3+Kindの環境にて実施
  • 手間をかけず動作確認したこともあり、ChatGPTを使って資材を用意

Let's Poc

セットアップ

環境構築スクリプト
#!/bin/bash

# --- Kindクラスタ作成用スクリプト ---
# 前提: Dockerインストール済み (Mac M3対応)
# 前提: istioctlインストール済み(https://istio.io/latest/docs/setup/getting-started/#download)
# Mac M3 (arm64) でも問題なく動作確認済み

# ✅ Mac環境向け補足 ✅
# - Docker Desktop (arm64版) 必須
# - NodePortアクセスは localhost から可能(例: http://localhost:18080)
# - Docker DesktopのResources→Networkでポート制限が無いか確認
# - istioctl はarm64バイナリあり

# クラスタ名
CLUSTER_NAME="istio-poc"

# Kindクラスタ構成ファイル作成
touch kind-config.yaml
cat <<EOF > kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
    extraPortMappings:
      - containerPort: 30080
        hostPort: 18080
        protocol: TCP
      - containerPort: 30443
        hostPort: 18443
        protocol: TCP
EOF

# クラスタ作成
kind create cluster --name $CLUSTER_NAME --config kind-config.yaml

# kubeconfig切り替え
echo "\n>>> 現在のコンテキスト:"
kubectl config current-context

# Istioインストール (demoプロファイル)
istioctl install --set profile=demo -y

# ✅ Ingress GatewayのServiceをNodePortに変更
kubectl patch svc istio-ingressgateway -n istio-system \
  -p '{"spec": {"type": "NodePort", "ports": [{"name": "http2","port": 80,"targetPort": 8080,"nodePort": 30080},{"name": "https","port": 443,"targetPort": 8443,"nodePort": 30443}]}}'
  
  # ✅ サンプルTLS証明書作成
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 \
  -subj "/CN=localhost" \
  -keyout tls.key -out tls.crt
kubectl create -n istio-system secret tls httpbin-credential --key=tls.key --cert=tls.crt

# labelで自動インジェクション有効化
target_namespace="default"
kubectl label namespace $target_namespace istio-injection=enabled --overwrite

# サンプルアプリデプロイ (httpbin + sleep)
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.26/samples/httpbin/httpbin.yaml

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.26/samples/sleep/sleep.yaml

# ✅ Istio Gateway + VirtualService を適用 (HTTP + HTTPS対応)
cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: httpbin-credential
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
  - "*"
  gateways:
  - httpbin-gateway
  http:
  - match:
    - uri:
        prefix: /ip
    route:
    - destination:
        host: httpbin
        port:
          number: 8000
EOF

# 動作確認コマンド例
echo "\n>>> curl from sleep to httpbin:\n"
kubectl exec deploy/sleep -c sleep -- curl -sS httpbin:8000/ip

# ✅ Mac環境: NodePortアクセス例 ✅
echo "\n>>> ブラウザやcurlでのアクセス例:"
echo "http://localhost:18080/ip"
echo "https://localhost:18443/ip (自己署名証明書のため警告あり)"

Pod経由で疎通確認。

kubectl exec deploy/sleep -c sleep -- curl -sS httpbin:8000/ip
{
  "origin": "127.0.0.6:37291"
}

NodePortアクセス例で疎通確認。

curl http://localhost:18080/ip                          
{
  "origin": "10.244.0.1"
}

# TLS
curl -k https://localhost:18443/ip 
{
  "origin": "10.244.0.1"
}

mTLS未対応Podのデプロイ(sleep-unmeshed)も検証のため作成しておく

kubectl create ns unmeshed
kubectl label ns unmeshed istio-injection=disabled
kubectl run sleep-unmeshed -n unmeshed --image=curlimages/curl -- sleep infinity

検証① - 承認ポリシー

PeerAuthenticationm(mTLS強制)

「メッシュ内部通信の暗号化」を制御するポリシーです。

  • PeerAuthentication (mTLS強制)を適用
cat <<EOF | kubectl apply -f -
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: default
spec:
  mtls:
    mode: STRICT
EOF
動作確認(詳細)
  • 外部 → Ingress Gateway (HTTP)
curl -v http://localhost:18080/ip

* Host localhost:18080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:18080...
* Connected to localhost (::1) port 18080
> GET /ip HTTP/1.1
> Host: localhost:18080
> User-Agent: curl/8.7.1
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 200 OK
< access-control-allow-credentials: true
< access-control-allow-origin: *
< content-type: application/json; charset=utf-8
< date: Sun, 20 Jul 2025 08:17:02 GMT
< content-length: 29
< x-envoy-upstream-service-time: 2
< server: istio-envoy
< 
{
  "origin": "10.244.0.1"
}

  • 外部 → Ingress Gateway (HTTPS)
curl -vk https://localhost:18443/ip
* Host localhost:18443 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:18443...
* Connected to localhost (::1) port 18443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=localhost
*  start date: Jul 20 07:32:58 2025 GMT
*  expire date: Jul 20 07:32:58 2026 GMT
*  issuer: CN=localhost
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://localhost:18443/ip
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: localhost:18443]
* [HTTP/2] [1] [:path: /ip]
* [HTTP/2] [1] [user-agent: curl/8.7.1]
* [HTTP/2] [1] [accept: */*]
> GET /ip HTTP/2
> Host: localhost:18443
> User-Agent: curl/8.7.1
> Accept: */*
> 
* Request completely sent off
< HTTP/2 200 
< access-control-allow-credentials: true
< access-control-allow-origin: *
< content-type: application/json; charset=utf-8
< date: Sun, 20 Jul 2025 08:16:13 GMT
< content-length: 29
< x-envoy-upstream-service-time: 1
< server: istio-envoy
< 
{
  "origin": "10.244.0.1"
}
* Connection #0 to host localhost left intact
  • メッシュ内部(sleep → httpbin)
kubectl exec deploy/sleep -c sleep -- curl -v httpbin:8000/ip
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Host httpbin:8000 was resolved.
* IPv6: (none)
* IPv4: 10.96.244.2
*   Trying 10.96.244.2:8000...
* Connected to httpbin (10.96.244.2) port 8000
* using HTTP/1.x
> GET /ip HTTP/1.1
> Host: httpbin:8000
> User-Agent: curl/8.15.0
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 200 OK
< access-control-allow-credentials: true
< access-control-allow-origin: *
< content-type: application/json; charset=utf-8
< date: Sun, 20 Jul 2025 08:07:04 GMT
< content-length: 34
< x-envoy-upstream-service-time: 0
< server: envoy
< 
{ [34 bytes data]
100    34  100    34    0     0  13583      0 --:--:-- --:--:-- --:--:-- 17000
* Connection #0 to host httpbin left intact
{
  "origin": "127.0.0.6:42037"
}

  • メッシュ内部(非mTLS Pod → httpbin)※サイドカー無しPodからはmTLS未対応で拒否
kubectl exec -n unmeshed sleep-unmeshed -- curl -v http://httpbin.default.svc.cluster.local:8000/ip
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Host httpbin.default.svc.cluster.local:8000 was resolved.
* IPv6: (none)
* IPv4: 10.96.244.2
*   Trying 10.96.244.2:8000...
* Connected to httpbin.default.svc.cluster.local (10.96.244.2) port 8000
* using HTTP/1.x
> GET /ip HTTP/1.1
> Host: httpbin.default.svc.cluster.local:8000
> User-Agent: curl/8.15.0
> Accept: */*
> 
* Recv failure: Connection reset by peer
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
* closing connection #0
curl: (56) Recv failure: Connection reset by peer
command terminated with exit code 56

動作まとめ:mTLS(STRICT)のみ適用時の挙動

通信経路 挙動 説明
外部 → Ingress Gateway (HTTP) 成功 外部(NodePort経由)からのHTTPアクセスはmTLS非対象。例: http://localhost:18080/ip
外部 → Ingress Gateway (HTTPS) 成功 HTTPS(TLS)は通常通り動作。自己署名証明書使用。例: https://localhost:18443/ip
メッシュ内部(sleep → httpbin) 成功 IstioサイドカーありPod間通信はmTLSで成功。例: kubectl exec sleep -- curl httpbin:8000/ip
非メッシュPod → httpbin 失敗 サイドカー無しPodからはmTLS未対応で拒否。例: curl (56) Recv failure: Connection reset by peer

補足
  • PeerAuthentication (mode: STRICT) は メッシュ内部通信 のみmTLSを強制します。
  • Ingress Gateway経由の通信は対象外。HTTP/HTTPSは通常通り通過。
  • 外部通信もブロックしたい場合は AuthorizationPolicy が必要です。

AuthorizationPolicy

Podレベルのアクセス制御 を行うためのポリシーです。
通信の「許可(ALLOW)」または「拒否(DENY)」をルールベースで定義できます。

  • AuthorizationPolicy(sleep Pod からの通信のみ許可)を適用
cat <<EOF | kubectl apply -f -
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: httpbin-allow-sleep
  namespace: default
spec:
  selector:
    matchLabels:
      app: httpbin
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/sleep"]
EOF
動作確認(詳細)
  • 外部 → Ingress Gateway (HTTP)
curl -v http://localhost:18080/ip
* Host localhost:18080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:18080...
* Connected to localhost (::1) port 18080
> GET /ip HTTP/1.1
> Host: localhost:18080
> User-Agent: curl/8.7.1
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 403 Forbidden
< content-length: 19
< content-type: text/plain
< date: Sun, 20 Jul 2025 08:29:32 GMT
< server: istio-envoy
< x-envoy-upstream-service-time: 9
< 
* Connection #0 to host localhost left intact
RBAC: access denied%                                
  • 外部 → Ingress Gateway (HTTPS)
curl -vk https://localhost:18443/ip
* Host localhost:18443 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:18443...
* Connected to localhost (::1) port 18443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=localhost
*  start date: Jul 20 07:32:58 2025 GMT
*  expire date: Jul 20 07:32:58 2026 GMT
*  issuer: CN=localhost
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://localhost:18443/ip
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: localhost:18443]
* [HTTP/2] [1] [:path: /ip]
* [HTTP/2] [1] [user-agent: curl/8.7.1]
* [HTTP/2] [1] [accept: */*]
> GET /ip HTTP/2
> Host: localhost:18443
> User-Agent: curl/8.7.1
> Accept: */*
> 
* Request completely sent off
< HTTP/2 403 
< content-length: 19
< content-type: text/plain
< date: Sun, 20 Jul 2025 08:29:58 GMT
< server: istio-envoy
< x-envoy-upstream-service-time: 1
< 
* Connection #0 to host localhost left intact
RBAC: access denied%                       
  • メッシュ内部(sleep → httpbin)
kubectl exec deploy/sleep -c sleep -- curl -vs httpbin:8000/ip

* Host httpbin:8000 was resolved.
* IPv6: (none)
* IPv4: 10.96.244.2
*   Trying 10.96.244.2:8000...
* Connected to httpbin (10.96.244.2) port 8000
* using HTTP/1.x
> GET /ip HTTP/1.1
> Host: httpbin:8000
> User-Agent: curl/8.15.0
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 200 OK
< access-control-allow-credentials: true
< access-control-allow-origin: *
< content-type: application/json; charset=utf-8
< date: Sun, 20 Jul 2025 08:30:33 GMT
< content-length: 34
< x-envoy-upstream-service-time: 0
< server: envoy
< 
{ [34 bytes data]
* Connection #0 to host httpbin left intact
{
  "origin": "127.0.0.6:45949"
}
  • 非メッシュPod(sleep-unmeshed)
kubectl exec -n unmeshed sleep-unmeshed -- curl -vs http://httpbin.default.svc.cluster.local:8000/ip
* Host httpbin.default.svc.cluster.local:8000 was resolved.
* IPv6: (none)
* IPv4: 10.96.244.2
*   Trying 10.96.244.2:8000...
* Connected to httpbin.default.svc.cluster.local (10.96.244.2) port 8000
* using HTTP/1.x
> GET /ip HTTP/1.1
> Host: httpbin.default.svc.cluster.local:8000
> User-Agent: curl/8.15.0
> Accept: */*
> 
* Request completely sent off
* Recv failure: Connection reset by peer
* closing connection #0
command terminated with exit code 56
  • メッシュ内部別Pod(例: sleep2)

sleep2 をデプロイ(同じ namespace)

kubectl run sleep2 --image=curlimages/curl -- sleep infinity

疎通確認

kubectl exec sleep2 -- curl -sv httpbin:8000/ip
* Host httpbin:8000 was resolved.
* IPv6: (none)
* IPv4: 10.96.244.2
*   Trying 10.96.244.2:8000...
* Connected to httpbin (10.96.244.2) port 8000
* using HTTP/1.x
> GET /ip HTTP/1.1
> Host: httpbin:8000
> User-Agent: curl/8.15.0
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 403 Forbidden
< content-length: 19
< content-type: text/plain
< date: Sun, 20 Jul 2025 08:32:06 GMT
< server: envoy
< x-envoy-upstream-service-time: 5
< 
{ [19 bytes data]
* Connection #0 to host httpbin left intact
RBAC: access denied%                          

動作まとめ:mTLS(STRICT)+ AuthorizationPolicy の挙動

通信経路 mTLSのみ (AuthorizationPolicyなし) mTLS + AuthorizationPolicyあり 説明
外部 → Ingress Gateway (HTTP) ✅ 成功 ❌ 拒否 AuthorizationPolicyが適用されると、外部アクセスも対象になるため拒否される
外部 → Ingress Gateway (HTTPS) ✅ 成功 ❌ 拒否 同上、HTTPSも拒否される
メッシュ内部(sleep → httpbin) ✅ 成功 ✅ 成功 sleep のServiceAccountは許可されるため成功
非メッシュPod(sleep-unmeshed) → httpbin ❌ 失敗 ❌ 失敗 mTLS強制により通信失敗(AuthorizationPolicy以前の段階で失敗)
メッシュ内部別Pod(例: sleep2) → httpbin ✅ 成功 ❌ 拒否 sleep 以外のPodは principals 不一致で拒否される

RequestAuthentication

RequestAuthentication は HTTPリクエストのJWTトークン検証 に使用します。
→ mTLS が「通信の暗号化」
→ RequestAuthentication は「HTTPリクエストの認証(JWT)」にフォーカスします。

[内部クライアント] ──> [Ingress Gateway] ──> [httpbin]
                    │
          +─────────┘
          │ mTLS (PeerAuthentication)
[外部] ──> [Ingress Gateway] ──> [httpbin]
                    │
          +─────────┘
          │ JWTトークン検証 (RequestAuthentication)

※検証をわかりやすくするために、AuthorizationPolicy(sleep Pod からの通信のみ許可)のポリシーは一度削除

  • RequestAuthentication マニフェスト例(JWT認証設定)
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: httpbin-jwt
  namespace: default
spec:
  selector:
    matchLabels:
      app: httpbin
  jwtRules:
  - issuer: "testing@secure.istio.io"
    jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.26/security/tools/jwt/samples/jwks.json"
  • AuthorizationPolicy
# Istioは mTLS と JWT の両方の認証情報を同時に使わないケースがある ため、以下動作をします:
# 	•	メッシュ内通信(mTLS)の場合:
# 	•	requestPrincipal は基本 空文字(””) になることが多い(特に Pod → Pod の時)
# 	•	JWTは通常 外部(Ingress Gateway)経由のみ評価対象
# ということで以下で分離
# Podからは principals 許可、外部は requestPrincipals 許可。例:ルールを2つに分ける。
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: httpbin-require-jwt
  namespace: default
spec:
  selector:
    matchLabels:
      app: httpbin
  action: ALLOW
  rules:
  - from:
    - source:
        principals:
        - cluster.local/ns/default/sa/sleep
  - from:
    - source:
        requestPrincipals:
        - "testing@secure.istio.io/testing@secure.istio.io"
  • これを適用すると、「PeerAuthentication+AuthorizationPolicyあり」の構成となる。
     メッシュ外からのトラフィック(Ingress Gateway経由)は mTLS無し なので、デフォルトで拒否 されます。
    つまり 外部からのHTTP(S)アクセスは、mTLSレイヤーでFail → AuthorizationPolicyの前で403(RBAC) が返る。
  • principalsの指定がない場合、mTLSが強制されていることが保証できないためか、sleep Pod経由であっても403応答となる。なので必須で指定する必要があった。
動作確認(詳細)
  • 準備
TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/release-1.26/security/tools/jwt/samples/demo.jwt -s)
echo $TOKEN

> eyJhbGciOiJSUzI1NiIsImtpZCI6IkRIRmJwb0lVcXJZOHQyenBBMnFYZkNtcjVWTzVaRXI0UnpIVV8tZW52dlEiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjQ2ODU5ODk3MDAsImZvbyI6ImJhciIsImlhdCI6MTUzMjM4OTcwMCwiaXNzIjoidGVzdGluZ0BzZWN1cmUuaXN0aW8uaW8iLCJzdWIiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5pbyJ9.CfNnxWP2tcnR9q0vxyxweaF3ovQYHYZl82hAUsn21bwQd9zP7c-LS9qd_vpdLG4Tn1A15NxfCjp5f7QNBUo-KC9PJqYpgGbaXhaGx7bEdFWjcwv3nZzvc7M__ZpaCERdwU7igUmJqYGBYQ51vr2njU9ZimyKkfDe3axcyiBZde7G6dabliUosJvvKOPcKIWPccCgefSj_GNfwIip3-SsFdlR7BtbVUcqR-yv-XOxJ3Uc1MI0tz3uMiiZcyPV7sNCU4KRnemRIMHVOfuvHsU60_GhGbiSFzgPTAa9WTltbnarTbxudb_YEOx12JiwYToeX0DCPb43W1tzIBxgm8NxUg
  • sleep Pod → JWT無し → 200 OK
kubectl exec deploy/sleep -c sleep -- curl -sv httpbin:8000/ip
* Host httpbin:8000 was resolved.
* IPv6: (none)
* IPv4: 10.96.244.2
*   Trying 10.96.244.2:8000...
* Connected to httpbin (10.96.244.2) port 8000
* using HTTP/1.x
> GET /ip HTTP/1.1
> Host: httpbin:8000
> User-Agent: curl/8.15.0
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 200 OK
< access-control-allow-credentials: true
< access-control-allow-origin: *
< content-type: application/json; charset=utf-8
< date: Sun, 20 Jul 2025 10:25:43 GMT
< content-length: 34
< x-envoy-upstream-service-time: 4
< server: envoy
< 
{ [34 bytes data]
* Connection #0 to host httpbin left intact
{
  "origin": "127.0.0.6:53881"
}
  • sleep Pod → JWTあり → 200 OK
kubectl exec deploy/sleep -c sleep -- curl -sv -H "Authorization: Bearer $TOKEN" httpbin:8000/ip
* Host httpbin:8000 was resolved.
* IPv6: (none)
* IPv4: 10.96.244.2
*   Trying 10.96.244.2:8000...
* Connected to httpbin (10.96.244.2) port 8000
* using HTTP/1.x
> GET /ip HTTP/1.1
> Host: httpbin:8000
> User-Agent: curl/8.15.0
> Accept: */*
> Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IkRIRmJwb0lVcXJZOHQyenBBMnFYZkNtcjVWTzVaRXI0UnpIVV8tZW52dlEiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjQ2ODU5ODk3MDAsImZvbyI6ImJhciIsImlhdCI6MTUzMjM4OTcwMCwiaXNzIjoidGVzdGluZ0BzZWN1cmUuaXN0aW8uaW8iLCJzdWIiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5pbyJ9.CfNnxWP2tcnR9q0vxyxweaF3ovQYHYZl82hAUsn21bwQd9zP7c-LS9qd_vpdLG4Tn1A15NxfCjp5f7QNBUo-KC9PJqYpgGbaXhaGx7bEdFWjcwv3nZzvc7M__ZpaCERdwU7igUmJqYGBYQ51vr2njU9ZimyKkfDe3axcyiBZde7G6dabliUosJvvKOPcKIWPccCgefSj_GNfwIip3-SsFdlR7BtbVUcqR-yv-XOxJ3Uc1MI0tz3uMiiZcyPV7sNCU4KRnemRIMHVOfuvHsU60_GhGbiSFzgPTAa9WTltbnarTbxudb_YEOx12JiwYToeX0DCPb43W1tzIBxgm8NxUg
> 
* Request completely sent off
< HTTP/1.1 200 OK
< access-control-allow-credentials: true
< access-control-allow-origin: *
< content-type: application/json; charset=utf-8
< date: Sun, 20 Jul 2025 10:26:20 GMT
< content-length: 34
< x-envoy-upstream-service-time: 0
< server: envoy
< 
{ [34 bytes data]
* Connection #0 to host httpbin left intact
{
  "origin": "127.0.0.6:38319"
}
  • sleep2 Pod → JWT無し → 403
kubectl exec sleep2 -- curl -sv httpbin:8000/ip 
* Host httpbin:8000 was resolved.
* IPv6: (none)
* IPv4: 10.96.244.2
*   Trying 10.96.244.2:8000...
* Connected to httpbin (10.96.244.2) port 8000
* using HTTP/1.x
> GET /ip HTTP/1.1
> Host: httpbin:8000
> User-Agent: curl/8.15.0
> Accept: */*
> 
* Request completely sent off
RBAC: access denied< HTTP/1.1 403 Forbidden
< content-length: 19
< content-type: text/plain
< date: Sun, 20 Jul 2025 10:27:41 GMT
< server: envoy
< x-envoy-upstream-service-time: 4
< 
{ [19 bytes data]
* Connection #0 to host httpbin left intact
  • sleep2 Pod → JWTあり → 403
kubectl exec sleep2 -- curl -sv -H "Authorization: Bearer $TOKEN" httpbin:8000/ip 
* Host httpbin:8000 was resolved.
* IPv6: (none)
* IPv4: 10.96.244.2
*   Trying 10.96.244.2:8000...
* Connected to httpbin (10.96.244.2) port 8000
* using HTTP/1.x
> GET /ip HTTP/1.1
> Host: httpbin:8000
> User-Agent: curl/8.15.0
> Accept: */*
> Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IkRIRmJwb0lVcXJZOHQyenBBMnFYZkNtcjVWTzVaRXI0UnpIVV8tZW52dlEiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjQ2ODU5ODk3MDAsImZvbyI6ImJhciIsImlhdCI6MTUzMjM4OTcwMCwiaXNzIjoidGVzdGluZ0BzZWN1cmUuaXN0aW8uaW8iLCJzdWIiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5pbyJ9.CfNnxWP2tcnR9q0vxyxweaF3ovQYHYZl82hAUsn21bwQd9zP7c-LS9qd_vpdLG4Tn1A15NxfCjp5f7QNBUo-KC9PJqYpgGbaXhaGx7bEdFWjcwv3nZzvc7M__ZpaCERdwU7igUmJqYGBYQ51vr2njU9ZimyKkfDe3axcyiBZde7G6dabliUosJvvKOPcKIWPccCgefSj_GNfwIip3-SsFdlR7BtbVUcqR-yv-XOxJ3Uc1MI0tz3uMiiZcyPV7sNCU4KRnemRIMHVOfuvHsU60_GhGbiSFzgPTAa9WTltbnarTbxudb_YEOx12JiwYToeX0DCPb43W1tzIBxgm8NxUg
> 
* Request completely sent off
RBAC: access denied< HTTP/1.1 403 Forbidden
< content-length: 19
< content-type: text/plain
< date: Sun, 20 Jul 2025 10:28:40 GMT
< server: envoy
< x-envoy-upstream-service-time: 1
< 
{ [19 bytes data]
* Connection #0 to host httpbin left intact
  • 外部 → JWT無し → 403
curl -v http://localhost:18080/ip
* Host localhost:18080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:18080...
* Connected to localhost (::1) port 18080
> GET /ip HTTP/1.1
> Host: localhost:18080
> User-Agent: curl/8.7.1
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 403 Forbidden
< content-length: 19
< content-type: text/plain
< date: Sun, 20 Jul 2025 10:29:08 GMT
< server: istio-envoy
< x-envoy-upstream-service-time: 9
< 
* Connection #0 to host localhost left intact
RBAC: access denied%                                 
  • 外部 → JWTあり → 200 OK
curl -v -H "Authorization: Bearer $TOKEN" http://localhost:18080/ip
* Host localhost:18080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:18080...
* Connected to localhost (::1) port 18080
> GET /ip HTTP/1.1
> Host: localhost:18080
> User-Agent: curl/8.7.1
> Accept: */*
> Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IkRIRmJwb0lVcXJZOHQyenBBMnFYZkNtcjVWTzVaRXI0UnpIVV8tZW52dlEiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjQ2ODU5ODk3MDAsImZvbyI6ImJhciIsImlhdCI6MTUzMjM4OTcwMCwiaXNzIjoidGVzdGluZ0BzZWN1cmUuaXN0aW8uaW8iLCJzdWIiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5pbyJ9.CfNnxWP2tcnR9q0vxyxweaF3ovQYHYZl82hAUsn21bwQd9zP7c-LS9qd_vpdLG4Tn1A15NxfCjp5f7QNBUo-KC9PJqYpgGbaXhaGx7bEdFWjcwv3nZzvc7M__ZpaCERdwU7igUmJqYGBYQ51vr2njU9ZimyKkfDe3axcyiBZde7G6dabliUosJvvKOPcKIWPccCgefSj_GNfwIip3-SsFdlR7BtbVUcqR-yv-XOxJ3Uc1MI0tz3uMiiZcyPV7sNCU4KRnemRIMHVOfuvHsU60_GhGbiSFzgPTAa9WTltbnarTbxudb_YEOx12JiwYToeX0DCPb43W1tzIBxgm8NxUg
> 
* Request completely sent off
< HTTP/1.1 200 OK
< access-control-allow-credentials: true
< access-control-allow-origin: *
< content-type: application/json; charset=utf-8
< date: Sun, 20 Jul 2025 11:21:05 GMT
< content-length: 29
< x-envoy-upstream-service-time: 6
< server: istio-envoy
< 
{
  "origin": "10.244.0.1"
}

✅ 通信パターン別の動作

通信元 JWTの有無 mTLS状況 結果 説明
sleep Pod ❌ 無し ✅ mTLS OK ✅ 200 OK ServiceAccount一致(principals許可)
sleep Pod ✅ あり ✅ mTLS OK ✅ 200 OK JWT無視、principals一致でOK
sleep2 Pod ❌ 無し ✅ mTLS OK ❌ 403 Forbidden principals不一致で拒否
sleep2 Pod ✅ あり ✅ mTLS OK ❌ 403 Forbidden principals不一致で拒否
外部 (Ingress Gateway) ❌ 無し ❌ mTLS無し ❌ 403 Forbidden JWT無し拒否
外部 (Ingress Gateway) ✅ あり ❌ mTLS無し ✅ 200 OK JWT検証成功し requestPrincipals 一致でOK
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?