LabHub
はじめる
배우기 러닝패스 코스

Istio 実測ラボ

ルートを替えたら半分しか通じなかった

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

istiod 의 자체 서명 루트를 우리가 만든 루트·중간 CA(플러그인 CA)로 바꾸고, 바꾸는 순간 한쪽만 새 인증서를 받은 워크로드 사이가 끊기는 것과 모두 갈린 뒤의 사슬·신원·수명을 인증서에서 직접 확인한다.

왜 중요한가

메시의 mTLS 는 모든 워크로드가 같은 루트를 믿는다는 전제 위에 서 있다. 그 루트를 조직의 PKI 로 옮기는 일은 보안상 꼭 필요하지만, 순서를 모르고 하면 서비스 사이가 절반씩 끊긴다. 끊김을 한 번 직접 보면 '두 루트를 함께 믿는 기간' 이 왜 필요한지 설명할 수 있게 된다.

단계

  1. kubectl apply -f /opt/fixtures/istlab/pluginca-app.yaml 로 재료를 올리고 준비될 때까지 기다리세요. 그다음 /root/istlab-ca/01-before.txt 에 세 줄을 적으세요 — root_subject=(네임스페이스 bank 의 ConfigMap istio-ca-root-cert 에 든 루트의 subject), root_sha256=(그 루트의 SHA-256 지문, openssl x509 -fingerprint -sha256 의 값 부분), leaf_issuer=(client 사이드카가 받은 워크로드 인증서의 issuer).
  2. /root/istlab-ca/certs 에서 배포판에 든 /usr/local/istio-1.31.0/tools/certs/Makefile.selfsigned.mk 로 루트(make -f … root-ca)와 클러스터 cluster1 용 중간 CA (make -f … cluster1-cacerts)를 만드세요. /root/istlab-ca/certs/root-cert.pem/root/istlab-ca/certs/cluster1/ 아래 ca-cert.pem·ca-key.pem·root-cert.pem·cert-chain.pem 이 생겨야 합니다.
  3. istio-system 에 Secret cacerts 를 만드세요 — /root/istlab-ca/certs/cluster1/ 의 네 파일(ca-cert.pem·ca-key.pem·root-cert.pem·cert-chain.pem)을 같은 이름의 키로. 그다음 istiod 를 재시작하고 준비될 때까지 기다리세요. 워크로드는 아직 재시작하지 않습니다.
  4. web 만 재시작하세요. 그다음 /root/istlab-ca/04-mixed.txt 에 세 줄을 적으세요 — code=(client 에서 http://web/ 의 상태 코드), client_root=(client 사이드카의 ROOTCA subject), web_leaf_issuer=(web 사이드카 워크로드 인증서의 issuer).
  5. client 도 재시작해 client → web 이 다시 200 이 되게 하세요. 그다음 client 사이드카의 워크로드 인증서 사슬 (default 의 certificateChain)을 PEM 으로 /root/istlab-ca/05-chain.pem 에 저장하세요.
  6. /root/istlab-ca/05-chain.pem 의 첫 인증서(워크로드 인증서)에서 SAN 의 URI 를 /root/istlab-ca/06-identity.txtspiffe= 로, 그 URI 의 신뢰 도메인(spiffe:// 뒤 첫 부분)을 trust_domain= 으로 적으세요.
  7. /root/istlab-ca/07-lifetimes.txt 에 세 줄을 적으세요 — leaf_hours=(워크로드 인증서의 notAfter − notBefore 를 시간으로, 소수점 버림), intermediate_days=(중간 CA 의 유효 기간을 일로), root_days=(루트의 유효 기간을 일로).
  8. /root/istlab-ca/08-report.md 에 다섯 줄 — old_root_subject=(1단계), new_root_subject=(/root/istlab-ca/certs/root-cert.pem 의 subject), mixed_code=(4단계), after_restart_code=(지금 client → web 의 상태 코드), leaf_hours=(7단계) — 을 적고 그 아래 배운 것을 네 줄 이상 적으세요.

참고

지금의 루트는 누가 만들었나

kubectl apply -f /opt/fixtures/istlab/pluginca-app.yaml 로 재료를 올리고 준비될 때까지 기다리세요. 그다음 /root/istlab-ca/01-before.txt 에 세 줄을 적으세요 — root_subject=(네임스페이스 bank 의 ConfigMap istio-ca-root-cert 에 든 루트의 subject), root_sha256=(그 루트의 SHA-256 지문, openssl x509 -fingerprint -sha256 의 값 부분), leaf_issuer=(client 사이드카가 받은 워크로드 인증서의 issuer).

istiod 는 cacerts 가 없으면 스스로 루트를 만들어 istio-system/istio-ca-secret 에 두고, 그 루트를 모든 네임스페이스의 istio-ca-root-cert ConfigMap 으로 뿌립니다. 워크로드 인증서는 사이드카가 istiod 에 요청해 받고, istioctl proxy-config secret deploy/client -n bank -o jsondefault(워크로드 인증서 사슬)와 ROOTCA(믿는 루트)에서 볼 수 있습니다. 값은 base64 로 들어 있습니다.

루트와 클러스터용 중간 CA 를 만든다

/root/istlab-ca/certs 에서 배포판에 든 /usr/local/istio-1.31.0/tools/certs/Makefile.selfsigned.mk 로 루트(make -f … root-ca)와 클러스터 cluster1 용 중간 CA (make -f … cluster1-cacerts)를 만드세요. /root/istlab-ca/certs/root-cert.pem/root/istlab-ca/certs/cluster1/ 아래 ca-cert.pem·ca-key.pem·root-cert.pem·cert-chain.pem 이 생겨야 합니다.

Istio 문서가 권하는 구조는 '루트는 오프라인에 두고, 클러스터마다 그 루트가 서명한 중간 CA 를 istiod 에 준다' 입니다. 그러면 클러스터 하나의 키가 새어도 루트를 갈 필요가 없고, 여러 클러스터가 같은 루트를 믿어 서로의 워크로드를 믿을 수 있습니다. 이 Makefile 은 시연용이라 운영에서는 Vault 같은 CA 를 쓰라고 문서가 밝힙니다. 만든 뒤 openssl verify -CAfile root-cert.pem cluster1/ca-cert.pem 으로 사슬을 확인해 보세요.

cacerts 를 꽂고 istiod 를 다시 띄운다

istio-system 에 Secret cacerts 를 만드세요 — /root/istlab-ca/certs/cluster1/ 의 네 파일(ca-cert.pem·ca-key.pem·root-cert.pem·cert-chain.pem)을 같은 이름의 키로. 그다음 istiod 를 재시작하고 준비될 때까지 기다리세요. 워크로드는 아직 재시작하지 않습니다.

istiod 는 뜰 때 cacerts 가 있는지 보고, 있으면 스스로 만든 루트 대신 그 중간 CA 로 서명합니다. 이미 떠 있는 istiod 는 Secret 이 생겨도 알아채지 않으므로 재시작합니다. 새로 뜬 istiod 의 로그에 cacerts 에서 루트를 읽었다는 줄이 남고, 각 네임스페이스의 istio-ca-root-cert 가 새 루트로 바뀝니다 — 그런데 이미 떠 있는 사이드카가 믿는 루트는 어떻게 되는지 4단계에서 봅니다.

한쪽만 새 인증서를 받으면

web 만 재시작하세요. 그다음 /root/istlab-ca/04-mixed.txt 에 세 줄을 적으세요 — code=(client 에서 http://web/ 의 상태 코드), client_root=(client 사이드카의 ROOTCA subject), web_leaf_issuer=(web 사이드카 워크로드 인증서의 issuer).

새 istiod 는 새로 뜬 web 에게 새 중간 CA 가 서명한 인증서를 줍니다. 그런데 재시작하지 않은 client 의 사이드카는 여전히 옛 루트만 믿습니다. mTLS 는 양쪽이 서로의 인증서를 검증하므로, 한쪽이라도 상대의 루트를 모르면 연결이 맺어지지 않습니다. 운영에서 루트를 바꿀 때 옛 루트와 새 루트를 함께 믿는 기간을 두는 이유가 이것입니다.

모두 새 인증서를 받게 한다

client 도 재시작해 client → web 이 다시 200 이 되게 하세요. 그다음 client 사이드카의 워크로드 인증서 사슬 (default 의 certificateChain)을 PEM 으로 /root/istlab-ca/05-chain.pem 에 저장하세요.

재시작한 client 는 새 루트를 믿고 새 중간 CA 가 서명한 인증서를 받습니다. 저장한 사슬은 워크로드 인증서 → 중간 CA → 루트 순서로 들어 있어서, openssl verify -CAfile /root/istlab-ca/certs/root-cert.pem -untrusted /root/istlab-ca/05-chain.pem /root/istlab-ca/05-chain.pem 으로 우리 루트까지 이어지는지 확인할 수 있습니다.

인증서가 말하는 신원

/root/istlab-ca/05-chain.pem 의 첫 인증서(워크로드 인증서)에서 SAN 의 URI 를 /root/istlab-ca/06-identity.txtspiffe= 로, 그 URI 의 신뢰 도메인(spiffe:// 뒤 첫 부분)을 trust_domain= 으로 적으세요.

Istio 의 워크로드 인증서는 subject 가 비어 있고 신원은 SAN 의 URI 하나(spiffe://<신뢰 도메인>/ns/<네임스페이스>/sa/<서비스어카운트>)에 담깁니다. 인가 정책의 principals 가 바로 이 값(스킴을 뺀 부분)입니다. CA 를 바꿔도 신뢰 도메인이 같으면 정책을 고칠 필요가 없습니다. openssl x509 -noout -ext subjectAltName 으로 봅니다.

누가 얼마나 오래 사는가

/root/istlab-ca/07-lifetimes.txt 에 세 줄을 적으세요 — leaf_hours=(워크로드 인증서의 notAfter − notBefore 를 시간으로, 소수점 버림), intermediate_days=(중간 CA 의 유효 기간을 일로), root_days=(루트의 유효 기간을 일로).

워크로드 인증서는 istiod 가 짧게(기본 24시간) 주고 사이드카가 만료 전에 알아서 갈아 끼웁니다. 그래서 새어도 피해 기간이 짧고, CA 를 바꾼 뒤 재시작하지 않은 워크로드도 머지않아 새 인증서를 받습니다 — 다만 그때까지 4단계 같은 끊김이 이어질 수 있습니다. 중간 CA 와 루트는 사람이 관리하므로 오래 삽니다. 날짜는 openssl x509 -noout -startdate -enddate 로 읽고 date -d 로 초로 바꿔 빼면 됩니다.

루트를 바꿀 때의 순서를 적는다

/root/istlab-ca/08-report.md 에 다섯 줄 — old_root_subject=(1단계), new_root_subject=(/root/istlab-ca/certs/root-cert.pem 의 subject), mixed_code=(4단계), after_restart_code=(지금 client → web 의 상태 코드), leaf_hours=(7단계) — 을 적고 그 아래 배운 것을 네 줄 이상 적으세요.

설명 줄에는 '이미 운영 중인 메시에서 루트를 바꾸려면 어떤 순서가 필요한가(옛 루트와 새 루트를 함께 믿는 기간)' 를 자기 말로 적어 두세요. 이 실습은 그 기간 없이 바꿔서 끊김을 일부러 보았습니다.