PKOS 스터디 소개
본 포스팅은 가시다님의 PKOS(Production Kubernetes Online Study)스터디 내용을 정리한 것이다.
이번 PKOS 스터디는 스터디, 스터디 노션 자료, 과제(본 포스팅) 모두 책 <24단계 실습으로 정복하는 쿠버네티스> 내용을 기반으로 진행한다.
AWS VPC CNI 소개
쿠버네티스 CNI란?
Container Network Interface. 쿠버네티스의 네트워크 환경을 구성하는 역할을 맡는다.
CNCF 프로젝트인 CNI는 Linux 컨테이너에서 네트워크 인터페이스를 구성하기 위한 플러그인을 작성하기 위한 사양 및 라이브러리와 지원되는 여러 플러그인으로 구성됩니다.
CNI는 '컨테이너의 네트워크 연결성'과 '컨테이너 삭제 시 할당된 리소스 제거'에만 관심이 있습니다.
출처: https://github.com/containernetworking/cni#what-is-cni
Calico, Flannel, Cilium, Weave 등 다양한 CNI 플러그인들이 존재한다.
https://kubernetes.io/docs/concepts/cluster-administration/addons/
https://github.com/containernetworking/cni#3rd-party-plugins
AWS VPC CNI란?
AWS에서 Elastic Network Interfaces 를 사용하는 쿠버네티스의 Pod 네트워킹을 위한 네트워킹 플러그인.
출처: https://github.com/aws/amazon-vpc-cni-k8s#amazon-vpc-cni-k8s
한마디로 AWS에서 만든 CNI 플러그인이라고 생각하면 편하다.
AWS VPC CNI의 특징
- 파드의 IP를 할당해준다
- 파드의 IP 네트워크 대역과 노드(워커)의 IP 대역이 같아서 직접 통신이 가능하다
본 스터디의 기본 환경인 Kops에서도 AWS VPC CNI를 정식으로 지원한다.
https://kops.sigs.k8s.io/networking/#supported-networking-options
https://kops.sigs.k8s.io/networking/aws-vpc/
쿠버네티스 CNI(Calico) 와 AWS VPC CNI 의 차이점은?
AWS VPC CNI의 특징은 노드와 Pod의 네트워크 대역이 동일하다는 것이다.
노드와 Pod의 네트워크 대역이 동일하면 무엇이 좋을까?
오버레이(VXLAN, IP-IP 등) 통신 기술 없이, VPC Native하게(클라우드 위엄) Pod간 직접 통신이 가능하다.
Pod간 직접 통신이 가능하면, 네트워크 통신의 최적화(성능, 지연)면에서 더 나은 결과를 얻을 수 있다.
쿠버네티스 네트워크
Service
Cluster IP
Cluster IP는 클러스터 내부에 한해서 Pod끼리 통신하기 위한 서비스다.
서비스를 만들 때 type을 별도로 지정하지 않으면 기본값으로 Cluster IP가 생성된다.
Cluster IP는 클러스터 외부에서 Pod로 접근할 수 없다.
apiVersion: v1
kind: Service
metadata:
name: svc-clusterip
spec:
selector:
app: pod
ports:
- port: 9000
targetPort: 8080
type: ClusterIP
NodePort
NodePort는 클러스터 외부로부터 모든 워커노드들의 특정 포트(=NodePort)를 통해서 Pod에 접근할 수 있도록 설정하는 서비스다.
노드포트 번호 대역은 30000~32767다.
apiVersion: v1
kind: Service
metadata:
name: svc-nodeport
spec:
selector:
app: pod
ports:
- port: 9000
targetPort: 8080
nodePort: 30000
type: NodePort
Load Balancer
클러스터 외부에서 올바른 포트로 트래픽을 전송할 수 있도록 접근 가능한 IP 주소를 제공하는 서비스다.
보통 CSP에서 제공하는 LB플러그인으로 설정한다.
apiVersion: v1
kind: Service
metadata:
name: svc-lb
spec:
selector:
app: example
ports:
- port: 8765
targetPort: 9376
type: LoadBalancer
Ingress
Ingress는 HTTP, HTTPS 등 네트워크 Layer 7에 대한 설정을 담당하는 리소스다.
https://lifeoncloud.kr/entry/Ingress
Ingress + ALB + ExternalDNS
# 변수 지정 - 자신의 full 도메인
WEBDOMAIN=<각자편한웹서버도메인>
WEBDOMAIN=albweb.$KOPS_CLUSTER_NAME
ingress2.yaml
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:
- host: ${WEBDOMAIN}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service-2048
port:
배포한다
# 게임 Pod와 Service, Ingress 배포
cat ~/pkos/3/ingress2.yaml | yh
WEBDOMAIN=$WEBDOMAIN envsubst < ~/pkos/3/ingress2.yaml | kubectl apply -f -
# 확인
kubectl get ingress,svc,ep,pod -n game-2048
# AWS R53 적용 확인
dig +short $WEBDOMAIN
dig +short $WEBDOMAIN @8.8.8.8
# 외부단말(집PC 등)에서 접속 확인 : curl or 웹브라우저
# 로그 확인
kubectl logs -n kube-system -f $(kubectl get po -n kube-system | egrep -o 'external-dns[A-Za-z0-9-]+')
# 삭제
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
이걸 그림으로 표현하면 다음과 같다.
<과제> 하위 path별 애플리케이션 연결하기
네임스페이스
apiVersion: v1
kind: Namespace
metadata:
name: game
mario 애플리케이션과 서비스
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: game
name: mario
labels:
app: mario
spec:
replicas: 1
selector:
matchLabels:
app: mario
template:
metadata:
labels:
app: mario
spec:
containers:
- name: mario
image: pengbai/docker-supermario
---
apiVersion: v1
kind: Service
metadata:
namespace: game
name: mario
annotations:
alb.ingress.kubernetes.io/healthcheck-path: /mario/index.html
spec:
selector:
app: mario
ports:
- port: 80
protocol: TCP
targetPort: 8080
type: NodePort
externalTrafficPolicy: Local
tetris 애플리케이션과 서비스
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: game
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:
namespace: game
name: tetris
annotations:
alb.ingress.kubernetes.io/healthcheck-path: /tetris/index.html
spec:
selector:
app: tetris
ports:
- port: 80
protocol: TCP
targetPort: 80
type: NodePort
Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: game
name: ingress-game-soojin
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/certificate-arn: {Certificate Manager에서 발급받은 정보}
alb.ingress.kubernetes.io/healthcheck-port: traffic-port
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/ssl-redirect: '443'
spec:
ingressClassName: alb
rules:
- host: {내 도메인}
http:
paths:
- path: /tetris
pathType: Prefix
backend:
service:
name: tetris
port:
number: 80
- path: /mario
pathType: Prefix
backend:
service:
name: mario
port:
number: 80
웹브라우저로 접속해보자
리소스 삭제
꺼진 불.. 아니 꺼진 리소스도 다시 보자.
위부터 아래로 순서대로 삭제하자
# kops 삭제
kops delete cluster --yes
# Cloud Formation 스택 삭제
aws cloudformation delete-stack --stack-name mykops
'Kubernetes' 카테고리의 다른 글
[PKOS] 3주차 - GitOps (0) | 2023.03.26 |
---|---|
쿠버네티스 시험 할인받는 법 (10) | 2023.03.24 |
[PKOS] 1주차 - AWS kops 설치 및 기본 사용 (2) | 2023.03.12 |
Network Policy (0) | 2023.03.10 |
Limit Ranges (0) | 2023.02.11 |