[AWES 3기] 2주차 스터디 내용 정리(2)

ajufresh·2025년 2월 15일
0

6. Service & AWS LoadBalancer Controller

서비스는 부하분산 장비와 유사하게 트래픽을 엔드포인트(서비스에 연동된 파드의 집합)로 전달된다. 고정 IP, Domain Name을 제공한다.

[서비스 종류]

  • Cluster IP

  • Node Port

  • Loadbalaner


기본값은 노드에 NodePort로 전달하고, IP 유형으로도 바꿀 수 있는데 이 경우에는 반드시 AWS LoadBalancer 컨트롤러 파드 및 정책 설정이 필요하다. 현재 배포된 로드밸런서는 Cloud Controller Manager를 통해 CLB/NLB Provisioning 한다.

[AWS LoadBalancer Controller 배포]

# 설치 전 CRD 확인
kubectl get crd

# Helm Chart 설치
helm repo add eks https://aws.github.io/eks-charts
helm repo update
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=$CLUSTER_NAME

설치 이후에 ingressclassparams.elbv2.k8s.aws, targetgroupbindings.elbv2.k8s.aws가 추가된 것을 확인할 수 있다. explain을 사용하면 설명을 확인할 수 있다.

kubectl get deployment -n kube-system aws-load-balancer-controller
kubectl describe deploy -n kube-system aws-load-balancer-controller
kubectl describe deploy -n kube-system aws-load-balancer-controller | grep 'Service Account'
  Service Account:  aws-load-balancer-controller
 
# 클러스터롤, 롤 확인
kubectl describe clusterrolebindings.rbac.authorization.k8s.io aws-load-balancer-controller-rolebinding
kubectl describe clusterroles.rbac.authorization.k8s.io aws-load-balancer-controller-role
...
PolicyRule:
  Resources                                     Non-Resource URLs  Resource Names  Verbs
  ---------                                     -----------------  --------------  -----
  targetgroupbindings.elbv2.k8s.aws             []                 []              [create delete get list patch update watch]
  events                                        []                 []              [create patch]
  ingresses                                     []                 []              [get list patch update watch]
  services                                      []                 []              [get list patch update watch]
  ingresses.extensions                          []                 []              [get list patch update watch]
  services.extensions                           []                 []              [get list patch update watch]
  ingresses.networking.k8s.io                   []                 []              [get list patch update watch]
  services.networking.k8s.io                    []                 []              [get list patch update watch]
  endpoints                                     []                 []              [get list watch]
  namespaces                                    []                 []              [get list watch]
  nodes                                         []                 []              [get list watch]
  pods                                          []                 []              [get list watch]
  endpointslices.discovery.k8s.io               []                 []              [get list watch]
  ingressclassparams.elbv2.k8s.aws              []                 []              [get list watch]
  ingressclasses.networking.k8s.io              []                 []              [get list watch]
  ingresses/status                              []                 []              [update patch]
  pods/status                                   []                 []              [update patch]
  services/status                               []                 []              [update patch]
  targetgroupbindings/status                    []                 []              [update patch]
  ingresses.elbv2.k8s.aws/status                []                 []              [update patch]
  pods.elbv2.k8s.aws/status                     []                 []              [update patch]
  services.elbv2.k8s.aws/status                 []                 []              [update patch]
  targetgroupbindings.elbv2.k8s.aws/status      []                 []              [update patch]
  ingresses.extensions/status                   []                 []              [update patch]
  pods.extensions/status                        []                 []              [update patch]
  services.extensions/status                    []                 []              [update patch]
  targetgroupbindings.extensions/status         []                 []              [update patch]
  ingresses.networking.k8s.io/status            []                 []              [update patch]
  pods.networking.k8s.io/status                 []                 []              [update patch]
  services.networking.k8s.io/status             []                 []              [update patch]
  targetgroupbindings.networking.k8s.io/status  []                 []              [update patch]
​

targetgroupbindings/status updat patch가 가능한 것을 확인할 수 있다.

[서비스/파드 배포 테스트 with NLB]

# 모니터링
watch -d kubectl get pod,svc,ep,endpointslices

# 디플로이먼트 & 서비스 생성
cat << EOF > echo-service-nlb.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-echo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: deploy-websrv
  template:
    metadata:
      labels:
        app: deploy-websrv
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: aews-websrv
        image: k8s.gcr.io/echoserver:1.5
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: svc-nlb-ip-type
  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-healthcheck-port: "8080"
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
spec:
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
  type: LoadBalancer
  loadBalancerClass: service.k8s.aws/nlb
  selector:
    app: deploy-websrv
EOF
kubectl apply -f echo-service-nlb.yaml

실시간으로 로드밸런서가 추가되는 것을 확인할 수 있다.

# 확인
aws elbv2 describe-load-balancers --query 'LoadBalancers[*].State.Code' --output text
kubectl get deploy,pod
kubectl get svc,ep,ingressclassparams,targetgroupbindings
kubectl get targetgroupbindings -o json | jq


AWS 콘솔에서도 로드밸런서가 Provisioning 되고 있는 것을 확인할 수 있다.

# AWS 관리콘솔에서 NLB 정보 확인
# 빠른 실습을 위해서 등록 취소 지연(드레이닝 간격) 수정 : 기본값 300초
echo-service-nlb.yaml 파일 IDE(VS code)에서 수정
..
apiVersion: v1
kind: Service
metadata:
  name: svc-nlb-ip-type
  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-healthcheck-port: "8080"
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
    service.beta.kubernetes.io/aws-load-balancer-target-group-attributes: deregistration_delay.timeout_seconds=60
...
kubectl apply -f echo-service-nlb.yaml


300 > 60초로 바뀐 것을 확인할 수 있다.

# 웹 접속 주소 확인
kubectl get svc svc-nlb-ip-type -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' | awk '{ print "Pod Web URL = http://"$1 }'

# 파드 로깅 모니터링
kubectl logs -l app=deploy-websrv -f
kubectl stern -l  app=deploy-websrv

접속하면 로깅이 잘 되는것을 확인할 수 있다.

# 분산 접속 확인
NLB=$(kubectl get svc svc-nlb-ip-type -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
curl -s $NLB
for i in {1..100}; do curl -s $NLB | grep Hostname ; done | sort | uniq -c | sort -nr
  52 Hostname: deploy-echo-55456fc798-2w65p
  48 Hostname: deploy-echo-55456fc798-cxl7z

# 지속적인 접속 시도 : 아래 상세 동작 확인 시 유용(패킷 덤프 등)
while true; do curl -s --connect-timeout 1 $NLB | egrep 'Hostname|client_address'; echo "----------" ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; done

56번 / 44번으로 트래픽이 분산된 것을 확인할 수 있다.

7. Ingress

내부의 서비스를 HTTP/HTTPS 통해 외부로 노출 하는 Web Proxy 역할을 한다.
AWS Load Balancer Controller + Ingress (ALB) IP 모드 동작 with AWS VPC CNI

[서비스/파드 배포 테스트 with Ingress(ALB)]

# 게임 파드와 Service, Ingress 배포
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: game-2048
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: game-2048
  name: deployment-2048
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: app-2048
  replicas: 2
  template:
    metadata:
      labels:
        app.kubernetes.io/name: app-2048
    spec:
      containers:
      - image: public.ecr.aws/l6m2t8p7/docker-2048:latest
        imagePullPolicy: Always
        name: app-2048
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  namespace: game-2048
  name: service-2048
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  type: NodePort
  selector:
    app.kubernetes.io/name: app-2048
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: game-2048
  name: ingress-2048
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: service-2048
              port:
                number: 80
EOF

# 모니터링
watch -d kubectl get pod,ingress,svc,ep,endpointslices -n game-2048

# 생성 확인
kubectl get ingress,svc,ep,pod -n game-2048
kubectl get-all -n game-2048
kubectl get targetgroupbindings -n game-2048

# ALB 생성 확인
aws elbv2 describe-load-balancers --query 'LoadBalancers[?contains(LoadBalancerName, `k8s-game2048`) == `true`]' | jq
ALB_ARN=$(aws elbv2 describe-load-balancers --query 'LoadBalancers[?contains(LoadBalancerName, `k8s-game2048`) == `true`].LoadBalancerArn' | jq -r '.[0]')
aws elbv2 describe-target-groups --load-balancer-arn $ALB_ARN
TARGET_GROUP_ARN=$(aws elbv2 describe-target-groups --load-balancer-arn $ALB_ARN | jq -r '.TargetGroups[0].TargetGroupArn')
aws elbv2 describe-target-health --target-group-arn $TARGET_GROUP_ARN | jq

# Ingress 확인
kubectl describe ingress -n game-2048 ingress-2048
kubectl get ingress -n game-2048 ingress-2048 -o jsonpath="{.status.loadBalancer.ingress[*].hostname}{'\n'}"

# 게임 접속 : ALB 주소로 웹 접속
kubectl get ingress -n game-2048 ingress-2048 -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' | awk '{ print "Game URL = http://"$1 }'

# 파드 IP 확인
kubectl get pod -n game-2048 -owide


pod, ingress, seevice, endpoints가 배포된 것을 확인할 수 있다.


모든 패스(*)로 들어온 것은 service-2048로 넘기겠다고 설정이 되어 있다.

service-2048의 endpoint에 연결되어 있는 파드는 192.168.1.225:80, 192.168.3.97:80이다.


리소스 맵에서는 ALB에서 Pod IP로 직접적으로 접근하는 것을 확인할 수 있다.

실습 이후 리소스 삭제

kubectl delete ingress ingress-2048 -n game-2048
kubectl delete svc service-2048 -n game-2048 && kubectl delete deploy deployment-2048 -n game-2048 && kubectl delete ns game-2048

8. ExternalDNS

서비스/인그레스 생성 시 도메인을 설정하면, AWS(Route 53) A 레코드(TXT 레코드)로 자동으로 생성하고 삭제하는 역할을 한다.

[AWS Route 53 정보 확인 & 변수 지정 : Public 도메인 소유를 하고 계셔야 합니다!]

# 자신의 도메인 변수 지정 : 소유하고 있는 자신의 도메인을 입력하시면 됩니다
MyDomain=ajufresh.com

# 자신의 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

Host를 관리하기 위해선 HostedZoneId가 필요하기 때문에 조회한 뒤 변수로 지정한다.

[ExternalDNS 설치]

# 자신의 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
cat externaldns.yaml
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

[Service(NLB) + 도메인 연동(ExternalDNS)]

# 테트리스 디플로이먼트 배포
cat <<EOF | kubectl apply -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

도메인과 연결된 것을 확인할 수 있다.


AWS 콘솔에서도 A 레코드가 추가된 것을 확인할 수 있다.

# 확인
dig +short tetris.$MyDomain @8.8.8.8
dig +short tetris.$MyDomain

# 도메인 체크
echo -e "My Domain Checker Site1 = https://www.whatsmydns.net/#A/tetris.$MyDomain"
echo -e "My Domain Checker Site2 = https://dnschecker.org/#A/tetris.$MyDomain"

# 웹 접속 주소 확인 및 접속
echo -e "Tetris Game URL = http://tetris.$MyDomain"

접속하면 잘 나오는 것을 확인할 수 있다.

kubectl delete deploy,svc tetris

삭제하면 A 레코드도 같이 삭제된다.

9. CoreDNS

쿠버네티스의 DNS 쿼리 Flow

10. Topology Aware Routing

기존에는 AZ간 통신을 할 때는 과금이 생기고, AZ 내에서 통신할 때에는 과금이 발생하지 않는다. 그래서 이걸 최적화하기 위해 같은 AZ 내에서만 접근할 수 있도록 하는 기술이 Topology Aware Routing이다. (Cross 비용을 절감하기 위해) => 결국 이걸 구현하는건 iptable rule

[테스트를 위한 디플로이먼트와 서비스 배포]

kubectl get node --label-columns=topology.kubernetes.io/zone

3개의 AZ에 배포가 되어 있다.

# 테스트를 위한 디플로이먼트와 서비스 배포
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-echo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: deploy-websrv
  template:
    metadata:
      labels:
        app: deploy-websrv
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: websrv
        image: registry.k8s.io/echoserver:1.5
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: svc-clusterip
spec:
  ports:
    - name: svc-webport
      port: 80
      targetPort: 8080
  selector:
    app: deploy-websrv
  type: ClusterIP
EOF

# 확인
kubectl get deploy,svc,ep,endpointslices
kubectl get pod -owide
kubectl get svc,ep svc-clusterip
kubectl get endpointslices -l kubernetes.io/service-name=svc-clusterip
kubectl get endpointslices -l kubernetes.io/service-name=svc-clusterip -o yaml

# 접속 테스트를 수행할 클라이언트 파드 배포
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: netshoot-pod
spec:
  containers:
  - name: netshoot-pod
    image: nicolaka/netshoot
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0
EOF

# 확인
kubectl get pod -owide

[테스트 파드(netshoot-pod)에서 ClusterIP 접속 시 부하분산 확인 : AZ(zone) 상관없이 랜덤 확률 부하분산 동작]

# 디플로이먼트 파드가 배포된 AZ(zone) 확인
kubectl get pod -l app=deploy-websrv -owide

# 테스트 파드(netshoot-pod)에서 ClusterIP 접속 시 부하분산 확인
kubectl exec -it netshoot-pod -- curl svc-clusterip | grep Hostname
Hostname: deploy-echo-7f67d598dc-h9vst

kubectl exec -it netshoot-pod -- curl svc-clusterip | grep Hostname
Hostname: deploy-echo-7f67d598dc-45trg

# 100번 반복 접속 : 3개의 파드로 AZ(zone) 상관없이 랜덤 확률 부하분산 동작
kubectl exec -it netshoot-pod -- zsh -c "for i in {1..100}; do curl -s svc-clusterip | grep Hostname; done | sort | uniq -c | sort -nr"
  35 Hostname: deploy-echo-7f67d598dc-45trg
  33 Hostname: deploy-echo-7f67d598dc-hg995
  32 Hostname: deploy-echo-7f67d598dc-h9vst

다른 AZ에 있는 파드에도 접근하는 것을 확인할 수 있다.

[(심화) IPTables 정책 확인 : ClusterIP는 KUBE-SVC-Y → KUBE-SEP-Z… (3곳) ⇒ 즉, 3개의 파드로 랜덤 확률 부하분산 동작]

ssh ec2-user@$N1 sudo iptables -t nat -nvL
ssh ec2-user@$N1 sudo iptables -v --numeric --table nat --list PREROUTING
ssh ec2-user@$N1 sudo iptables -v --numeric --table nat --list KUBE-SERVICES
  305 18300 KUBE-SVC-KBDEBIL6IU6WL7RF  tcp  --  *      *       0.0.0.0/0            10.100.155.216       /* default/svc-clusterip:svc-webport cluster IP */ tcp dpt:80
  ...


# 노드1에서 SVC 정책 확인 : SEP(Endpoint) 파드 3개 확인 >> 즉, 3개의 파드로 랜덤 확률 부하분산 동작
ssh ec2-user@$N1 sudo iptables -v --numeric --table nat --list KUBE-SVC-KBDEBIL6IU6WL7RF
  

서비스 세개에 일정 확률로(30%, 50%(2개 남았으니까), 100%) Pod IP로 전달하는 것을 확인할 수 있다. => 랜덤 부하분산이 된다.

이 rule은 모든 워커 노드에 동일하게 저장되어 있다.

[Topology Mode(구 Aware Hint) 설정 후 테스트 파드(netshoot-pod)에서 ClusterIP 접속 시 부하분산 확인 : 같은 AZ(zone)의 목적지 파드로만 접속]

# Topology Aware Routing 설정 : 서비스에 annotate에 아래처럼 추가
kubectl annotate service svc-clusterip "**service.kubernetes.io/topology-mode=auto"**

# endpointslices 확인 시, 기존에 없던 hints 가 추가되어 있음 >> 참고로 describe로는 hints 정보가 출력되지 않음
**kubectl get endpointslices -l kubernetes.io/service-name=svc-clusterip -o yaml**
apiVersion: v1
items:
- addressType: IPv4
  apiVersion: discovery.k8s.io/v1
  endpoints:
  **- addresses:**
    - 192.168.3.13
    conditions:
      ready: true
      serving: true
      terminating: false
    **hints:
      forZones:
      - name: ap-northeast-2c**
    **nodeName**: **ip-192-168-3-228**.ap-northeast-2.compute.internal
    targetRef:
      kind: Pod
      name: deploy-echo-7f67d598dc-hg995
      namespace: default
      uid: c1ce0e9c-14e7-417d-a1b9-2dfd54da8d4a
    **zone**: ap-northeast-2c
  **- addresses:**
    - 192.168.2.65
    conditions:
      ready: true
      serving: true
      terminating: false
    **hints:
      forZones:
      - name: ap-northeast-2b**
    **nodeName: ip-192-168-2-248**.ap-northeast-2.compute.internal
    targetRef:
      kind: Pod
      name: deploy-echo-7f67d598dc-h9vst
      namespace: default
      uid: 77af6a1b-c600-456c-96f3-e1af621be2af
    **zone**: ap-northeast-2b
  **- addresses:**
    - 192.168.1.240
    conditions:
      ready: true
      serving: true
      terminating: false
    **hints:
      forZones:
      - name: ap-northeast-2a**
    **nodeName: ip-192-168-1-225**.ap-northeast-2.compute.internal
    targetRef:
      kind: Pod
      name: deploy-echo-7f67d598dc-45trg
      namespace: default
      uid: 53ca3ac7-b9fb-4d98-a3f5-c312e60b1e67
    **zone**: ap-northeast-2a
  kind: EndpointSlice
...

hints 설정이 추가된 것을 확인할 수 있다.

# 100번 반복 접속 : 테스트 파드(netshoot-pod)와 같은 AZ(zone)의 목적지 파드로만 접속
kubectl exec -it netshoot-pod -- zsh -c "for i in {**1..100**}; do curl -s **svc-clusterip** | grep Hostname; done | sort | uniq -c | sort -nr"
  100 Hostname: deploy-echo-7f67d598dc-45trg


이번에는 아까와 달리 같은 AZ에만 있는 노드에 접근하는 것을 확인할 수 있다.

[(심화) IPTables 정책 확인 : ClusterIP는 KUBE-SVC-Y → KUBE-SEP-Z… (1곳, 해당 노드와 같은 AZ에 배포된 파드만 출력) ⇒ 동일 AZ간 접속]

ssh ec2-user@$N1 sudo iptables -v --numeric --table nat --list KUBE-SVC-KBDEBIL6IU6WL7RF

아까와 똑같이 명령어를 입력해본다.

아까는 rule이 3개가 보였는데 이번에는 1개만 보이는 것을 확인할 수 있다.
=> 동일 AZ로의만 접근만 허용함

만약 AZ마다 파드가 없으면 다른 AZ로 경로가 변경될 수 있도록 rule을 만들어주고 hints는 사라지게 된다. 그렇기 때문에 장애가 날 일은 없다.

10. Amazon EKS now supports Amazon Application Recovery Controller

12. Using AWS Load Balancer Controller for blue/green deployment, canary deployment and A/B testing

[Deploy the sample application version 1 and version 2]

#
**git clone https://github.com/paulbouwer/hello-kubernetes.git**
tree hello-kubernetes/

# Install sample application version 1
helm install --create-namespace --namespace hello-kubernetes v1 \
  ./hello-kubernetes/deploy/helm/hello-kubernetes \
  --set message="You are reaching hello-kubernetes version 1" \
  --set ingress.configured=true \
  --set service.type="ClusterIP"

# Install sample application version 2
helm install --create-namespace --namespace hello-kubernetes v2 \
  ./hello-kubernetes/deploy/helm/hello-kubernetes \
  --set message="You are reaching hello-kubernetes version 2" \
  --set ingress.configured=true \
  --set service.type="ClusterIP"

# 확인
kubectl get-all -n hello-kubernetes
kubectl get pod,svc,ep -n hello-kubernetes
kubectl get pod -n hello-kubernetes --label-columns=app.kubernetes.io/instance,pod-template-hash

[Deploy ingress and test the blue/green deployment]

cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: "hello-kubernetes"
  namespace: "hello-kubernetes"
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/actions.blue-green: |
      {
        "type":"forward",
        "forwardConfig":{
          "targetGroups":[
            {
              "serviceName":"hello-kubernetes-v1",
              "servicePort":"80",
              "weight":100
            },
            {
              "serviceName":"hello-kubernetes-v2",
              "servicePort":"80",
              "weight":0
            }
          ]
        }
      }
  labels:
    app: hello-kubernetes
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: blue-green
                port:
                  name: use-annotation
EOF

annotation에 따라 target-group을 선택한다 (hello-kubernetes-v1, hello-kubernetes-v2)

현재는 v1로 100%로 이동하는 것을 확인할 수 있다.

[Blue/green deployment]

#
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: "hello-kubernetes"
  namespace: "hello-kubernetes"
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/actions.blue-green: |
      {
        "type":"forward",
        "forwardConfig":{
          "targetGroups":[
            {
              "serviceName":"hello-kubernetes-v1",
              "servicePort":"80",
              "weight":0
            },
            {
              "serviceName":"hello-kubernetes-v2",
              "servicePort":"80",
              "weight":100
            }
          ]
        }
      }
  labels:
    app: hello-kubernetes
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: blue-green
                port:
                  name: use-annotation
EOF

# 확인
kubectl describe ingress -n hello-kubernetes 

조금 있다가 확인해보면 100%로 라우팅하는 TG가 바뀐 것을 확인할 수 있다.

(리소스 삭제)

kubectl delete ingress -n hello-kubernetes hello-kubernetes && kubectl delete ns hello-kubernetes

17. 네트워크 분석 툴

[Kubeskoop 설치 및 웹 접속]

kubectl apply -f https://raw.githubusercontent.com/alibaba/kubeskoop/main/deploy/skoopbundle.yaml
kubectl patch service webconsole -n kubeskoop -p '{"spec": {"type": "LoadBalancer"}}'
kubectl patch service prometheus-service -n kubeskoop -p '{"spec": {"type": "LoadBalancer"}}'
kubectl patch service grafana -n kubeskoop -p '{"spec": {"type": "LoadBalancer"}}'

# cpu 부족하니, 미사용 파드/디플로이먼트는 삭제(kube-ops-view, netshootpod 등) 혹은 워커노드를 증설
kubectl get-all -n kubeskoop
kubectl get pod -n kubeskoop

#
kubectl get svc -n kubeskoop webconsole

# kubeskoop 웹 접속 : admin / kubeskoop
kubectl get svc -n kubeskoop webconsole -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' | awk '{ print "KubeSkoop URL = http://"$1""}'

# 프로메테우스 웹 접속
kubectl get svc -n kubeskoop prometheus-service -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' | awk '{ print "prometheus URL = http://"$1""}'

# 그라파나 웹 접속 : admin / kubeskoop
kubectl get svc -n kubeskoop grafana -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' | awk '{ print "grafana URL = http://"$1""}'

웹 콘솔로 확인이 가능하다. 여기에서 프로메테우스, 그라파나도 접속 가능하고 패킷캡처나 연결 분석도 가능하다.

profile
공블로그

0개의 댓글

관련 채용 정보