2. Ingress

- 클러스터 내부의 서비스(ClusterIP, NodePort, Loadbalacner)를 외부로 노출(HTTP/HTTPS)
- Web Proxy 역할
- AWS LB Controller + Ingress (ALB) IP 모드 동작 with AWS VPC CNI
2.1 인그레스(Ingress) 를 통한 통신 흐름

Nginx Ingress Controller
외부에서 Ingress로 접속 시, Nginx Ingress Controller Pod에 인입되고, 이후 애플리케이션 Pod의 IP로 직접 통신합니다.
클러스터 내부를 외부에 노출
2.1.1 파드 생성

K8S 클러스터 내부에서만 접속이 가능합니다.
2.1.2 서비스(Cluster Type) 연결

K8S 클러스터 내부에서만 접속이 가능합니다.
동일한 애플리케이션의 다수의 파드 접속을 용이하게 하기 위한 서비스에 접속합니다.
2.1.3 서비스(NodePort Type) 연결

서비스(NodePort Type)의 일부 단점을 보완한 서비스인 LoadBalancer Type도 있습니다.
NodePort
ㆍ클러스터의 각 노드에서 지정된 포트를 개방하여 외부에서 접근 가능
ㆍ부하 분산이 제대로 되지 않음
ㆍ클라이언트가 직접 관리 필요
ㆍ클라이언트가 직접 노드를 알아야 함
LoadBalancer
ㆍ고정된 외부 IP 제공
ㆍ트래픽 자동 분산
2.1.4 Ingress Controller Pod 배치

Service 앞단에 HTTP 고급 라우팅 등 기능 동작을 위한 배치
Ingress(정책)이 적용된 Ingress Controller Pod(ex. Nginx Pod)를 앞단에 배치하여 고급 라우팅 등 기능을 제공합니다.
2.1.5 Ingress Controller Pod 이중화 구성

Active(Leader) - Standby(Follower) 로 Active 파드 장애에 대비합니다.
2.1.6 Ingress Controller Pod를 외부에 노출

Ingress Controller Pod를 외부에서 접속하기 위해 노출(expose)합니다.
Ingress Controller 노출 시 서비스(NodePort Type)보다는 좀 더 많은 기능을 제공하는 서비스(LoadBalancer Type)를 권장합니다.
2.1.7 Ingress와 Pod 간 내부 연결의 효율화 방안

Ingress Controller Pod(Layer 7 동작)에서 실 서비스 Pod의 IP로 직접 연결합니다.
Ingress Controller Pod는 K8S API Server 로부터 서비스의 엔드포인트(Pod의 IP)를 통해 파드 연결합니다.
지원되는 Ingress Controller: Nginx, Traefix 등
2.1.4 Nginx Ingress Controller 설치

Ingress
클러스터 내부의 HTTP/HTTPS 서비스를 외부로 노출합니다.
Ingress Controller
Ingress의 실제 동작 구현은 Ingress Controller(Nginx, Kong 등)가 처리
Calico 기준 K8S에서 Ingress에 대한 설명 및 실습은 스터디 마친 이후에 정리 및 진행해보려고 합니다.
Exposing a Service : In-tree Service Controller

Ingress Implementations : External Load Balancer

Ingress Implementations : Internal Reverse Proxy

Kubernetes Gateway API

3. ExternalDNS

- K8S 서비스/인그레스 생성 시 도메인을 설정하면, AWS(Route53), Azure(DNS), GCP(Cloud DNS)에 A 레코드(TXT 레코드) 자동 생성/삭제
- External DNS Controller 권한 주는 법: Node IAM Role, Static credentials, IRSA
- Ingres, Deployment가 생성되면 ExternalDNS Controller가 CSP Route53에 레코드 등록 진행
참조: https://gasidaseo.notion.site/K8S-Ingress-b38c1cbed5f9481bafa4d5315999e66a
AWS Route 53 정보 확인 & 변수 지정
# 자신의 도메인 변수 지정 : 소유하고 있는 자신의 도메인을 입력하시면 됩니다
MyDomain=<자신의 도메인>
MyDomain=jihobiztechi.com
echo "export MyDomain=jihobiztechi.com" >> /etc/profile
# 자신의 Route 53 도메인 ID 조회 및 변수 지정
aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." | jq
aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Name"
aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text
MyDnzHostedZoneId=`aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text`
echo $MyDnzHostedZoneId
# (옵션) NS 레코드 타입 첫번째 조회
aws route53 list-resource-record-sets --output json --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'NS']" | jq -r '.[0].ResourceRecords[].Value'
# (옵션) A 레코드 타입 모두 조회
aws route53 list-resource-record-sets --output json --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']"
# A 레코드 타입 조회
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A'].Name" | jq
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A'].Name" --output text
# A 레코드 값 반복 조회
while true; do aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq ; date ; echo ; sleep 1; done
사전에 LoadBalancer Controller 설치 및 배포된 환경이어야 합니다.
그리고 Public 도메인 소유하고 있어야 합니다.
ExternalDNS 설치
# EKS 배포 시 Node IAM Role 설정되어 있음
# eksctl create cluster ... --external-dns-access ...
#
MyDomain=<자신의 도메인>
MyDomain=gasida.link
# 자신의 Route 53 도메인 ID 조회 및 변수 지정
MyDnzHostedZoneId=$(aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text)
# 변수 확인
echo $MyDomain, $MyDnzHostedZoneId
# ExternalDNS 배포
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/aews/externaldns.yaml
sed -i "s/0.13.4/0.14.0/g" externaldns.yaml
cat externaldns.yaml | yh
MyDomain=$MyDomain MyDnzHostedZoneId=$MyDnzHostedZoneId envsubst < externaldns.yaml | kubectl apply -f -
# 확인 및 로그 모니터링
kubectl get pod -l app.kubernetes.io/name=external-dns -n kube-system
kubectl logs deploy/external-dns -n kube-system -f
(참조) 위에서 배포한 externaldns.yaml 내용
apiVersion: v1
kind: ServiceAccount
metadata:
name: external-dns
namespace: kube-system
labels:
app.kubernetes.io/name: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: external-dns
labels:
app.kubernetes.io/name: external-dns
rules:
- apiGroups: [""]
resources: ["services","endpoints","pods","nodes"]
verbs: ["get","watch","list"]
- apiGroups: ["extensions","networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get","watch","list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: external-dns-viewer
labels:
app.kubernetes.io/name: external-dns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: external-dns
namespace: kube-system # change to desired namespace: externaldns, kube-addons
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
namespace: kube-system
labels:
app.kubernetes.io/name: external-dns
spec:
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: external-dns
template:
metadata:
labels:
app.kubernetes.io/name: external-dns
spec:
serviceAccountName: external-dns
containers:
- name: external-dns
image: registry.k8s.io/external-dns/external-dns:v0.15.0
args:
- --source=service
- --source=ingress
- --domain-filter=${MyDomain} # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
- --provider=aws
#- --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization
- --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both)
- --registry=txt
- --txt-owner-id=${MyDnzHostedZoneId}
env:
- name: AWS_DEFAULT_REGION
value: ap-northeast-2 # change to region where EKS is installed
(참고) 기존에 ExternalDNS를 통해 사용한 A/TXT 레코드가 있는 존의 경우에 policy 정책을 upsert-only 로 설정 후 사용 하자
- --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization
Service(NLB) + 도메인 연동(ExternalDNS)
# 터미널1 (모니터링)
watch -d 'kubectl get pod,svc'
kubectl logs deploy/external-dns -n kube-system -f
# 테트리스 디플로이먼트 배포
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: tetris
labels:
app: tetris
spec:
replicas: 1
selector:
matchLabels:
app: tetris
template:
metadata:
labels:
app: tetris
spec:
containers:
- name: tetris
image: bsord/tetris
---
apiVersion: v1
kind: Service
metadata:
name: tetris
annotations:
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
#service.beta.kubernetes.io/aws-load-balancer-healthcheck-port: "80"
spec:
selector:
app: tetris
ports:
- port: 80
protocol: TCP
targetPort: 80
type: LoadBalancer
loadBalancerClass: service.k8s.aws/nlb
EOF
# 배포 확인
kubectl get deploy,svc,ep tetris
# NLB에 ExternanDNS 로 도메인 연결
kubectl annotate service tetris "external-dns.alpha.kubernetes.io/hostname=tetris.$MyDomain"
while true; do aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq ; date ; echo ; sleep 1; done
# Route53에 A레코드 확인
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A']" | jq
aws route53 list-resource-record-sets --hosted-zone-id "${MyDnzHostedZoneId}" --query "ResourceRecordSets[?Type == 'A'].Name" | jq .[]
# 확인
dig +short tetris.$MyDomain @8.8.8.8
dig +short tetris.$MyDomain
# 도메인 체크
echo -e "My Domain Checker = https://www.whatsmydns.net/#A/tetris.$MyDomain"
# 웹 접속 주소 확인 및 접속
echo -e "Tetris Game URL = http://tetris.$MyDomain"
추가 실습
Service(NLB + TLS) + 도메인 연동(ExternalDNS)
Ingress(ALB + HTTPS) + 도메인 연동(ExternalDNS)
추후에 진행하고자 합니다.
(참고) ACM 퍼블릭 인증서 요청 및 해당 인증서에 대한 Route53 도메인 검증 설정 with AWS CLI
# 각자 자신의 도메인 변수 지정
MyDomain=<각자 자신의 도메인>
# ACM 퍼블릭 인증서 요청
CERT_ARN=$(aws acm request-certificate \
--domain-name $MyDomain \
--validation-method 'DNS' \
--key-algorithm 'RSA_2048' \
|jq --raw-output '.CertificateArn')
# 생성한 인증서 CNAME 이름 가져오기
CnameName=$(aws acm describe-certificate \
--certificate-arn $CERT_ARN \
--query 'Certificate.DomainValidationOptions[*].ResourceRecord.Name' \
--output text)
# 생성한 인증서 CNAME 값 가져오기
CnameValue=$(aws acm describe-certificate \
--certificate-arn $CERT_ARN \
--query 'Certificate.DomainValidationOptions[*].ResourceRecord.Value' \
--output text)
# 정상 출력 확인하기
echo $CERT_ARN, $CnameName, $CnameValue
# 레코드 파일
cat <<EOT > cname.json
{
"Comment": "create a acm's CNAME record",
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "CnameName",
"Type": "CNAME",
"TTL": 300,
"ResourceRecords": [
{
"Value": "CnameValue"
}
]
}
}
]
}
EOT
# CNAME 이름, 값 치환하기
sed -i "s/CnameName/$CnameName/g" cname.json
sed -i "s/CnameValue/$CnameValue/g" cname.json
cat cname.json
# 해당 인증서에 대한 Route53 도메인 검증 설정을 위한 Route53 레코드 생성
aws route53 change-resource-record-sets --hosted-zone-id $MyDnzHostedZoneId --change-batch file://cname.json
4. Istio
4.1 서비스 매시(Service Mesh)
구글, IBM, Lyft 등 여러 회사들이 공동으로 개발한 오픈 소스
C++로 만들어진 엔보이(Envoy)를 사용하여 서비스 매시를 구성합니다.
- 등장 배경: MSA 환경의 시스템 전체 모니터링 어려움, 운영 시 시스템 문제 발생할 때 원인과 병목 구간 찾기 어려움
- 개념: 마이크로서비스 간 매시 형태의 통신이나 그 경로를 제어
ex) Istio, Linkerd, AWS App Mesh - 기본 동작: 파드 간 통신 경로에 프록시(Proxy)를 두고 트래픽 모니터링이나 트래픽 제어
→ 기존 Application 코드 수정 없이 구성 가능 - 트래픽 모니터링: 요청의 '에러율, Latency, Connection 수, Request 수' 등 Metric 모니터링, 특정 서비스 간 필터링
→ 원인 파악 용이 ! - 트래픽 제어:
ㆍ트래픽 시프팅(Traffic Shifting)
특정 단말/사용자는 신규앱에 전달하여 단계적으로 적용하는 Canary 배포 가능
ex) 99% 기존앱 + 1% 신규앱
ㆍ서킷 브레이커(Circuit Breaker):
목적지 마이크로서비스에 문제가 있을 시 접속 차단 및 출발지 마이크로서비스에 요청 에러 반환
시스템 전체 장애 예방
ㆍ폴트 인젝션(Fault Injection):
의도적으로 요청 지연 및 실패 구현
ㆍ속도 제한(Rate Limit):
요청 개수 제한
4.2 Istio 구성 요소와 envoy
4.2.1 Istio 구성요소

data plane(istio-proxy > envoy), control plane(istiod)으로 구성됩니다.
- istiod
- Pilot
Data Plane과 통신하며 라우팅 규칙 동기화, ADS - Gally
Istio와 K8S 연동, Endpoint 갱신 - Citadel
연결 암호화, 인증서 관리 등
- Pilot
- Envoy proxy
- C++ 구현된 고성능 프록시
- 다양한 필터 체인 지원(HTTP L7)

Istio는 각 파드 안에 Sidecar로 Envoy Proxy가 들어가 있는 형태입니다.
모든 마이크로서비스 간 통신은 Envoy를 통과하며, 메트릭을 수집하거나 트래픽 컨트롤을 할 수 있습니다.
트래픽 컨트롤을 하기 위해 Envoy Proxy에 전송 룰을 설정합니다.
마이크로서비스 간 통신을 mutual TLS(mTLS)으로 서로 TLS 인증으로 암호화 가능합니다.
각 애플리케이션은 파드 내 Envoy Proxy에 접속하기 위해 localhost 에 TCP 접속을 합니다.
Data Plane
- intelligent proxies (Envoy)들로 구성됨 (sidecar 형태로 배포됨)
Envoy (proxies)
- 마이크로서비스 간 중계 및 제어
- 트래픽 제어: HTTP, gRPC, WebSocket, TCP 라우팅- 보안 및 인가: 구성 API를 통해 보안 정책 강화, 접근 제어 강화 등
- 메시 트래픽에 대한 사용자 지정 정책 시행
- 네트워크 탄력성: 재시도, 페일오버, 서킷브레이저, 폴인젝션 설정
- 모든 Mesh Traffic을 수집 및 보고
- 빌트인 기능
- 로드밸런싱
- 서킷 브레이커
- 단계적 롤아웃
- 헬스체크
- TLS 종료
- 동적 서비스 복원
4.2.2 Envoy 구성요소


- Cluster
envoy가 트래픽을 포워드할 수 있는 논리적인 서비스
실제 요청이 처리되는 IP 또는 Endpoint 묶음 - Endpoint
IP 주소, 실제 접근이 가능한 엔드포인트
엔드포인트가 모여서 하나의 Cluster가 됨 - Listener
무엇을 받을지 그리고 어떻게 처리할지 IP/Port를 바인딩
요청 처리 측면에서 다운스트림을 조정 - Route
Listener로 들어온 요청을 어디로 라우팅할 것인지 정의
라우팅 대상은 일반적으로 Cluster에 대해 이뤄짐 - Upstream
envoy 요청을 포워딩해서 연결하는 백엔드 네트워크 노드
Sidecar일 때, application app. 아닐 때, 원격 백엔드 - DownStream
envoy와 연결된 객체. Sidecar가 아닌 경우에는 원격 client.
4.3 Envoy 설치
4.3.1 Docker를 사용하여 Envoy 설치
출처: https://popappendtistory.com, https://www.envoyproxy.io/docs/envoy/latest/start/install#install
# docker 활용한 envoy 배포
docker pull envoyproxy/envoy:dev-68e64b4f7f834183cb7ba0ff96f0536dd50e7e92
docker run --rm envoyproxy/envoy:dev-68e64b4f7f834183cb7ba0ff96f0536dd50e7e92 --version
# envoy 명령어 사용
docker run --rm envoyproxy/envoy:dev-68e64b4f7f834183cb7ba0ff96f0536dd50e7e92 --version
docker run --rm envoyproxy/envoy:dev-68e64b4f7f834183cb7ba0ff96f0536dd50e7e92 --help
4.3.1 Envoy proxy 실습
# 데모 config 적용하여 실행
curl -O https://www.envoyproxy.io/docs/envoy/latest/_downloads/92dcb9714fb6bc288d042029b34c0de4/envoy-demo.yaml
envoy -c envoy-demo.yaml
# 에러 출력되면서 실행 실패
error initializing configuration 'envoy-demo.yaml': Field 'connect_timeout' is missing in: name: "service_envoyproxy_io"
# (터미널1) connect_timeout 추가 후 다시 실행
sed -i'' -r -e "/dns_lookup_family/a\ connect_timeout: 5s" envoy-demo.yaml
envoy -c envoy-demo.yaml
## 출력 로그
[2021-12-13T12:20:25.981Z] "GET / HTTP/1.1" 200 - 0 4472 1140 1080 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36" "a6999dc1-5e5e-4029-89b7-331b081fca27" "www.envoyproxy.io" "52.220.193.16:443"
[2021-12-13T12:22:21.634Z] "GET / HTTP/1.1" 200 - 0 17228 247 121 "-" "curl/7.74.0" "39b7b07d-3f79-4e61-81b4-2944bd041535" "www.envoyproxy.io" "167.99.78.230:443"
# (터미널2) 정보 확인
ss -tnlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 0.0.0.0:10000 0.0.0.0:* users:(("envoy",pid=8007,fd=18),("envoy",pid=8007,fd=16))
# 접속 테스트
curl -s http://127.0.0.1:10000 | grep -o "<title>.*</title>"
<title>Envoy Proxy - Home</title>
# 자신의PC(웹브라우저)에서 작업용EC2 접속 확인 >> 어느 사이트로 접속이 되는가?
echo -e "Envoy Proxy Demo = http://$(curl -s ipinfo.io/ip):10000"
# 연결 정보 확인
ss -tnp
# (터미널1) envoy 실행 취소(CTRL+C) 후 (관리자페이지) 설정 덮어쓰기 - 링크
cat <<EOT> envoy-override.yaml
admin:
address:
socket_address:
address: 0.0.0.0
port_value: 9902
EOT
envoy -c envoy-demo.yaml --config-yaml "$(cat envoy-override.yaml)"
# 웹브라우저에서 http://192.168.10.254:9902 접속 확인!
# 자신의PC(웹브라우저)에서 작업용EC2 접속 확인 >> 어느 사이트로 접속이 되는가?
echo -e "Envoy Proxy Demo = http://$(curl -s ipinfo.io/ip):9902"
5. CoreDNS

5.1 CoreDNS 기본 정보 확인
# CoreDNS Deployment, Configmap 확인
kubectl get deploy coredns -n kube-system -o yaml | kubectl neat | yh
kubectl get cm -n kube-system coredns -o yaml | kubectl neat | yh


5.2 EKS CoreDNS의 Addon 기능 topologySpreadConstraints 추가
topologySpreadConstraints
ㆍK8S가 Pod를 배포할 때 노드 간 균형을 맞추는 정책
ㆍCoreDNS를 실행하는 Pod가 Pod들이 스케줄링 시, 특정 노드에만 몰리지 않도록 여러 가용 영역(AZ)에 분산시킴
# EKS에서 CoreDNS 애드온 설명 확인
aws eks describe-addon-configuration --addon-name coredns --addon-version v1.10.1-eksbuild.2 --query 'configurationSchema' --output text | jq .
# EKS에서 CoreDNS 애드온 topologySpreadConstraints 매개변수 설명 확인
aws eks describe-addon-configuration --addon-name coredns --addon-version v1.10.1-eksbuild.2 --query 'configurationSchema' --output text | jq . | grep -A3 topologySpreadConstraints
# CoreDNS의 topologySpreadConstraints(노드 분산 정책) 확인
kubectl get deploy -n kube-system coredns -o yaml | grep topologySpreadConstraints -A8



5.2.1 EKS CoreDNS의 Addon 기능 topologySpreadConstraints 설정 파일 생성
# EKS에서 CoreDNS 애드온 상태 확인
aws eks describe-addon --cluster-name $CLUSTER_NAME --addon-name coredns | jq
# CoreDNS의 Addon 기능인 topologySpreadConstraints 설정을 파일로 생성
cat << EOT > topologySpreadConstraints.yaml
"topologySpreadConstraints":
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
k8s-app: kube-dns
EOT


5.2.2 EKS CoreDNS의 Addon 기능 topologySpreadConstraints 설정 적용
# EKS 애드온 설정 변경 (CoreDNS에 적용)
aws eks update-addon --cluster-name $CLUSTER_NAME --addon-name coredns --configuration-values 'file://topologySpreadConstraints.yaml'
# CoreDNS 애드온이 정상적으로 적용되었는지 확인
aws eks describe-addon --cluster-name $CLUSTER_NAME --addon-name coredns | jq


5.2.3 EKS CoreDNS의 배포 상태 확인
# CoreDNS의 실제 배포 상태 확인
kubectl get deploy coredns -n kube-system -o yaml | kubectl neat | yh

5.3 EKS CoreDNS의 Addon 기능 PDB(Pod Disruption Budget) 추가
Pod Disruption Budget (PDB)
ㆍCoreDNS와 같은 중요한 서비스가 일정 수 이상 중단되지 않도록 설정하는 방식
ㆍ예기치 않은 장애나 노드 유지보수 작업 중에 특정 수의 CoreDNS Pod가 항상 가동 중인 상태를 유지하도록 보장
ㆍ서비스에 대한 최소 가용 Pod 수 설정
# "coredns" add-on v1.9.3-eksbuid.5 and v1.9.3-eksbuid.6
kubectl get pdb -n kube-system coredns
NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
coredns 1 N/A 1 13h
# "coredns" add-on v1.10.1-eksbuild.2 and v1.10.1-eksbuild.3
kubectl get pdb -n kube-system coredns
NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
coredns N/A 1 1 27h
CoreDNS v1.9.3
- 최소 1개의 CoreDNS Pod가 항상 가용해야 한다는 설정
- 최대 1개의 Pod만 중단될 수 있는 제한
CoreDNS v1.10.1
- 최소 가용 Pod 수 설정이 없음
- 최대 1개의 Pod만 비가용 상태가 될 수 있는 제한
→ 최소 가용 Pod 수를 설정하지 않고, 대신 최대 비가용 Pod 수를 1로 설정하여 한 Pod가 중단되더라도 서비스에는 영향을 미치지 않도록 변경됨
5.3 EKS CoreDNS의 Addon 기능 lameduck 옵션 추가
lameduck
ㆍDNS 서비스를 중단하거나 업데이트할 때의 서비스 가용성을 높이고 DNS 쿼리 실패를 최소화하는 데 도움이 되는 기능
ㆍCoreDNS가 종료되기 전에 DNS 쿼리를 계속 처리
ㆍ예를 들어, CoreDNS가 리로드되거나 종료될 때, 서비스가 완전히 종료되기 전에 일정 시간 동안 DNS 요청을 처리하며 점진적으로 종료
ㆍ상태 엔드포인트가 여전히 200으로 응답하는 동안 DURATION초 동안 종료를 지연
ㆍ 플러그인에 lameduck을 추가하면 CoreDNS 포드 다시 시작(예: 상태 문제, 노드 종료 등으로 인해) 또는 배포 롤아웃 중에 DNS 확인 실패가 최소화됨
# CoreDNS 기본 정보 확인
kubectl get cm -n kube-system coredns -o yaml | kubectl neat | yh

kubectl get deploy coredns -n kube-system -o yaml | kubectl neat | yh

5.4 EKS CoreDNS의 Addon 기능 On Pod에 대한 Label 설정
# CoreDNS의 설정 파일인 ConfigMap에서 이미 ready 플러그인이 활성화 상태 확인
kubectl get cm -n kube-system coredns -o yaml | kubectl neat | yh

# 파드 Labels 확인
kubectl get deploy coredns -n kube-system -o yaml | kubectl neat | yh
# pod labels
aws eks describe-addon-configuration --addon-name coredns --addon-version v1.10.1-eksbuild.3 \
--query 'configurationSchema' --output text | jq . | grep -A4 '\"podLabels\"'
"podLabels": {
"properties": {},
"title": "The podLabels Schema",
"type": "object"
},
# YAML configuration blob
cat << EOT > podLabels.yaml
podLabels:
foo: bar
EOT
# apply changes : 적용 시 coredns 파드 재시작됨
aws eks update-addon --cluster-name $CLUSTER_NAME --addon-name coredns --configuration-values 'file://podLabels.yaml'
watch -d kubectl get pod -n kube-system
# wait a while until the add-on is ACTIVE again
aws eks describe-addon --cluster-name $CLUSTER_NAME --addon-name coredns
# 파드 Labels 확인
kubectl get deploy coredns -n kube-system -o yaml | kubectl neat | yh
kubectl get pod -n kube-system -l foo=bar
kubectl get po -n kube-system -l=k8s-app=kube-dns -o custom-columns="POD-NAME":.metadata.name,"POD-LABELS":.metadata.labels
6. Gateway API
7. 파드 간 속도 측정
8. Gateway API
9. kube-ops-view
kube-ops-view
# 설치
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set env.TZ="Asia/Seoul" --namespace kube-system
kubectl patch svc -n kube-system kube-ops-view -p '{"spec":{"type":"LoadBalancer"}}'
kubectl annotate service kube-ops-view -n kube-system "external-dns.alpha.kubernetes.io/hostname=kubeopsview.$MyDomain"
# 접속 주소 확인 : 각각 1배, 1.5배, 3배 크기
echo -e "Kube Ops View URL = http://kubeopsview.$MyDomain:8080"
echo -e "Kube Ops View URL = http://kubeopsview.$MyDomain:8080/#scale=1.5"
echo -e "Kube Ops View URL = http://kubeopsview.$MyDomain:8080/#scale=3.0"
# nginx 파드 배포
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/2/nginx-dp.yaml
kubectl apply -f nginx-dp.yaml
kubectl scale deployment nginx-deployment --replicas 15
kubectl scale deployment nginx-deployment --replicas 40
kubectl delete -f nginx-dp.yaml
'세미나 & 교육 & Tech' 카테고리의 다른 글
[Amazon EKS STUDY] #2주차 (이론) AWS VPC CNI (1) (0) | 2025.02.16 |
---|---|
[Amazon EKS STUDY] #1주차 (도전과제6~9) (0) | 2025.02.10 |
[Amazon EKS STUDY] #1주차 (도전과제1~5) EKS 원클릭 배포 가이드 (0) | 2025.02.10 |
[Amazon EKS STUDY] #1주차 (실습) eksctl를 활용한 EKS 배포 (0) | 2025.02.04 |
[Amazon EKS STUDY] #1주차 (이론) Amazon EKS의 개념 및 구성 요소 (0) | 2025.02.04 |