GKE(K8s)上のPodからオンプレミスサーバへ通信を行う(IPマスカレードエージェントの構成)
投稿者:常田
オンプレミスとGKEを接続した際に通信がうまく行うことが出来ずにハマったため記載します。
症状
通常GKEのPodネットワークは外部との通信を行うことが出来ません
ネットワーク環境
- VPCはカスタムで作成
- オンプレミス側とはInternetVPNで接続
- ルーティング情報は、ルートベース(BGPではない)での定義(またこの際にPodのアドレスは定義していない)
GKE環境
- GKE 1.17.12-gke.1504
- Podからオンプレミス上のサーバ 192.168.1.10 へアクセスを実施したい(あくまでもPod→オンプレミスの通信方向であることに注意)
- 今回の構成はIdentity Aware ProxyのDeploymentで構成された環境で実施
解決方法
解決手段はいくつかあるようですが今回はシンプルな「IPマスカレードエージェント」を利用した方式で行います。
「IPマスカレードエージェント」は異なるネットワーク上の相手とPodを通信させるための手段の一つです。設定を行うと、Podの実行元である管理ノードのIPを利用してマスカレードされた通信を行い異なるネットワーク上(ここではオンプレミス側)と通信を行います。この設定の良いところは、GKE内部のPodのアドレスをオンプレミス側に伝搬させる必要が無い点です。
このIPマスカレードエージェントですが、GKEのバージョンと環境によっては自動で構成されるとあります(https://cloud.google.com/kubernetes-engine/docs/how-to/ip-masquerade-agent#how_ipmasq_works )
今回の環境では条件に当てはまっている気がするのですが対象外のようで構成されていませんでしたので手動で構成を行います。
実施方法自体はGEKのドキュメントとおりとなり特に変更は行っていません。
以下のファイルを ip-masq-agent.yaml
として作成します。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ip-masq-agent
namespace: kube-system
spec:
selector:
matchLabels:
k8s-app: ip-masq-agent
template:
metadata:
labels:
k8s-app: ip-masq-agent
spec:
hostNetwork: true
containers:
- name: ip-masq-agent
image: gcr.io/google-containers/ip-masq-agent-amd64:v2.4.1
args:
- --masq-chain=IP-MASQ
# To non-masquerade reserved IP ranges by default, uncomment the line below.
# - --nomasq-all-reserved-ranges
securityContext:
privileged: true
volumeMounts:
- name: config
mountPath: /etc/config
volumes:
- name: config
configMap:
# Note this ConfigMap must be created in the same namespace as the
# daemon pods - this spec uses kube-system
name: ip-masq-agent
optional: true
items:
# The daemon looks for its config in a YAML file at /etc/config/ip-masq-agent
- key: config
path: ip-masq-agent
tolerations:
- effect: NoSchedule
operator: Exists
- effect: NoExecute
operator: Exists
- key: "CriticalAddonsOnly"
operator: "Exists"
以下のコマンドを実行します
kubectl apply -f ip-masq-agent.yaml
仮にクラスタ内部との通信とVPC内の通信にはマスカレードを行いたくないばあいには以下のConfigMapを作成します。ファイルは config
という名前で作成します。
nonMasqueradeCIDRs:
- 10.0.0.0/14 # my-gke-cluster CIDR
- 192.168.250.0/24 # my-project CIDR
resyncInterval: 60s
この設定を以下のコマンドで反映させます。
kubectl create configmap ip-masq-agent --from-file config --namespace kube-system
上記の設定で、Podからオンプレミス側に通信ができることを確認できました。別記事にある、CloudDNSの転送 ( https://www.niandc.co.jp/sol/tech/date20201102_1924.php ) を実施することでPod内部からオンプレミスのDNSにて名前を解決して通信を行うことも出来ます。