목차
- 헤드리스 서비스
- 헤드리스 서비스 생성
- DNS로 파드 찾기
- 서비스 문제
- 마치며
헤드리스 서비스
Kubernetes의 헤드리스 서비스는 클러스터 IP가 할당되지 않은 특수한 유형의 서비스입니다. 대신 서비스 뒤의 개별 포드를 직접 검색하고 연결하는 방법을 제공합니다. 헤드리스 서비스는 부하 분산이나 서비스에 대한 단일 IP 주소에 의존하지 않고 클라이언트와 포드 간에 직접 연결을 설정해야 하는 경우에 유용합니다. 이는 안정적인 네트워크 ID가 필요한 분산 시스템 또는 상태 저장 애플리케이션과 같은 경우에 유용할 수 있습니다.
헤드 리스 서비스로 개별 파드를 찾기 위해서는 먼저 클라이언트가 모든 파드에 연결을 할 수 있어야 합니다. 클라이언트가 모든 파드에 연결하기 위해서는 각 파드의 IP를 알아야하고, 그 중 한 가지 옵션은 클라이언트가 쿠버네티스 API 서버를 호출해 파드와 IP 주소 목록을 가져오도록 하는 것인데, 애플리케이션을 쿠버네티스와 무관하게 유지하려고 노력해야 하기 때문에 항상 API 서버를 사용하는 것은 바람직하지 않습니다.
다행히 쿠버네티스는 클라이언트가 DNS 조회로 파드 IP를 찾을 수 있도록 합니다. 일반적으로 서비스에 대한 DNS 조회를 수행하면 DNS 서버는 하나의 IP를 반환합니다. 그러나 쿠버네티스 서비스에 클러스터 IP가 필요하지 않다면 DNS 서버는 하나의 서비스 IP 대신 파드 IP들을 반환합니다.
DNS 서버는 하나의 DNS A 레코드를 반환하는 대신 서비스에 대한 여러 개의 A 레코드를 반환합니다. 각 레코드는 해당 시점에 서비스를 지원하는 개별 파드의 IP를 가리킵니다. 따라서 클라이언트는 간단한 DNS A 레코드 조회를 수행하고 서비스에 포함된 모든 파드의 IP를 얻을 수 있습니다. 그런 다음 클라이언트는 해당 정보를 사용해 하나 혹은 다수의 또는 모든 파드에 연결할 수 있습니다.
헤드리스 서비스 생성
서비스 스펙의 clusterIP 필드를 None으로 설정하면 쿠버네티스는 클라이언트가 서비스의 파드에 연결할 수 있는 클러스터 IP를 할당하지 않기 때문에 서비스가 헤드리스 상태가됩니다.
apiVersion: v1
kind: Service
metadata:
name: kubia-headless
spec:
clusterIP: None > 이 부분이 있어야 서비스를 헤드리스 서비스로 만듭니다.
ports:
- port: 80
tragetPort: 8080
selector:
app: kubia
kubectl create로 서비스 생성 후 kubectl get과 kubectl describe로 서비스를 살펴볼 수 있습니다. 클러스터 IP가 없고 엔드포인트에 파드 셀렉터와 일치하는 파드가 포함돼 있음을 알 수 있습니다. 파드에 레디니스 프로브가 포함돼 있기 때문에 준비된 파드만 서비스의 엔드포인트로 조회됩니다.
DNS로 파드 찾기
파드가 준비되면 DNS 조회로 실제 파드 IP를 얻을 수 있는지 확인할 수 있습니다. 이 때 파드 내부에서 조회해야 합니다. 안타깝게도 kubia 컨테이너 이미지에는 nslookup 바이너리가 포함돼 있지 않으므로 DNS 조회를 수행하는 데 사용할 수 없습니다.
따라서 필요한 바이너리가 포함된 이미지를 기반으로 새 파드를 실행하면 DNS 관련 작업을 수행하려면 도커 허브의 nslookup 및 dig 바이너리를 모두 포함하는 tutum/dnsutuls 컨테이너 이미지를 사용하면 좋습니다.
파드를 실행하려면 YAML 매니페스트를 만들어 kubectl create로 전달하는 전체 프로세스를 수행할 수 있지만 지나치게 많은 작업이 필요합니다. 때문에 다음 방법을 이용할 수 있습니다. 이 방법으로 진행하면 파드를 관리하는 레플리케이션 컨트롤러를 만들 필요 없이 바로 파드만 만들 수 있습니다.
kubectl run dnsutils --image=tutum/dnsuitls --generator-run-pod/v1 --command -- sleep infinity
트릭은 --generator-run-pod/v1 옵션에 있고, kubectl은 어떤 종류의 레플리케이션컨트롤러나 그와 유사한 장치 없이 파드를 직접 생성하도록 지시합니다. 이제 다음 명령어를 사용해 새 파드로 DNS를 조회할 수 있습니다.
kubectl exec dnsutils nslookup kubia-headless
DNS 서버는 kubia-headless.default.svc.cluster.local FQDN에 대해 서로 다른 두 개의 IP를 반환할 것입니다. 바로 준비됐다고 보고된 파드 두 개의 IP입니다. kubectl get pods -o wide로 파드를 조회하면 이를 확인할 수 있는데, 이것은 파드의 IP를 보여줍니다.
이는 kubia 서비스와 같이 일반 서비스를 DNS가 반환하는 것과는 다릅니다. 반환된 IP는 서비시스의 클러스터 IP 입니다.
kubectl exec dnsutils nslookup kubia
헤드리스 서비스는 일반 서비스와 다르게 보일 수 있지만 클라이언트의 관점에서는 다르지 않습니다. 헤드리스 서비스르 사용하더라도 클라이언트는 일반 서비스와 마찬가지로 서비스의 DNS 이름에 연결해 파드에 연결할 수 있습니다. 그러나 헤드리스 서비스에서는 DNS가 파드의 IP를 반환하기 때문에 클라이언트는 서비스 프록시 대신 파드에 직접 연결합니다.
서비스 문제
서비스는 쿠버네티스에서 정말 중요한 개념이고 많은 개발자가 좌절하는 이유기도 합니다. 많은 개발자들이 서비스 IP 또는 FQDN으로 파드에 연결할 수 없는 이유를 파악하는 데 많은 시간을 허비하는 경우가 꾀 많았습니다. 이런 이유로 서비스 문제 해결법을 간략히 살펴보려 합니다. 서비스로 파드에 액세스할 수 없는 경우 다음과 같은 내용을 확인후 다시 시작해봅시다.
- 먼저 외부가 아닌 클러스터 내에서 서비스의 클러스터 IP에 연결되는지 확인합니다.
- 서비스에 액세스할 수 있는지 확인하려고 서비스 IP로 핑을 할 필요 없습니다. 서비스의 클러스터 IP는 가상 IP이기 때문입니다.
- 레디니스 프로브를 정의했다면 성공했는지 확인합니다. 그렇지 않으면 파드는 서비스에 포함되지 않습니다.
- 파드가 서비스의 일부인지 확인하려면 kubectl get endpoints를 사용해 해당 엔드포인트 오브젝트를 확인합니다.
- FQDN이나 그 일부로 서비스에 액세스하려고 하는데 작동하지 않는 경우, FQDN 대신 클러스터 IP를 사용해 액세스할 수 있는지 확인합니다.
- 대상 포트가 아닌 서비스로 노출된 포트에 연결하고 있는지 확인합니다.
- 파드 IP에 직접 연결해 파드가 올바른 포트에 연결되어 있는지 확인합니다.
- 파드 IP로 애플리케이션에 액세스할 수 없는 경우 애플리케이션이 로컬호스트에만 바인딩하고 있는지 확인합니다.
이 내용은 서비스 관련된 많은 부분의 문제를 해결하는 데 도움이 될 것입니다. 나중에 서비스 동작 방식을 더 깊이 다뤄보려하는데 구현 방식을 정확히 이해하면 서비스 문제를 해결하기 훨씬 쉬워질 것입니다.
이제 서비스의 남은 부분은 잠시 뒤로 넘겨두고 스토리지와 볼륨에 대해 다뤄보려고 합니다. 뒤로 갈수록 점점 어려워짐에 따라 포스팅 시간도 늘어나 공부가 쉽지 않네요. 쿠버네티스를 정리하는 과정은 이제 약 25%정도가 다루었습니다. 이제 에티버스러닝에서도 쿠버네티스는 끝났고 vSphere에 대해 다루기 시작했는데 이것도 정리하려고 하면 수일이 걸릴거 같아 벌써 앞이 깜깜하네요.
이제 곧 2달이 되어가는데, 항상 느끼는 것은 네트워크도 그렇고 리눅스도 그렇고 어떻게 한번에 되는게 거의 없는지 처음에는 많이 답답했는데, 이제는 오류가 안나오면 그게 더 이상합니다. 최근 재해 복구 솔루션에 대해 뉴스에서 많이 언급되고 있는데, 그 이유에 대해서 조금은 알 것 같기도 합니다. 똑같이 했는데도 어디선가 오류가 나오고 틀어져, 물리적으로 피해를 입는 것이 아니더라도 온전히 서비스하는 것은 쉽지 않겠구나 생각이 듭니다.
현직자이신 강사님들(현직에 종사하면서 회사차원에서 강의하러 오시는 강사님들도 계십니다.)께서도 강의 중 발생한 문제 때문에 트러블슈팅하느라 진땀빼는 일이 비일비재하니 실제로 서비스를 하게 된다면 말 다했죠. 이렇게 돌아보면 힘들긴 했지만 또 이 상황이 웃기기도 합니다.
IT에서 취업을 준비하시는 분, 개인적으로 공부하시는 분들 노력 하나하나가 내용을 알면 알수록 점점 크고 대단하게 느껴집니다. 한 걸음 다가가면 5걸음은 멀어지는 느낌이라 힘들지만 언제가는 뛰어갈 수 있도록 노력해야겠죠? 저도 얼른 걸음마에 적응하고 뛸 준비를 할 수 있도록 코어를 키워봐야겠습니다. 끝까지 읽어주셔서 감사하고 여러분들께 항상 행운이 가득하길 소망해보겠습니다.
'Container > Kubernetes' 카테고리의 다른 글
[Kubernetes Volume] 2. 파드 내부 컨테이너간 데이터 공유(emptyDir, gitRepo) (0) | 2023.04.12 |
---|---|
[Kubernetes Volume] 1. 쿠버네티스 볼륨과 볼륨의 유형 (0) | 2023.04.12 |
[Kubernetes Service] 6. 레디니스 프로브(readyness probe)로 수신 요청 (0) | 2023.04.11 |
[Kubernetes Service] 5. 인그레스로 통신 및 TLS로 보안 (0) | 2023.04.11 |
[Kubernetes Service] 4. 클라이언트 외부에 서비스 노출 (2) | 2023.04.11 |