前回の記事では、Dockerコンテナのネットワーク最適化とKubernetesとの連携について解説しました。今回は、コンテナネットワークのセキュリティを強化する方法と、マルチクラスタ環境でのネットワーク戦略について詳しく解説します。
1. コンテナネットワークセキュリティの基本
ゼロトラストモデルの適用
コンテナネットワークのセキュリティにおいて、「ゼロトラスト」の考え方が重要です。これは「内部ネットワークも信頼しない」という前提に基づいています。
ゼロトラストの主な原則:
- デフォルトで全ての通信を拒否
- 必要な通信のみを明示的に許可
- 常に認証と認可を実施
- トラフィックを継続的に監視
セキュリティの階層
コンテナネットワークセキュリティを階層的に考えることが重要です:
- インフラストラクチャ層: ホストOSとネットワークインフラのセキュリティ
- コンテナ層: コンテナランタイムとイメージのセキュリティ
- オーケストレーション層: Kubernetes等のオーケストレーションツールのセキュリティ
- アプリケーション層: コンテナ内アプリケーションのセキュリティ
2. Dockerコンテナのネットワークセキュリティ強化
ネットワーク分離
# 内部通信用の分離ネットワークを作成
docker network create --internal backend-network
# インターネットアクセスが不要なコンテナを接続
docker run --network backend-network -d mysql
--internal
フラグを使用すると、そのネットワークに接続されたコンテナはインターネットに接続できなくなります。
コンテナ間通信の制限
# ユーザー定義ブリッジネットワークを使用
docker network create app-network
# コンテナ実行時に接続したいコンテナのみと通信可能に
docker run --name web --network app-network -d nginx
docker run --name app --network app-network -d my-app
ユーザー定義のブリッジネットワークを使用することで、同じネットワーク上のコンテナ同士のみが通信可能になります。
ポート公開の最小化
必要なポートのみを公開し、不要なポート公開を避けましょう:
# 必要なポートのみ公開
docker run -p 443:443 -d nginx
# 特定のインターフェースのみに公開
docker run -p 127.0.0.1:3306:3306 -d mysql
127.0.0.1にバインドすることで、コンテナのポートはローカルホストからのみアクセス可能になります。
ケーパビリティの制限
コンテナに必要最小限のケーパビリティのみを付与します:
# 必要なケーパビリティのみを追加
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE -d nginx
# ネットワーク管理権限の削除
docker run --cap-drop NET_ADMIN --cap-drop NET_RAW -d alpine
特にNET_ADMIN
とNET_RAW
は、ネットワークスニッフィングや偽装に使用される可能性があるため、注意が必要です。
3. Kubernetesにおけるネットワークセキュリティ
NetworkPolicyによる通信制御
Kubernetesでは、NetworkPolicyリソースを使用してポッド間の通信を制限できます:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-netpolicy
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: backend
ports:
- protocol: TCP
port: 5432
この例では、role=db
ラベルを持つポッドは、role=backend
ラベルを持つポッドからの5432ポートへのトラフィックのみを受け入れます。
名前空間レベルの分離
名前空間ごとにネットワークポリシーを適用することで、環境を分離できます:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-from-other-namespaces
namespace: production
spec:
podSelector: {} # 名前空間内の全ポッドに適用
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: production # 同じ名前空間からのみ許可
この例では、production名前空間内のポッドは同じ名前空間からのトラフィックのみを受け入れます。
mTLS(相互TLS)による通信の暗号化
サービスメッシュ(例:Istio)を導入することで、サービス間通信を暗号化できます:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: istio-system
spec:
mtls:
mode: STRICT # クラスタ全体でmTLSを強制
Istioを使用すると、証明書の管理や更新も自動化されます。
セキュアなイングレス設定
外部からのアクセスをセキュアに管理します:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: secure-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
tls:
- hosts:
- secure.example.com
secretName: tls-secret
rules:
- host: secure.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
このIngressは、HTTPSリダイレクトを強制し、TLS証明書を使用してセキュアな接続を提供します。
4. マルチクラスタ環境のネットワーク戦略
マルチクラスタの利点とユースケース
マルチクラスタ環境を構築する主な理由:
- 高可用性の向上: 地理的に分散したクラスタでの冗長性
- リージョン分散: グローバルサービスのレイテンシ軽減
- テナント分離: クライアントごとに専用クラスタを提供
- 規制対応: 地域ごとのデータ主権要件への対応
- 段階的デプロイ: ブルー/グリーンデプロイなどの実現
マルチクラスタネットワーキングの課題
マルチクラスタ環境では以下の課題があります:
- IPアドレス空間の衝突
- クラスタ間のサービスディスカバリ
- トラフィックルーティングとロードバランシング
- セキュアなクラスタ間通信
- 統合監視と可観測性
マルチクラスタネットワーキングのアプローチ
1. フラットネットワーク
すべてのクラスタが同じネットワーク空間を共有:
# クラスタ作成時にPodCIDRを重複しないように設定
kind create cluster --name cluster1 --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
podSubnet: "10.1.0.0/16"
serviceSubnet: "10.101.0.0/16"
EOF
kind create cluster --name cluster2 --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
podSubnet: "10.2.0.0/16"
serviceSubnet: "10.102.0.0/16"
EOF
2. サービスメッシュを活用したマルチクラスタ接続
IstiioのMulti-Primary構成を例に:
# クラスタ1のIstio設定
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: istio-control-plane
spec:
profile: default
values:
global:
meshID: mesh1
multiCluster:
clusterName: cluster1
network: network1
複数のクラスタにIstioをインストールし、APIサーバー間の接続を確立することで、サービスメッシュを拡張できます。
3. マルチクラスタイングレス戦略
グローバルロードバランサーを使用する例:
# クラスタ1のサービス
apiVersion: v1
kind: Service
metadata:
name: frontend
annotations:
multicluster.kubernetes.io/service-name: frontend
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: frontend
type: LoadBalancer
同様のサービスを各クラスタにデプロイし、グローバルDNSで複数のロードバランサーIPを管理します。
5. マルチクラスタセキュリティの実装
クラスタ間通信の暗号化
クラスタ間の通信を保護するためのVPN設定例:
# Wireguardを使用したVPN設定
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: wireguard-vpn
namespace: kube-system
spec:
selector:
matchLabels:
app: wireguard-vpn
template:
metadata:
labels:
app: wireguard-vpn
spec:
hostNetwork: true
containers:
- name: wireguard
image: linuxserver/wireguard
securityContext:
privileged: true
volumeMounts:
- name: config
mountPath: /config
volumes:
- name: config
configMap:
name: wireguard-config
ゼロトラストアーキテクチャの実装
Istioを使用したサービス間認証の例:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: payment-service-policy
namespace: payment
spec:
selector:
matchLabels:
app: payment-service
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/order/sa/order-service"]
to:
- operation:
methods: ["POST"]
paths: ["/api/payments"]
この例では、特定のサービスアカウントからの特定のパスとメソッドへのリクエストのみを許可しています。
セキュリティポリシーの統合管理
Kyverno(ポリシーエンジン)を使用したマルチクラスタポリシー適用の例:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-network-policy
spec:
validationFailureAction: enforce
rules:
- name: require-network-policy-for-namespaces
match:
resources:
kinds:
- Namespace
validate:
message: "Namespaces must have a NetworkPolicy applied"
deny:
conditions:
- key: "{{ request.object.metadata.name }}"
operator: NotIn
value: ["kube-system", "kube-public", "istio-system"]
- key: "{{ checkForNetworkPolicy('{{ request.object.metadata.name }}') }}"
operator: Equals
value: false
この例では、特定の名前空間を除いたすべての名前空間にNetworkPolicyが適用されていることを強制しています。
6. マルチクラスタ環境での可観測性
分散トレーシング
OpenTelemetryを使用した分散トレーシングの設定例:
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: cluster-collector
spec:
mode: deployment
config: |
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
memory_limiter:
limit_mib: 1500
exporters:
otlp:
endpoint: jaeger-collector.observability:4317
tls:
insecure: true
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlp]
集中ログ管理
FluentdとElasticsearchを使用した例:
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-config
namespace: logging
data:
fluent.conf: |
<source>
@type kubernetes_metadata
tag kube.*
</source>
<match kube.**>
@type elasticsearch
host elasticsearch.logging
port 9200
logstash_format true
logstash_prefix k8s-${record['kubernetes']['namespace_name']}
<buffer>
@type file
path /var/log/fluentd-buffers/kubernetes.system.buffer
flush_mode interval
retry_type exponential_backoff
</buffer>
</match>
7. 実装例:セキュアなマルチリージョンeコマースプラットフォーム
最後に、これまで説明した概念を組み合わせた実装例を示します:
アーキテクチャ概要
- 3つのリージョンにKubernetesクラスタを配置(アジア、欧州、北米)
- リージョン間VPNでセキュアに接続
- Istioを使用したサービスメッシュ
- グローバルDNSとCDNでユーザートラフィックを最適化
ユーザーフローのセキュリティ実装
# ユーザー認証サービスのネットワークポリシー
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: auth-service-policy
namespace: auth
spec:
podSelector:
matchLabels:
app: auth-service
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: frontend
ports:
- protocol: TCP
port: 443
egress:
- to:
- namespaceSelector:
matchLabels:
name: database
ports:
- protocol: TCP
port: 5432
グローバルデータレプリケーション戦略
# データレプリケーションポリシー
apiVersion: replication.database/v1
kind: ReplicationPolicy
metadata:
name: user-data-replication
spec:
source:
cluster: asia-east
namespace: database
service: user-db
destinations:
- cluster: europe-west
namespace: database
service: user-db-replica
- cluster: us-east
namespace: database
service: user-db-replica
schedule: "*/15 * * * *" # 15分ごとのレプリケーション
dataProtection:
encryption: true
dataMasking:
fields: ["credit_card", "ssn"]
災害復旧とフェイルオーバー設定
# 自動フェイルオーバー設定
apiVersion: failover.k8s/v1
kind: FailoverPolicy
metadata:
name: global-failover
spec:
primaryCluster: asia-east
secondaryClusters:
- europe-west
- us-east
healthCheck:
endpoint: /healthz
interval: 30s
timeout: 10s
failureThreshold: 3
autoFailover: true
notifications:
slack:
channel: "#ops-alerts"
まとめ
コンテナネットワークのセキュリティ強化とマルチクラスタ環境の構築は、現代のクラウドネイティブアプリケーションにおいて重要な要素です。
主なポイント:
- ゼロトラストアプローチ: デフォルトですべての通信を拒否し、必要な通信のみを明示的に許可
- 多層防御: ネットワークレベル、コンテナレベル、アプリケーションレベルでセキュリティ対策を実装
- マルチクラスタ設計: 高可用性、地理的冗長性、規制対応などの目的に合わせた設計
- 一貫したポリシー管理: すべてのクラスタで統一されたポリシーを適用
- エンドツーエンド暗号化: クラスタ間およびサービス間の通信を暗号化
- 包括的な可観測性: 複数クラスタにまたがる分散トレーシングとロギング
適切に設計されたマルチクラスタ環境は、スケーラビリティ、回復力、セキュリティを向上させ、グローバルなサービス提供を可能にします。一方で、複雑性も増すため、自動化とポリシー管理が重要になります。
次回は、さらに一歩進んで、コンテナネットワークのサービスメッシュパターンとトラフィック管理戦略について解説します。
コメント