์ง๋ ๊ธ์์ 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 ์ ๋ค์ํ ์๋น์ค ๊ณต๊ธ์๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋ค๋ฅธ ๋ฐฉ๋ฒ๋ ๊ฒฐ๊ตญ ๋น์ทํ๋ค๋ณด๋ ์ด๋ ต์ง ์๊ฒ ์ ์ฉํ ์ ์์ ๊ฑฐ ๊ฐ์ต๋๋ค.
๊ทธ๋ผ ์ค๋์ ์ฌ๊ธฐ๊น์ง!