# NGINX 인그레스(Ingress) 컨트롤러로 Minikube에서 인그레스 설정하기

LLMS index: [llms.txt](/llms.txt)

---

<!-- overview -->

[인그레스](/ko/docs/concepts/services-networking/ingress/)는 클러스터의 서비스에 대한 외부 액세스를 허용하는 규칙을 정의하는 
API 객체이다. 
[인그레스 컨트롤러](/ko/docs/concepts/services-networking/ingress-controllers/)는
인그레스에 설정된 규칙을 이행한다.

이 페이지에서는 HTTP URI에 따라 요청을 Service 'web' 또는 'web2' 로 라우팅하는
간단한 인그레스를 설정하는 방법을 보여준다.

## 시작하기 전에

이 튜토리얼에서는 로컬 Kubernetes 클러스터를 실행하기 위해 `minikube`를 사용한다고 가정한다.
`minikube` 설치 방법은 [도구 설치](/ko/docs/tasks/tools/#minikube) 문서를 참고하자.


<div class="alert alert-info" role="note"><h4 class="alert-heading">참고:</h4>이 튜토리얼에서는 AMD64 아키텍처를 필요로 하는 컨테이너를 사용한다.
다른 CPU 아키텍처를 사용하는 컴퓨터에서 minikube를 실행하는 경우,
AMD64 아키텍처를 에뮬레이션할 수 있는 드라이버를 사용하는 방법을 고려할 수 있다.
예를 들어, Docker Desktop 드라이버가 이를 지원한다.</div>


<p>쿠버네티스 클러스터가 필요하고, kubectl 커맨드-라인 툴이 클러스터와
통신할 수 있도록 설정되어 있어야 한다. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 적어도 2개 포함된 클러스터에서 실행하는 것을 추천한다. 만약, 아직 클러스터를 가지고
있지 않다면,
<a href="/ko/docs/tasks/tools/#minikube">minikube</a>를 사용해서 생성하거나
다음 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있다.</p>
<ul>
<li><a href="https://labs.iximiuz.com/playgrounds?category=kubernetes&filter=all">iximiuz Labs</a></li>
<li><a href="https://killercoda.com/playgrounds/scenario/kubernetes">Killercoda</a></li>
<li><a href="https://kodekloud.com/public-playgrounds">KodeKloud</a></li>
</ul>
 
 
 쿠버네티스 서버의 버전은 다음과 같거나 더 높아야 함. 버전: 1.19.
  <p>버전 확인을 위해서, 다음 커맨드를 실행  <code>kubectl version</code>.</p>

만약 이보다 더 이전 버전의 쿠버네티스를 사용하고 있다면, 해당 쿠버네티스 버전의 문서를 참고한다.

### Minikube 클러스터 생성하기

아직 클러스터를 로컬에 생성하지 않았다면,
  `minikube start`를 실행하여 클러스터를 생성한다.

<!-- steps -->

## 인그레스 컨트롤러 활성화

1. NGINX 인그레스 컨트롤러를 활성화하기 위해 다음 명령을 실행한다.

    ```shell
    minikube addons enable ingress
    ```

1. NGINX 인그레스 컨트롤러가 실행 중인지 확인한다.

   ```shell
    kubectl get pods -n ingress-nginx
   ```

   
<div class="alert alert-info" role="note"><h4 class="alert-heading">참고:</h4>파드가 정상적으로 실행되기까지 1분 정도 소요될 수 있다.</div>


   결과는 다음과 같다.

   ```
    NAME                                        READY   STATUS      RESTARTS    AGE
    ingress-nginx-admission-create-g9g49        0/1     Completed   0          11m
    ingress-nginx-admission-patch-rqp78         0/1     Completed   1          11m
    ingress-nginx-controller-59b45fb494-26npt   1/1     Running     0          11m
   ```

## hello, world 앱 배포하기

1. 다음 명령을 사용하여 디플로이먼트(Deployment)를 생성한다.

   ```shell
   kubectl create deployment web --image=gcr.io/google-samples/hello-app:1.0
   ```

   결과는 다음과 같다.

   ```
   deployment.apps/web created
   ```

    디플로이먼트가 준비(Ready) 상태인지 확인한다.

    ```shell
   kubectl get deployment web 
   ```  

   결과는 다음과 같다.

   ```none
   NAME   READY   UP-TO-DATE   AVAILABLE   AGE
   web    1/1     1            1           53s
   ``` 



1. 디플로이먼트를 노출시킨다.

   ```shell
   kubectl expose deployment web --type=NodePort --port=8080
   ```

   결과는 다음과 같다.

   ```
   service/web exposed
   ```

1. 서비스(Service)가 생성되고 노드 포트에서 사용할 수 있는지 확인한다.

   ```shell
   kubectl get service web
   ```

   결과는 다음과 같다.

   ```
   NAME      TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
   web       NodePort   10.104.133.249   <none>        8080:31637/TCP   12m
   ```

1. [`minikube service`](https://minikube.sigs.k8s.io/docs/handbook/accessing/#using-minikube-service-with-tunnel) 를 사용하여 노드포트(NodePort)를 통해 서비스에 접속한다. 사용 중인 플랫폼에 해당하는 지침을 따라 진행한다. 

   <ul class="nav nav-tabs" id="tabs-minikube-service" role="tablist"><li class="nav-item"><a data-bs-toggle="tab" class="nav-link active" href="#tabs-minikube-service-0" role="tab" aria-controls="tabs-minikube-service-0" aria-selected="true">Linux</a></li>
	  
		<li class="nav-item"><a data-bs-toggle="tab" class="nav-link" href="#tabs-minikube-service-1" role="tab" aria-controls="tabs-minikube-service-1">MacOS</a></li></ul>

<div class="tab-content" id="tabs-minikube-service-content"><div class="tab-body tab-pane fadeshow active"
        id="tabs-minikube-service-0" role="tabpanel" aria-labelledby="tabs-minikube-service-0-tab" tabindex="minikube-service"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">minikube service web --url
</span></span></code></pre></div><p>결과는 다음과 같다.</p>
<pre tabindex="0"><code>http://172.17.0.15:31637
</code></pre><p>이전 단계의 출력에서 얻은 URL을 호출한다.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">curl http://172.17.0.15:31637 
</span></span></code></pre></div></div><div class="tab-body tab-pane fade"
        id="tabs-minikube-service-1" role="tabpanel" aria-labelledby="tabs-minikube-service-1-tab" tabindex="minikube-service"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># 별도의 터미널에서 명령어를 실행한다.</span>
</span></span><span class="line"><span class="cl">minikube service web --url 
</span></span></code></pre></div><p>결과는 다음과 같다.</p>
<pre tabindex="0"><code class="language-none" data-lang="none">http://127.0.0.1:62445
! Because you are using a Docker driver on darwin, the terminal needs to be open to run it.
</code></pre><p>다른 터미널에서, 이전 단계 출력에서 얻은 URL을 호출한다.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">curl http://127.0.0.1:62445 
</span></span></code></pre></div></div></div>
 
   <br>
   결과는 다음과 같다.

   ```
   Hello, world!
   Version: 1.0.0
   Hostname: web-55b8c6998d-8k564
   ```

   이제 Minikube IP 주소와 노드포트를 통해 샘플 앱에 액세스할 수 있다. 다음 단계에서는 
   인그레스 리소스를 사용하여 앱에 액세스할 수 있다.

## 인그레스 생성하기

다음 매니페스트는 `hello-world.example`를 통해 
서비스로 트래픽을 보내는 인그레스를 정의한다.

1. 다음 파일을 통해 `example-ingress.yaml`을 만든다.

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight code-sample">
       <div class="copy-code-icon">
       <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/ko/examples/service/networking/example-ingress.yaml" download="service/networking/example-ingress.yaml"><code>service/networking/example-ingress.yaml</code>
       </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('service-networking-example-ingress-yaml')" title="Copy service/networking/example-ingress.yaml to clipboard"></img></div>
       <div class="includecode" id="service-networking-example-ingress-yaml"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">networking.k8s.io/v1</span><span class="w">
   </span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">Ingress</span><span class="w">
   </span></span></span><span class="line"><span class="cl"><span class="nt">metadata</span><span class="p">:</span><span class="w">
   </span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">example-ingress</span><span class="w">
   </span></span></span><span class="line"><span class="cl"><span class="nt">spec</span><span class="p">:</span><span class="w">
   </span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ingressClassName</span><span class="p">:</span><span class="w"> </span><span class="l">nginx</span><span class="w">
   </span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">rules</span><span class="p">:</span><span class="w">
   </span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">host</span><span class="p">:</span><span class="w"> </span><span class="l">hello-world.info</span><span class="w">
   </span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">http</span><span class="p">:</span><span class="w">
   </span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">paths</span><span class="p">:</span><span class="w">
   </span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">/</span><span class="w">
   </span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">pathType</span><span class="p">:</span><span class="w"> </span><span class="l">Prefix</span><span class="w">
   </span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">backend</span><span class="p">:</span><span class="w">
   </span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">service</span><span class="p">:</span><span class="w">
   </span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">web</span><span class="w">
   </span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">port</span><span class="p">:</span><span class="w">
   </span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">number</span><span class="p">:</span><span class="w"> </span><span class="m">8080</span></span></span></code></pre></div></div>
   </div>

1. 다음 명령어를 실행하여 인그레스 오브젝트를 생성한다.

   ```shell
   kubectl apply -f https://k8s.io/examples/service/networking/example-ingress.yaml
   ```

   결과는 다음과 같다.

   ```
   ingress.networking.k8s.io/example-ingress created
   ```

1. IP 주소가 설정되었는지 확인한다.

   ```shell
   kubectl get ingress
   ```

   
<div class="alert alert-info" role="note"><h4 class="alert-heading">참고:</h4>이 작업은 몇 분 정도 소요될 수 있다.</div>


   다음 예시와 같이, ADDRESS 열에서 IPv4 주소를 확인할 수 있다.

   ```
   NAME              CLASS    HOSTS                 ADDRESS        PORTS   AGE
   example-ingress   <none>   hello-world.example   172.17.0.15    80      38s
   ```


1. Ingress 컨트롤러가 트래픽을 제대로 라우팅하는지 확인한다. 사용 중인 플랫폼에 맞는 지침을 따른다.

  
<div class="alert alert-info" role="note"><h4 class="alert-heading">참고:</h4>MacOS(Darwin)에서 Docker 드라이버를 사용하는 경우, 네트워크가 제한되어 Node IP에 직접 접근할 수 없다. 인그레스를 동작시키려면 새 터미널을 열고 <code>minikube tunnel</code>을 실행해야 한다.
이 과정에서는 <code>sudo</code> 권한이 필요하므로, 요청이 나오면 비밀번호를 입력한다.</div>

  

  <ul class="nav nav-tabs" id="tabs-ingress" role="tablist"><li class="nav-item"><a data-bs-toggle="tab" class="nav-link active" href="#tabs-ingress-0" role="tab" aria-controls="tabs-ingress-0" aria-selected="true">Linux</a></li>
	  
		<li class="nav-item"><a data-bs-toggle="tab" class="nav-link" href="#tabs-ingress-1" role="tab" aria-controls="tabs-ingress-1">MacOS</a></li></ul>

<div class="tab-content" id="tabs-ingress-content"><div class="tab-body tab-pane fadeshow active"
        id="tabs-ingress-0" role="tabpanel" aria-labelledby="tabs-ingress-0-tab" tabindex="ingress"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">curl --resolve <span class="s2">&#34;hello-world.example:80:</span><span class="k">$(</span> minikube ip <span class="k">)</span><span class="s2">&#34;</span> -i http://hello-world.example
</span></span></code></pre></div></div><div class="tab-body tab-pane fade"
        id="tabs-ingress-1" role="tabpanel" aria-labelledby="tabs-ingress-1-tab" tabindex="ingress"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">minikube tunnel
</span></span></code></pre></div><p>결과는 다음과 같다.</p>
<pre tabindex="0"><code class="language-none" data-lang="none">Tunnel successfully started

NOTE: Please do not close this terminal as this process must stay alive for the tunnel to be accessible ...

The service/ingress example-ingress requires privileged ports to be exposed: [80 443]
sudo permission will be asked for it.
Starting tunnel for service example-ingress.
</code></pre><p>새 터미널을 열고 다음 명령어를 실행한다.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">curl --resolve <span class="s2">&#34;hello-world.example:80:127.0.0.1&#34;</span> -i http://hello-world.example
</span></span></code></pre></div></div></div>
 
  <br>
  결과는 다음과 같다.

  ```none
  Hello, world!
  Version: 1.0.0
  Hostname: web-55b8c6998d-8k564
  ```

1. 원한다면 브라우저에서 `hello-world.example` 에 접속할 수도 있다. 
   
   호스트 컴퓨터의 `/etc/hosts` 파일 맨 아래에 
   다음 행을 추가한다 (관리자 권한 필요).

     <ul class="nav nav-tabs" id="tabs-hosts" role="tablist"><li class="nav-item"><a data-bs-toggle="tab" class="nav-link active" href="#tabs-hosts-0" role="tab" aria-controls="tabs-hosts-0" aria-selected="true">Linux</a></li>
	  
		<li class="nav-item"><a data-bs-toggle="tab" class="nav-link" href="#tabs-hosts-1" role="tab" aria-controls="tabs-hosts-1">MacOS</a></li></ul>

<div class="tab-content" id="tabs-hosts-content"><div class="tab-body tab-pane fadeshow active"
        id="tabs-hosts-0" role="tabpanel" aria-labelledby="tabs-hosts-0-tab" tabindex="hosts"><p>minikube 에서 알려준 external IP 주소를 확인한다.</p>
<pre tabindex="0"><code class="language-none" data-lang="none">  minikube ip 
</code></pre>   <br>
<pre tabindex="0"><code class="language-none" data-lang="none">  172.17.0.15 hello-world.example
</code></pre><div class="alert alert-info" role="note"><h4 class="alert-heading">참고:</h4>IP 주소를 <code>minikube ip</code> 출력 값에 맞게 바꾼다.</div>
</div><div class="tab-body tab-pane fade"
        id="tabs-hosts-1" role="tabpanel" aria-labelledby="tabs-hosts-1-tab" tabindex="hosts"><pre tabindex="0"><code class="language-none" data-lang="none">127.0.0.1 hello-world.example
</code></pre></div></div>


     <br>

    이렇게 하면, 웹 브라우저가
   `hello-world.example` URL에 대한 요청을 Minikube로 보낸다.

## 두 번째 디플로이먼트 생성하기

1. 다음 명령을 사용하여 두 번째 디플로이먼트를 생성한다.

   ```shell
   kubectl create deployment web2 --image=gcr.io/google-samples/hello-app:2.0
   ```
   
   결과는 다음과 같다.

   ```
   deployment.apps/web2 created
   ```
   디플로이먼트가 준비(Ready) 상태인지 확인한다.

   ```shell
   kubectl get deployment web2 
   ```  

   결과는 다음과 같다.

   ```none
   NAME   READY   UP-TO-DATE   AVAILABLE   AGE
   web2    1/1     1            1           53s
   ```

1. 두 번째 디플로이먼트를 노출시킨다.

   ```shell
   kubectl expose deployment web2 --port=8080 --type=NodePort
   ```

   결과는 다음과 같다.

   ```
   service/web2 exposed
   ```

## 기존 인그레스 수정하기 {#edit-ingress}

1. 기존 `example-ingress.yaml` 매니페스트를 편집하고, 
하단에 다음 줄을 추가한다.

    ```yaml
    - path: /v2
      pathType: Prefix
      backend:
        service:
          name: web2
          port:
            number: 8080
    ```

1. 변경 사항을 적용한다.

   ```shell
   kubectl apply -f example-ingress.yaml
   ```

   결과는 다음과 같다.

   ```
   ingress.networking/example-ingress configured
   ```

## 인그레스 테스트하기

1. Hello World 앱의 첫 번째 버전에 액세스한다.

   <ul class="nav nav-tabs" id="tabs-ingress2-v1" role="tablist"><li class="nav-item"><a data-bs-toggle="tab" class="nav-link active" href="#tabs-ingress2-v1-0" role="tab" aria-controls="tabs-ingress2-v1-0" aria-selected="true">Linux</a></li>
	  
		<li class="nav-item"><a data-bs-toggle="tab" class="nav-link" href="#tabs-ingress2-v1-1" role="tab" aria-controls="tabs-ingress2-v1-1">MacOS</a></li></ul>

<div class="tab-content" id="tabs-ingress2-v1-content"><div class="tab-body tab-pane fadeshow active"
        id="tabs-ingress2-v1-0" role="tabpanel" aria-labelledby="tabs-ingress2-v1-0-tab" tabindex="ingress2-v1"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">curl --resolve <span class="s2">&#34;hello-world.example:80:</span><span class="k">$(</span> minikube ip <span class="k">)</span><span class="s2">&#34;</span> -i http://hello-world.example
</span></span></code></pre></div></div><div class="tab-body tab-pane fade"
        id="tabs-ingress2-v1-1" role="tabpanel" aria-labelledby="tabs-ingress2-v1-1-tab" tabindex="ingress2-v1"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">minikube tunnel
</span></span></code></pre></div><p>결과는 다음과 같다.</p>
<pre tabindex="0"><code class="language-none" data-lang="none">Tunnel successfully started

NOTE: Please do not close this terminal as this process must stay alive for the tunnel to be accessible ...

The service/ingress example-ingress requires privileged ports to be exposed: [80 443]
sudo permission will be asked for it.
Starting tunnel for service example-ingress.
</code></pre><p>새로운 터미널을 열고, 아래 명령을 입력한다.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">curl --resolve <span class="s2">&#34;hello-world.example:80:127.0.0.1&#34;</span> -i http://hello-world.example
</span></span></code></pre></div></div></div>

   <br>

   결과는 다음과 같다.

   ```none
   Hello, world!
   Version: 1.0.0
   Hostname: web-55b8c6998d-8k564
   ```

1. Hello World 앱의 두 번째 버전에 액세스한다.

   <ul class="nav nav-tabs" id="tabs-ingress2-v2" role="tablist"><li class="nav-item"><a data-bs-toggle="tab" class="nav-link active" href="#tabs-ingress2-v2-0" role="tab" aria-controls="tabs-ingress2-v2-0" aria-selected="true">Linux</a></li>
	  
		<li class="nav-item"><a data-bs-toggle="tab" class="nav-link" href="#tabs-ingress2-v2-1" role="tab" aria-controls="tabs-ingress2-v2-1">MacOS</a></li></ul>

<div class="tab-content" id="tabs-ingress2-v2-content"><div class="tab-body tab-pane fadeshow active"
        id="tabs-ingress2-v2-0" role="tabpanel" aria-labelledby="tabs-ingress2-v2-0-tab" tabindex="ingress2-v2"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">curl --resolve <span class="s2">&#34;hello-world.example:80:</span><span class="k">$(</span> minikube ip <span class="k">)</span><span class="s2">&#34;</span> -i http://hello-world.example/v2
</span></span></code></pre></div></div><div class="tab-body tab-pane fade"
        id="tabs-ingress2-v2-1" role="tabpanel" aria-labelledby="tabs-ingress2-v2-1-tab" tabindex="ingress2-v2"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">minikube tunnel
</span></span></code></pre></div><p>결과는 다음과 같다.</p>
<pre tabindex="0"><code class="language-none" data-lang="none">Tunnel successfully started

NOTE: Please do not close this terminal as this process must stay alive for the tunnel to be accessible ...

The service/ingress example-ingress requires privileged ports to be exposed: [80 443]
sudo permission will be asked for it.
Starting tunnel for service example-ingress.
</code></pre><p>새로운 터미널을 열고, 아래 명령을 입력한다.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">curl --resolve <span class="s2">&#34;hello-world.example:80:127.0.0.1&#34;</span> -i http://hello-world.example/v2
</span></span></code></pre></div></div></div>


   결과는 다음과 같다.

   ```none
   Hello, world!
   Version: 2.0.0
   Hostname: web2-75cd47646f-t8cjk
   ```

   
<div class="alert alert-info" role="note"><h4 class="alert-heading">참고:</h4>옵션으로 <code>/etc/hosts</code>를 수정했다면, 브라우저에서 <code>hello-world.example</code> 과
<code>hello-world.example/v2</code> 에도 접속할 수 있다.</div>


## 다음 내용

* [인그레스](/ko/docs/concepts/services-networking/ingress/)에 대해 더 보기.
* [인그레스 컨트롤러](/ko/docs/concepts/services-networking/ingress-controllers/)에 대해 더 보기.
* [서비스](/ko/docs/concepts/services-networking/service/)에 대해 더 보기.
