Ansible: NGINX Gateway Fabric과 Gateway API 자동 배포
이번 포스트에서는 Ansible을 사용해 Kubernetes 환경에 NGINX Gateway Fabric과 Gateway API 리소스를 자동으로 배포하는 과정을 정리합니다.
Ansible의 kubernetes.core.k8s 모듈은 Kubernetes Python client를 사용해 Kubernetes 오브젝트를 생성하고 관리할 수 있으며, YAML 파일이나 Jinja2 템플릿 기반 리소스 적용도 지원합니다.
실습에서는 Ansible을 사용해 Gateway와 HTTPRoute 리소스를 자동으로 구성합니다. Ansible을 활용하면 다양한 자동화 시나리오를 Kubernetes 환경에 적용할 수 있습니다.
목차
1. Ansible이란?
2. Ansible 실행 환경 구성
2-1. 실습 사전 준비
2-2. Python 가상환경 생성 및 활성화
2-3. Ansible 패키지 설치
2-4. kubernetes Python Client 설치
3. 실습 디렉터리 및 변수 파일 구성
3-1. 실습 디렉터리 구조
3-2. 변수 파일 작성
4. Kubernetes 리소스 템플릿 작성
4-1. 테스트 애플리케이션 템플릿 작성
4-2. Gateway 및 HTTPRoute 템플릿 작성
5. Ansible Playbook 작성 및 실행
5-1. Playbook 작성
5-2. Playbook 실행
5-3. 배포 결과 확인
6. Gateway API 동작 테스트
6-1. curl 요청 테스트
6-2. 요청/응답 헤더 확인
7. 결론
1. Ansible이란?
Ansible은 서버 설정, 애플리케이션 배포, 클라우드 및 네트워크 장비 구성 등을 자동화할 수 있는 오픈소스 자동화 도구입니다. 복잡한 스크립트를 직접 작성하지 않아도, 사람이 이해하기 쉬운 YAML 형식의 Playbook을 통해 반복 작업을 정의하고 실행할 수 있습니다.
2. Ansible 실행 환경 구성
먼저 Ansible을 실행할 python 가상환경을 만들고, 그 안에 Ansible과 Kubernetes Python Client를 설치합니다.
이번 실습에서는 Ansible의 Kubernetes.core.k8s 모듈을 사용해 Kubernetes 리소스를 생성하기 때문에, Kubernetes API와 통신할 수 있는 Python Client가 필요합니다.
2-1. 실습 사전 준비
| 구분 | 사전 준비 리소스 |
| Kubernetes 환경 | 실습용 Kubernetes 클러스터, kubectl 접속 환경, ngf-lab Namespace |
| Gateway API 환경 | NGINX Gateway Fabric Controller, nginx GatewayClass, 테스트용 echo-app Service |
2-2. Python 가상환경 생성 및 활성화
$ python3 -m venv ~/ansible-venv
$ source ~/ansible-venv/bin/activate
(ansible-venv) hangyeol@ubuntu:~$
위 명령어를 사용하여 가상환경을 생성하고 적용합니다.
2-3. Ansible 패키지 설치
$ python -m pip install ansible
Python 패키지를 통해 Ansible을 설치합니다.
$ ansible --version
ansible [core 2.20.5] config file = None configured module search path = ['/home/hangyeol/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /home/hangyeol/ansible-venv/lib/python3.12/site-packages/ansible ansible collection location = /home/hangyeol/.ansible/collections:/usr/share/ansible/collections executable location = /home/hangyeol/ansible-venv/bin/ansible python version = 3.12.3 (main, Mar 3 2026, 12:15:18) [GCC 13.3.0] (/home/hangyeol/ansible-venv/bin/python) jinja version = 3.1.6 pyyaml version = 6.0.3 (with libyaml v0.2.5)
버전을 확인하는 명령어를 사용하여 정상 설치를 확인합니다.
2-4. Kubernetes Python Client 설치
$ python -m pip install kubernetes
가상환경이 활성화된 상태에서 다음 명령어를 실행합니다.
$ python -m pip show kubernetes
Name: kubernetesVersion: 35.0.0Summary: Kubernetes python clientHome-page: https://github.com/kubernetes-client/pythonAuthor: KubernetesAuthor-email: License: Apache License Version 2.0Location: /home/hangyeol/ansible-venv/lib/python3.12/site-packagesRequires: certifi, durationpy, python-dateutil, pyyaml, requests, requests-oauthlib, six, urllib3, websocket-clientRequired-by:
버전을 확인하는 명령어를 사용하여 정상 설치를 확인합니다.
3. 실습 디렉터리 및 변수 파일 구성
3-1. 실습 디렉터리 구조
$ mkdir ~/ngf-ansible-lab/templates$ mkdir ~/ngf-ansible-lab/vars$ cd ~/ngf-ansible-lab
3-2. 변수 파일 작성
먼저 vars/main.yaml 파일을 생성합니다.
$ vi vars/main.yaml
lab_namespace: ngf-labapp_name: echo-appapp_port: 80gateway_name: ngf-gatewaygateway_class_name: nginxhttproute_name: echo-routehostname: echo.example.comrequest_header_name: x-lab-requestrequest_header_value: ansible-ngfresponse_header_name: x-lab-responseresponse_header_value: nginx-gateway-fabric
4. Kubernetes 리소스 템플릿 작성
4-1. 테스트 애플리케이션 확인
이번 실습에서는 Gateway API 라우팅 구성을 확인하기 위해 Echo 애플리케이션을 미리 배포해둔 상태에서 진행합니다.
따라서 Ansible Playbook에서는 애플리케이션 Deployment와 Service를 생성하지 않고, 이미 존재하는 Service를 HTTPRoute의 backend로 연결합니다.
먼저 Echo 애플리케이션이 배포되어 있는지 확인합니다.
$ kubectl get deployment -n ngf-lab$ kubectl get pod -n ngf-lab$ kubectl get svc -n ngf-lab
NAME READY UP-TO-DATE AVAILABLE AGEecho-app 1/1 1 1 31mNAME READY STATUS RESTARTS AGEecho-app-668fc885b4-kbz9v 1/1 Running 0 31mNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEecho-app ClusterIP 10.97.182.77 80/TCP 31m
4-2. Gateway 및 HTTPRoute 템플릿 작성
NGINX Gateway Fabric이 처리할 Gateway와 HTTPRoute 리소스를 Ansible 템플릿으로 작성합니다.
Gateway 템플릿 작성
$ vi templates/gateway.yaml.j2
apiVersion: gateway.networking.k8s.io/v1kind: Gatewaymetadata: name: {{ gateway_name }} namespace: {{ lab_namespace }}spec: gatewayClassName: {{ gateway_class_name }} listeners: - name: http protocol: HTTP port: 80 hostname: {{ hostname }} allowedRoutes: namespaces: from: Same
HTTPRoute 템플릿 작성
$ vi templates/httproute.yaml.j2
apiVersion: gateway.networking.k8s.io/v1kind: HTTPRoutemetadata: name: {{ httproute_name }} namespace: {{ lab_namespace }}spec: parentRefs: - name: {{ gateway_name }} hostnames: - {{ hostname }} rules: - filters: - type: RequestHeaderModifier requestHeaderModifier: add: - name: {{ request_header_name }} value: {{ request_header_value }} - type: ResponseHeaderModifier responseHeaderModifier: add: - name: {{ response_header_name }} value: {{ response_header_value }} backendRefs: - name: {{ app_name }} port: {{ app_port }}
5. Ansible Playbook 작성 및 실행
5-1. Playbook 작성
앞에서 작성한 Namespace, Deployment, Service, Gateway, HTTPRoute 템플릿을 하나의 Playbook에 추가합니다.
$ vi playbook.yaml
- name: Deploy NGINX Gateway Fabric routing resources hosts: localhost connection: local gather_facts: false vars_files: - vars/main.yaml tasks: - name: Create Gateway kubernetes.core.k8s: state: present template: templates/gateway.yaml.j2 - name: Create HTTPRoute kubernetes.core.k8s: state: present template: templates/httproute.yaml.j2
5-2. Playbook 실행
$ source ~/ansible-venv/bin/activate$ cd ~/ngf-ansible-lab$ ansible-playbook playbook.yaml
[WARNING]: No inventory was parsed, only implicit localhost is available[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'PLAY [Deploy NGINX Gateway Fabric lab resources] ****************************************************************************TASK [Create Gateway] *******************************************************************************************************changed: [localhost]TASK [Create HTTPRoute] *****************************************************************************************************changed: [localhost]PLAY RECAP ******************************************************************************************************************localhost : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
5-3. 배포 결과 확인
$ kubectl get gateway -n ngf-lab$ kubectl get httproute -n ngf-lab
NAME CLASS ADDRESS PROGRAMMED AGEgateway.gateway.networking.k8s.io/ngf-gateway nginx True 54mNAME HOSTNAMES AGEhttproute.gateway.networking.k8s.io/echo-route ["echo.example.com"] 54m
6. Gateway API 동작 테스트
6-1. curl 요청 테스트
$ curl -i -H "Host: echo.example.com" http://localhost:8080
6-2. 요청/응답 헤더 확인
HTTP/1.1 200 OKServer: nginxDate: Fri, 08 May 2026 07:09:12 GMTContent-Type: application/json; charset=utf-8Content-Length: 1269Connection: keep-aliveETag: W/"4f5-YjLwsaUCMWuWr7Hp16REgnEPv5A"x-lab-response: nginx-gateway-fabric{ "host": { "hostname": "echo.example.com", "ip": "::ffff:10.244.0.15", "ips": [] }, "http": { "method": "GET", "protocol": "http", "originalUrl": "/" }, "request": { "headers": { "host": "echo.example.com", "user-agent": "curl/8.5.0", "x-real-ip": "127.0.0.1", "x-forwarded-for": "127.0.0.1", "x-forwarded-proto": "http", "x-lab-request": "ansible-ngf" } }, "environment": { "HOSTNAME": "echo-app-668fc885b4-kbz9v", "NODE_VERSION": "20.11.0", "KUBERNETES_SERVICE_HOST": "10.96.0.1" }}
7. 결론
이번 포스트에서는 Ansible과 Jinja2 템플릿을 사용해 NGINX Gateway Fabric 기반 Gateway API 리소스를 자동으로 배포했습니다.
Gateway, HTTPRoute를 Playbook으로 관리하면서 수동 kubectl apply 작업을 줄이고, 반복 가능한 배포 구조를 만들 수 있었습니다.
결과적으로 Ansible을 활용하면 Kubernetes Gateway API 구성을 보다 일관성 있게 관리하고 자동화할 수 있습니다.
NGINX STORE에 문의하여 더 자세한 정보를 확인하세요.