콘텐츠로 이동
Study NoteCKA

실전 과제 — 서비스와 네트워크

결론부터
  • 포트 노출 과제는 컨테이너의 ports 선언과 Service 생성이 따로 채점된다. 둘 다 한다.
  • NodePort Service는 kubectl expose --type=NodePort 한 줄로 만들고 EndpointSlice로 연결을 확인한다.
  • Ingress를 Gateway API로 옮길 때 TLS와 진입 포트는 Gateway로, 호스트·경로·백엔드는 HTTPRoute로 간다.
  • Gateway와 HTTPRoute는 만든 뒤 status.conditions가 True인지까지 본다.

과제는 연습용으로 만든 시나리오이고 이름과 값은 예시다. 과제마다 조건 → 풀이 → 확인 → 함정 순서로 읽고, 원리는 링크한 개념 페이지에서 확인한다. 호스트 접속과 네임스페이스 확인은 문제마다 반복하는 3단계를 따른다.

컨테이너 포트를 선언하고 NodePort로 노출하기

섹션 제목: “컨테이너 포트를 선언하고 NodePort로 노출하기”

과제

  • 네임스페이스 storefront의 Deployment catalog에서 컨테이너 nginx가 80/tcp 포트를 선언하도록 고친다.
  • 이 포트를 노출하는 Service catalog-svc를 만든다.
  • Service는 노드의 포트로도 접근할 수 있어야 한다.

준비

터미널 창
kubectl create namespace storefront
kubectl create deployment catalog -n storefront --image=nginx:1.28 --replicas=2

풀이

  1. 컨테이너에 포트 선언을 넣는다. kubectl edit로 nginx 컨테이너 아래에 추가한다.

    터미널 창
    kubectl edit deployment catalog -n storefront
    containers:
    - name: nginx
    image: nginx:1.28
    ports: # 추가
    - containerPort: 80
    protocol: TCP
  2. Service를 NodePort 타입으로 만든다.

    터미널 창
    kubectl expose deployment catalog -n storefront \
    --name=catalog-svc --type=NodePort --port=80 --target-port=80
  3. Service가 Pod을 잡았는지, 실제로 응답하는지 본다.

    터미널 창
    kubectl rollout status deployment catalog -n storefront
    kubectl get svc catalog-svc -n storefront # PORT(S) 80:3xxxx/TCP
    kubectl get endpointslices -n storefront \
    -l kubernetes.io/service-name=catalog-svc # Pod IP 2개
    curl http://<노드IP>:<할당된-nodePort>

세 포트의 구분은 세 포트를 구분하자, NodePort의 동작은 NodePort에서 본다.

과제

  • 네임스페이스 shop의 Ingress shop이 하던 일을 Gateway API로 옮긴다. HTTPS 접근은 그대로 유지한다.
  • 호스트 gw.shop.example.com으로 받는 Gateway shop-gateway를 만든다. TLS 설정은 기존 Ingress의 것을 쓴다.
  • 같은 호스트의 HTTPRoute shop-route를 만든다. 라우팅 규칙은 기존 Ingress의 것을 쓴다.
  • 클러스터에는 GatewayClass nginx가 설치되어 있다.

기존 Ingress는 다음과 같다고 가정한다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: shop
namespace: shop
spec:
ingressClassName: nginx
tls:
- hosts: [shop.example.com]
secretName: shop-tls
rules:
- host: shop.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service: { name: api-svc, port: { number: 8080 } }
- path: /
pathType: Prefix
backend:
service: { name: shop-svc, port: { number: 80 } }

이 과제를 따라 하려면 Gateway API CRD와 구현체가 설치되어 있어야 한다. 설치 구조는 Gateway API — Ingress의 후속에서 본다.

풀이

  1. 옮길 값을 Ingress에서 읽는다. TLS Secret 이름, 경로, 백엔드 Service와 포트가 필요하다.

    터미널 창
    kubectl get ingress shop -n shop -o yaml
    kubectl get gatewayclass
  2. Gateway를 만든다. TLS Secret과 HTTPS 포트가 여기로 온다.

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
    name: shop-gateway
    namespace: shop
    spec:
    gatewayClassName: nginx
    listeners:
    - name: https
    protocol: HTTPS
    port: 443
    hostname: gw.shop.example.com
    tls:
    mode: Terminate
    certificateRefs:
    - kind: Secret
    name: shop-tls
  3. HTTPRoute를 만든다. 경로와 백엔드가 여기로 온다.

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
    name: shop-route
    namespace: shop
    spec:
    parentRefs:
    - name: shop-gateway
    hostnames:
    - gw.shop.example.com
    rules:
    - matches:
    - path: { type: PathPrefix, value: /api }
    backendRefs:
    - name: api-svc
    port: 8080
    - matches:
    - path: { type: PathPrefix, value: / }
    backendRefs:
    - name: shop-svc
    port: 80
  4. 적용하고 상태를 확인한다. 두 리소스 모두 조건이 True여야 한다.

    터미널 창
    kubectl apply -f gateway.yaml -f httproute.yaml
    kubectl get gateway,httproute -n shop
    kubectl describe gateway shop-gateway -n shop # Accepted, Programmed
    kubectl describe httproute shop-route -n shop # Accepted, ResolvedRefs
  5. HTTPS로 실제 요청을 보낸다. <주소>는 kubectl get gateway의 ADDRESS 값이다.

    터미널 창
    curl -k --resolve gw.shop.example.com:443:<주소> https://gw.shop.example.com/

필드별 대응은 Ingress 필드를 옮기는 자리, 조건의 뜻은 진단에서 본다.