Istio์—์„œ Zero-Trust Network๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ธธ ๐Ÿ” PeerAuthentication์œผ๋กœ Istio ์›Œํฌ๋กœ๋“œ์˜ ์ ‘๊ทผ๋งŒ ํ—ˆ์šฉํ•˜๊ธฐ, AuthorizationPolicy๋กœ ์š”์ฒญ์˜ ์ถœ๋ฐœ์ง€/๋„์ฐฉ์ง€/์†์„ฑ์„ ๊ธฐ์ค€์œผ๋กœ ์ ‘๊ทผ ์ œ์–ดํ•˜๊ธฐ, Sidecar๋กœ Envoy Sidecar ๊ตฌ์„ฑ ์ปค์Šคํ…€ ํ•˜๊ธฐ

13 minute read

๋ถ„์‚ฐ ์‹œ์Šคํ…œ ์œ„์—์„œ โ€œ์™„๋ฒฝํ•œโ€ ์„œ๋น„์Šค ๋ฉ”์‰ฌ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด์„œ Istio๋Š” โ€œ๋ณด์•ˆโ€ ๊ด€๋ จ๋œ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ๋“ค์„ ์ œ๊ณตํ•œ๋‹ค!!

PeerAuthentication

์š”๊ฑด istio ์›Œํฌ๋กœ๋“œ์— mTLS์˜ ํŠธ๋ž˜ํ”ฝ์˜ ์ ‘๊ทผ๋งŒ ํ—ˆ์šฉํ•  ๊ฒƒ์ธ์ง€(STRICT) ์•„๋‹ˆ๋ฉด mTLS๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š์€ ํŠธ๋ž˜ํ”ฝ ์ ‘๊ทผ๋„ ํ—ˆ์šฉํ•  ๊ฒƒ์ธ์ง€(PERMISSIVE) ๊ฒฐ์ •ํ•˜๋Š” ์ •์ฑ…์ด๋‹ค.

$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: only-mtls-allow
  namespace: default
spec:
  mtls:
    mode: STRICT
EOF

์ด๋ ‡๊ฒŒ ์„ค์ •ํ•  ๊ฒฝ์šฐ, default ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋กœ ํ–ฅํ•˜๋Š” ํŠธ๋ž˜ํ”ฝ์€ ๋ชจ๋‘ mTLS๋กœ ์•”ํ˜ธํ™” ๋˜์–ด์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ, mTLS ์•”ํ˜ธํ™”๊ฐ€ ๋˜์—ˆ๋‹ค๋Š” ๋ง์ด ๊ณง ๊ทธ ์›Œํฌ๋กœ๋“œ๊ฐ€ Istio ์„œ๋น„์Šค ๋ฉ”์‰ฌ ์œ„์— ์žˆ๋‹ค๋Š” ๋ง์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฐ๊ตญ Istio ์„œ๋น„์Šค ๋ฉ”์‰ฌ์˜ ์›Œํฌ๋กœ๋“œ์˜ ์ ‘๊ทผ๋งŒ ํ—ˆ์šฉํ•˜๊ฒ ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

$ kubectl exec ... -n non-istio -- sh
~# curl helloworld.default:5000/hello
curl: (56) Recv failure: Connection reset by peer

๋งŒ์•ฝ istio ์›Œํฌ๋กœ๋“œ๊ฐ€ ์•„๋‹Œ ๊ณณ์—์„œ ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค๋ฉด ์ด๋ ‡๊ฒŒ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

istio -> non-istio ๋ฐฉํ–ฅ์˜ ํŠธ๋ž˜ํ”ฝ ๋ง‰๊ธฐ

์œ„์˜ PeerAuthentication์€ non-istio โžก๏ธ istio ๋ฐฉํ–ฅ์˜ ์ ‘๊ทผ์„ ๋ง‰๋Š” ๋ฐฉ์‹์ด์—ˆ๋‹ค. ๊ทธ๋ ‡๋‹ด ๋ฐ˜๋Œ€๋กœ istio โžก๏ธ non-istio ๋ฐฉํ–ฅ์˜ ์ ‘๊ทผ์„ ๋ง‰์„ ์ˆ˜๋Š” ์—†์„๊นŒ?

์š”๊ฑด istio๊ฐ€ Istio Service Registry์— ๋“ฑ๋ก๋œ ์›Œํฌ๋กœ๋“œ์—๋งŒ ์ ‘๊ทผํ•˜๋„๋ก MeshConfig.OutboundTrafficPolicy.mode๋ฅผ STRICT๋กœ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•  ๊ฒฝ์šฐ, K8s Service์™€ ServiceEntry๋กœ ๋“ฑ๋กํ•œ ์—”๋“œํฌ์ธํŠธ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

ํ•˜์ง€๋งŒ ๋‹จ์ ์ด ์žˆ๋Š”๋ฐ ๋ณธ์ธ์ด ํ™•์ธ ํ–ˆ์„ ๋• ๋ชจ๋“  K8s Service๋Š” istio๊ฑด non-istio๊ฑด ๋ชจ๋‘ Istio Service Registry์— ๋“ฑ๋ก๋œ๋‹ค. ๊ทธ๋ž˜์„œ โ€œistio โžก๏ธ non-istio K8s Svcโ€ ๋ฐฉํ–ฅ์˜ ์ ‘๊ทผ์€ ๋ง‰์„ ์ˆ˜ ์—†๋‹ค. ์ด ๋ฐฉ์‹์€ โ€œistio โžก๏ธ non-istio external endpointโ€ ๋ฐฉํ–ฅ์˜ ์ ‘๊ทผ๋งŒ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.

Istio Service Registry์— ๋Œ€ํ•ด ๋” ๊ถ๊ธˆํ•˜๋‹ค๋ฉด, ํ›„์† ํฌ์ŠคํŠธ๋ฅผ ์ฐธ๊ณ 

โžก๏ธ Istio Service Registry

AuthorizationPolicy

Istio์˜ AuthorizationPolicy๋Š” ์„œ๋น„์Šค์˜ ์ ‘๊ทผ ๊ทœ์น™์„ ๋ฏธ์„ธํ•œ ์ˆ˜์ค€์„ ์ œ์–ดํ•˜๋Š” ๋ฆฌ์†Œ์Šค์ด๋‹ค. ์š”์ฒญ(request)์˜ ์ถœ๋ฐœ์ง€(source) ์†์„ฑ์„ ๊ธฐ์ค€์œผ๋กœ ์ œ์–ดํ•  ์ˆ˜๋„ ์žˆ๊ณ , ์š”์ฒญ์˜ ๋„์ฐฉ์ง€(to) ์†์„ฑ์„ ๊ธฐ์ค€์œผ๋กœ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ์™ธ์— ์š”์ฒญ์ด ๊ฐ€์ง„ ์†์„ฑ๋“ค(ex: request headers, JWT token principal ๋“ฑ)์„ ๊ธฐ์ค€์œผ๋กœ ์ œ์–ดํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ ์‚ดํŽด๋ณด๋Š” 3๊ฐ€์ง€ ๋ฆฌ์†Œ์Šค ์ค‘์—์„œ ์š” ๋…€์„์ด ์ œ์ผ ์–ด๋ ค์› ๋‹ค ใ… ใ… 

๊ฐ€์žฅ ๊ฐ„๋‹จํžˆ default ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ์›Œํฌ๋กœ๋“œ๋ฅผ test ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•˜๋Š” AuthorizationPolicy๋ถ€ํ„ฐ ์‚ดํŽด๋ณด์ž.

$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: protect-from-test
  namespace: default
spec:
  action: DENY
  rules:
  - from:
    - source:
        namespaces: ["test"]
EOF

์œ„์™€ ๊ฐ™์€ AuthPolicy๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ๋‹ค๋ฉด, test ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋Š” ์›Œํฌ๋กœ๋“œ์— ์ ‘๊ทผํ•˜๋ ค๊ณ  ํ•  ๋•Œ, ์ด๋Ÿฐ ์—๋Ÿฌ๋ฅผ ๋ฐ›๋Š”๋‹ค.

$ kubectl exec -n test ... -- sh
~# curl helloworld.default:5000/hello
RBAC: access denied

๊ทธ๋Ÿฐ๋ฐ ์œ„์˜ AuthPolicy๋Š” test ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ์ ‘๊ทผ์„ ๋ง‰์•˜์„ ๋ฟ ๋‹ค๋ฅธ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์—์„œ์˜ ์ ‘๊ทผ์€ ์ž˜ ์ด๋ค„์ง„๋‹ค!

๋งŒ์•ฝ, ๋ฐ˜๋Œ€๋กœ ํŠน์ • ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ์ ‘๊ทผ๋งŒ์„ ํ—ˆ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋ฆฌ์†Œ์Šค๋ฅผ ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด๋ณด์ž.

$ kubectl delete authorizationpolicy -n default protect-from-test
$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: only-allow-from-test
  namespace: default
spec:
  action: ALLOW
  rules:
  - from:
    - source:
        namespaces: ["test"]
EOF

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด, ๋ฐ˜๋Œ€๋กœ test ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ์ ‘๊ทผ์€ ํ—ˆ์šฉํ•˜์ง€๋งŒ, ๋‹ค๋ฅธ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋กœ๋ถ€ํ„ฐ์˜ ์ ‘๊ทผ์€ ๊ฑฐ๋ถ€ ๋œ๋‹ค.

๋‹จ, ๊ฐ™์€ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์ธ default ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ๋ฆฌ์†Œ์Šค๋“ค ๊ฐ„์˜ ํ†ต์‹ ๋„ ๊ฑฐ๋ถ€๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์˜ํ•  ๊ฒƒ!!

์ •์ฑ… ํ‰๊ฐ€ ์ˆœ์„œ

AuthorizaitonPolicy์˜ ์ •์ฑ…์€ ALLOW, DENY, CUSTOM, AUDIT(๋…ผ์™ธ)๊ฐ€ ๊ฐ€๋Šฅํ•œ๋ฐ, ์ •์ฑ… ๋ณ„๋กœ ํ‰๊ฐ€๋˜๋Š” ์ˆœ์„œ๊ฐ€ ๋‹ค๋ฅด๋‹ค.

  • ์•„๋ฌด๊ฒƒ๋„ ์•ˆ ๊ฑธ๋ ค ์žˆ๋‹ค๋ฉด
    • ๋ชจ๋“  ์š”์ฒญ์„ ์ˆ˜์šฉ
  • CUSTOM ์ •์ฑ…์ด ๊ฑธ๋ ค ์žˆ๋‹ค๋ฉด
    • ์ •์ฑ…์„ ํ‰๊ฐ€ํ•œ ํ›„์— ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ ์š”์ฒญ์„ ์ˆ˜์šฉํ•˜๊ฑฐ๋‚˜ ๊ฑฐ๋ถ€
  • DENY ์ •์ฑ…์ด ๊ฑธ๋ ค ์žˆ๋‹ค๋ฉด
    • ์ •์ฑ…์˜ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์š”์ฒญ์€ ๊ฑฐ๋ถ€. ๋‚˜๋จธ์ง€๋Š” ์ˆ˜์šฉ
  • ALLOW ์ •์ฑ…์ด ๊ฑธ๋ ค ์žˆ๋‹ค๋ฉด
    • ์ •์ฑ…์˜ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์š”์ฒญ๋งŒ ์ˆ˜์šฉ. ๋‚˜๋จธ์ง€๋Š” ๊ฑฐ๋ถ€

๋‹จ, DENY ์ •์ฑ…์œผ๋กœ ์š”์ฒญ์ด ๊ฑฐ๋ถ€ ๋˜์—ˆ๋”๋ผ๋„, ALLOW ์ •์ฑ…์—์„œ ํ—ˆ์šฉํ•ด์ค€๋‹ค๋ฉด ํ•ด๋‹น ์š”์ฒญ์„ ์ˆ˜์šฉ ๋œ๋‹ค.

Request์˜ ์ถœ๋ฐœ์ง€ ์†์„ฑ์„ ๊ธฐ์ค€์œผ๋กœ

์•„๋ž˜์˜ ์š”์ฒญ์˜ ์ถœ๋ฐœ์ง€ ์†์„ฑ์„ ๊ธฐ์ค€์œผ๋กœ ์ ‘๊ทผ์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค.

  • namespace
  • principal
  • ipBlocks
  • remoteIpBlocks

์œ„์˜ ์˜ˆ์ œ์—์„œ namespace ๊ธฐ์ค€์€ ํ•ด๋ดค์œผ๋‹ˆ principal์„ ๊ธฐ์ค€์œผ๋กœ ํ•ด๋ณด์ž.

$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: only-allow-from-sleep-sa
  namespace: default
spec:
  action: ALLOW
  rules:
  - from:
    - source:
        principals:
          - "cluster.local/ns/default/sa/sleep"
EOF

์š”๋ ‡๊ฒŒ ํ•˜๋ฉด ํŠน์ • K8s ServiceAccount๋ฅผ ๋ฐ”์ธ๋”ฉํ•œ ์›Œํฌ๋กœ๋“œ์˜ ์š”์ฒญ๋งŒ ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค!! (,,โ€ขoโ€ข,,)

์ฐธ๊ณ ๋กœ ServiceAccount์˜ ํŒจํ„ด์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  • <TRUST_DOMAIN>/ns/<NAMESPACE>/sa/<SERVICE_ACCOUNT>
  • ์˜ˆ์‹œ: cluster.local/ns/default/sa/sleep

Request์˜ ๋„์ฐฉ์ง€ ์†์„ฑ์„ ๊ธฐ์ค€์œผ๋กœ

์š”์ฒญ์ด ๋„์ฐฉ์ง€์— ๋„๋‹ฌํ•ด์„œ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…(operation)์„ ๊ธฐ์ค€์œผ๋กœ ์ ‘๊ทผ์„ ์ œ์–ดํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

  • hosts
  • ports
  • methods
  • paths
$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: only-deny-get-access
  namespace: default
spec:
  action: DENY
  rules:
  - to:
    - operation:
        methods: ["GET"]
EOF

์œ„์™€ ๊ฐ™์ด ์„ค์ •ํ•˜๋ฉด, default ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ์›Œํฌ๋กœ๋“œ์— ๋“ค์–ด์˜ค๋Š” ๋ชจ๋“  GET ์š”์ฒญ์ด ๊ฑฐ๋ถ€๋œ๋‹ค.

๊ทธ์™ธ์—๋„ hsots, ports, paths๋ฅผ ์‚ฌ์šฉํ•ด ๋” ์„ธ๋ถ€์ ์œผ๋กœ ์ ‘๊ทผ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

Request๊ฐ€ ๊ฐ€์ง„ ์†์„ฑ์„ ๊ธฐ์ค€์œผ๋กœ

๋งˆ์ง€๋ง‰์œผ๋กœ when ์กฐ๊ฑด์„ ํ†ตํ•ด์„œ ์š”์ฒญ์ด ๊ฐ€์ง„ ์†์„ฑ์„ ๊ธฐ์ค€์œผ๋กœ ์ ‘๊ทผ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

๊ทธ ๋ชฉ๋ก์€ โ€œAuthorization Policy Conditionsโ€ ๋ฌธ์„œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ๋ช‡๊ฐ€์ง€ ์‚ฌ๋ก€๋ฅผ ์˜ˆ์‹œ์™€ ํ•จ๊ป˜ ์‚ดํŽด๋ณด์ž.

$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: only-allow-header-haha-hoho
  namespace: default
spec:
  action: ALLOW
  rules:
  - when:
    - key: request.headers[haha]
      values: ["hoho"]
EOF

์œ„์™€ ๊ฐ™์€ AuthorizationPolicy๋ฅผ ๋งŒ๋“ค๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์ด header์— haha: hoho๊ฐ€ ์žˆ๋Š” ์š”์ฒญ๋งŒ ํ—ˆ์šฉ ํ•œ๋‹ค.

# With Header
$ curl -H "haha: hoho" http://helloworld.default:5000/hello
Hello version: v1, instance: helloworld-v1-77489ccb5f-jstpc

# No Header
$ curl http://helloworld.default:5000/hello
RBAC: access denied

๋˜, ์œ„์—์„œ source, to ๊ทœ์น™์— ์‚ฌ์šฉ ํ–ˆ๋˜ ๋ช‡๋ช‡ ์†์„ฑ๋“ค์„ when ๊ทœ์น™์—์„œ๋„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์š”์ฒญ ์›Œํฌ๋กœ๋“œ์˜ principal์„ ๊ธฐ์ค€์œผ๋กœ ์ ‘๊ทผ ์ œ์–ดํ•˜๋Š” ๊ฒƒ์„ when ์กฐ๊ฑด์—์„œ๋„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: only-allow-sleep-sa
  namespace: default
spec:
  action: ALLOW
  rules:
  - when:
    - key: source.principal
      values: ["cluster.local/ns/default/sa/sleep"]
EOF

๊ทธ ์™ธ์—๋„ ์š”์ฒญ์— ๋‹ด๊ธด JWT ํ† ํฐ์˜ ์ •๋ณด๋ฅผ ๊ธฐ์ค€์œผ๋กœ๋„ ์ ‘๊ทผ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ํ•œ๋‹ค. (์ •๋ง ๋งŽ๊ตฌ๋งŒ!!!)

Sidecar

Istio ์„œ๋น„์Šค๋ฉ”์‰ฌ์—์„œ Envoy SideCar์— ๋Œ€ํ•œ ๋„คํŠธ์›Œํฌ ๊ตฌ์„ฑ์„ ๋ช…์‹œํ•˜๋Š” ๋ฆฌ์†Œ์Šค์ด๋‹ค.

Egress Listener

์˜ˆ๋ฅผ ๋“ค์–ด, ์•„๋ž˜์˜ Sidecar ๋ฆฌ์†Œ์Šค๋ฅผ ๋งŒ๋“ค๋ฉด, default ๋„ค์ž„์ŠคํŽ˜์ด์Šค์—์„œ default์™€ test์˜ ์›Œํฌ๋กœ๋“œ๋กœ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
  name: default-egress
  namespace: default
spec:
  egress:
  - hosts:
    - "default/*"
    - "test/*"
EOF

๋งŒ์•ฝ ๋ช…์‹œ๋˜์ง€ ์•Š์€ ์›Œํฌ๋กœ๋“œ์— curl ๋ช…๋ น์„ ๋‚ ๋ฆฌ๋ฉด ์•„๋ฌด response๋„ ๋ฐ›์ง€ ๋ชป ํ•˜๊ณ  ํ•„ํ„ฐ๋ง ๋œ๋‹ค.

์š”๋ ‡๊ฒŒ Sidecar์˜ egress ๊ทœ์น™์„ ํ™œ์šฉํ•˜๋ฉด, ํ•ด๋‹น ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋‚˜ ์›Œํฌ๋กœ๋“œ์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ K8s ๋˜๋Š” Istio ์„œ๋น„์Šค ๋ฉ”์‹œ๋ฅผ ์ œํ•œํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ์ตœ์†Œํ•œ์˜ ํ•„์š”๋กœ ํ•˜๋Š” ๋ณด์•ˆ ์ ‘๊ทผ๋งŒ์„ ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. (Zero-Trust Network์˜ ์กฐ๊ฑด์„ ์ถฉ์กฑ!)

์•„ ๊ทธ๋ฆฌ๊ณ  ๋งŒ์•ฝ ๊ฐ™์€ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ์›Œํฌ๋กœ๋“œ๋กœ๋งŒ egress host๋ฅผ ํ—ˆ์šฉํ•˜๋ ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

...
spec:
  egress:
  - hosts:
    - "./*"
    - "./helloworld"

์ด๋ ‡๊ฒŒ ์ƒ๋Œ€๊ฒฝ๋กœ ํ‘œํ˜„์‹ ์ฒ˜๋Ÿผ ./๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ™์€ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ์›Œํฌ๋กœ๋“œ๋งŒ ํ—ˆ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

Ingress Listener

์ด๋ฒˆ์—๋Š” ๋ฐ˜๋Œ€๋กœ ์š” ์›Œํฌ๋กœ๋“œ์— ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ port๋ฅผ ์ œํ•œํ•ด๋ณด์ž.

$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
  name: default-ingress
  namespace: default
spec:
  ingress:
  - port: 5000
EOF

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด, default ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ๋ชจ๋“  ์›Œํฌ๋กœ๋“œ์— ๋Œ€ํ•ด์„œ 5000 ํฌํŠธ๋งŒ ์—ด๋ ค์žˆ๊ฒŒ ๋œ๋‹ค.

์™œ ingress๋Š” port๋ฅผ ์ œํ•œํ• ๊นŒ ์ƒ๊ฐ์„ ์ข€ ํ•ด๋ดค๋Š”๋ฐโ€ฆ

๋ณดํ†ต K8s์˜ ์›Œํฌ๋กœ๋“œ์— ์ ‘๊ทผํ•˜๋ ค๊ณ  ํ•˜๋ฉด K8s Service ๋ฆฌ์†Œ์Šค์˜ CoreDNS ์ฃผ์†Œ๋กœ ์ ‘๊ทผ ํ•œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ, ์ด๊ฑด ํŽธ์˜๋ฅผ ์œ„ํ•ด ์“ฐ๋˜ ๊ฒƒ์ด๊ณ  ์‚ฌ์‹ค์€ ๊ฐ Pod์ด ๋ถ€์—ฌ ๋ฐ›์€ Private IP๋กœ๋„ ์›Œํฌ๋กœ๋“œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

K8s Service๋ฅผ ์ ‘๊ทผํ•  ๋•Œ๋Š” K8s Service๋ฅผ ์ •์˜ํ•˜๋ฉด์„œ ์›Œํฌ๋กœ๋“œ์˜ ์–ด๋–ค ํฌํŠธ๋ฅผ ๋…ธ์ถœํ• ์ง€ ๊ฒฐ์ •์„ ํ•˜๊ฒŒ ๋˜์ง€๋งŒ, ์–ด๋–ค ํฌํŠธ๋Š” K8s Svc๋กœ ๋…ธ์ถœํ•˜๊ณ  ์‹ถ์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๋‹ค.

Istio Sidecar๋Š” ์ด๋ ‡๊ฒŒ Native K8s๊ฐ€ ๊ฐ–๋Š” ์›์น˜ ์•Š๋Š” ์›Œํฌ๋กœ๋“œ์˜ ํฌํŠธ๊ฐ€ ๋…ธ์ถœ๋˜์ง€ ์•Š๋„๋ก Envoy Sidecar ์ˆ˜์ค€์—์„œ ingress port๋ฅผ ์ œํ•œํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ์–ด๋–ป๊ฒŒ ๋ณด๋ฉด, AWS SG์˜ Ingress Rule์ฒ˜๋Ÿผ Inbound ํฌํŠธ๋ฅผ ์ œํ•œํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ด๊ธฐ๋„ ํ•œ๋‹ค.

Workload Selector

์œ„์˜ Sidecar ์˜ˆ์‹œ๋“ค์€ metadata.namespace์˜ ๋ชจ๋“  Envoy Sidecar์— ์ ์šฉ๋˜๋Š” ๊ทœ์น™์ด์—ˆ๋‹ค. ๋งŒ์•ฝ ํŠน์ • ์›Œํฌ๋กœ๋“œ์˜ Envoy Sidecar์—๋งŒ ์ ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์ด workflowSelector๋ฅผ ํฌํ•จํ•˜๋ฉด ๋œ๋‹ค.

$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
  name: default-egress
  namespace: default
spec:
  workloadSelector:
    labels:
      app: helloworld
  egress:
  - hosts:
    - "./*"
EOF

์™€์šฐ! ์œ„์™€ ๊ฐ™์ด Sidecar๋ฅผ ๊ตฌ์„ฑํ•˜๋ฉด helloworld ์›Œํฌ๋กœ๋“œ๋Š” ์˜ค์ง ๊ฐ™์€ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ์›Œํฌ๋กœ๋“œ๋กœ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค!!

Istio์™€ Zero-trust Network

Istio๋ฅผ ๊ณต๋ถ€ํ•˜๋ฉด์„œ โ€œZero-trust Networkโ€(์ดํ•˜ ZTN)๋ผ๋Š” ์šฉ์–ด๋ฅผ ์ฒ˜์Œ ๋ณด๊ฒŒ ๋˜์—ˆ๋‹ค. ๋ณธ์ธ์ด ๋ณด์•ˆ ์ „๋ฌธ๊ฐ€๋Š” ์•„๋‹ˆ๋ผ์„œ ์‰ฝ๊ฒŒ ์ดํ•ด ๋˜์ง€๋Š” ์•Š์•˜๋Š”๋ฐโ€ฆ

ํ† ์Šคใ…ฃSLASH 23 - ๊ณ ๊ฐ ๋ถˆ์•ˆ์„ 0์œผ๋กœ ๋งŒ๋“œ๋Š” ํ† ์Šค์˜ Istio Zero Trust์˜ ์˜์ƒ์ด Istio ZTN๋ฅผ ์ดํ•ดํ•˜๋Š”๋ฐ ํฐ ๋„์›€์ด ๋˜์—ˆ๋‹ค.

ํ† ์Šค๋Š” ์•„๋ฌด๋ž˜๋„ ๊ธˆ์šฉ ๊ธฐ์—…์ด๋‹ˆ ์›Œํฌ๋กœ๋“œ๋ฅผ ์šด์˜ํ•  ๋•Œ ๋†’์€ ์ˆ˜์ค€์˜ ๋ณด์•ˆ์„ ์š”๊ตฌํ•  ๊ฒƒ ๊ฐ™๋‹ค. Istio๋Š” ํ† ์Šค์˜ K8s ํด๋Ÿฌ์Šคํ„ฐ์— ZTN๋ฅผ ์ œ๊ณตํ•˜๋Š” ์†”๋ฃจ์…˜์œผ๋กœ ์ž˜ ๊ธฐ๋Šฅํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

์ง€๊ธˆ๋ถ€ํ„ฐ๋Š” ์œ„์˜ ์˜์ƒ์˜ ๋‚ด์šฉ ์š”์•ฝ์ด๋‹ค!

  • ํ† ์Šค๋Š” ๋ชจ๋“  ์›Œํฌ๋กœ๋“œ์— mTLS STRICT ๋ชจ๋“œ์ด๋‹ค. ์ฆ‰, Istio ์„œ๋น„์Šค ๋ฉ”์‰ฌ ๋ฐ–์—์„œ๋Š” ์„œ๋น„์Šค ๋ฉ”์‰ฌ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค.
  • ํ† ์Šค๋Š” Istio์˜ Sidecar ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์›Œํฌ๋กœ๋“œ๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” egress host๋ฅผ ์ œํ•œํ•œ๋‹ค. ๋”ฐ๋กœ ์„ค์ •ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ์–ด๋–ค ์›Œํฌ๋กœ๋“œ์—๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค. (Least Privilliage ์‚ฌ๋ก€)
  • ํ† ์Šค๋Š” Istio์˜ AuthorizationPolicy ๋ฆฌ์†Œ์Šค๋ฅผ ์„ค์ •ํ•˜์—ฌ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์›Œํฌ๋กœ๋“œ์˜ ์ ‘๊ทผ์„ ๋ง‰๊ณ , ์›Œํฌ๋กœ๋“œ์˜ ์ ‘๊ทผ์€ Endpoint ๋ ˆ๋ฒจ๊นŒ์ง€ ์ œํ•œํ•œ๋‹ค.

์ฆ‰, ์›Œํฌ๋กœ๋“œ A๊ฐ€ ์›Œํฌ๋กœ๋“œ B์— ์ ‘๊ทผํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด, (1) ๋‘˜๋‹ค Istio ์„œ๋น„์Šค ๋ฉ”์‰ฌ ์•ˆ์— ์žˆ์–ด์•ผ ํ•˜๊ณ , (2) ์›Œํฌ๋กœ๋“œ A์˜ Sidecar๋ฅผ ์„ค์ •ํ•ด์„œ ์›Œํฌ๋กœ๋“œ B์— egress ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ—ˆ์šฉํ•ด์•ผ ํ•˜๊ณ , (3) ์›Œ๋ฅด์ฝ”๋“œ B์— AuthorizationPolicy๋ฅผ ์„ค์ •ํ•ด ์›Œํฌ๋กœ๋“œ A์˜ ingress ํŠธ๋ž˜ํ”ฝ์„ ํ—ˆ์šฉํ•ด์ค˜์•ผ ํ•œ๋‹ค.

ํ† ์Šค์˜ ๊ฒฝ์šฐ, Sidecar์˜ egress host ๋ชฉ๋ก์ด ๋ณ€๊ฒฝ ๋œ๋‹ค๊ฑฐ๋‚˜, ์•„๋‹˜ ๋“ฑ๋ก๋˜์ง€ ์•Š์€ egress host๋กœ ์š”์ฒญ์ด ๋ฐœ์ƒํ•œ๋‹ค๋ฉด Slack ๋ฉ”์‹œ์ง€๋„ ์˜ค๋Š” ๋“ฑ Istio๋ฅผ ์„ธ๋ฐ€ํ•˜๊ฒŒ ๋ชจ๋‹ˆํ„ฐ๋ง ํ•˜๊ณ  ์žˆ๋‹ค. (์ตœ๊ทผ ์ฝ”๋“œ ์ปค๋ฏธํ„ฐ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ๋„ ์‹ ๊ธฐํ•˜๋„คโ€ฆ ๐Ÿ‘€)

์ฒ˜์Œ์—๋Š” Istio๋ฅผ ์„œ๋น„์Šค ๋ฉ”์‰ฌ? ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ์„ ๋ชจ๋‹ˆํ„ฐ๋ง ํ•˜๊ณ , ๋˜ ์นด๋‚˜๋ฆฌ ๋ฐฐํฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฑฐ๊ตฌ๋‚˜~~ ๋ผ๊ณ ๋งŒ ์ƒ๊ฐํ–ˆ๋Š”๋ฐ, ๋ถ„์‚ฐ์ฒ˜๋ฆฌ ์‹œ์Šคํ…œ๊ณผ ๊ทธ๊ฒƒ์˜ ๋ณด์•ˆ์„ ์œ„ํ•ด ์ž˜ ๊ณ ์•ˆ๋œ ์„œ๋น„์Šค ๋ฉ”์‰ฌ๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค. (์—ญ์‹œ CNCF!)

์ฐธ๊ณ ์ž๋ฃŒ