๋กœ์ผ“๐Ÿพ
article thumbnail
๋ฐ˜์‘ํ˜•

 

 

 

์ง€๋‚œ ๊ธ€์—์„œ Cloudflare ์—์„œ ์ƒ์„ฑํ•œ ๋„๋ฉ”์ธ๊ณผ Let's Encrypt ๋ฅผ ์ด์šฉํ•ด์„œ TLS ๋ฅผ httpbin ์— ์ ์šฉํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค. 

 

์ด๋ฒˆ์—๋Š” Cloudflare ๋ณด๋‹ค ๋” ๋Œ€์ค‘์ ์ธ Route53 ์—์„œ ์ƒ์„ฑํ•œ ๋„๋ฉ”์ธ์—๋„ TLS ๋ฅผ ์ ์šฉํ•ด๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

 

Route53 ์—์„œ ๊ตฌ๋งคํ•œ ๋„๋ฉ”์ธ์— ๋Œ€ํ•ด์„œ๋Š” AWS ACM ์„ ์ด์šฉํ•ด์„œ ๋ฌด๋ฃŒ๋กœ TLS ๋ฅผ ๋ฐœ๊ธ‰๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฐœ๊ธ‰๋ฐ›์€ TLS ๋ฅผ AWS ALB ์— ๋ฐ”๋กœ ์ ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ์•„์ฃผ ์‰ฝ๊ฒŒ TLS ํ†ต์‹ ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋ž˜์„œ ALB ์™€ Istio ๋ฅผ ์ด์šฉํ•˜๊ฒŒ ๋˜๋ฉด ๋Œ€๋žต ์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ฃ . 

ํ•˜์ง€๋งŒ ์™ธ๋ถ€๋งŒ TLS ๋ฅผ ํ†ต์‹ ์ด ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ๋‚ด๋ถ€์—์„  TLS ํ†ต์‹ ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

ACM ์„ ํ†ตํ•ด ๋„๋ฉ”์ธ์— ๋Œ€ํ•œ Cert ๋ฅผ ๋ฐœ๊ธ‰๋ฐ›์„ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด ๊ฐ’์€ ๋‹ค์šด๋ฐ›์•„์„œ ์‚ฌ์šฉ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
์ฆ‰, tls.cert ์™€ ๊ฐ™์ด ํŒŒ์ผ๋กœ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•ด ๋‚ด์šฉ์€ ํ™•์ธํ•  ์ˆ˜ ์—†์–ด AWS ์™ธ๋ถ€ ์„œ๋น„์Šค์—์„  ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

 

Istio mTLS ๋„ ๋‚ด๋ถ€ TLS ํ†ต์‹ ์˜ ๋Œ€์•ˆ์ด ๋  ์ˆœ ์žˆ๊ฒ ์ง€๋งŒ! ๊ทธ๋ž˜๋„ ์—ฌ๊ธฐ์„  Route53 + Let's Ecrypt ๋ฅผ ํ†ตํ•ด TLS ๋ฅผ ๋ฐœ๊ธ‰๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ํ•ด๋ณด์ฃ .

 

Istio mTLS ์— ๋Œ€ํ•ด ๊ถ๊ธˆํ•˜๋‹ค๋ฉด ์—ฌ๊ธฐ ์ฐธ๊ณ !

 

๊ฐœ๋…์€ ์ง€๋‚œ ๊ธ€์—์„œ ์ถฉ๋ถ„ํžˆ ๋‹ค๋ค˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฒˆ ๊ธ€์ด ์ž˜ ์ดํ•ด๊ฐ€ ์•ˆ๊ฐ„๋‹ค๋ฉด ์ง€๋‚œ ๊ธ€์„ ๋ณด๊ณ  ์˜ค์‹œ๋Š” ๊ฑธ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค!

 

๊ทธ๋Ÿผ ๋ ›์ธ ๋‘๋”์ฝ”๋“œ~

 

Route53 ์— ๋„๋ฉ”์ธ์„ ๊ตฌ๋งคํ–ˆ๊ณ , *.kingbj0429.link ์™€ kingbj0429.link ์˜ A ๋ ˆ์ฝ”๋“œ๋ฅผ ๋ฏธ๋‹ˆ PC ์˜ ๋…ธ๋“œ IP ๋กœ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์‚ฌ์‹ค kingbj0429.uk ๋„๋ฉ”์ธ์„ ์ด๋ฏธ ๊ตฌ๋งคํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— Route53 ์œผ๋กœ ์ด์ „ํ•ด์„œ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ–ˆ๋Š”๋ฐ..
์ตœ์†Œ 60์ผ์ด ์ง€๋‚˜๋ฉด ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•ด์„œ ๊ฒฐ๊ตญ $5 ์ฃผ๊ณ  ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค ใ…œใ…œ

 

Route53 ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ Cert Manager ๊ณต์‹ ๋ฌธ์„œ์— ์ž์„ธํžˆ ๋‚˜์™€์žˆ์Šต๋‹ˆ๋‹ค.

 

Route53 ์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด AWS Credential ์ด ํ•„์š”ํ•œ๋ฐ, ์ €๋Š” ๊ทธ๋ƒฅ IAM User ์˜ AccessKey ๋ฅผ Secret ๋ฆฌ์†Œ์Šค์— ํ•˜๋“œ ์ฝ”๋”ฉํ•ด์„œ ์ž๊ฒฉ์„ ์ฆ๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

EKS ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด, IRSA ๋ฅผ ์ด์šฉํ•ด์„œ ์‰ฝ๊ฒŒ ์ž๊ฒฉ ์ฆ๋ช…์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ IAM Role ์„ ๋ฐœ๊ธ‰ ๋ฐ›์€ ํ›„ Role ์˜ AccessKey ๋กœ๋„ ์ž๊ฒฉ ์ฆ๋ช…์ด ๊ฐ€๋Šฅํ•œ๋ฐ, Role ์€ ๋งŒ๋ฃŒ๊ธฐ๊ฐ„์ด ์ตœ๋Œ€ 24์‹œ๊ฐ„์ด์—ฌ์„œ ๊ทธ๋ƒฅ IAM User ์˜ AccessKey ๋ฅผ ์ด์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

 

Certificate ๋ฅผ ์‚ญ์ œํ•˜๊ณ  ์ƒ์„ฑํ•˜๊ณ  ์‚ญ์ œํ•˜๊ณ  ์ƒ์„ฑํ•˜๋‹ค๋ณด๋ฉด Let's Encrypt ์—์„œ ํ•ด๋‹น ๋„๋ฉ”์ธ์— ๋Œ€ํ•ด ์ดํ‹€ ๋™์•ˆ TLS ๋ฅผ ๋ฐœ๊ธ‰๋ฐ›์„ ์ˆ˜ ์—†๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ Deploy ์™€ ๋‹ค๋ฅด๊ฒŒ ํ•œ๋ฒˆ ์ƒ์„ฑํ•˜๋ฉด ํฌ๊ฒŒ ๋งŒ์งˆ ์ผ์ด ์—†์„ ๊ฑฐ ๊ฐ™์•„์„œ ํ…Œ๋ผํผ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด hcl ๋ฅผ ์ด์šฉํ•ด ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

resource "kubernetes_secret_v1" "route53_credentials_secret" {
  metadata {
    name      = "route53-credentials-secret"
    namespace = "istio-system"
  }

  data = {
    access-key-id     = "<not encoded key>"
    secret-access-key = "<not encoded key>"
  }

  type = "Opaque"
}

resource "kubernetes_manifest" "letsencrypt_dns01_route53_issuer" {
  manifest = {
    apiVersion = "cert-manager.io/v1"
    kind       = "Issuer"

    metadata = {
      name      = "letsencrypt-dns01-route53-issuer"
      namespace = "istio-system"
    }

    spec : {
      acme = {
        server = "https://acme-v02.api.letsencrypt.org/directory"
        email  = "kingbj0429@gmail.com"

        privateKeySecretRef = {
          name = "letsencrypt-dns01-route53-key-pair"
        }

        solvers = [
          {
            selector = {
              dnsZones = [
                "kingbj0429.link"
              ]
            }
            dns01 = {
              route53 = {
                region = "ap-northeast-2"
                hostedZoneID = "Z025..."

                accessKeyIDSecretRef = {
                  name = kubernetes_secret_v1.route53_credentials_secret.metadata[0].name
                  key  = "access-key-id"
                }
                secretAccessKeySecretRef = {
                  name = kubernetes_secret_v1.route53_credentials_secret.metadata[0].name
                  key  = "secret-access-key"
                }
              }
            }
          }
        ]
      }
    }
  }
}

resource "kubernetes_manifest" "kingbj0429_link_cert" {
  manifest = {
    apiVersion = "cert-manager.io/v1"
    kind       = "Certificate"

    metadata = {
      name      = "kingbj0429-link-cert"
      namespace = "istio-system"
    }

    spec = {
      secretName = "kingbj0429-link-key-pair"
      commonName = "kingbj0429.link"

      dnsNames = [
        "kingbj0429.link",
        "httpbin.kingbj0429.link"
      ]

      duration    = "2160h0m0s" # 90d
      renewBefore = "360h0m0s" # 15d

      privateKey = {
        algorithm = "RSA"
        encoding  = "PKCS1"
        size      = 4096
      }

      issuerRef = {
        name  = "letsencrypt-dns01-route53-issuer"
        kind  = "Issuer"
        group = "cert-manager.io"
      }
    }
  }

 

์ •๋ง ์ค‘์š”ํ•œ ๊ฒƒ์ด ํ•œ๊ฐ€์ง€ ์žˆ์Šต๋‹ˆ๋‹ค.
Istio Gateway ์—์„œ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ฐ˜๋“œ์‹œ ๋ฐœ๊ธ‰ ๋ฐ›์€ ์ธ์ฆ์„œ๊ฐ€ istio-system ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์กด์žฌํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ ์ฐธ๊ณ !

 

์ดํ›„ terraform apply ๋ฅผ ํ†ตํ•ด ์ƒ์„ฑํ•ด์ค์‹œ๋‹ค.

$ k get certificate -n istio-system
#NAME                   READY   SECRET                     AGE
#kingbj0429-link-cert   True    kingbj0429-link-key-pair   14s

 

๋ฌธ์ œ์—†์ด ์ƒ์„ฑ๋์Šต๋‹ˆ๋‹ค. (์ง€๋‚œ ๊ธ€์—์„œ๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์— ๋Œ€ํ•ด ์„ค๋ช…๋˜์–ด ์žˆ์œผ๋‹ˆ ๊ถ๊ธˆํ•˜์‹œ๋‹ค๋ฉด ์ง€๋‚œ ๊ธ€ ์ฐธ๊ณ !)

 

์ดํ›„ ํ…Œ์ŠคํŠธ ํ•ด๋ณผ ํŒŒ๋“œ๋„ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: kingbj0429-link-gateway
spec:
  selector:
    istio: gateway
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "httpbin.kingbj0429.link"
    - port:
        number: 443
        name: https
        protocol: HTTPS
      tls:
        mode: SIMPLE
        credentialName: kingbj0429-link-key-pair # ํ•ด๋‹น ์‹œํฌ๋ฆฟ์€ ๋ฐ˜๋“œ์‹œ istio ๋ฅผ ๋ฐฐํฌํ•œ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์™€ ์ผ์น˜ํ•  ๊ฒƒ!
      hosts:
        - "httpbin.kingbj0429.link"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: kingbj0429-link-virtual-service
spec:
  hosts:
    - "httpbin.kingbj0429.link"
  gateways:
    - kingbj0429-link-gateway
  http:
    - match:
        - uri:
            prefix: /
      route:
        - destination:
            host: httpbin
            port:
              number: 8000
---
apiVersion: v1
kind: Service
metadata:
  name: kingbj0429-link-httpbin
  labels:
    app: kingbj0429-link-httpbin
    service: httpbin
spec:
  ports:
    - name: http
      port: 8000
      targetPort: 80
  selector:
    app: kingbj0429-link-httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kingbj0429-link-httpbin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kingbj0429-link-httpbin
      version: v1
  template:
    metadata:
      labels:
        app: kingbj0429-link-httpbin
        version: v1
    spec:
      containers:
        - image: docker.io/kong/httpbin
          imagePullPolicy: IfNotPresent
          name: httpbin
          ports:
            - containerPort: 80

 

๋ฐฐํฌ๋ฅผ ์ง„ํ–‰ํ•œ ํ›„ httpbin.kingbj0429.link ๋กœ ์ ‘์†ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ธ์ฆ์„œ ๋ทฐ์–ด๋กœ ํ™•์ธํ•ด๋ณด๋‹ˆ Let's Encrypt ๊ฐ€ ์ž˜ ๋ฐœ๊ธ‰ํ•ด์ค€ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

์ฒ˜์Œ์ด ์–ด๋ ค์› ์ง€ CloudFlare ๋กœ ์ง„ํ–‰ํ•œ ํ›„ Route53 ์— ์ ์šฉํ•ด๋ณด๋‹ˆ ์•„์ฃผ ์‰ฌ์› ์Šต๋‹ˆ๋‹ค.

์ด์™ธ์—๋„ ACME DNS01 ์€ ๋‹ค์–‘ํ•œ ์„œ๋น„์Šค ๊ณต๊ธ‰์ž๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•๋„ ๊ฒฐ๊ตญ ๋น„์Šทํ•˜๋‹ค๋ณด๋‹ˆ ์–ด๋ ต์ง€ ์•Š๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿผ ์˜ค๋Š˜์€ ์—ฌ๊ธฐ๊นŒ์ง€!

๋ฐ˜์‘ํ˜•
profile on loading

Loading...