네트워크 단절을 위해 EC2 인스턴스 스토어로 구성된 AWS Outposts 로컬 Amazon EKS 클러스터 준비하기
네트워크 단절을 위해 EC2 인스턴스 스토어로 구성된 AWS Outposts 로컬 Amazon EKS 클러스터 준비하기
로컬 네트워크를 AWS Cloud에 연결하는 AWS Outposts 서비스 링크가 연결을 잃은 경우에도 Outpost의 로컬 Amazon EKS 클러스터를 계속 사용할 수 있어요. 이 주제에서는 네트워크 단절에 대비해 로컬 클러스터를 준비하는 방법과 관련 고려 사항을 다룹니다.
출처: 문서
본문
로컬 클러스터는 일시적이고 계획되지 않은 네트워크 단절 중에도 안정성과 지속적인 운영을 가능하게 해요. AWS Outposts는 데이터 센터의 AWS Cloud 확장판 역할을 하는 완전 연결형 제공물로 남아 있습니다. Outpost와 AWS Cloud 사이에 네트워크 단절이 발생하면 연결 복원을 시도하는 것이 좋습니다. 지침은 AWS Outposts 사용 설명서의 AWS Outposts 랙 네트워크 문제 해결 체크리스트를 참고하세요.
Outposts는 ConnectedStatus 메트릭을 내보내며, 이를 사용해 Outpost의 연결 상태를 모니터링할 수 있어요. 자세한 내용은 AWS Outposts 사용 설명서의 Outposts 메트릭을 참고하세요.
네트워크 단절 중 인증
로컬 클러스터는 여러 인증 메커니즘을 지원합니다. 네트워크 단절 중 이들의 가용성은 다양해요.
| 인증 메커니즘 | 단절 중 사용 가능? |
|---|---|
AWS IAM(액세스 항목, aws-auth ConfigMap) |
아니요. IAM은 AWS 리전에 대한 연결이 필요합니다. |
| OIDC(고객 제공 공급자) | 공급자 위치에 따라 다름. OIDC 공급자가 Outpost의 로컬 네트워크에서 연결 가능하면 인증이 계속 작동합니다. |
| x.509 클라이언트 인증서 | 예. 인증서는 Kubernetes API 서버가 로컬로 검증합니다. |
| IRSA(서비스 계정용 IAM 역할) | 아니요. 단절 중의 IRSA 및 Pod Identity를 참고하세요. |
| EKS Pod Identity | 아니요. 단절 중의 IRSA 및 Pod Identity를 참고하세요. |
x.509 클라이언트 인증서
네트워크 단절 중에도 kubectl 액세스를 유지하려면 단절이 발생하기 전에 클라이언트 x.509 인증서를 생성하세요.
관리자 인증서를 생성하려면:
- 프라이빗 키와 인증서 서명 요청(CSR)을 생성합니다.
openssl req -new -newkey rsa:4096 -nodes \
-keyout admin.key -out admin.csr -subj "/CN=admin"
- Kubernetes
CertificateSigningRequest리소스를 생성하고 승인합니다.
cat admin.csr | base64 | tr -d '\n' > admin.csr.b64
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: admin-csr
spec:
request:
signerName: kubernetes.io/kube-apiserver-client
usages:
- client auth
kubectl apply -f admin-csr.yaml
kubectl certificate approve admin-csr
- 서명된 인증서를 검색합니다.
kubectl get csr admin-csr -o jsonpath='{.status.certificate}' | base64 --decode > admin.crt
- 관리자 액세스 권한을 부여하는
ClusterRoleBinding을 생성합니다.
kubectl create clusterrolebinding admin --clusterrole=cluster-admin \
--user=admin --group=system:masters
- 인증서를 사용하는
kubeconfig를 구성합니다.
kubectl config --kubeconfig admin.kubeconfig set-cluster my-cluster \
--certificate-authority=ca.crt --server $APISERVER_ENDPOINT --embed-certs
kubectl config --kubeconfig admin.kubeconfig set-credentials admin \
--client-certificate=admin.crt --client-key=admin.key --embed-certs
kubectl config --kubeconfig admin.kubeconfig set-context admin@my-cluster \
--cluster my-cluster --user admin
kubectl config --kubeconfig admin.kubeconfig use-context admin@my-cluster
단절 중 클러스터 엔드포인트 DNS 확인
로컬 클러스터의 Kubernetes API 서버 엔드포인트는 Amazon Route 53에 호스팅되며 Amazon EKS가 서브넷에 생성하는 교차 계정 탄력적 네트워크 인터페이스(ENI)의 프라이빗 IP 주소로 확인됩니다. 이러한 ENI는 정상적인 클러스터 운영 중에는 변경되지 않는 정적 프라이빗 IP 주소를 가져요.
네트워크 단절 중에는 Outpost가 Route 53에 연결할 수 없으므로 로컬 확인 경로를 준비하지 않았다면 클러스터 엔드포인트 호스트 이름이 확인되지 않습니다. API 서버에 연결해야 하는 클라이언트 카테고리는 세 가지입니다.
kubectl을 실행하는 클러스터 관리자.- 노드 하트비트를 보내고 스펙을 가져오는 워커 노드(
kubelet). - 각 노드의
kube-proxy(클러스터 Service IP를 설정).
옵션 1: 로컬 DNS 솔루션(권장)
AWS는 클러스터 엔드포인트 레코드를 캐시하고 Outpost가 단절된 동안 제공하는 로컬 DNS 솔루션 배포를 권장합니다. 온프레미스 환경에서 클러스터 엔드포인트 레코드를 캐시하는 자체 DNS 서버를 실행할 수 있어요.
로컬 DNS 솔루션을 사용한다면 kubeconfig와 워커 노드 AMI를 클러스터 엔드포인트 호스트 이름(ENI IP 주소가 아닌)으로 지정해 로컬 DNS 솔루션과 일관되게 확인되도록 하는 것이 좋습니다.
옵션 2: 정적 IP 기반 액세스
로컬 DNS 솔루션을 실행하고 싶지 않다면 정적 IP 기반 액세스를 사용할 수 있어요.
- 관리자:
kubeconfig를 교차 계정 ENI 프라이빗 IP 주소를 직접 가리키도록 구성합니다. AWS 계정에서 설명에Amazon EKS cluster-name이 있는 네트워크 인터페이스를 검색해 ENI를 찾으세요. 각 ENI의 IP 주소는 정상 운영 중에는 클러스터 수명 동안 안정적입니다. - 워커 노드(Amazon EKS 최적화 AMI): Amazon EKS 최적화 AMI에서 워커 노드를 시작하면 부트스트랩 스크립트가 ENI IP 주소로 클러스터 엔드포인트를
/etc/hosts에 추가합니다. 추가 구성이 필요 없어요. - 워커 노드(사용자 지정 AMI): 사용자 지정 부트스트랩에서
/etc/hosts에 클러스터 엔드포인트 호스트 이름과 ENI IP 주소를 추가하세요. 그렇지 않으면 단절 중kubelet과kube-proxy가 API 서버에 연결할 수 없습니다.
중요: 교차 계정 ENI가 삭제되거나 IP 주소가 변경되면 — 예를 들어 삭제하거나 Amazon EKS가 다시 연결하지 못하는 방식으로 수정하면 — 정적 IP 기반 액세스를 사용하는 모든 노드와 모든 관리자를 수동으로 업데이트해야 합니다. 로컬 DNS 솔루션을 사용하면 수동 개입이 필요 없습니다.
단절 중 Pod DNS 확인
단절 중 DNS 오류를 방지하려면 워커 노드 시작 템플릿을 구성해 kubelet의 resolvConf 설정을 재정의하세요. userdata에서 nameserver 10.0.0.2만 포함하는(즉 VPC 검색 도메인 없이) 사용자 지정 resolv.conf 파일(예: /etc/kubernetes/resolv.conf)을 생성한 다음 NodeConfig에서 spec.kubelet.config.resolvConf: /etc/kubernetes/resolv.conf를 설정합니다. 이렇게 하면 Pod DNS 구성에서 region-code.compute.internal 검색 도메인이 제거되어 단절 중 연결할 수 없는 VPC DNS 확인자로 쿼리가 전달되는 것을 방지합니다.
다음 예시는 워커 노드 userdata를 보여줍니다.
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="BOUNDARY"
--BOUNDARY
Content-Type: text/x-shellscript; charset="us-ascii"
#!/bin/bash
mkdir -p /etc/kubernetes
echo "nameserver 10.0.0.2" > /etc/kubernetes/resolv.conf
--BOUNDARY
Content-Type: application/node.eks.aws
---
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
cluster:
name: my-cluster
...
kubelet:
config:
resolvConf: /etc/kubernetes/resolv.conf
--BOUNDARY--
단절 중 IRSA 및 Pod Identity
중요: IRSA와 EKS Pod Identity는 AWS 리전에서 실행되는 AWS STS에 의존합니다. 네트워크 단절 중에는 IRSA 또는 Pod Identity를 사용하는 워크로드가 새 자격 증명을 얻을 수 없습니다. 기존 자격 증명은 일정 시간이 지나면 만료됩니다.
네트워크 단절 중에도 계속 사용할 수 있어야 하는 워크로드의 경우 리전 기반 AWS 서비스에 대한 기능적 또는 운영적 의존을 두지 않는 것이 좋습니다.
단절 중 etcd 동작
네트워크 단절 중에는 etcd 스냅샷을 백업할 수 없습니다. 단절 중에 etcd 인스턴스가 둘 이상 사용 불가능해지면 etcd가 쿼럼을 잃고, Outpost가 다시 연결되고 etcd 쿼럼이 복원될 때까지 Kubernetes API 작업을 사용할 수 없습니다. 이미 실행 중인 워크로드는 계속 작동합니다.
단절 중 제어 플레인 로깅
네트워크 단절 중에는 제어 플레인 로그가 제어 플레인 인스턴스에 로컬로 캐시됩니다. 연결이 복원되면 로그는 상위 AWS 리전의 Amazon CloudWatch Logs로 전송됩니다. 제어 플레인에 로깅 에이전트를 설치하거나 유지 관리할 필요가 없습니다.
로컬 관측성
Prometheus, Grafana 또는 기타 타사 솔루션을 사용해 Kubernetes API 서버 메트릭 엔드포인트를 스크랩함으로써 단절 중 클러스터를 로컬로 모니터링할 수 있어요.
로컬 이미지 저장소
추가 복제본으로 배포를 확장하거나 단절 중 Pod 오류를 복구하려면 로컬 컨테이너 이미지 저장소(예: Docker 레지스트리)가 있어야 하거나, 단절 전에 이미지가 노드에 캐시되어 있어야 합니다. Amazon ECR은 네트워크 단절 중에는 사용할 수 없습니다.
Kubernetes Pod 장애 조치 동작 튜닝
네트워크 단절 중 Kubernetes 제어 플레인은 AWS 리전과 통신할 수 없습니다. 노드에 연결할 수 없게 되면 기본 Kubernetes 동작은 시간 초과 기간 후 Pod를 축출하는 것입니다. Pod 사양의 톨러레이션과 tolerationSeconds를 사용해 이 동작을 튜닝하여 분할 중 Pod가 얼마나 빨리 다시 예약되는지 제어할 수 있어요. 자세한 지침과 예시는 Amazon EKS 모범 사례 가이드의 Kubernetes Pod 장애 조치 동작 튜닝을 참고하세요.
네트워크 단절 시뮬레이션
로컬 클러스터로 프로덕션에 들어가기 전에 단절을 시뮬레이션해 단절 상태에서 클러스터에 액세스할 수 있는지 확인하세요.
- Outpost를 AWS 리전에 연결하는 네트워킹 장치에 방화벽 규칙을 적용합니다. 이렇게 하면 Outpost의 서비스 링크가 단절됩니다.
- 생성한 x.509 인증서를 사용해 로컬 클러스터에 대한 연결을 테스트합니다.
kubectl --kubeconfig admin.kubeconfig get nodes
참고: Outpost에서 이미 프로덕션에 서비스가 있다면 단절을 시뮬레이션하지 마세요. 서비스 링크를 단절하면 Outpost에서 실행되는 모든 서비스에 영향을 미칩니다.