사용 중단된 API 매니페스트 업데이트

KubernetesBeginner
지금 연습하기

소개

Kubernetes API 는 지속적으로 발전합니다. 이전 클러스터에서 작동하던 매니페스트가 새로운 클러스터에서는 API 버전이 제거되었거나 필드 구조가 변경되어 실패할 수 있습니다. CKAD 업무에서 이는 일반적으로 실무적인 유지보수 작업으로 나타납니다. 즉, 오류를 읽고, 현재 API 를 식별하며, 매니페스트를 업데이트하고, 새로운 버전이 정상적으로 수용되는지 확인하는 과정입니다.

이 실습에서는 오래된 Ingress 매니페스트를 networking.k8s.io/v1beta1에서 networking.k8s.io/v1으로 마이그레이션합니다. 먼저 Ingress 가 참조할 서비스를 생성한 다음, 이전 매니페스트가 실패하는 것을 확인하고, kubectl 검색 명령을 사용하여 현재 API 를 검사하고, 매니페스트를 다시 작성한 뒤 수정된 Ingress 를 적용합니다.

서비스 참조 준비

이 단계에서는 깨끗한 네임스페이스와 간단한 서비스를 준비합니다. 이전 및 새로운 Ingress 매니페스트 모두 이 서비스를 가리키게 하여, 마이그레이션 작업이 파드 (Pod) 준비 상태나 트래픽 라우팅이 아닌 API 구조에 집중되도록 합니다.

/home/labex/project에서 시작합니다:

mkdir -p /home/labex/project
cd /home/labex/project

Kubernetes API 서버에 연결할 수 있는지 확인합니다. VM 이 막 시작되어 노드가 아직 준비되지 않았다면 몇 초 기다린 후 명령을 다시 실행하세요.

kubectl get nodes --request-timeout=5s

예상 출력은 다음과 같습니다:

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

ckad-prep-api-migration이라는 이름의 네임스페이스를 생성하고 현재 네임스페이스로 설정합니다:

kubectl create namespace ckad-prep-api-migration
kubectl config set-context --current --namespace=ckad-prep-api-migration

app-web이라는 이름의 ClusterIP 서비스를 생성합니다. --tcp=80:80 옵션은 서비스가 포트 80에서 수신 대기하며, 일치하는 파드가 있을 경우 대상 포트 80으로 전달함을 의미합니다. 이 마이그레이션 실습에서는 HTTP 트래픽이 아닌 Ingress API 필드를 검증하는 것이 목적이므로 서비스 객체 자체만으로 충분합니다.

kubectl create service clusterip app-web --tcp=80:80

서비스가 존재하는지 확인합니다:

kubectl get service app-web

예상 출력은 다음과 같습니다:

NAME      TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
app-web   ClusterIP   ...          <none>        80/TCP    ...

사용 중단된 매니페스트 실패 확인

이 단계에서는 오래된 Ingress 매니페스트를 생성하고 현재 클러스터에서 거부되도록 합니다. 마이그레이션 작업의 첫 번째 단서는 종종 API 서버의 오류 메시지이므로, 이는 유용한 실습입니다.

old-ingress.yaml을 생성합니다:

cat > old-ingress.yaml <<'EOF'
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: app-web
spec:
  rules:
  - host: app.example.local
    http:
      paths:
      - path: /
        backend:
          serviceName: app-web
          servicePort: 80
EOF

파일의 상단을 읽어봅니다. apiVersion 필드는 어떤 API 그룹과 버전이 이 객체를 처리해야 하는지 Kubernetes 에 알려줍니다.

sed -n '1,20p' old-ingress.yaml

예상 출력은 다음과 같습니다:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
...
          serviceName: app-web
          servicePort: 80

API 서버에 매니페스트를 생성하지 않고 검증하도록 요청합니다. --dry-run=server는 검증을 위해 객체를 API 서버로 전송하며, || true는 이 실패가 예상된 결과이므로 튜토리얼이 중단되지 않도록 합니다.

kubectl apply --dry-run=server -f old-ingress.yaml || true

예상 출력에는 다음과 유사한 오류가 포함됩니다:

error: resource mapping not found for name: "app-web" namespace: "" from "old-ingress.yaml": no matches for kind "Ingress" in version "networking.k8s.io/v1beta1"

중요한 증거는 no matches for kind "Ingress" in version "networking.k8s.io/v1beta1"입니다. 이는 현재 클러스터가 더 이상 해당 API 버전을 제공하지 않음을 의미합니다.

현재 Ingress API 구조 탐색

이 단계에서는 파일을 다시 작성하기 전에 현재 Ingress API 를 검사합니다. 이는 마이그레이션 작업을 체계적으로 수행하는 방법입니다. 클러스터가 허용하는 구조를 보여줄 수 있을 때 새로운 필드를 추측하지 마세요.

제공되는 Ingress 리소스를 나열합니다:

kubectl api-resources | grep -i '^ingresses'

예상 출력은 다음과 같습니다:

ingresses   ing   networking.k8s.io/v1   true   Ingress

kubectl explain을 사용하여 현재 백엔드 서비스 필드를 검사합니다. 서비스 백엔드는 spec.rules[].http.paths[].backend.service 아래에 중첩되어 있어 경로가 깁니다.

kubectl explain ingress.spec.rules.http.paths.backend.service --recursive | sed -n '1,80p'

예상 출력은 다음과 같습니다:

GROUP:      networking.k8s.io
KIND:       Ingress
VERSION:    v1

FIELD: service <IngressServiceBackend>
...
  name        <string> -required-
  port        <ServiceBackendPort> -required-

이제 마이그레이션된 current-ingress.yaml을 생성합니다. 새로운 매니페스트는 networking.k8s.io/v1을 사용하고, pathType을 추가하며, serviceName과 servicePort를 중첩된 service.name 및 service.port.number 필드로 대체합니다.

cat > current-ingress.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-web
spec:
  rules:
  - host: app.example.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-web
            port:
              number: 80
EOF

서버 측 드라이 런 (dry run) 으로 마이그레이션된 매니페스트를 검증합니다:

kubectl apply --dry-run=server -f current-ingress.yaml

예상 출력:

ingress.networking.k8s.io/app-web created (server dry run)

마이그레이션된 Ingress 적용 및 검사

이 단계에서는 마이그레이션된 Ingress 를 생성하고 Kubernetes 에 저장된 필드를 검사합니다. 리소스를 적용하는 것은 매니페스트가 현재 API 서버와 일치한다는 최종 증명입니다.

마이그레이션된 매니페스트를 적용합니다:

kubectl apply -f current-ingress.yaml

예상 출력:

ingress.networking.k8s.io/app-web created

Ingress 를 나열합니다:

kubectl get ingress app-web

예상 출력은 다음과 같습니다:

NAME      CLASS   HOSTS               ADDRESS   PORTS   AGE
app-web   ...     app.example.local    ...       80      ...

저장된 객체에서 마이그레이션된 백엔드 필드를 직접 검사합니다:

kubectl get ingress app-web -o jsonpath='{.apiVersion}{" "}{.spec.rules[0].http.paths[0].pathType}{" "}{.spec.rules[0].http.paths[0].backend.service.name}{":"}{.spec.rules[0].http.paths[0].backend.service.port.number}{"\n"}'

예상 출력:

networking.k8s.io/v1 Prefix app-web:80

이 출력은 세 가지를 동시에 증명합니다. 객체가 현재 API 버전을 사용하고 있고, 경로에 명시적인 pathType이 있으며, 백엔드가 networking.k8s.io/v1에서 요구하는 중첩된 서비스 참조를 사용하고 있다는 점입니다.

요약

실무적인 API 마이그레이션 워크플로우를 실습했습니다. 오래된 networking.k8s.io/v1beta1 Ingress 매니페스트를 생성하고, 서버 측 드라이 런을 사용하여 현재 클러스터가 이를 거부함을 확인했으며, 제공되는 networking.k8s.io/v1 API 를 검사하고, pathType과 중첩된 서비스 참조를 사용하여 백엔드 필드를 다시 작성한 뒤, 마이그레이션된 Ingress 를 적용하고 검사했습니다.