AmbientとKubernetes NetworkPolicy
KubernetesのNetworkPolicyを使用すると、レイヤー4トラフィックがPodに到達する方法を制御できます。
NetworkPolicy
は通常、クラスターにインストールされた CNI によって適用されます。Istio は CNI ではなく、NetworkPolicy
を適用または管理しません。また、すべての場合において尊重します。アンビエントは Kubernetes NetworkPolicy
の適用をバイパスすることはありませんし、今後もありません。
このことの含意として、Istio トラフィックをブロックしたり、Istio の機能を妨げたりする Kubernetes NetworkPolicy
を作成できる可能性があります。そのため、NetworkPolicy
とアンビエントを一緒に使用する場合は、いくつかの注意点があります。
AmbientトラフィックオーバーレイとKubernetes NetworkPolicy
アプリケーションをアンビエントメッシュに追加すると、アンビエントのセキュアな L4 オーバーレイは、ポート 15008 経由でポッド間のトラフィックをトンネリングします。セキュリティ保護されたトラフィックが宛先ポート 15008 でターゲットポッドに入ると、トラフィックは元の宛先ポートにプロキシバックされます。
ただし、NetworkPolicy
はポッドの外側のホストで適用されます。つまり、たとえば、アンビエントポッドへのインバウンドトラフィックをすべてのポート(443 を除く)で拒否する既存の NetworkPolicy
がある場合は、ポート 15008 の例外をその NetworkPolicy
に追加する必要があります。
たとえば、次の NetworkPolicy
は、ポート 15008 の my-app
へのインバウンド HBONE トラフィックをブロックします
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
spec:
ingress:
- ports:
- port: 9090
protocol: TCP
podSelector:
matchLabels:
app.kubernetes.io/name: my-app
そして、次のように変更する必要があります
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
spec:
ingress:
- ports:
- port: 8080
protocol: TCP
- port: 15008
protocol: TCP
podSelector:
matchLabels:
app.kubernetes.io/name: my-app
my-app
がアンビエントメッシュに追加された場合。
Ambient、ヘルスプローブ、およびKubernetes NetworkPolicy
Kubernetes ヘルスチェックプローブは問題を引き起こし、Kubernetes トラフィックポリシー全般で特殊なケースを作成します。これらは、クラスター内の別のポッドからではなく、ノード上でプロセスとして実行されている kubelet から発信されます。それらはプレーンテキストであり、セキュリティ保護されていません。kubelet または Kubernetes ノードのどちらも、通常、独自の暗号化 ID を持っていないため、アクセス制御は不可能です。ヘルスプローブポートですべてのトラフィックを許可するだけでは不十分です。悪意のあるトラフィックも kubelet と同じようにそのポートを簡単に使用できるからです。さらに、多くのアプリがヘルスプローブと正当なアプリケーショントラフィックに同じポートを使用するため、単純なポートベースの許可は受け入れられません。
さまざまな CNI 実装は、さまざまな方法でこれを解決し、kubelet ヘルスプローブを通常のポリシー適用から静かに除外するか、それらのポリシー例外を構成することで、問題を回避しようとしています。
Istio アンビエントでは、この問題は、iptables ルールとソースネットワークアドレス変換(SNAT)の組み合わせを使用して、ローカルノードから確実に発信されたパケットのみを固定のリンクローカル IP で書き換えることで解決されます。これにより、セキュリティ保護されていないヘルスプローブトラフィックとして Istio ポリシーの適用によって明示的に無視できます。リンクローカル IP は、通常、イングレス-エグレスコントロールでは無視され、IETF 標準ではローカルサブネットワークの外部ではルーティングできないため、デフォルトとして選択されました。
この動作は、ポッドをアンビエントメッシュに追加すると透過的に有効になり、デフォルトでは、アンビエントはリンクローカルアドレス 169.254.7.127
を使用して、kubelet ヘルスプローブパケットを識別し、正しく許可します。
ただし、ワークロード、名前空間、またはクラスターに既存のイングレスまたはエグレス NetworkPolicy
がある場合、使用している CNI によっては、このリンクローカルアドレスを持つパケットが明示的な NetworkPolicy
によってブロックされる可能性があり、ポッドをアンビエントメッシュに追加すると、アプリケーションポッドのヘルスプローブが失敗し始める可能性があります。
たとえば、名前空間に次の NetworkPolicy
を適用すると、my-app
ポッドへのすべてのトラフィック(Istio かどうかに関係なく)がブロックされます。kubelet ヘルスプローブも含まれます。CNI によっては、kubelet プローブとリンクローカルアドレスがこのポリシーによって無視されたり、ブロックされたりする可能性があります。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-ingress
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: my-app
policyTypes:
- Ingress
ポッドがアンビエントメッシュに登録されると、ヘルスプローブパケットは SNAT を介してリンクローカルアドレスが割り当てられるようになるため、ヘルスプローブが CNI の NetworkPolicy
実装によってブロックされ始める可能性があります。アンビエントヘルスプローブが NetworkPolicy
をバイパスできるようにするには、ホストノードからのトラフィックをポッドに許可することで、このトラフィックにアンビエントが使用するリンクローカルアドレスを許可リストに明示的に追加します。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-ingress-allow-kubelet-healthprobes
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: my-app
ingress:
- from:
- ipBlock:
cidr: 169.254.7.127/32