[k8s] Cilium: Egress Gateway (with kube-vip)

[์›๋ณธ ๋งํฌ]

Egress Gateway๋Š” cilium์˜ ์ฃผ์š” ํ™•์žฅ ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜๋‹ค.
Egress, ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ์•„์›ƒ๋ฐ”์šด๋“œ ํŠธ๋ž˜ํ”ฝ์„ ์–ด๋–ค IP๋กœ ๋‚˜๊ฐ€๊ฒŒ ํ• ์ง€ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.




๊ธฐ๋ณธ ์›๋ฆฌ

๊ธฐ๋ณธ์ ์ธ ๋…ผ๋ฆฌ๋Š” ๊ทธ๋‹ค์ง€ ๋ณต์žกํ•  ๊ฒƒ์€ ์—†๋‹ค.

๊ฒŒ์ดํŠธ์›จ์ด ๋…ธ๋“œ๋ฅผ ํ•˜๋‚˜ ์žก์•„๋†“์œผ๋ฉด, ๊ทธ๋†ˆ์„ ํ†ตํ•ด ํŠธ๋ž˜ํ”ฝ์„ ๊ฒฝ์œ ํ•ด์„œ ๋‚˜๊ฐ€๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

๊ตฌ์„ฑํ•˜๊ธฐ์— ๋”ฐ๋ผ์„œ ๋‹ค์–‘ํ•œ ํ๋ฆ„์œผ๋กœ ์ „๊ฐœ๋ฅผ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ผ๋‹จ ๊ธฐ๋ณธ ๋…ผ๋ฆฌ๋Š” ํ•œ๋†ˆ์ด ๊ฐ–๊ณ  ์žˆ๋Š” IP๋กœ SNAT์„ ๋•Œ๋ฆฌ๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น IP๋ฅผ ํŠน์ • WAN์— ๋ฌผ๋ ค์„œ ๋‚ด๋ณด๋‚ด๋ฉด ๋œ๋‹ค.

๊ทธ๋ž˜์„œ ๊ธฐ๋ณธ ๊ตฌ์กฐ์—์„œ๋Š” ์ด๊ฒŒ ๋‹ค์šดํƒ€์ž„์ด ํ•ญ์ƒ ์ƒ๊ธธ ์ˆ˜๋ฐ–์— ์—†๊ธฐ๋„ ํ•˜๋‹ค. ์ผ๋‹จ์€ ํ•˜๋‚˜์˜ ๋…ธ๋“œ๊ฐ€ IP๋ฅผ ๋ฌผ๊ณ  ๋Œ€ํ–‰์„ ํ•ด์ค˜์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋ถ€ํ•˜์˜ ๋ฌธ์ œ๋„ ์žˆ๊ณ , ํ•ด๋‹น ๋…ธ๋“œ๊ฐ€ ์ฃฝ์—ˆ์„ ๋•Œ๋„ ๋‹ค์šดํƒ€์ž„์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

cilium egress์—๋„ ๊ณ ๊ฐ€์šฉ์„ฑ ์˜ต์…˜์ด ์žˆ๊ธด ํ•œ๋ฐ, ์ด๊ฑด cilium ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ์—์„œ๋งŒ ์ œ๊ณต๋˜๋Š” ๊ธฐ๋Šฅ์ด๊ณ , ์ง์ ‘ ๊ตฌ์„ฑํ•˜๋ ค๋ฉด ์†์„ ์ข€ ์จ์•ผํ•œ๋‹ค.




์‚ฌ์ „ ์กฐ๊ฑด

์ด๊ฑธ ์‚ฌ์šฉํ•˜๋ ค๋ฉด cilium์„ ์„ค์น˜ํ•  ๋•Œ ํŠน์ • ์˜ต์…˜์„ ์ผœ์ค˜์•ผ ํ•œ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์ด ์•„๋‹ˆ๋‹ค.
cilium CLI๋ฅผ ํ†ตํ•ด ์„ค์น˜ํ•  ๊ฒฝ์šฐ ๊ธฐ๋ณธ๊ฐ’์— ์ด๊ฒŒ ํฌํ•จ๋˜์–ด์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ƒฅ ๊น”์•˜๋‹ค๊ฐ„ ๋†“์น  ์ˆ˜ ์žˆ๋‹ค.

helm์„ ํ†ตํ•ด ์„ค์น˜ํ•  ๊ฒฝ์šฐ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์˜ต์…˜์„ ๋„ฃ์–ด์„œ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

# Egress Gateway ์ „์ œ์กฐ๊ฑด. BPF ๋กœ Service โ†’ Backend ๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑ ์ˆ˜ํ–‰.
kubeProxyReplacement: true

egressGateway:
  enabled: true

์ด๊ฑฐ 2๊ฐ€์ง€๊ฐ€ ํ•ต์‹ฌ์ด๋‹ค.
์ด 2๊ฐ€์ง€ ๊ฐ’์€ ๋‹ค์šดํƒ€์ž„์ด ์ˆ˜๋ฐ˜๋˜๋Š” ๋ณ€๊ฒฝ์ด๋ผ์„œ, ๊ฐ€๊ธ‰์ ์ด๋ฉด ์ฒ˜์Œ๋ถ€ํ„ฐ ๋„ฃ์–ด์ฃผ๋Š”๊ฒŒ ์ข‹๋‹ค.




Egress Gateway ์‚ฌ์šฉํ•ด๋ณด๊ธฐ

์ผ๋‹จ ์ด๋Ÿฐ์ €๋Ÿฐ ๋ถ€๊ฐ€ ์˜ต์…˜ ๋นผ๊ณ  ๊ทธ๋ƒฅ ๋„์›Œ์„œ ์“ฐ๋Š”๊ฒŒ ๋ชฉ์ ์ด๋ผ๋ฉด, ์„ธํŒ…์€ ๋งค์šฐ ๊ฐ„๋‹จํ•˜๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์ฑ…๋งŒ ํ•˜๋‚˜ ์ •์˜ํ•ด์ฃผ๋ฉด ๋์ธ ๊ฒƒ์ด๋‹ค.

apiVersion: cilium.io/v2
kind: CiliumEgressGatewayPolicy
metadata:
  name: egress-wan4
spec:
  selectors:
    - podSelector:
        matchLabels:
          egress.myyrakle.io/profile: wan4

  destinationCIDRs:
    - 0.0.0.0/0
  excludedCIDRs:
    - 10.42.0.0/16
    - 10.43.0.0/16
    - 192.168.88.0/24

  egressGateway:
    nodeSelector:
      matchLabels:
        egress.myyrakle.io/pool: default
    egressIP: 192.168.88.222

์ด ์ •์˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง„๋‹ค.

  1. "egress.myyrakle.io/profile: wan4"๊ฐ€ ๋ถ™์–ด์žˆ๋Š” pod์— ๋Œ€ํ•ด์„œ ์ ์šฉํ•œ๋‹ค.
  2. "egress.myyrakle.io/pool: default"๊ฐ€ ๋ถ™์–ด์žˆ๋Š” node๋ฅผ gateway ๋…ธ๋“œ๋กœ ์„ ํƒํ•œ๋‹ค.
  3. ๋‚ด๋ณด๋‚ด๋Š” ์ตœ์ข… IP๋Š” 192.168.88.222๋‹ค. (SNAT)

๊ทธ๋ฆฌ๊ณ  pod๋ฅผ ์ •์˜ํ• ๋•Œ ์œ„ ์กฐ๊ฑด์— ๋งž์ถฐ์„œ ๋ผ๋ฒจ๋งŒ ๋‹ฌ์•„์ฃผ๋ฉด ๋œ๋‹ค.

spec:
  ...
  template:
    metadata:
      labels:
        ...
        egress.myyrakle.io/profile: wan4

๊ทธ๋ฆฌ๊ณ  ํ…Œ์ŠคํŠธํ•ด๋ณผ๋•Œ๋Š” ์ด๋Ÿฐ ์‹์œผ๋กœ ํ•˜๋ฉด ๋œ๋‹ค.

kubectl run egress-test-wan4 --image=alpine:3.20 \
--labels=egress.myyrakle.io/profile=wan4 --restart=Never \
--command -- sh -c 'sleep 5; for i in 1 2 3; do wget -qO- -T 8 http://ifconfig.me/ip; echo " rc=$?"; done'

kubectl logs egress-test-wan4

๊ทธ๋Ÿผ ์„ค์ •ํ•œ๋Œ€๋กœ wan4์— ๋ถ™์–ด์žˆ๋Š” ๊ณต์ธ IP๋กœ ๋‚˜๊ฐ„ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.




kube-vip์™€ ๊ณ ๊ฐ€์šฉ์„ฑ

๊ทผ๋ฐ ์œ„ ๋ฐฉ์‹์—๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค.
๋…ธ๋“œ๊ฐ€ ํ˜ผ์ž ๋ชธ๋นตํ•˜๋Š” ๊ฒƒ๋„ ๋ฌธ์ œ๋ผ๋ฉด ๋ฌธ์ œ์ธ๋ฐ, ์ผ๋‹จ ๊ฒŒ์ดํŠธ์›จ์ด ์—ญํ• ์„ ๋งก์€ ๋…ธ๋“œ๊ฐ€ ๋ป—์œผ๋ฉด ์ „์ฒด ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ด๋Ÿด๋•Œ ํ™œ์šฉํ•˜๊ธฐ ์ข‹์€ ๊ฒƒ์ด kube-vip๋‹ค.
https://blog.naver.com/sssang97/224428580085
์ด๊ฑธ ์‚ฌ์šฉํ•˜๋ฉด ๋‚ด๋ณด๋‚ผ IP ์ž์ฒด๋ฅผ ํŠน์ • ๋…ธ๋“œ์— ์ข…์†์‹œํ‚ค๊ธฐ ์•Š๊ณ , ๋‹ค๋ฅธ ๋…ธ๋“œ์— ์ธ๊ณ„ํ•ด์„œ ์žฅ์• ๊ฐ€ ์ž๋™์œผ๋กœ ํšŒ๋ณต๋˜๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

ํ•˜๋‚˜์˜ ๋…ธ๋“œ์— ๋ถ€ํ•˜๊ฐ€ ๊ณผ์ค‘๋˜๋Š”๊ฑด ๊ทธ๋ƒฅ IP ์ž์ฒด๋ฅผ ๋ถ„์‚ฐํ•ด๋†“๊ณ  ๋™์ผ WAN์— ๋ผ์šฐํŒ…ํ•˜๋ฉด ๋˜๋Š” ๊ฒƒ์ด๊ณ , ๊ฐ€์šฉ์„ฑ์„ ์ฑ™๊ธฐ๋Š”๊ฑด ์ด vip๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ๊ดœ์ฐฎ๋‹ค.

์—ฌ๊ธฐ์„œ๋Š” kube-vip๋ฅผ ํ™œ์šฉํ•ด์„œ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹ค๋ค„๋ณธ๋‹ค.

๋‚ด ๊ฒฝ์šฐ์—๋Š” wan์ด 8๊ฐœ๊ฐ€ ๋„˜๋Š”๋ฐ, ์ด๊ฑธ ๋‹ค ์—ฐ๋™ํ•ด์•ผํ•ด์„œ ๊ตฌ์„ฑ์ด ์กฐ๊ธˆ ๋ณต์žกํ•˜๋‹ค.

๊ทธ๋ฆฌ๊ณ  vip๋ฅผ ์“ฐ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€์ƒ ip๋กœ ์‚ฌ์šฉํ•  ip ๋ชฉ๋ก์„ ๋ฏธ๋ฆฌ ์ •ํ•ด๋†“๊ณ  DHCP ๋ฒ”์œ„์—์„œ ๋นผ๋†“๋Š” ํŽธ์ด ์ข‹๋‹ค.
๋‚ด ๊ฒฝ์šฐ์—๋Š” 192.168.88.200~๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.




๊ฒŒ์ดํŠธ์›จ์ด์šฉ ๋ผ๋ฒจ ๋ถ™์ด๊ธฐ

์ž, ์ผ๋‹จ Egress Gateway๋กœ ์‚ฌ์šฉํ•  ํ›„๋ณด๊ตฐ์„ ๋ผ๋ฒจ๋กœ ์ „๋ถ€ ๋ถ™์—ฌ์ค€๋‹ค.

kubectl label node ๋…ธ๋“œ๋ช… egress.myyrakle.io/pool=default --overwrite
kubectl get nodes -L egress.myyrakle.io/pool

์ ์œผ๋ฉด ์–ด์ฉ” ์ˆ˜ ์—†๊ณ , 2๊ฐœ ์ด์ƒ์œผ๋กœ ํ•ด๋†“์œผ๋ฉด ์ž๋™์œผ๋กœ ํšŒ๋ณต๋˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.




kube-vip ๋ฐ๋ชฌ์…‹ ๋งŒ๋“ค๊ธฐ

๊ทธ๋ฆฌ๊ณ  kube-vip์šฉ ๊ธฐ๋ณธ ๋ฐ๋ชฌ์…‹์„ ํ•˜๋‚˜ ์ •์˜ํ•ด์ค€๋‹ค.
์ด๊ฑด ์•„๊นŒ ๋ผ๋ฒจ์„ ๋ถ™์ธ ๋…ธ๋“œ์—๋งŒ ์‹คํ–‰๋˜๋ฉฐ, ํ•ต์‹ฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค. wan์„ ์—ฌ๋Ÿฌ๊ฐœ ๋ถ™์ด๋”๋ผ๋„ ์ด๊ฑด ํ•œ๋ฒˆ๋งŒ ๋งŒ๋“ค์–ด๋„ ๋œ๋‹ค.

# kube-vip egress VIP (services mode) โ€” WAN ํ•˜๋‚˜๋‹น LoadBalancer Service ํ•˜๋‚˜ (04-vips/)
apiVersion: v1
kind: Namespace
metadata:
  name: kube-vip-egress
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-vip-egress-svc
  namespace: kube-system
  labels:
    app.kubernetes.io/name: kube-vip-egress
    app.kubernetes.io/instance: svc
spec:
  selector:
    matchLabels:
      name: kube-vip-egress-svc
  template:
    metadata:
      labels:
        name: kube-vip-egress-svc
        app.kubernetes.io/name: kube-vip-egress
        app.kubernetes.io/instance: svc
    spec:
      hostNetwork: true
      serviceAccountName: kube-vip
      nodeSelector:
        egress.myyrakle.io/pool: default
      tolerations:
        - operator: Exists
          effect: NoSchedule
      containers:
        - name: kube-vip
          image: ghcr.io/kube-vip/kube-vip:v1.2.4
          args: [manager]
          env:
            # Node name ์€ ๋ฐ˜๋“œ์‹œ downwardAPI ๋กœ ๋„˜๊ฒจ์•ผ kube-vip ๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ k8s ๋…ธ๋“œ์— label ํŒจ์น˜ ๊ฐ€๋Šฅ
            - name: NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            - name: vip_nodename
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            - { name: vip_arp,              value: "true" }
            - { name: vip_cidr,             value: "32" }
            - { name: cp_enable,            value: "false" }
            - { name: lb_enable,            value: "false" }
            - { name: svc_enable,           value: "true" }
            - { name: svc_election,         value: "true" }
            - { name: svc_namespace,        value: kube-vip-egress }
            - { name: lb_class_name,        value: myyrakle.io/egress-vip }
            - { name: lb_class_only,        value: "true" }
            - { name: lb_class_legacy_handling, value: "false" }
            - { name: vip_leaseduration,    value: "5" }
            - { name: vip_renewdeadline,    value: "3" }
            - { name: vip_retryperiod,      value: "1" }
            - { name: enable_node_labeling, value: "true" }
            # hostNetwork ๋ผ :2112 ๋Š” control-plane kube-vip ๊ฐ€ ์ด๋ฏธ ์ ์œ 
            - { name: prometheus_server,    value: ":2113" }
          securityContext:
            capabilities:
              add: [NET_ADMIN, NET_RAW]



kube-vip ์„œ๋น„์Šค ๋งŒ๋“ค๊ธฐ

์ด๊ฑด wan๋งˆ๋‹ค ํ•˜๋‚˜์”ฉ ๋งŒ๋“ค๋ฉด ๋œ๋‹ค.
wan4๋งŒ ๋จผ์ € ๋งŒ๋“ค์–ด๋ณด๊ฒ ๋‹ค.

apiVersion: v1
kind: Service
metadata:
  name: egress-wan4
  namespace: kube-vip-egress
  labels:
    app.kubernetes.io/name: kube-vip-egress
  annotations:
    kube-vip.io/loadbalancerIPs: "192.168.88.222"
    kube-vip.io/allow-reconcile-without-endpoints: "true"
spec:
  type: LoadBalancer
  loadBalancerClass: myyrakle.io/egress-vip
  externalTrafficPolicy: Cluster
  ports:
    - name: unused
      port: 65535
      protocol: TCP
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
  name: egress-wan4
  namespace: kube-vip-egress
  labels:
    kubernetes.io/service-name: egress-wan4
addressType: IPv4
endpoints: []

์ ๋‹นํžˆ ๋งŒ๋“ค์–ด์ฃผ๊ณ , ์—ฌ๊ธฐ๊นŒ์ง€ ๋์œผ๋ฉด ์ด์ œ ๋ผ์šฐํ„ฐ์— ๋“ค์–ด๊ฐ€์„œ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.




๋ผ์šฐํ„ฐ ์„ค์ • (microtik)

์ž. ์ด์ œ ํ•ด์•ผํ•  ๊ฒƒ์€ ์•„๊นŒ ๋งคํ•‘ํ•ด๋†“์€ vip๋ฅผ ํŠน์ • wan๋กœ ๋‚˜๊ฐ€๋„๋ก ์ตœ์ข… ๋งคํ•‘์„ ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.
์ด๊ฑด microtik์˜ ์˜ˆ์‹œ์ด๊ธด ํ•œ๋ฐ, ์–ด๋–ค ๋ผ์šฐํ„ฐ๋“  ๊ฑฐ์˜ ๋น„์Šทํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

# ๋ผ์šฐํŒ… ํ…Œ์ด๋ธ” ๋งŒ๋“ค๊ธฐ
/routing table add fib name=egress-wan4

# 192.168.88.222์—์„œ ์‹œ์ž‘๋œ ์—ฐ๊ฒฐ์— ๋งˆํ‚น
/ip firewall mangle add chain=prerouting src-address=192.168.88.222 action=mark-connection new-connection-mark=egress-wan4 passthrough=yes comment="egress VIP .222 to wan4 conn"
/ip firewall mangle add chain=prerouting src-address=192.168.88.222 connection-mark=egress-wan4 action=mark-routing new-routing-mark=egress-wan4 passthrough=no comment="egress wan4 routing-mark"

# egress-wan4 ๋ผ์šฐํŒ… ํ…Œ์ด๋ธ”์— ๊ฒฝ๋กœ ์ถ”๊ฐ€ => wan4๋กœ ๋‚˜๊ฐ€๋„๋ก
/ip route add dst-address=0.0.0.0/0 gateway=61.74.171.254%wan4 routing-table=egress-wan4 distance=1 comment="egress wan4 route"

# ์ตœ์ข… NAT ์ฒ˜๋ฆฌ
/ip firewall nat add chain=srcnat out-interface=wan4 action=masquerade comment="egress SNAT via wan4"

์˜ค๋ฅ˜ ์—†์ด ์ž˜ ๋˜๋ฉด ๋œ ๊ฒƒ์ด๋‹ค.




๊ฒŒ์ดํŠธ์›จ์ด ์ •์ฑ… ์ƒ์„ฑ

์ด์ œ ๋‹ค์‹œ ์ ์ ˆํžˆ ๋งž์ถฐ์„œ ๊ฒŒ์ดํŠธ์›จ์ด ์ •์ฑ…์„ ๋งŒ๋“ค์–ด์ฃผ๋ฉด ๋์ด๋‹ค.

apiVersion: cilium.io/v2
kind: CiliumEgressGatewayPolicy
metadata:
  name: egress-wan4
spec:
  selectors:
    - podSelector:
        matchLabels:
          egress.myyrakle.io/profile: wan4

  destinationCIDRs:
    - 0.0.0.0/0
  excludedCIDRs:
    - 10.42.0.0/16
    - 10.43.0.0/16
    - 192.168.88.0/24

  egressGateway:
    nodeSelector:
      matchLabels:
        egress.myyrakle.io/pool: default
        service-provided.kube-vip.io/egress-wan4.kube-vip-egress: "192.168.88.222"
    egressIP: 192.168.88.222

์ด๋Ÿฌ๋ฉด ์ € vip๋ฅผ ๋“ค๊ณ  ์žˆ๋Š” ๋†ˆ์„ ๊ฒŒ์ดํŠธ์›จ์ด๋กœ ์‚ผ์•„์„œ ๋™์ ์œผ๋กœ ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

์—ฌ๊ธฐ๊นŒ์ง€ ํ•˜๋ฉด ๋์ด๋‹ค. ํ•„์š”ํ•œ๋งŒํผ wan ์„ธํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , ๊ฒŒ์ดํŠธ์›จ์ด ๋…ธ๋“œ๋กœ ์„ ํƒ๋œ ๋…€์„์„ ํ„ฐ๋œจ๋ ค์„œ ๋ณต๊ตฌ๊ฐ€ ๋˜๋Š”์ง€ ํ™•์ธ๊นŒ์ง€ ํ•ด๋ณด๋ฉด ๋œ๋‹ค.




ํ•œ๊ณ„

์ด ๋ฐฉ์‹์—๋Š” ๋ช‡๊ฐ€์ง€ ํ•œ๊ณ„์ ๋“ค์ด ์กด์žฌํ•œ๋‹ค. ๋ช‡๊ฐ€์ง€๋Š” Cilium Egress์˜ ๊ทผ๋ณธ์ ์ธ ํ•œ๊ณ„์ ์ด๊ธฐ๋„ ํ•˜๋‹ค.



๋‹ค์šดํƒ€์ž„

๊ฒŒ์ดํŠธ์›จ์ด ๋…ธ๋“œ๊ฐ€ ์ฃฝ์œผ๋ฉด, vip๋ฅผ ํ†ตํ•ด์„œ ๊ณ„์Šน๋ฐ›๊ณ  ๋ณต๊ตฌ๋˜๊ธฐ๊นŒ์ง€ ๋ณดํ†ต ๋ช‡์ดˆ ์ •๋„์˜ ๋‹ค์šดํƒ€์ž„์ด ๋ฐœ์ƒํ•œ๋‹ค.
์ด๊ฑด ์™„์ „ํžˆ ์—†์• ๊ธฐ ์–ด๋ ต๋‹ค. ๋ณต๊ตฌ๋ฅผ ๋น ๋ฅด๊ฒŒ, ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ค„ ๋ฟ์ด๋‹ค.



๋…ธ๋“œ ๊ณผ๋ถ€ํ•˜

์ผ๋‹จ Egress Gateway Policy๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์ตœ์ข… ๊ฒŒ์ดํŠธ์›จ์ด ๋…ธ๋“œ๋Š” ํ•˜๋‚˜๋‹ค. ๊ทธ๋ž˜์„œ ๋ถ€ํ•˜๊ฐ€ ๊ณผ๋„ํ•˜๊ฒŒ ๋ชฐ๋ฆฌ๋Š” ๊ฒƒ ์ž์ฒด๋ฅผ ๊น”๋”ํ•˜๊ฒŒ ํ•ด๊ฒฐํ•˜์ง„ ์•Š๋Š”๋‹ค.

๊ฐ€์žฅ ๋‹จ์ˆœํ•œ ์™„ํ™” ๋ฐฉ๋ฒ•์€, ๊ฐ™์€ WAN์œผ๋กœ ๋ผ์šฐํŒ…๋˜๋Š” ๋‚ด๋ถ€ IP๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ๋งŒ๋“ค๊ณ , ๊ฐ๊ฐ ํ•˜๋‚˜์”ฉ Egress Gateway๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ง์ ‘ ๋ถ„์‚ฐ์„ ์‹œํ‚ค๋Š” ๊ฒƒ์ด๋‹ค.

์ด๋Ÿฐ ์‹์œผ๋กœ ๋ง์ด๋‹ค.

192.168.88.222 โ†’ gateway-1 โ†’ WAN4
192.168.88.223 โ†’ gateway-2 โ†’ WAN4
192.168.88.224 โ†’ gateway-3 โ†’ WAN4

๋Œ€์‹  ๊ด€๋ฆฌ๋‚˜ ์‚ฌ์šฉ์ด ์ข€ ๋ณต์žกํ•ด์ง„๋‹ค.



Egress ๋”œ๋ ˆ์ด

cilium egress ๋ผ์šฐํŒ… ์ž์ฒด์—๋„ ๋”œ๋ ˆ์ด๊ฐ€ ์žˆ๋‹ค. ์ด๊ฒŒ ์‚ฌ์‹ค Pod๊ฐ€ ๋œฐ๋•Œ ๋ฐ”๋กœ ๋ถ™๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ, ๋น„๋™๊ธฐ์ ์œผ๋กœ ๋‚˜์ค‘์— ๋ถ™๋Š”๋‹ค.

๊ทธ๋ž˜์„œ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹œ์ž‘๋˜๊ณ  ๋ช‡์ดˆ ์ •๋„๋Š” ์›๋ž˜์˜ IP๋กœ ๋‚˜๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฑธ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด ๊ทธ๋ƒฅ ์ปจํ…Œ์ด๋„ˆ์— ์‹œ์ž‘ ๋Œ€๊ธฐ์‹œ๊ฐ„์„ ๋„ฃ๊ฑฐ๋‚˜, ์›ํ•˜๋Š” IP๊ฐ€ ๋ถ™์„๋•Œ๊นŒ์ง€ ํ”„๋กœ๊ทธ๋žจ ์‹œ์ž‘์„ ์ง€์—ฐ์‹œํ‚ค๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ฐ•๊ฑฐ๋‚˜ ํ•ด์•ผํ•œ๋‹ค.




์ฐธ์กฐ
https://christianhuth.de/a-highly-available-egress-gateway-for-kubernetes-with-cilium-and-kube-vip/
https://tech.kakaopay.com/post/cilium-egress-gateway/
https://docs.cilium.io/en/stable/network/egress-gateway/egress-gateway/
https://cilium.io/use-cases/egress-gateway/
https://blog.naver.com/sssang97/224428580085
https://blog.naver.com/sssang97/224428274080
https://blog.naver.com/sssang97/224425032860

Search