실습 4탄 = 6/17
목표
서비스인 CLB, NLB , NLB IP 타입에 대해 실습해보자.
Cluster IP 타입?
NodePort 타입 ?
로드 밸랜서 타입 (기본 모드)
1
Cluster IP 타입?
클러스터 환경 내부에서만 접속 가능함.
외부에서 안됨.
Control Plane에서 IP Table로 각 node 의 Pod로 분산함
외부에서 되도록 하는게 Node 타입과 로드 밸런서 타입이 있다.
2
NodePort 타입 ?
외부에서 워커노드로 접속 하면, IP Table로 분산함.
워커 노드의 허용된 포트가 열림
3
로드 밸랜서 타입 (기본 모드)
CLB와 NLB를 통해서 서비스 함
외부 ------- 로드 밸런서 --------- 노드 ---- 노드의 IP Table로 분산함.
1
게임 만들기
deployment-2048 만들기 ?
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
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: alexwhen/docker-2048
name: app-2048
ports:
- containerPort: 80
EOF
// replicas: 2
2
kubectl get deploy,pod -owide
watch -d 'kubectl get deploy,pod,svc,ep -owide'
3
서비스 LB 생성
kubectl expose deployment deployment-2048 --port=80 --type=LoadBalancer
/// 노출하라. 80으로 외부 LB 이용하라
// AWS Console에서 CLB 생성 된것이 확인 가능하다.
4
스마트폰에서도 접속 가능하다.
5
쿠버 네티스에서 생성 확인
kubectl get svc,ep
kubectl describe svc deployment-2048
echo http://$(kubectl get svc deployment-2048 -o jsonpath='{.status.loadBalancer.ingress[*].hostname}')
6
kubectl get svc,ep
(t6-admin@myeks:default) [root@myeks-host ~]# kubectl get svc,ep
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/deployment-2048 LoadBalancer 10.100.30.79 a76-1.ap-northeast-2.elb.amazonaws.com 80:30537/TCP 82s
service/kube-ops-view LoadBalancer 10.100.154.244 a0c2-210.ap-northeast-2.elb.amazonaws.com 80:32458/TCP 144m
service/kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 7h51m
NAME ENDPOINTS AGE
endpoints/deployment-2048 192.168.1.68:80,192.168.2.74:80 82s
endpoints/kube-ops-view 192.168.1.115:8080 144m
endpoints/kubernetes 192.168.1.27:443,192.168.2.121:443 7h51m
7
kubectl describe svc deployment-2048
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app.kubernetes.io/name=app-2048
Type: LoadBalancer
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.100.30.79
IPs: 10.100.30.79
LoadBalancer Ingress: a7b72dd3baea84620ab66f52153ab1a6-1665226617.ap-northeast-2.elb.amazonaws.com
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 30537/TCP
Endpoints: 192.168.1.68:80,192.168.2.74:80
Session Affinity: None
External Traffic Policy: Cluster
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal EnsuringLoadBalancer 100s service-controller Ensuring load balancer
Normal EnsuredLoadBalancer 98s service-controller Ensured load balancer
8
echo http://$(kubectl get svc deployment-2048 -o jsonpath='{.status.loadBalancer.ingress[*].hostname}')
http://a7b72dd3baea84620ab66f52153ab1a6-1665226617.ap-northeast-2.elb.amazonaws.com
9
웹 브라우저로 게임 접속
http://a7b72dd3baea84620ab66f52153ab1a6-1665226617.ap-northeast-2.elb.amazonaws.com
10
pod 수 늘리기 ?
kubectl scale deployment deployment-2048 --replicas=4
11
route53 cname으로 연결
12
리소스 삭제
kubectl delete deploy,svc deployment-2048
1
타켓 그룹이 ?
인스턴스 타입 과 IP타입이 있다.
2
IP 타입은 반드시 'AWS LoadBalancer 컨트롤러' 파드를 만들어야 한다.
3
여기서는 인스턴스 유형으로 실습
4
NLB 테스트로 echo pod 씁니다~
echo pod는 요청하면 요청자 ip등 응답을 주는 pod입니다.
디플로이 이름은 deploy-echo
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
EOF
5
디플로이먼트 deploy-echo 와 Pod deploy-echo 확인 하자
kubectl get deploy,pod
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/deploy-echo 2/2 2 2 36s
deployment.apps/kube-ops-view 1/1 1 1 164m
NAME READY STATUS RESTARTS AGE
pod/deploy-echo-55456fc798-8dwbb 1/1 Running 0 36s
pod/deploy-echo-55456fc798-d7bbh 1/1 Running 0 36s
pod/kube-ops-view-5557846b44-5rwwj 1/1 Running 0 164m
pod/pod-1 1/1 Running 0 5h15m
pod/pod-2 1/1 Running 0 5h15m
kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deploy-echo-55456fc798-8dwbb 1/1 Running 0 67s 192.168.2.156 ip-192-168-2-4.ap-northeast-2.compute.internal <none> <none>
deploy-echo-55456fc798-d7bbh 1/1 Running 0 67s 192.168.1.68 ip-192-168-1-90.ap-northeast-2.compute.internal <none> <none>
6
pod ip 확인 ?
kubectl get pod -o wide -l app=deploy-websrv |awk 'NR>1 {print $6}'
192.168.2.156
192.168.1.68
// pod 생성시 lable 을 deploy-websrv 으로 만들어 deploy-websrv 으로 IP 조회~
7
EchoPod1=192.168.2.156
curl -s $EchoPod1:8080
// curl 결과
Hostname: deploy-echo-55456fc798-8dwbb
// pod의 이름과 같다. k get pods로 확인
Pod Information:
-no pod information available-
Server values:
server_version=nginx: 1.13.0 - lua: 10008
Request Information:
client_address=192.168.1.100 // 접근한 내 IP도 나온다.
method=GET
real path=/
query=
request_version=1.1
request_uri=http://192.168.2.156:8080/
Request Headers:
accept=*/*
host=192.168.2.156:8080
user-agent=curl/7.61.1
Request Body:
-no body in request-
8
NLB를 2개 만든다.
1) 교차 영역 비활성화로 1개 만든다.
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Service
metadata:
name: svc-nlb1-instance-type
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
ports:
- name: awsnlb1-webport
port: 80
targetPort: 8080
nodePort: 30001
selector:
app: deploy-websrv
type: LoadBalancer
EOF
// annotations 에서 nlb로 지정한다. annotations = 주석이다.
9
2) 교차 영역 활성화로 1개 만든다.
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Service
metadata:
name: svc-nlb2-instance-type
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
spec:
ports:
- name: awsnlb1-webport
port: 80
targetPort: 8080
nodePort: 30002
selector:
app: deploy-websrv
type: LoadBalancer
externalTrafficPolicy: Local
EOF
10
kubectl get svc,ep
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kube-ops-view LoadBalancer 10.100.154.244 a8fac4b98210.ap-northeast-2.elb.amazonaws.com 80:32458/TCP 169m
service/kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 8h
service/svc-nlb1-instance-type LoadBalancer 10.100.165.70 a598ef11c996e41b.elb.ap-northeast-2.amazonaws.com 80:30001/TCP 86s
service/svc-nlb2-instance-type LoadBalancer 10.100.60.113 a2c0117a1fcbccea4b.elb.ap-northeast-2.amazonaws.com 80:30002/TCP 76s
NAME ENDPOINTS AGE
endpoints/kube-ops-view 192.168.1.115:8080 169m
endpoints/kubernetes 192.168.1.27:443,192.168.2.121:443 8h
endpoints/svc-nlb1-instance-type 192.168.1.68:8080,192.168.2.156:8080 86s
endpoints/svc-nlb2-instance-type 192.168.1.68:8080,192.168.2.156:8080 76s
11
AWS 콘솔에서 네트워크 로드 밸런서 확인하자
NLB를 확인하자
health check on 되었는지 확인하자
12
kubectl describe svc svc-nlb1-instance-type
kubectl describe svc svc-nlb2-instance-type
kubectl describe svc svc-nlb1-instance-type
Name: svc-nlb1-instance-type
Namespace: default
Labels: <none>
Annotations: service.beta.kubernetes.io/aws-load-balancer-type: nlb
Selector: app=deploy-websrv
Type: LoadBalancer
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.100.165.70
IPs: 10.100.165.70
LoadBalancer Ingress: a598ef17c766349148a62f93ef53f5b9-86e80d51c996e41b.elb.ap-northeast-2.amazonaws.com
Port: awsnlb1-webport 80/TCP
TargetPort: 8080/TCP
NodePort: awsnlb1-webport 30001/TCP
Endpoints: 192.168.1.68:8080,192.168.2.156:8080
Session Affinity: None
External Traffic Policy: Cluster
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal EnsuringLoadBalancer 5m40s service-controller Ensuring load balancer
Normal EnsuredLoadBalancer 5m38s service-controller Ensured load balancer
kubectl describe svc svc-nlb2-instance-type
Name: svc-nlb2-instance-type
Namespace: default
Labels: <none>
Annotations: service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: true
service.beta.kubernetes.io/aws-load-balancer-type: nlb
Selector: app=deploy-websrv
Type: LoadBalancer
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.100.60.113
IPs: 10.100.60.113
LoadBalancer Ingress: a2c011d05442e4a36ad1c55c61735c50-9d7c7a1fcbccea4b.elb.ap-northeast-2.amazonaws.com
Port: awsnlb1-webport 80/TCP
TargetPort: 8080/TCP
NodePort: awsnlb1-webport 30002/TCP
Endpoints: 192.168.1.68:8080,192.168.2.156:8080
Session Affinity: None
External Traffic Policy: Local
HealthCheck NodePort: 32535
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal EnsuringLoadBalancer 6m4s service-controller Ensuring load balancer
Normal EnsuredLoadBalancer 6m2s service-controller Ensured load balancer
13
echo http://$(kubectl get svc svc-nlb1-instance-type -o jsonpath='{.status.loadBalancer.ingress[*].hostname}')
http://a598ef17c766349148a62f93ef53f5b9-86e80d51c996e41b.elb.ap-northeast-2.amazonaws.com
echo http://$(kubectl get svc svc-nlb2-instance-type -o jsonpath='{.status.loadBalancer.ingress[*].hostname}')
http://a2c011d05442e4a36ad1c55c61735c50-9d7c7a1fcbccea4b.elb.ap-northeast-2.amazonaws.com
14
로드밸런서로 접속 로그 확인
kubectl logs -l app=deploy-websrv -f
15
NLB1=a598ef17c766349148a62f93ef53f5b9-86e80d51c996e41b.elb.ap-northeast-2.amazonaws.com
NLB2=a2c011d05442e4a36ad1c55c61735c50-9d7c7a1fcbccea4b.elb.ap-northeast-2.amazonaws.com
13
curl -s $NLB1 | egrep 'Hostname|client_address'
모니터링 결과
kubectl logs -l app=deploy-websrv -f
192.168.1.90 - - [30/Aug/2021:11:59:42 +0000] "GET / HTTP/1.1" 200 692 "-" "curl/7.61.1"
// 내부 ip가 나온다.
curl -s $NLB2 | egrep 'Hostname|client_address'
모니터링 결과
kubectl logs -l app=deploy-websrv -f
13.125.211.37 - - [30/Aug/2021:12:00:15 +0000] "GET / HTTP/1.1" 200 693 "-" "curl/7.61.1"
// client ip 가 나온다.
// externalTrafficPolicy: Local 옵션 때문에 나온다!!
14
부하 분산 확인?
for i in {1..100}; do curl -s $NLB1 | grep Hostname ; done | sort | uniq -c | sort -nr
61 Hostname: deploy-echo-55456fc798-8dwbb
39 Hostname: deploy-echo-55456fc798-d7bbh
for i in {1..100}; do curl -s $NLB2 | grep Hostname ; done | sort | uniq -c | sort -nr
59 Hostname: deploy-echo-55456fc798-d7bbh
41 Hostname: deploy-echo-55456fc798-8dwbb
15
삭제
kubectl delete deploy deploy-echo; kubectl delete svc svc-nlb1-instance-type svc-nlb2-instance-type
kubectl delete deploy,svc --all
// ops-view까지 다 지원진다.
1
IP 모드 ?
로드밸러서가 서비스 nodeport를 바이패스 하고, Pod와 바로 접속 한다.
// iptable rule 안쓰는 구조.
로드 밸런서가 Pod의 IP를 알아야 한다.
그래서, Load Balancer Controller 파드를 반드시 만들어야 한다.
Pod 정보를 LB에 알려준다.
Pod IP 를 지속적으로 제공한다.
IAM에 있는 role 을 사용한다.
Load Balancer Controller 파드가 role을 사용한다.
2
디플로이먼트 배포 ?
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
EOF
3
echo pod 2개 만들어짐
k get pod -w
NAME READY STATUS RESTARTS AGE
deploy-echo-55456fc798-6nd2t 1/1 Running 0 25s
deploy-echo-55456fc798-tpbzx 1/1 Running 0 25s
4
nlb 서비스를 만들어 본다.
ip 타입으로 만든다.
안 만들어진다.
왜냐면 Load Balancer Controller 파드가 없으므로 안만들어짐.
5
서비스 ?
NLB는 서비스에서 IP 타입으로 지정한다.
서비스에서 Pod로 가기 때문이다.
ALB는 인그래스에서 IP 타입으로 지정한다.
IP모드 생성 실패!!!
echo $CLUSTER_NAME
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Service
metadata:
name: svc-nlb-ip-type
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: external
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-subnets: $CLUSTER_NAME-PublicSubnet1, $CLUSTER_NAME-PublicSubnet2
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
type: LoadBalancer
selector:
app: deploy-websrv
EOF
안만들어 진다.
팬딩 된다!!!!
6
kubectl get svc,ep
admin@myeks:default) [root@myeks-host ~]# kubectl get svc,ep
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 7m8s
service/svc-nlb-ip-type LoadBalancer 10.100.149.71 <pending> 80:32649/TCP 23s
7
kubectl describe svc svc-nlb-ip-type | grep Events: -A5
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal EnsuringLoadBalancer 55s service-controller Ensuring load balancer
Warning FailedBuildModel 11s (x14 over 54s) service Failed build model due to couldn't find all subnets, nameOrIDs: [first-eks-PublicSubnet1 first-eks-PublicSubnet2], found: 0
1
IP 타입은 Load Balancer 컨트롤러가 필요하다.
2
iam policy 필요 (정책)
로드밸런서의 대상타켓 등록등 정책
curl -o iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json
aws iam create-policy --policy-name AWSLoadBalancerControllerIAMPolicy --policy-document file://iam-policy.json
3
다시 만들고자 삭제는 삭제후
aws iam delete-policy --policy-arn arn:aws:iam:
// arn 확인
4
role을 만든다.
이 role을 사용할수 있는 쿠버네티스 서비스 어카운트를 만들어야 한다.
쿠버네티스 서비스 어카운트를 자동으로 생성해 준다.
정책이름
AWSLoadBalancerControllerIAMPolicy
콘솔에서 정책 확인
IAM > Policy
role
eksctl-first-eks-addon-iamserviceaccount-kub-Role1
3
LB를 위한 서비스 어카운트 생성 순서
ACCOUNT_ID=`aws sts get-caller-identity --query 'Account' --output text`
echo $ACCOUNT_ID
echo $CLUSTER_NAME
eksctl create iamserviceaccount --cluster=$CLUSTER_NAME --namespace=kube-system --name=aws-load-balancer-controller \
--attach-policy-arn=arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy --override-existing-serviceaccounts --approve
// cloudformation으로 생성됨.
// cloudformation에서 확인. iam load balancer service account
// aws 에서는 iam role이 만들어 지고, 쿠버네티스에는 서비스 어카운트가 만들어 진다.
arn:aws:iam::68:role/eksctl-myeks-addon-iamserviceaccount-kube-sy-Role1-10N
5
인증서 관리자
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.4.3/cert-manager.yaml
6
AWS LB 컨트롤 생성
curl -s -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/AKOS/v2_2_0_full.yaml
sed -i "s/your-cluster-name/$CLUSTER_NAME/g" v2_2_0_full.yaml
k apply -f v2_2_0_full.yaml
7
pending된 NLB가 활성화 된다. (5분 걸림)
watch -d 'kubectl get svc,ep'
service/svc-nlb-ip-type LoadBalancer 10.100.195.217 k8s-default-svcnlbip-23b413b61f-d773f.elb.ap-southeast-1.amazonaws.com
8
웹브라우저로 접속해본다.
9
kubectl describe clusterroles.rbac.authorization.k8s.io aws-load-balancer-controller-role
// 서비스 어카운트가 확인 할수 있는것은 ?
pods 상태, 서비스 상태, 인그레스 상태등 확인을 한다.
10
# 서비스 어카운트 확인
kubectl get sa aws-load-balancer-controller -n kube-system
NAME SECRETS AGE
aws-load-balancer-controller 1 76s
11
role 확인
kubectl get sa aws-load-balancer-controller -n kube-system -o yaml
eksctl-first-eks-addon-iamserviceaccount-kub-Role
12
참고
서비스 어카운트 만들기
https://aws-eks-web-application.workshop.aws/ko/60-ingress-controller/100-launch-alb.html
13
kubectl get svc,ep
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 23m
service/svc-nlb-ip-type LoadBalancer 10.100.149.71 k8s-default-svcnlbip-5f1-7dlb.ap-northeast-2.amazonaws.com 80:32649/TCP 16m
NAME ENDPOINTS AGE
endpoints/kubernetes 192.168.1.27:443,192.168.2.121:443 23m
endpoints/svc-nlb-ip-type 192.168.1.55:8080,192.168.2.64:8080 16m
14
터미널2에서 로그 확인
kubectl logs -l app=deploy-websrv -f
15
nlb 상태확인 ?
콘솔에서 NLB 확인 ?
대상 그룹 확인 - 대상그룹의 대상은 노드 IP가 아닌 Pod IP 이다!!
워커노드의 불필요한 iptable을 타지 않는다.
16
NLB 접속 확인
NLB=$(kubectl get svc svc-nlb-ip-type -o jsonpath='{.status.loadBalancer.ingress[*].hostname}')
curl -s -m3 -v $NLB
Hostname: deploy-echo-55456fc798-r6mlp
Pod Information:
-no pod information available-
Server values:
server_version=nginx: 1.13.0 - lua: 10008
Request Information:
client_address=192.168.2.31
for i in {1..100}; do curl -s $NLB | grep Hostname ; done | sort | uniq -c | sort -nr
56 Hostname: deploy-echo-55456fc798-k7ndn
44 Hostname: deploy-echo-55456fc798-r6mlp
17
로그
kubectl logs -l app=deploy-websrv -f
192.168.2.31 - - [26/Sep/2021:01:40:24 +0000] "GET / HTTP/1.1" 200 690 "-" "curl/7.76.1"
192.168.2.31 - - [26/Sep/2021:01:40:24 +0000] "GET / HTTP/1.1" 200 690 "-" "curl/7.76.1"
192.168.1.209 - - [26/Sep/2021:01:40:24 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.76.1"
192.168.2.31 - - [26/Sep/2021:01:40:24 +0000] "GET / HTTP/1.1" 200 690 "-" "curl/7.76.1"
192.168.2.31 - - [26/Sep/2021:01:40:24 +0000] "GET / HTTP/1.1" 200 690 "-" "curl/7.76.1"
192.168.1.209 - - [26/Sep/2021:01:40:24 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.76.1"
192.168.2.31 - - [26/Sep/2021:01:40:24 +0000] "GET / HTTP/1.1" 200 690 "-" "curl/7.76.1"
192.168.1.209 - - [26/Sep/2021:01:40:24 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.76.1"
18
ip보전은 안된다.
프록시 버전2를 활성화 하면 된다.
19
pod ip가 변경되므로, ALB Load Balancer 컨트롤러 가 필요하다.
서비스 어카운트 필요
20
기타
인증서의 경우는 해당 리전에서 만들어주어야 한다.
NLB와 ALB는 리전 내에서만 동작하므로..
버지니아에서 인증서 만들어주는건 Cloud Front용이다.
따로 해당 리전에서 만들어야 한다.
kubectl delete deploy deploy-echo; kubectl delete svc svc-nlb-ip-type
kubectl delete ingress,deploy,svc --all
https://brunch.co.kr/@topasvga/1869
https://www.eksworkshop.com/beginner/110_irsa/iam-role-for-sa-1/
https://brunch.co.kr/@topasvga/1816
감사합니다.