
서비스 kubectl 명령어, 왜 운영자의 필수 무기일까요
새로 배포한 애플리케이션에 접속하려는데, 분명히 포드는 잘 떠 있지만 연결이 되지 않아 당황했던 적이 있으신가요? IP를 확인하고 포트를 맞췄는데도 응답이 없을 때, 가장 먼저 의심해야 할 대상은 바로 쿠버네티스 서비스(Kubernetes Service) 설정이에요. 서비스가 포드를 제대로 가리키고 있는지, 혹은 네트워크 경로가 잘못되었는지를 확인하는 과정은 운영 업무의 절반 이상을 차지한다고 해도 과언이 아니에요.
단순히 kubectl get pods만 입력해서 상태가 Running인 것을 확인했다고 해서 안심하기에는 일러요. 서비스는 포드라는 개별 객체들을 하나의 고정된 주소로 묶어주는 게이트웨이 역할을 하기 때문이에요. 이 게이트웨이가 고장 나면 아무리 튼튼한 포드라도 외부에서는 접근할 수 없는 고립된 섬이 되고 말아요.
이 글을 끝까지 읽으시면 서비스의 상태를 눈 깜짝할 사이에 파악하는 조회 명령부터, 설정 오류를 즉시 잡아내는 디버깅 명령어, 그리고 실무에서 실수하기 쉬운 수정 및 삭제 절차까지 모두 마스터할 수 있어요. 주니어 개발자가 실무에서 겪는 막막함을 해결하기 위해 가장 빈번하게 쓰이는 명령어들만 엄선했어요.
이 글에서 다루는 핵심 내용이에요:
- 서비스의 현재 상태와 상세 설정을 확인하는 조회 명령
- YAML 파일을 활용한 서비스 생성 및 실시간 수정 방법
- 트러블슈팅을 위한 엔드포인트와 로그 확인 팁
- 출력 형식을 자유자재로 바꾸는 필터링 기술
작업 시작 전 반드시 알아야 할 서비스 기본 개념
명령어를 입력하기 전에 우리가 다루는 대상이 어떤 성격인지 정확히 이해하는 것이 중요해요. 쿠버네티스 서비스는 크게 네 가지 타입으로 나뉘는데, 각 타입에 따라 사용하는 명령어의 목적과 확인해야 할 네트워크 경로가 완전히 달라지기 때문이에요. 잘못된 타입을 선택하면 외부에서 접속이 안 되거나, 불필요하게 클러스터 내부 자원을 낭비할 수 있어요.
서비스는 포드의 동적인 IP를 고정된 가상 IP(ClusterIP)로 변환해주는 추상화 레이어예요. 이를 통해 포드가 재시작되어 IP가 바뀌더라도 서비스 주소는 변하지 않고 유지돼요.
먼저 어떤 상황에 어떤 서비스를 써야 하는지 판단 기준을 명확히 세워야 해요. 아래 표를 통해 상황별 적절한 서비스 타입을 선택해 보세요.
| 서비스 타입 | 주요 용도 | 접근 범위 | 비고 |
|---|---|---|---|
| ClusterIP | 클러스터 내부 통신 | 클러스터 내부 전용 | 기본값이며 가장 많이 쓰여요 |
| NodePort | 외부에서 노드 IP로 접속 | 외부 노드 IP + 포트 | 포트 번호 충돌 주의가 필요해요 |
| LoadBalancer | 클라우드 로드밸런서 연결 | 외부 인터넷 전체 | 클라우드 환경에서만 유효해요 |
| ExternalName | 외부 도메인을 서비스로 매핑 | 클러스터 내부에서 호출 | CNAME 레코드를 생성해요 |
실무에 투입되면 가장 많이 접하게 될 것은 ClusterIP와 LoadBalancer예요. 내부 마이크로서비스 간의 통신은 ClusterIP로 처리하고, 사용자에게 직접 보여줘야 하는 웹 프론트엔드 등은 LoadBalancer를 사용하는 것이 정석이에요. 만약 테스트 환경에서 간단하게 외부 접속을 확인하고 싶다면 NodePort가 가장 빠르고 간편한 선택지가 될 수 있어요.
NodePort를 사용할 때는 클러스터가 사용하는 포트 범위(기본적으로 30000-32767)를 반드시 확인해야 해요. 이 범위를 벗어나는 포트를 지정하면 서비스 생성 자체가 실패할 수 있어요.
준비가 끝났다면 이제 본격적으로 명령어를 통해 서비스를 제어해 볼 차례예요. 모든 작업은 명령어를 입력하기 전에 현재 사용 중인 네임스페이스(Namespace)가 맞는지 확인하는 습관을 가져야 해요. kubectl config view로 현재 컨텍스트를 점검하는 것을 잊지 마세요.
실전 서비스 관리: 조회부터 디버깅까지 단계별 가이드
이제 본격적으로 명령어를 사용해 볼 시간이에요. 단순히 명령어를 외우는 것보다, 어떤 상황에서 어떤 명령어가 필요한지 흐름을 이해하는 것이 훨씬 중요해요. 실제 운영 시나리오에 맞춰 5단계로 나누어 정리했어요.
STEP 1. 서비스 목록 및 상세 상태 조회하기
가장 기본이 되는 작업은 현재 어떤 서비스들이 떠 있는지 확인하는 것이에요. kubectl get svc 명령어를 입력하면 현재 네임스페이스에 있는 모든 서비스의 요약 정보를 볼 수 있어요. 여기서 ClusterIP와 PORT(S) 정보를 눈여겨봐야 해요. 만약 특정 서비스의 설정이 의심된다면 kubectl describe svc <서비스명>을 사용하세요. 이 명령어는 서비스의 ‘신분증’과 같아서, 셀렉터(Selector)가 무엇인지, 실제로 연결된 엔드포인트(Endpoints)가 있는지 아주 상세하게 알려줘요.
특히 Endpoints 항목이 비어 있다면 서비스가 포드를 하나도 찾지 못하고 있다는 뜻이에요. 이는 거의 90% 확률로 서비스의 Label Selector와 포드의 Label이 일치하지 않기 때문에 발생하는 문제예요. 이럴 때는 kubectl get pods --show-labels를 통해 포드의 라벨을 먼저 확인해 보세요.
STEP 2. YAML 파일을 활용한 서비스 생성하기
실무에서는 명령어를 한 줄씩 치기보다는 이미 작성된 YAML 파일을 적용하는 방식을 선호해요. kubectl apply -f <파일명>.yaml 명령어가 그 주인공이에요. 이 명령어는 선언적(Declarative) 방식이라서, 파일에 적힌 내용이 현재 클러스터 상태와 다르면 알아서 변경 사항을 적용해 줘요. 만약 명령어로 즉석에서 서비스를 만들고 싶다면 kubectl create service clusterip <이름> --tcp=80:80처럼 사용할 수도 있지만, 복잡한 설정을 위해서는 반드시 YAML 파일을 사용하는 습관을 들이는 것이 좋아요.
YAML 파일 작성 시
targetPort와 port를 헷갈리지 마세요. port는 서비스가 외부(또는 내부 다른 서비스)로부터 받는 포트이고, targetPort는 실제 포드 내부의 애플리케이션이 듣고 있는 포트예요.STEP 3. 실행 중인 서비스 실시간 수정하기
서비스를 운영하다 보면 포트 번호를 바꾸거나 셀렉터를 수정해야 할 때가 있어요. 이때 파일을 다시 수정하고 적용하는 방법도 있지만, 빠르게 테스트하고 싶다면 kubectl edit svc <서비스명> 명령어를 사용해 보세요. 이 명령어를 실행하면 즉시 텍스트 에디터가 열리고, 여기서 설정을 바꾼 뒤 저장하면 클러스터에 즉시 반영돼요. 만약 특정 값만 아주 빠르게 바꾸고 싶다면 kubectl patch 명령어를 활용하는 것도 고급 기술 중 하나예요.
STEP 4. 잘못된 서비스 삭제 및 정리하기
테스트용으로 만든 서비스가 클러스터를 어지럽히고 있다면 kubectl delete svc <서비스명>으로 깔끔하게 지워주세요. 만약 실수로 중요한 서비스를 삭제했다면 당황하지 말고, 미리 백업해둔 YAML 파일을 통해 kubectl apply로 즉시 복구해야 해요. 서비스를 삭제할 때는 해당 서비스와 연결된 엔드포인트도 함께 사라진다는 점을 기억하세요. 포드 자체는 삭제되지 않지만, 외부에서 해당 포드로 가는 길은 완전히 끊기게 돼요.
STEP 5. 고급 필터링으로 원하는 정보만 뽑아내기
클러스터 규모가 커지면 수백 개의 서비스 목록을 보는 것조차 고역이에요. 이때 유용한 것이 바로 출력 포맷 제어예요. kubectl get svc -o wide를 사용하면 서비스의 IP뿐만 아니라 더 넓은 범위의 정보를 볼 수 있고, kubectl get svc -o jsonpath='{.items[*].spec.clusterIP}'와 같은 명령어를 쓰면 수많은 정보 중 딱 필요한 IP 주소들만 골라낼 수 있어요. 데이터 자동화 스크립트를 짤 때 이 기술은 정말 빛을 발하게 될 거예요.
실무 시나리오 예시:
사용자가 “웹 서비스에 접속이 안 돼요!”라고 요청했습니다. 여러분은 다음 순서로 대응하세요.
kubectl get svc로 서비스가 존재하고 타입이LoadBalancer인지 확인해요.kubectl get endpoints <서비스명>을 쳐서 IP 목록이 나오는지 확인해요. 만약 없다면 라벨 매칭 오류예요.- 라벨이 맞다면
kubectl logs <포드명>을 통해 실제 애플리케이션이 해당 포트에서 정상 동작 중인지 확인해요.
자주 하는 실수와 해결법 및 자주 묻는 질문
자주 하는 실수와 해결법
운영 현장에서 반복적으로 발생하는 실수들을 정리했어요. 비슷한 상황을 겪고 있다면 아래 해결법을 따라 해 보세요.
- ❌ 실수: 서비스는 생성되었는데 엔드포인트가 비어 있음
→ 왜 발생하는가: 서비스의selector에 정의된 라벨이 실제 포드의 라벨과 일치하지 않아요.
→ ✅ 해결법:kubectl get pods --show-labels로 포드의 라벨을 확인하고, 서비스 YAML의 selector 부분을 수정하세요. - ❌ 실수: NodePort로 접속했는데 연결 거부(Connection Refused) 발생
→ 왜 발생하는가: 포트 번호가 30000-32767 범위를 벗어났거나, 클라우드 보안 그룹(Security Group)에서 해당 포트를 막아두었을 가능성이 커요.
→ ✅ 해결법: 서비스 포트 범위를 재확인하고, 클라우드 콘솔에서 인바운드 규칙을 점검하세요. - ❌ 실수: ClusterIP를 사용하면서 외부에서 접속을 시도함
→ 왜 발생하는가: ClusterIP는 클러스터 내부 통신용이라 외부에서는 접근할 수 없는 주소예요.
→ ✅ 해결법: 외부 노출이 필요하다면 타입을LoadBalancer나NodePort로 변경하세요. - ❌ 실수: targetPort 설정 오류로 인한 통신 실패
→ 왜 발생하는가: 애플리케이션은 8080 포트에서 돌고 있는데, 서비스의targetPort를 80으로 설정한 경우예요.
→ ✅ 해결법: 애플리케이션 컨테이너 설정과 서비스의targetPort가 일치하는지 확인하세요. - ❌ 실수: 잘못된 네임스페이스에서 명령어 실행
→ 왜 발생하는가: 서비스는production에 있는데, 명령어를default네임스페이스에서 치고 있어요.
→ ✅ 해결법:kubectl get svc -n <네임스페이스명>처럼 항상 네임스페이스를 명시하거나 컨텍스트를 확인하세요.
자주 묻는 질문
Q. 서비스 IP(ClusterIP)는 왜 계속 변하나요?
서비스를 삭제하고 다시 생성하면 새로운 IP가 할당되는 것이 기본 동작이에요. 고정된 IP가 반드시 필요하다면 spec.clusterIP를 직접 지정할 수 있지만, 이는 권장되지 않으며 DNS 이름을 사용하는 것이 더 안정적이에요.
Q. 서비스와 인그레스(Ingress)의 차이가 무엇인가요?
서비스는 L4 계층(포트/IP 기반)에서 동작하고, 인그레스는 L7 계층(도메인/경로 기반)에서 동작해요. 보통 인그레스가 외부 요청을 받아 적절한 서비스로 전달해주는 구조를 가져요.
Q. kubectl edit 명령어를 쓰면 서비스가 즉시 중단되나요?
설정을 수정하고 저장하는 순간 반영되지만, 기존 연결이 즉시 끊기지는 않아요. 다만, 포트 번호처럼 구조적인 변경을 하면 기존 연결 중인 클라이언트가 끊길 수 있으니 주의가 필요해요.
Q. 서비스 타입을 LoadBalancer로 바꿨는데 외부 IP가 계속 <pending> 상태예요.
클라우드 공급자의 로드밸런서 생성 시간이 필요하거나, 클라우드 설정 권한이 부족할 때 발생해요. 클라우드 콘솔의 이벤트 로그를 확인해 보세요.
핵심 요약과 다음 단계
오늘 배운 내용을 바탕으로 서비스 관리 역량을 한 단계 높여보세요. 명령어 하나를 정확히 쓰는 것이 장애 대응 시간을 획기적으로 줄여줄 거예요.
- 서비스 조회는
kubectl get svc, 상세 확인은kubectl describe svc를 활용하세요. - 연결이 안 된다면 반드시
Endpoints항목이 비어 있는지 확인하세요. - 설정 변경은
kubectl apply(파일 방식)나kubectl edit(즉시 수정)을 사용하세요. - 서비스 타입(ClusterIP, NodePort, LoadBalancer)을 목적에 맞게 선택하세요.
- 라벨 셀렉터(Selector) 일치 여부가 트러블슈팅의 핵심입니다.
오늘 바로 해볼 일:
- 현재 운영 중인 클러스터에서
kubectl get svc -A를 입력해 모든 네임스페이스의 서비스를 훑어보세요. - 임의의 서비스 하나를 골라
describe명령어로 엔드포인트가 잘 연결되어 있는지 직접 확인해 보세요.
이번 주 학습 목표:
서비스를 넘어, 외부 트래픽을 더 정교하게 제어할 수 있는 인그레스(Ingress)와 네트워크 정책(Network Policy)에 대해 학습해 보시는 것을 강력히 추천해요. 서비스가 길을 만든다면, 인그레스는 그 길에 표지판을 세우는 역할을 한답니다.
실습 중에 명령어가 뜻대로 작동하지 않거나, 이해가 가지 않는 오류 메시지가 나온다면 주저하지 말고 댓글로 질문을 남겨 주세요. 함께 고민하며 해결해 나가요! 더 깊이 있는 쿠버네티스 운영 노하우가 궁금하시다면, 쿠버네티스 서비스 기본 개념 글과 클러스터 구축 입문 글을 이어서 읽어보시는 것도 큰 도움이 될 거예요.