인프런에서 쿠버네티스 강의를 듣는데, 강의 환경은 VM 3개를 띄워서 1대는 마스터 노드, 나머지 2대는 워커노드로 사용을 한다.
이번 강의에서 실습한 내용은 아래와 같다
- Pod에 Service를 붙이기
- Master Node에서 curl로 Cluster IP를 호출한다
- 해당 IP의 9000번 포트에 접근하여 hostname을 url 매개변수로 넘겨주면 9000번 포트에 올라가 있는 Pod의 호스트 네임이 출력된다. (Pod의 이미지의 내용이 이렇다)
우선 각 오브젝트들의 매니페스트 정보는 다음과 같다
pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-1
labels:
app: pod
spec:
nodeSelector:
kubernetes.io/hostname: aks-agentpool-19228959-vmss000000
containers:
- name: container
image: tmkube/app
ports:
- containerPort: 8080
- 3개의 Worker Node 중 aks-agentpool-19228959-vmss000000에 pod-1을 배포한다.
- 이 Pod의 내용은 url에 hostname이 들어오면 해당 hostname을 출력해주는 것이다.
service.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-1
spec:
selector:
app: pod
ports:
- port: 9000
targetPort: 8080
- Type을 따로 명시하지 않았으므로 Cluster IP로 기본 설정된다.
- 9000번 포트로 접근하면 (Pod가 떠있는)8080번 포트로 연결을 해준다
pod-1에 문제가 생겨 pod-1을 수동으로 삭제하거나, 자동으로 삭제되었다가 다시 pod-1이 만들어지면, svc-1의 selector로 pod-1의 label을 설정했기 때문에 pod-1을 삭제하고 다시 만들어도 svc-1에 자동으로 연결되게 된다.
이때 pod-1의 IP는 바뀌지만, svc-1의 IP는 그대로 유지되기 때문에 사용자 입장에서는 처음부터 사용하던 IP로 접속을 해도 아무 지장이 없다. 이것이 Service를 사용하는 이유이자 장점이다.
단, Type이 Cluster IP이므로 클러스터 내부에서만 접근 가능하다.
- 외부에서 접근 하려면 Type을 LoadBalancer로 지정해주면 된다
강의와 다른점
강의에서는 Master Node에서 아래와 같이 IP를 호출하면 호스트네임을 출력해준다.
하지만 내가 사용하는 AKS의 경우 Master Node가 Azure자체이고 사용자가 접근, 관리하는 노드는 워커노드이다. 그렇기 때문에 강의에서 curl 명령어로 한 것을 똑같이 하면 요청을 받지 못한다.
$ curl 10.240.0.4:9000/hostname
curl: (7) Failed to connect to 10.240.0.4 port 9000: Connection timed out
현재 떠있는 Pod, Service, Node의 상태는 아래와 같다.
$ ktl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-1 1/1 Running 0 4h49m 10.244.2.5 aks-agentpool-19228959-vmss000000 <none> <none>
replication-1-jjwqq 1/1 Running 0 14h 10.244.1.21 aks-agentpool-19228959-vmss000001 <none> <none>
$ ktl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
hello-svc ClusterIP 10.0.157.34 52.231.64.238 8200/TCP 38h app=hello
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 10d <none>
svc-2 NodePort 10.0.187.187 <none> 9000:30000/TCP 4h17m app=pod
svc-3 LoadBalancer 10.0.169.32 20.194.48.15 9000:31923/TCP 3h30m app=pod
$ ktl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
aks-agentpool-19228959-vmss000000 Ready agent 10d v1.18.10 10.240.0.4 <none> Ubuntu 18.04.5 LTS 5.4.0-1034-azure docker://19.3.12
aks-agentpool-19228959-vmss000001 Ready agent 10d v1.18.10 10.240.0.5 <none> Ubuntu 18.04.5 LTS 5.4.0-1036-azure docker://19.3.12
aks-agentpool-19228959-vmss000002 Ready agent 10d v1.18.10 10.240.0.6 <none> Ubuntu 18.04.5 LTS 5.4.0-1034-azure docker://19.3.12
이를 그림으로 나타내면 아래와 같다
여기서 node들은 vmss로 '가상머신 확장집합'이다.
즉, VM인 것이다. 강의에서 처럼 curl 을 통해 클러스터 내부 IP로 통신을 하는 것을 테스트 해보려면 node안으로 들어가야 한다. 방법은 아래 문서를 참고해서 할 수 있다.
AKS에서 Worker Node에 ssh로 접속하기
$ CLUSTER_RESOURCE_GROUP=$(az aks show --resource-group {resource-group-name} --name {aks-name} --query nodeResourceGroup -o tsv)
$ SCALE_SET_NAME=$(az vmss list --resource-group $CLUSTER_RESOURCE_GROUP --query [0].name -o tsv)
$ az vmss list --resource-group $CLUSTER_RESOURCE_GROUP --query [0].name -o tsv
# 접속을 위한 ssh key 생성.
$ ssh-keygen -t rsa -C "inflearn-aks-node"
# SSH 키 가상 머신 확장 집합 노드에 추가
$ az vmss extension set \
--resource-group $CLUSTER_RESOURCE_GROUP \
--vmss-name $SCALE_SET_NAME \
--name VMAccessForLinux \
--publisher Microsoft.OSTCExtensions \
--version 1.4 \
--protected-settings "{\"username\":\"azureuser\", \"ssh_key\":\"$(cat ~/.ssh/id_rsa.pub)\"}"
$ az vmss update-instances --instance-ids '*' \
--resource-group $CLUSTER_RESOURCE_GROUP \
--name $SCALE_SET_NAME
# 도우미 Pod 생성 (--rm 옵션이 붙어있어서 접속된 파드에서 나오면 파드가 죽는다. 죽으면 여기서부터 새로 다시 해줘야 한다)
$ kubectl run -it --rm aks-ssh --image=debian
# 도우미 Pod내에서 openssh 설치
root@aks-ssh:/# apt-get update && apt-get install openssh-client -y
# 도우미 Pod의 접속을 유지한 채로 새로운 터미널 창에서 작업 다시한다.
$ kubectl cp ~/.ssh/id_rsa $(kubectl get pod -l run=aks-ssh -o jsonpath='{.items[0].metadata.name}'):/id_rsa
root@aks-ssh:/# chmod 0600 id_rsa
root@aks-ssh:/# ssh -i id_rsa azureuser@10.240.0.4 # vmss의 private IP로 접속
접속 테스트
이렇게 하면 Worker Node 중 하나인 0000번 노드에 접속을 할 수 있다.
접속해서 아래와 같이 cluster IP를 호출하면 hostname이 정상적으로 출력되는 것을 볼 수 있다.
# svc-2의 clusterIP 호출 (type : Nodeport)
azureuser@aks-agentpool-19228959-vmss000000:~$ curl 10.0.187.187:9000/hostname
Hostname : pod-1
# svc-2에서 30000번 포트 호출 : 여기서는 왜 localhost로 해야하는지 잘 모르겠다..
azureuser@aks-agentpool-19228959-vmss000000:~$ curl localhost:30000/hostname
Hostname : pod-1
# svc-3의 clusterIP 호출 (type : LoadBalancer)
azureuser@aks-agentpool-19228959-vmss000000:~$ curl 10.0.169.32:9000/hostname
Hostname : pod-1
# svc-3의 External-IP호출 (type : LoadBalancer)
azureuser@aks-agentpool-19228959-vmss000000:~$ curl 20.194.48.15:9000/hostname
Hostname : pod-1
LoadBalancer의 경우 AKS와 같은 SaaS를 이용하면 기본적으로 제공해주는 기능이지만, 직접 VM에 구축하는 경우에는 추가적인 플러그인을 설치해야만 LoadBalancer를 사용할 수 있다.
'DevOps > Kubernetes' 카테고리의 다른 글
[Kubernetes Study - 06] Volume - emptyDir, hostPath, PV/PVC (0) | 2021.02.09 |
---|---|
Kubernetes 명령어 정리 (0) | 2021.02.03 |
[Kubernetes Study - 03] 기본 실습 (1) - yaml 파일 작성 및 Pod 내 컨테이너 접속 (0) | 2021.01.21 |
[Kubernetes Study - 02] 기본 개념 이해 (0) | 2021.01.19 |
[Kubernetes Study - 01] Introduction (0) | 2021.01.04 |