교육, 커뮤니티 후기/PKOS 쿠버네티스 스터디

PKOS 쿠버네티스 스터디 2주차 - 쿠버네티스 네트워크

Somaz 2023. 1. 16. 00:17
728x90
반응형

출처 : 이현수님

 

Overview

가시다님이 진행하시는 쿠버네티스 스터디 2주차가 되었다.

 

오늘은 쿠버네티스 네트워크에 대해 공부를 해보려고 한다.

 

2주차 과제 내용

 

[과제1]

파드간 통신 시 tcpdump 내용을 확인하고 관련 스샷을 올려주세요.

 

Pod 1 -> Pod 2 any 통신

 

Pod 1 -> Pod 2 ens5 통신

 

Pod 1 -> Pod 2 ens6 통신 실패

AWS VPC ENI는 첫번째 ENI1(ens5)로만 통신이 되도록 iptables나 라우팅 테이블이 그렇게 설정되어있다.

따라서 ENI2(ens6)으로는 통신되지 않는다.

 

 

[과제2]

어떤 방식을 사용하더라고 좋으니, 워커 노드 1대에 100대의 파드가 배포되게 설정하고 관련 스샷을 올려주세요

  • 해결방안 : Prefix Delegation, WARM & MIN IP/Prefix Targets

 

Prefix Delegation을 사용하여 100대의 파드가 배포되게 설정해보자.

아래의 사이트를 참고하였다.

https://trans.yonghochoi.com/translations/aws_vpc_cni_increase_pods_per_node_limits.ko

 

결과 사진

 

작업 내용

kops 원클릭 배포를 사용하여 c5.large node 1대를 배포한다.

c5.large 스펙은 아래와 같다.

모델 vCPU 메모리(GiB) 인스턴스 스토리지(GB) 네트워크 대역폭(Gbps) EBS 대역폭(Mbps)
c5.large 2 4 EBS 전용 최대 10 최대 4,750

 

생성이 완료되었다.

  • 확인해보니 t3.medium으로도 가능하다고 한다.

 

(somaz:N/A) [root@kops-ec2 ~]# kubectl get nodes
NAME                  STATUS   ROLES           AGE    VERSION
i-074d6c35d90fc4c1d   Ready    node            46s    v1.24.9
i-0b90857120855f2f6   Ready    control-plane   2m6s   v1.24.9

 

CNI 버전 확인

(somaz:N/A) [root@kops-ec2 ~]# kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
amazon-k8s-cni-init:v1.11.4
amazon-k8s-cni:v1.11.4

 

c5.x 인스턴스의 ENI 정보를 확인한다.

# c5 타입의 정보(필터) 확인
(somaz:N/A) [root@kops-ec2 ~]# aws ec2 describe-instance-types --filters Name=instance-type,Values=c5.* \
>  --query "InstanceTypes[].{Type: InstanceType, MaxENI: NetworkInfo.MaximumNetworkInterfaces, IPv4addr: NetworkInfo.Ipv4AddressesPerInterface}" \
>  --output table
---------------------------------------
|        DescribeInstanceTypes        |
+----------+----------+---------------+
| IPv4addr | MaxENI   |     Type      |
+----------+----------+---------------+
|  30      |  8       |  c5.4xlarge   |
|  15      |  4       |  c5.xlarge    |
|  50      |  15      |  c5.metal     |
|  30      |  8       |  c5.12xlarge  |
|  50      |  15      |  c5.24xlarge  |
|  30      |  8       |  c5.9xlarge   |
|  15      |  4       |  c5.2xlarge   |
|  10      |  3       |  c5.large     |
|  50      |  15      |  c5.18xlarge  |
+----------+----------+---------------+

 

Node의 Allocatable pod 개수를 확인한다.

(somaz:N/A) [root@kops-ec2 ~]# kubectl describe node |grep Allocatable: -A6
Allocatable:
  cpu:                2
  ephemeral-storage:  119703055367
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             3698676Ki
  pods:               29
--
Allocatable:
  cpu:                2
  ephemeral-storage:  59763732382
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             3854320Ki
  pods:               17

 

maxPods 개수를 늘린다.

(somaz:N/A) [root@kops-ec2 ~]# kops edit cluster
...
  kubelet:
    anonymousAuth: false
    maxPods: 110
...

 

 

접두사 할당 모드 활성화(Enabling prefix assignment mode) 후 WARM_PREFIX_TARTGET을 1로 한다.

(somaz:N/A) [root@kops-ec2 ~]# kubectl set env daemonset aws-node -n kube-system ENABLE_PREFIX_DELEGATION=true
daemonset.apps/aws-node env updated

(somaz:N/A) [root@kops-ec2 ~]# kubectl set env ds aws-node -n kube-system WARM_PREFIX_TARGET=1
daemonset.apps/aws-node env updated

(somaz:N/A) [root@kops-ec2 ~]# kubectl describe daemonsets.apps -n kube-system aws-node | egrep 'ENABLE_PREFIX_DELEGATION|WARM_PREFIX_TARGET'
      ENABLE_PREFIX_DELEGATION:  true
      WARM_PREFIX_TARGET:        1
      ENABLE_PREFIX_DELEGATION:               true
      WARM_PREFIX_TARGET:                     1

 

kops cluster update를 진행한다.

(somaz:N/A) [root@kops-ec2 ~]# kops update cluster --yes && echo && sleep 5 && kops rolling-update cluster
W0125 14:26:40.668176    4212 builder.go:231] failed to digest image "602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon-k8s-cni:v1.11.4"
W0125 14:26:41.129000    4212 builder.go:231] failed to digest image "602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon-k8s-cni-init:v1.11.4"
I0125 14:26:45.064912    4212 executor.go:111] Tasks: 0 done / 103 total; 48 can run
I0125 14:26:45.972186    4212 executor.go:111] Tasks: 48 done / 103 total; 21 can run
I0125 14:26:46.741629    4212 executor.go:111] Tasks: 69 done / 103 total; 28 can run
I0125 14:26:47.492451    4212 executor.go:111] Tasks: 97 done / 103 total; 3 can run
I0125 14:26:47.596862    4212 executor.go:111] Tasks: 100 done / 103 total; 3 can run
I0125 14:26:47.686129    4212 executor.go:111] Tasks: 103 done / 103 total; 0 can run
I0125 14:26:48.434643    4212 dns.go:238] Pre-creating DNS records
I0125 14:26:48.493909    4212 update_cluster.go:326] Exporting kubeconfig for cluster
kOps has set your kubectl context to somaz.link
W0125 14:26:48.512214    4212 update_cluster.go:350] Exported kubeconfig with no user authentication; use --admin, --user or --auth-plugin flags with `kops export kubeconfig`

Cluster changes have been applied to the cloud.


Changes may require instances to restart: kops rolling-update cluster


NAME                    STATUS          NEEDUPDATE      READY   MIN     TARGET  MAX     NODES
master-ap-northeast-2a  NeedsUpdate     1               0       1       1       1       1
nodes-ap-northeast-2a   NeedsUpdate     1               0       1       1       1       1
nodes-ap-northeast-2c   Ready           0               0       0       0       0       0

Must specify --yes to rolling-update.


(somaz:N/A) [root@kops-ec2 ~]# kops rolling-update cluster --yes

 

업데이트 후 Node의 Allocatable pod 개수를 확인한다

(somaz:N/A) [root@kops-ec2 ~]# kubectl describe node |grep Allocatable: -A6
Allocatable:
  cpu:                2
  ephemeral-storage:  59763732382
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             3854328Ki
  pods:               110

 

LimitRange 정책을 삭제한다.

(somaz:N/A) [root@kops-ec2 ~]# kubectl describe limitranges
Name:       limits
Namespace:  default
Type        Resource  Min  Max  Default Request  Default Limit  Max Limit/Request Ratio
----        --------  ---  ---  ---------------  -------------  -----------------------
Container   cpu       -    -    100m             -              -

(somaz:N/A) [root@kops-ec2 ~]# kubectl delete limitranges limits
limitrange "limits" deleted

 

 

파드 100개가 생성되는지 nginx pod로 확인해본다.

(somaz:N/A) [root@kops-ec2 ~]# kubectl apply -f ~/pkos/2/nginx-dp.yaml
deployment.apps/nginx-deployment created

(somaz:N/A) [root@kops-ec2 ~]# kubectl scale deployment nginx-deployment --replicas=30
deployment.apps/nginx-deployment scaled

(somaz:N/A) [root@kops-ec2 ~]# kubectl get deployment nginx-deployment
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   30/30   30           30          35s


(somaz:N/A) [root@kops-ec2 ~]# kubectl scale deployment nginx-deployment --replicas=100
deployment.apps/nginx-deployment scaled

(somaz:N/A) [root@kops-ec2 ~]# kubectl get deployment nginx-deployment
NAME               READY     UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   100/100   100          100         100s

 

워커 노드에 들어가 네트워크를 확인해본다.

(somaz:N/A) [root@kops-ec2 ~]# aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value}" --filters Name=instance-state-name,Values=running --output table
---------------------------------------------------------------
|                      DescribeInstances                      |
+--------------------------------------------+----------------+
|                InstanceName                |  PublicIPAdd   |
+--------------------------------------------+----------------+
|  master-ap-northeast-2a.masters.somaz.link |  52.78.92.100  |
|  nodes-ap-northeast-2a.somaz.link          |  3.36.61.175   |
|  kops-ec2                                  |  54.180.9.94   |
+--------------------------------------------+----------------+

(somaz:N/A) [root@kops-ec2 ~]# W1PIP=3.36.61.175

(somaz:N/A) [root@kops-ec2 ~]# ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP

ubuntu@i-0c1fa4e451a8e4f34:~$ ip -c link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether 02:9f:34:f0:09:ce brd ff:ff:ff:ff:ff:ff
    altname enp0s5
3: eni8ec657da2b7@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP mode DEFAULT group default
    link/ether f6:cb:d4:bd:10:7b brd ff:ff:ff:ff:ff:ff link-netns cni-7b863180-b549-af51-90f6-461010a5f043
4: eni617b6dca1c7@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP mode DEFAULT group default
    link/ether 0e:8e:97:c7:7d:a0 brd ff:ff:ff:ff:ff:ff link-netns cni-44c2a748-6dad-94b6-5cd0-fc11849ef512
5: eni5c7aa6ebe37@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP mode DEFAULT group default
    link/ether da:09:bd:63:8b:9f brd ff:ff:ff:ff:ff:ff link-netns cni-a55591c4-ae4e-4fb5-1532-a78c78c336fd
6: eni09cf4ff0e85@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP mode DEFAULT group default
    link/ether 72:0f:4f:3b:0c:f6 brd ff:ff:ff:ff:ff:ff link-netns cni-0f9ff967-def9-d071-5a63-615476707760
23: eni074549d1a1b@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP mode DEFAULT group default
    link/ether 02:df:4f:c0:70:22 brd ff:ff:ff:ff:ff:ff link-netns cni-9e63f294-7a51-0d83-5d92-35fa2d10fbf7
24: eni27492347c98@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP mode DEFAULT group default
    link/ether 86:07:1c:83:fc:32 brd ff:ff:ff:ff:ff:ff link-netns cni-c57d2653-3351-6dca-5fbb-a9aae728f652
    ...
    118: enica6bfd7fb92@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP mode DEFAULT group default
    link/ether c6:b5:a8:38:10:b9 brd ff:ff:ff:ff:ff:ff link-netns cni-18c31f76-abc1-d183-12e9-16996ea8fd62
119: eniae9c9530721@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP mode DEFAULT group default
    link/ether 4a:22:24:4e:31:1a brd ff:ff:ff:ff:ff:ff link-netns cni-ef317151-c345-7ff9-7834-463489705b1c
120: eni1d4533ab526@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP mode DEFAULT group default
    link/ether 96:37:17:04:f0:35 brd ff:ff:ff:ff:ff:ff link-netns cni-173e2a7a-af25-0f82-283b-7ac1532496ad
121: eni5d8c12d7dfd@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP mode DEFAULT group default
    link/ether 06:4a:97:b1:90:8b brd ff:ff:ff:ff:ff:ff link-netns cni-74bf568b-b5e5-a1d2-d93f-3ad797ad9571
122: eni6944f438782@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP mode DEFAULT group default
    link/ether da:4a:25:c6:da:a7 brd ff:ff:ff:ff:ff:ff link-netns cni-777d672e-00b0-90bb-2c40-d72663b8ac6e

 

 

 

 

 

[과제3]

서비스(NLB)/파드 배포 시 ExternalDNS 설정해서, 각자 자신의 도메인으로 NLB를 통해 애플리케이션(파드)로 접속해보고 관련 스샷을 올려주세요

  • 퍼블릭 도메인이 없는 멤버분들은, ExternalDNS 제외하고 NLB 도메인으로 접속한 결과를 올려주세요

 

결과 사진

 

작업 내용

 

git clone 후 네임스페이스 생성 후 변경

# git clone
(somaz:N/A) [root@kops-ec2 ~]# git clone https://github.com/dockersamples/example-voting-appCloning into 'example-voting-app'...
remote: Enumerating objects: 1080, done.
remote: Total 1080 (delta 0), reused 0 (delta 0), pack-reused 1080
Receiving objects: 100% (1080/1080), 1.01 MiB | 15.96 MiB/s, done.
Resolving deltas: 100% (407/407), done.

(somaz:N/A) [root@kops-ec2 ~]# cd example-voting-app/k8s-specifications/

(somaz:N/A) [root@kops-ec2 k8s-specifications]# tree
.
├── db-deployment.yaml
├── db-service.yaml
├── redis-deployment.yaml
├── redis-service.yaml
├── result-deployment.yaml
├── result-service.yaml
├── vote-deployment.yaml
├── vote-service.yaml
└── worker-deployment.yaml

0 directories, 9 files

# 네임스페이스 생성 후 변경
(somaz:N/A) [root@kops-ec2 k8s-specifications]# kubectl create ns vote
namespace/vote created

(somaz:N/A) [root@kops-ec2 k8s-specifications]# kubectl ns vote
Context "somaz.link" modified.
Active namespace is "vote".

 

서비스 파일 변경

# 서비스 파일 변경
(somaz:vote) [root@kops-ec2 k8s-specifications]# rm -rf vote-service.yaml result-service.yaml

(somaz:vote) [root@kops-ec2 k8s-specifications]# cp ~/pkos/2/vote-service.yaml .
(somaz:vote) [root@kops-ec2 k8s-specifications]# cp ~/pkos/2/result-service.yaml .

(somaz:vote) [root@kops-ec2 k8s-specifications]# cat vote-service.yaml | yh
apiVersion: v1
kind: Service
metadata:
  labels:
    app: vote
  name: vote
  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: "80"
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
spec:
  loadBalancerClass: service.k8s.aws/nlb
  type: LoadBalancer
  ports:
  - name: "vote-service"
    port: 80
    targetPort: 80
  selector:
    app: vote

(somaz:vote) [root@kops-ec2 k8s-specifications]# cat result-service.yaml | yh
apiVersion: v1
kind: Service
metadata:
  labels:
    app: result
  name: result
  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: "80"
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
spec:
  loadBalancerClass: service.k8s.aws/nlb
  type: LoadBalancer
  ports:
  - name: "result-service"
    port: 80
    targetPort: 80
  selector:
    app: result

 

서비스 배포 후 다른창 열어서 모니터링

# 서비스 배포 
(somaz:N/A) [root@kops-ec2 k8s-specifications]# kubectl apply -f .
deployment.apps/db created
service/db created
deployment.apps/redis created
service/redis created
deployment.apps/result created
service/result created
deployment.apps/vote created
service/vote created
deployment.apps/worker created

# 다른창 열어서 모니터링
(somaz:N/A) [root@kops-ec2 ~]# watch "kubectl get po,svc"
...
Every 2.0s: kubectl get po,svc                                      Sun Jan 15 22:33:30 2023

NAME                         READY   STATUS    RESTARTS   AGE
pod/db-58478bbc69-gcmxd      1/1     Running   0          37s
pod/pod-1                    1/1     Running   0          114m
pod/pod-2                    1/1     Running   0          112m
pod/redis-549d6f9fc6-pdj5n   1/1     Running   0          37s
pod/result-b8f984f98-r22zn   1/1     Running   0          37s
pod/vote-64bf8cb656-6b9xt    1/1     Running   0          37s
pod/worker-f54cd56ff-dtrrw   1/1     Running   0          37s

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/db           ClusterIP   100.71.9.42      <none>        5432/TCP         37s
service/kubernetes   ClusterIP   100.64.0.1       <none>        443/TCP          141m
service/redis        ClusterIP   100.67.183.131   <none>        6379/TCP         37s
service/result       NodePort    100.70.213.29    <none>        5001:31001/TCP   37s
service/vote         NodePort    100.67.102.38    <none>        5000:31000/TCP   37s

 

ExternalDNS 추가

# ExternalDNS 추가
## 각자 자신의 도메인 정보 입력
(somaz:N/A) [root@kops-ec2 k8s-specifications]# MyDOMAIN1=vote.somaz.link
(somaz:N/A) [root@kops-ec2 k8s-specifications]# MyDOMAIN2=result.somaz.link

(somaz:N/A) [root@kops-ec2 k8s-specifications]# kubectl annotate service vote "external-dns.alpha.kubernetes.io/hostname=$MyDOMAIN1."
service/vote annotated

(somaz:N/A) [root@kops-ec2 k8s-specifications]# kubectl annotate service result "external-dns.alpha.kubernetes.io/hostname=$MyDOMAIN2."
service/result annotated

(somaz:N/A) [root@kops-ec2 ~]# kubectl describe svc vote | grep Annotations: -A4
Annotations:              external-dns.alpha.kubernetes.io/hostname: vote.somaz.link.
                          service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: true
                          service.beta.kubernetes.io/aws-load-balancer-healthcheck-port: 80
                          service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
                          service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing

(somaz:vote) [root@kops-ec2 ~]# kubectl describe svc result | grep Annotations: -A4
Annotations:              external-dns.alpha.kubernetes.io/hostname: result.somaz.link.
                          service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: true
                          service.beta.kubernetes.io/aws-load-balancer-healthcheck-port: 80
                          service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
                          service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing

 

[과제4]

NLB 에 TLS 적용하기

 

  • 사전 준비 : 공인도메인 소유, AWS Route53 도메인등록 상태, NLB 가 위치한 리전(서울)의 인증서 요청/발급 완료상태, ExternalDNS 준비완료상태

 

결과 사진

 

 

작업 내용

 

[과제3]을 하면서 나머지는 전부 완료한 상태이고, 도메인 인증서를 발급하려고 한다.

 

 

도메인 인증서 발급

 

먼저 AWS의 Certificate Manager로 생성한 인증서는 무료이다.

 

1. AWS Certificate Manager로 들어가 인증서 요청을 한다.

 

 

2. 퍼블릭 인증서 요청을 선택 후 다음으로 이동한다.

 

 

3. 본인이 SSL을 설치하고자 하는 도메인을 등록합니다.

아래와 같이 *.somaz.com 식으로 등록하면 *로 인해 하위 도메인들이 모두 사용할 수 있는 인증서가 된다.

(ex.www.somaz.com)

 

다만, somaz.com에선 사용할 수 없는 인증서이라서 2차 도메인(somaz.com)과 3차 도메인(*.somaz.com)을 사용하려면 아래와 같이 도메인 이름을 모두 추가한다.

 

그리고 검증방법을 DNS 검증을 선택 후 요청을 누른다.

 

요청 후 확인을 해보면 인증서가 검증 대기중으로 떠있다.

 

그리고 해당 인증서로 들어가 Route 53에서 레코드 생성을 해준다.

 

그리고 30분정도 기다려주면 아래와 같이 결과가 나온다.

신 인증서 (DNS 검증)은 상태가 발급됨, 사용중 X, 갱신 자격 부적격으로 되어있으면 정상입니다.

 

 

나머지 작업 내용

 

ARN 확인, 도메인 변수 지정, 생성

# 사용 리전의 인증서 ARN 확인
(somaz:default) [root@kops-ec2 ~]# aws acm list-certificates --max-items 10
{
    "CertificateSummaryList": [
        {
            "CertificateArn": "arn:aws:acm:ap-northeast-2:611841095956:certificate/75e6fb4f-5999-4701-80f2-ab94e015bc9b",
            "DomainName": "*.somaz.link",
            "SubjectAlternativeNameSummaries": [
                "*.somaz.link",
                "somaz.link"

(somaz:default) [root@kops-ec2 ~]# aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text
arn:aws:acm:ap-northeast-2:611841095956:certificate/75e6fb4f-5999-4701-80f2-ab94e015bc9b

(somaz:default) [root@kops-ec2 ~]# CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`

(somaz:default) [root@kops-ec2 ~]# echo $CERT_ARN
arn:aws:acm:ap-northeast-2:611841095956:certificate/75e6fb4f-5999-4701-80f2-ab94e015bc9b

# 자신의 도메인 변수 지정
(somaz:default) [root@kops-ec2 ~]# MyDomain=websrv.somaz.link

# 생성
cat <<EOF | kubectl create -f -
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: akos-websrv
        image: k8s.gcr.io/echoserver:1.5
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: svc-nlb-ip-type
  annotations:
    external-dns.alpha.kubernetes.io/hostname: "${MyDomain}"
    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-ssl-ports: "https"
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: ${CERT_ARN}
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
spec:
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
      name: http
    - port: 443
      targetPort: 8080
      protocol: TCP
      name: https
  type: LoadBalancer
  loadBalancerClass: service.k8s.aws/nlb
  selector:
    app: deploy-websrv
EOF

 

모니터링, 확인

# 모니터링
watch "kubectl get po,svc"
...
Every 2.0s: kubectl get svc,ep                                      Sun Jan 15 23:41:34 2023

NAME                      TYPE           CLUSTER-IP       EXTERNAL-IP
                                                  PORT(S)                      AGE
service/kubernetes        ClusterIP      100.64.0.1       <none>
                                                  443/TCP                      3h29m
service/svc-nlb-ip-type   LoadBalancer   100.71.185.216   k8s-default-svcnlbip-4eca1f860b-959096705f3c2028.elb.ap-northeast-2.amazonaws.com   80:32663/TCP,443:32662/TCP   41s

NAME                        ENDPOINTS
    AGE
endpoints/kubernetes        172.30.35.141:443
    3h29m
endpoints/svc-nlb-ip-type   172.30.48.21:8080,172.30.71.46:8080,172.30.48.21:8080 + 1 more...41s

# 확인
(somaz:default) [root@kops-ec2 ~]# kubectl get svc,ep
NAME                      TYPE           CLUSTER-IP       EXTERNAL-IP                                                                         PORT(S)                      AGE
service/kubernetes        ClusterIP      100.64.0.1       <none>                                                                              443/TCP                      3h30m
service/svc-nlb-ip-type   LoadBalancer   100.71.185.216   k8s-default-svcnlbip-4eca1f860b-959096705f3c2028.elb.ap-northeast-2.amazonaws.com   80:32663/TCP,443:32662/TCP   76s

NAME                        ENDPOINTS                                                           AGE
endpoints/kubernetes        172.30.35.141:443                                                   3h30m
endpoints/svc-nlb-ip-type   172.30.48.21:8080,172.30.71.46:8080,172.30.48.21:8080 + 1 more...   76s

(somaz:default) [root@kops-ec2 ~]# kubectl describe svc svc-nlb-ip-type
Name:                     svc-nlb-ip-type
Namespace:                default
Labels:                   <none>
Annotations:              external-dns.alpha.kubernetes.io/hostname: websrv.somaz.link
                          service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
                          service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: true
                          service.beta.kubernetes.io/aws-load-balancer-healthcheck-port: 8080
                          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-ssl-cert:
                            arn:aws:acm:ap-northeast-2:611841095956:certificate/75e6fb4f-5999-4701-80f2-ab94e015bc9b
                          service.beta.kubernetes.io/aws-load-balancer-ssl-ports: https
Selector:                 app=deploy-websrv
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       100.71.185.216
IPs:                      100.71.185.216
LoadBalancer Ingress:     k8s-default-svcnlbip-4eca1f860b-959096705f3c2028.elb.ap-northeast-2.amazonaws.com
Port:                     http  80/TCP
TargetPort:               8080/TCP
NodePort:                 http  32663/TCP
Endpoints:                172.30.48.21:8080,172.30.71.46:8080
Port:                     https  443/TCP
TargetPort:               8080/TCP
NodePort:                 https  32662/TCP
Endpoints:                172.30.48.21:8080,172.30.71.46:8080
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type    Reason                  Age   From     Message
  ----    ------                  ----  ----     -------
  Normal  SuccessfullyReconciled  107s  service  Successfully reconciled
  
  
(somaz:default) [root@kops-ec2 ~]# kubectl describe svc svc-nlb-ip-type | grep Annotations: -A8
Annotations:              external-dns.alpha.kubernetes.io/hostname: websrv.somaz.link
                          service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
                          service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: true
                          service.beta.kubernetes.io/aws-load-balancer-healthcheck-port: 8080
                          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-ssl-cert:
                            arn:aws:acm:ap-northeast-2:611841095956:certificate/75e6fb4f-5999-4701-80f2-ab94e015bc9b
                          service.beta.kubernetes.io/aws-load-balancer-ssl-ports: https

 

외부 접속 테스트

# 외부 접속 테스트

(somaz:default) [root@kops-ec2 ~]# curl -s http://websrv.somaz.link| grep Hostname
Hostname: deploy-echo-5c4856dfd6-zmdzk

(somaz:default) [root@kops-ec2 ~]# curl -s -k https://websrv.somaz.link| grep Hostname
Hostname: deploy-echo-5c4856dfd6-zmdzk

 

 

스터디 주요 내용

 

1. CNI란?

Container Network Interface의 약자로 Linux 컨테이너에서 네트워크 인터페이스를 구성하기 위한 규격이다.

컨테이너를 네트워크에 연결하거나 분리하는 것과 관련이 있다.

 

 

 

K8S CNI

CNI는 k8s 네트워크 환경을 구성해주고 다양한 플러그인이 존재한다.

 

AWS VPC CNI

파드 IP를 할당해주고, 파드의 IP 네트워크 대역과 노드의 IP 대역이 같아서 직접 통신이 가능하다.

 

출처 : 가시다님 스터디 노션

 

K8S Calico CNI와 AWS VPC CNI 차이

파드 간 통신 시 일반적으로 K8S CNI는 오버레이 통신을 하고, AWS VPC CNI는 동일 대역으로 직접 통신을 한다.

출처 : 가시다님 스터디 노션

 

워커 노드에 최대 생성 가능한 파드 갯수는 몇개일까?

 

  • Secondary IPv4 addresses : 인스턴스 유형에 최대 ENI 갯수와 할당 가능 IP 수를 조합하여 선정
  • IPv4 Prefix Delegation : IPv4 28bit 서브넷(prefix)를 위임하여 할당 가능 IP 수와 인스턴스 유형에 권장하는 최대 갯수로 선정

출처 : 가시다님 스터디 노션

 

2. 노드에서 기본 네트워크 정보 확인

Network 네임스페이스는 호스트(Root)와 파드 별(Per Pod)로 구분된다.

특정한 파드(kube-proxy, aws-node)는 호스트(Root)의 IP를 그대로 사용한다.

t3.medium 의 경우 ENI 에 최대 6개의 IP를 가지고 자신의 IP 이외에 추가적으로 5개의 보조 프라이빗 IP를 가진다.

coredns 파드는 veth으로 호스트에는 eniY@ifN 인터페이스와  파드에 eth0가 연결되어 있다.

출처 : 가시다님 스터디 노션

 

3. 노드 간 파드 통신

AWS VPC ENI는 첫번째 ENI1(ens5)로만 통신이 되도록 iptables나 라우팅 테이블이 설정되어있다.

따라서 ENI2(ens6)으로는 통신되지 않는다.

 

출처 : 가시다님 스터디 노션

 

4. 파드에서  외부통신

iptable 에 SNAT 을 통하여 노드의 eth0 IP로 변경되어서 외부와 통신된다.

또한 VPC CNI 의 External source network address translation (SNAT) 설정에 따라, 외부(인터넷) 통신 시 SNAT 하거나 혹은 SNAT 없이 통신을 할 수 있다

출처 :&nbsp;https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/images/ping2external.png

 

SNAT(Source NAT)란?

먼저 SNAT는 패킷의 Source 주소를 변경하는 것으로 SNAT 혹은 Source NAT라고 한다.

즉 출발지 주소를 변경하는 것이다. 사설에서 공인으로 통신할 때 많이 사용한다.

( 내부 -> 외부)

  • NAT(Network Address Translation) : 즉 IP 패킷 헤더의 IP 주소를 변경하는 기능이다.
    • PREROUTING : DNAT를 이용하여 패킷이 생길 때
    • POSTROUTING: SNAT를 이용하여 패킷이 나갈 때
  • DNAT(Destination NAT) : 도착지 주소를 변경하는 NAT이다. (외부 -> 내부)
    • 로드밸런서에 많이 사용한다. 또한, 사내가 아닌 대외망과의 네트워크 구성에도 사용한다.

 

5. 서비스

서비스에는 ClusterIP 타입과, NodePort 타입, LoadBalancer 타입 총 3개가 있다.

 

아래의 공부했던 내용을 다시 한번 적어본다.

2022.08.29 - [교육, 커뮤니티 후기] - <인프런> 대세는 쿠버네티스 [초급] - No.9 Object - Service

 

ClusterIP

그 중 가장 기본적인 방식인 ClusterIP라는 방식이 있다.

이 IP는 Cluster 내에서만 접근이 가능하다. Pod가 가지고 있는 IP와 동일하게 외부에서는 접근이 불가하다.

 

NodePort

NodePort 타입의  Service는 ClusterIP와 동일한 특성을 가지고 있다.

NodePort 타입만의 큰 특징은 Kubernetes Cluster에 할당되어 있는 모든 Node에게 똑같은 Port가 할당이 된다.

따라서 Node1,2든 해당 IP에 Port로 접속을 하면, Service에 연결이 된다.

 

LoadBalancer

Load Balancer 타입의  Service는 NodePort와 동일한 특성을 가지고 있다.  추가적으로 LoadBalancer라는 걸 이용해서 각각의 Node에 Traffic을 분산시켜주는 역할을 한다. 다만, Load Balancer가 가지고 있는 IP는 Kubernetes를 설치 햇을 때 생기지 않는다. 별도로 외부접속 IP를 할당을 해주는 Plugin이 설치가 되어있어야 IP가 생긴다.

 

 

6. ExternalDNS

K8S 서비스/인그레스 생성 시 도메인을 설정하면, AWS(Route 53), Azure(DNS), GCP(Cloud DNS) 에 A 레코드(TXT 레코드)로 자동 생성/삭제된다.

https://edgehog.blog/a-self-hosted-external-dns-resolver-for-kubernetes-111a27d6fc2c

 

스터디 2주차 후기

쿠버네티스 네트워크에 대해 중점적으로 배울수 있는 시간이 되었던 것 같습니다!

과제2번이 잘되지 않아 삽질을 좀 하긴 했지만, 가시다님께서 노션에 방법을 공유해주셔 수월하게 해결할 수 있었습니다.

실습과 자료가 적절하고 좋은 스터디인 것 같습니다. 마지막까지 화이팅입니다!

 

Reference

 

https://jojoldu.tistory.com/434

https://programforlife.tistory.com/112

https://trans.yonghochoi.com/translations/aws_vpc_cni_increase_pods_per_node_limits.ko

https://sarc.io/index.php/aws/1779-snat-dnat-difference

https://zigispace.net/1121

https://docs.aws.amazon.com/cli/latest/reference/ec2/unassign-private-ip-addresses.html

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/work-with-prefixes.html

728x90
반응형