はじめに
Kubernetes リソースと外部との通信制限を実施するには Network Policy
と loadBalancerSourceRanges
を使用する方法がある
それぞれの方法で Web サーバ(nginx)へ 1クライアントからのみアクセス許可する設定を試したので記載する
Network 制限試験
-
試験環境 (構築内容)
- Kubernetes : v1.25.4
- Loadbalancer : MetalLB (BGP) v0.12.1
-
試験内容
- Nginx で Web サーバを立てて、Loadbalancer で IP を公開する
- 外部からの IP アクセスを
192.168.129.12
の試験サーバからのみアクセス可能にする - 試験方法は
Network Policy
とloadBalancerSourceRanges
の2パターンで実施する
---
kind: Namespace
apiVersion: v1
metadata:
name: test-restrict-external-ip
labels:
name: test-restrict-external-ip
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: test-restrict-external-ip
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.22.1
ports:
- name: http
containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: test-restrict-external-ip
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
loadBalancerIP: 192.168.131.1
Network Policy
Network Policy ではクラスタ内外のトラフィック制限が IP/Port, Ingress/Egress で可能
spec.ingress
でクライアントからの通信、spec.egress
でサーバ発の通信を許可する
ここではspec.ingress
でクライアントIP(192.168.129.12
)をingress.from.ipBlock
で許可する
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: test-restrict-external-ip
spec:
podSelector:
matchLabels:
app: nginx
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 192.168.129.12/32
- podSelector:
matchLabels:
app: nginx
ports:
- protocol: TCP
port: 80
上記 yaml を適用して制限する
kubectl apply -f test-nwpolicy.yaml
制限された状態でアクセスすると、下記の通り許可サーバからはアクセスできるが、許可サーバ外からはConnection timed out
となる
# 許可されたクライアントからのアクセス
[suzuyu@rocky01 ~]$ ip addr show | grep 192.168
inet 192.168.129.12/24 brd 192.168.129.255 scope global dynamic noprefixroute ens192
[suzuyu@rocky01 ~]$ curl 192.168.131.1
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[suzuyu@rocky01 ~]$
# 許可されてないクライアントからのアクセス
suzuyu@Xubuntu01:~$ ip addr show | grep 192.
inet 192.168.129.91/24 brd 192.168.129.255 scope global dynamic noprefixroute ens160
suzuyu@Xubuntu01:~$ curl 192.168.131.1
curl: (7) Failed to connect to 192.168.131.1 port 80: Connection timed out
suzuyu@Xubuntu01:~$
設定マニフェストを削除して切り戻す
kubectl delete -f test-nwpolicy.yaml
loadBalancerSourceRanges
spec.type.Loadbalancer
で送信元 IP 制限が実装可能
Network Policy と違い、実装によっては外部 Loadbalancer 側へ処理をオフロードできるのでレイテンシを気にする場合はこちらを利用する
spec.loadBalancerSourceRanges
で許可する IP レンジを設定する
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: test-restrict-external-ip
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
+ loadBalancerSourceRanges:
+ - 192.168.129.12/32
下記コマンドで追加設定も可能
kubectl patch -n test-restrict-external-ip service nginx -p '{"spec":{"loadBalancerSourceRanges":["192.168.129.12/32"]}}'
前回同様にアクセス試験を実施
# 許可されたクライアントからのアクセス
[suzuyu@rocky01 ~]$ ip addr show | grep 192.168
inet 192.168.129.12/24 brd 192.168.129.255 scope global dynamic noprefixroute ens192
[suzuyu@rocky01 ~]$ curl 192.168.131.1
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[suzuyu@rocky01 ~]$
# 許可されてないクライアントからのアクセス
suzuyu@Xubuntu01:~$ ip addr show | grep 192.
inet 192.168.129.91/24 brd 192.168.129.255 scope global dynamic noprefixroute ens160
suzuyu@Xubuntu01:~$ curl 192.168.131.1
curl: (7) Failed to connect to 192.168.131.1 port 80: Connection timed out
suzuyu@Xubuntu01:~$
下記で設定切り戻し可能
kubectl patch -n test-restrict-external-ip service nginx --type=json -p='[{"op": "remove", "path": "/spec/loadBalancerSourceRanges"}]'
まとめ
クラスタ外からのアクセス制御にNetwork Policy
とloadBalancerSourceRanges
での制御方法を試した
Network Policy
はクラスタ内やEgress
の通信制御にも使用可能なので別途深掘りが必要
参照