Helm을 사용하여 Kubernetes에서 Nginx 인그레스를 설정하는 방법
저자는 Write for DOnations 프로그램을 선택했습니다.
소개
Kubernetes 수신은 클러스터 외부에서 내부 Kubernetes 서비스로 트래픽을 라우팅하는 유연한 방법을 제공합니다. Ingress 리소스는 HTTP 및 HTTPS 트래픽을 서비스로 라우팅하기 위한 규칙을 정의하는 Kubernetes의 객체입니다. 이것이 작동하려면 인그레스 컨트롤러가 트래픽을 수락하고(대부분 로드 밸런서를 통해) 적절한 서비스로 라우팅하여 규칙을 구현해야 합니다. 대부분의 인그레스 컨트롤러는 모든 인그레스에 대해 하나의 전역 로드 밸런서만 사용하므로 노출하려는 모든 서비스마다 로드 밸런서를 만드는 것보다 효율적입니다.
Helm은 Kubernetes를 관리하기 위한 패키지 관리자입니다. Kubernetes와 함께 Helm 차트를 사용하면 Kubernetes 애플리케이션을 업데이트, 롤백 및 삭제할 수 있는 구성 가능성 및 수명 주기 관리가 제공됩니다.
이 가이드에서는 인그레스를 보호할 Let's Encrypt TLS 인증서를 자동으로 프로비저닝하기 위해 Kubernetes에서 유지 관리하는 Cert Manager를 클러스터에 설정합니다.
전제 조건
- 버전 1.20 이상의 Kubernetes 클러스터는
kubectl
기본값으로 구성된 연결 구성으로 설정됩니다. 이 설정에서는 Kubernetes Quickstart를 사용합니다.\n - 로컬 환경에 설치되고 클러스터에 연결하도록 구성된
kubectl
명령줄 도구. DigitalOcean Kubernetes 클러스터 문서에 연결하는 방법에서kubectl
설치에 대한 자세한 내용을 읽을 수 있습니다.\n -
doctl
사용에 대한 자세한 내용은 DigitalOcean 명령줄 클라이언트, doctl 사용 방법을 참조하십시오.\n - 개발 환경에서 사용할 수 있는 Helm 3 패키지 관리자. Helm 3 패키지 관리자 튜토리얼을 사용하여 Kubernetes 클러스터에 소프트웨어를 설치하는 방법의 1단계를 완료하십시오.\n
- 두 개의 사용 가능한 A 레코드가 있는 완전히 등록된 도메인 이름. 이 자습서에서는 전체적으로
hw1.your_domain
및hw2.your_domain
을 사용합니다. Freenom에서 도메인 이름을 구입하거나 선택한 도메인 등록 기관을 사용할 수 있습니다. 이러한 A 레코드는 2단계에서 생성할 로드 밸런서로 전달됩니다.\n
1단계 - Hello World 배포 설정
Nginx 인그레스를 배포하기 전에 hello-kubernetes
라는 "Hello World\ 앱을 배포하여 트래픽을 라우팅할 일부 서비스를 확보합니다. Nginx 인그레스가 제대로 작동하는지 확인하려면 다음 단계에서는 브라우저에서 액세스할 때 표시되는 다른 환영 메시지와 함께 두 번 배포합니다.
로컬 컴퓨터에 배포 구성을 저장합니다. 원하는 경우 구성을 저장할 이 자습서용 디렉터리를 만들 수도 있습니다. 첫 번째 배포 구성은 hello-kubernetes-first.yaml
이라는 파일에 있습니다. 선호하는 텍스트 편집기로 작성하십시오.
- nano hello-kubernetes-first.yaml
다음 줄을 추가합니다.
apiVersion: v1
kind: Service
metadata:
name: hello-kubernetes-first
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8080
selector:
app: hello-kubernetes-first
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-kubernetes-first
spec:
replicas: 3
selector:
matchLabels:
app: hello-kubernetes-first
template:
metadata:
labels:
app: hello-kubernetes-first
spec:
containers:
- name: hello-kubernetes
image: paulbouwer/hello-kubernetes:1.10
ports:
- containerPort: 8080
env:
- name: MESSAGE
value: Hello from the first deployment!
이 구성은 배포
및 서비스
를 정의합니다. Deployment
는 paulbouwer/hello-kubernetes:1.7
이미지의 복제본 3개와 MESSAGE
라는 환경 변수로 구성됩니다. 당신은 앱에 액세스). 여기서 서비스
는 포트 80
에서 클러스터 내 배포
를 노출하도록 정의됩니다.
파일을 저장하고 닫습니다.
그런 다음 다음 명령을 실행하여 Kubernetes에서 hello-kubernetes
앱의 첫 번째 변형을 생성합니다.
- kubectl create -f hello-kubernetes-first.yaml
-f
옵션은 create
명령이 hello-kubernetes-first.yaml
파일을 사용하도록 지시합니다.
다음과 같은 결과가 표시됩니다.
Outputservice/hello-kubernetes-first created
deployment.apps/hello-kubernetes-first created
서비스 생성을 확인하려면 다음 명령을 실행합니다.
- kubectl get service hello-kubernetes-first
출력은 다음과 같습니다.
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-kubernetes-first ClusterIP 10.245.124.46 <none> 80/TCP 7s
새로 생성된 서비스에 ClusterIP
가 할당되어 제대로 작동하고 있음을 알 수 있습니다. 전송된 모든 트래픽은 포트 8080
에서 선택한 배포로 전달됩니다. 이제 hello-kubernetes
앱의 첫 번째 변형을 배포했으므로 두 번째 변형을 작업할 것입니다.
hello-kubernetes-second.yaml
이라는 새 파일을 만듭니다.
- nano hello-kubernetes-second.yaml
다음 줄을 추가합니다.
apiVersion: v1
kind: Service
metadata:
name: hello-kubernetes-second
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8080
selector:
app: hello-kubernetes-second
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-kubernetes-second
spec:
replicas: 3
selector:
matchLabels:
app: hello-kubernetes-second
template:
metadata:
labels:
app: hello-kubernetes-second
spec:
containers:
- name: hello-kubernetes
image: paulbouwer/hello-kubernetes:1.10
ports:
- containerPort: 8080
env:
- name: MESSAGE
value: Hello from the second deployment!
이 변형은 이전 구성과 동일한 구조를 가집니다. 충돌을 방지하려면 배포 및 서비스 이름에 사용되는 이름
을 변경합니다. 또한 브라우저에 로드될 메시지
의 값
을 업데이트합니다.
파일을 저장하고 닫습니다.
이제 다음 명령을 사용하여 Kubernetes에서 생성합니다.
- kubectl create -f hello-kubernetes-second.yaml
출력은 다음과 같습니다.
Outputservice/hello-kubernetes-second created
deployment.apps/hello-kubernetes-second created
모든 서비스를 나열하여 두 번째 서비스가 실행 중인지 확인합니다.
- kubectl get service
출력은 다음과 유사합니다.
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-kubernetes-first ClusterIP 10.245.124.46 <none> 80/TCP 49s
hello-kubernetes-second ClusterIP 10.245.254.124 <none> 80/TCP 10s
kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 65m
hello-kubernetes-first
및 hello-kubernetes-second
가 모두 나열되며 이는 Kubernetes가 성공적으로 생성했음을 의미합니다.
함께 제공되는 서비스와 함께 hello-kubernetes
앱의 두 가지 배포를 만들었습니다. 각각은 배포 사양에 다른 메시지 세트가 있어 테스트 중에 구분됩니다. 다음 단계에서는 Nginx 수신 컨트롤러 자체를 설치합니다.
2단계 - Kubernetes Nginx 인그레스 컨트롤러 설치
이제 Helm을 사용하여 Kubernetes에서 유지 관리하는 Nginx 수신 컨트롤러를 설치합니다.
Nginx 수신 컨트롤러는 포드와 서비스로 구성됩니다. 포드는 사용 가능한 인그레스 리소스에 대한 업데이트를 위해 클러스터의 API 서버에서 /ingresses
엔드포인트를 지속적으로 폴링하는 컨트롤러를 실행합니다. 서비스는 LoadBalancer
유형입니다. DigitalOcean Kubernetes 클러스터에 배포하기 때문에 클러스터는 모든 외부 트래픽이 컨트롤러로 흐르는 DigitalOcean 로드 밸런서를 자동으로 생성합니다. 그런 다음 컨트롤러는 인그레스 리소스에 정의된 대로 트래픽을 적절한 서비스로 라우팅합니다.
LoadBalancer 서비스만이 자동으로 생성된 Load Balancer의 IP 주소를 알고 있습니다. 일부 앱(예: ExternalDNS)은 IP 주소를 알아야 하지만 Ingress 구성을 읽을 수만 있습니다. 컨트롤러는 helm 설치
중에 controller.publishService.enabled
매개변수를 true
로 설정하여 각 Ingress에서 IP 주소를 게시하도록 구성할 수 있습니다. 로드 밸런서의 IP 주소에 의존할 수 있는 애플리케이션을 지원하려면 이 설정을 활성화하는 것이 좋습니다.
클러스터에 Nginx 인그레스 컨트롤러를 설치하려면 먼저 다음을 실행하여 해당 리포지토리를 Helm에 추가해야 합니다.
- helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
출력은 다음과 같습니다.
Output"ingress-nginx" has been added to your repositories
포함된 내용을 Helm에 알리도록 시스템을 업데이트합니다.
- helm repo update
로드하는 데 시간이 걸릴 수 있습니다.
OutputHang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "ingress-nginx" chart repository
Update Complete. ⎈Happy Helming!⎈
마지막으로 다음 명령을 실행하여 Nginx 인그레스를 설치합니다.
- helm install nginx-ingress ingress-nginx/ingress-nginx --set controller.publishService.enabled=true
이 명령은 stable
차트 리포지토리에서 Nginx 수신 컨트롤러를 설치하고 Helm 릴리스 이름을 nginx-ingress
로 지정하고 publishService
매개변수를 참
.
실행되면 다음과 유사한 출력이 표시됩니다(이 출력은 잘렸습니다).
OutputNAME: nginx-ingress
LAST DEPLOYED: Thu Dec 1 11:40:28 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
...
Helm은 차트 설치의 일부로 Kubernetes에서 생성한 리소스를 기록했습니다.
이 명령을 실행하여 로드 밸런서를 사용할 수 있는지 확인합니다.
- kubectl --namespace default get services -o wide -w nginx-ingress-ingress-nginx-controller
이 명령은 default
네임스페이스에서 Nginx Ingress 서비스를 가져와 해당 정보를 출력하지만 명령이 즉시 종료되지는 않습니다. -w
인수를 사용하면 변경 사항이 발생할 때 출력을 감시하고 새로 고칩니다.
Load Balancer를 사용할 수 있을 때까지 기다리는 동안 pending
응답을 받을 수 있습니다.
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
nginx-ingress-ingress-nginx-controller LoadBalancer 10.245.3.122 <pending> 80:30953/TCP,443:30869/TCP 36s ...
일정 시간이 지나면 새로 만든 로드 밸런서의 IP 주소가 나타납니다.
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
nginx-ingress-ingress-nginx-controller LoadBalancer 10.245.3.122 167.99.16.184 80:30953/TCP,443:30869/TCP 2m29s ...
다음으로 두 도메인이 A 레코드를 통해 로드 밸런서를 가리키는지 확인해야 합니다. 이는 DNS 공급자를 통해 수행됩니다. DigitalOcean에서 DNS 레코드를 구성하려면 DNS 레코드 관리 방법을 참조하십시오.
Kubernetes 커뮤니티에서 유지 관리하는 Nginx Ingress를 설치했습니다. 로드 밸런서에서 인그레스 리소스에 구성된 적절한 백엔드 서비스로 HTTP 및 HTTPS 트래픽을 라우팅합니다. 다음 단계에서는 Ingress 리소스를 사용하여 hello-kubernetes
앱 배포를 노출합니다.
3단계 - Ingress를 사용하여 앱 노출
이제 Ingress 리소스를 생성하고 이를 사용하여 원하는 도메인에서 hello-kubernetes
앱 배포를 노출합니다. 그런 다음 브라우저에서 액세스하여 테스트합니다.
인그레스를 hello-kubernetes-ingress.yaml
이라는 파일에 저장합니다. 편집기를 사용하여 생성합니다.
- nano hello-kubernetes-ingress.yaml
파일에 다음 줄을 추가합니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-kubernetes-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: "hw1.your_domain_name"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello-kubernetes-first
port:
number: 80
- host: "hw2.your_domain_name"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello-kubernetes-second
port:
number: 80
hello-kubernetes-ingress
라는 이름으로 인그레스 리소스를 정의합니다. 그런 다음 hw1.your_domain
이 hello-kubernetes-first
서비스로 라우팅되도록 두 개의 호스트 규칙을 지정하고 hw2.your_domain
은 두 번째 배포(hello-kubernetes-second
)에서 서비스로 라우팅됩니다.
강조 표시된 도메인을 자신의 도메인으로 바꾼 다음 파일을 저장하고 닫으십시오.
다음 명령을 실행하여 Kubernetes에서 생성합니다.
- kubectl apply -f hello-kubernetes-ingress.yaml
이제 브라우저에서 hw1.your_domain
으로 이동할 수 있습니다. 첫 번째 배포가 로드됩니다.

두 번째 변형(hw2.your_domain
)은 다른 메시지를 표시합니다.

인그레스 컨트롤러가 요청을 올바르게 라우팅하는지 확인했습니다. 이 경우 두 도메인에서 서로 다른 두 서비스로 라우팅됩니다.
도메인에서 hello-kubernetes
앱 배포를 제공하기 위해 Ingress 리소스를 만들고 구성했습니다. 다음 단계에서는 Let’s Encrypt의 무료 TLS 인증서로 Ingress 리소스를 보호하도록 Cert-Manager를 설정합니다.
4단계 - Cert-Manager를 사용하여 인그레스 보안
Ingress 리소스를 보호하려면 Cert-Manager를 설치하고 프로덕션용 ClusterIssuer
를 만들고 TLS 인증서를 사용하도록 Ingress 구성을 수정합니다. 설치 및 구성이 완료되면 앱이 HTTPS 뒤에서 실행됩니다.
ClusterIssuers
는 전체 클러스터에 대한 TLS 인증서를 프로비저닝하는 Kubernetes의 Cert-Manager 리소스입니다. ClusterIssuer
는 특정 유형의 Issuer
입니다.
Helm을 통해 클러스터에 Cert-Manager를 설치하기 전에 이를 위한 네임스페이스를 생성합니다.
- kubectl create namespace cert-manager
Cert-Manager 차트를 호스팅하는 Helm에 Jetstack Helm 리포지토리를 추가해야 합니다. 이렇게 하려면 다음 명령을 실행합니다.
- helm repo add jetstack https://charts.jetstack.io
Helm은 다음 출력을 반환합니다.
Output"jetstack" has been added to your repositories
그런 다음 Helm의 차트 캐시를 업데이트합니다.
- helm repo update
업데이트에 시간이 걸릴 수 있습니다.
OutputHang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "ingress-nginx" chart repository
...Successfully got an update from the "jetstack" chart repository
Update Complete. ⎈Happy Helming!⎈
마지막으로 다음 명령을 실행하여 Cert-Manager를 cert-manager
네임스페이스에 설치합니다.
- helm install cert-manager jetstack/cert-manager --namespace cert-manager --version v1.10.1 --set installCRDs=true
이 명령에서 Helm 설치 중에 cert-manager CustomResourceDefinition
매니페스트를 설치하기 위해 installCRDs
매개변수를 true
로 설정합니다. 작성 당시에는 v1.10.1
이 최신 버전이었습니다. ArtifactHub를 참조하여 최신 버전 번호를 찾을 수 있습니다.
다음 출력을 받게 됩니다.
OutputNAME: cert-manager
LAST DEPLOYED: Wed Nov 30 19:46:39 2022
NAMESPACE: cert-manager
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
cert-manager v1.10.1 has been deployed successfully!
...
출력은 설치가 성공했음을 나타냅니다.
출력의 NOTES
(위 디스플레이에서 잘림)는 TLS 인증서를 발급하기 위해 발급자
를 설정해야 함을 나타냅니다.
이제 Let’s Encrypt 인증서를 발급하는 인증서를 만들고 구성을 production_issuer.yaml
이라는 파일에 저장합니다. 다음 파일을 만들고 엽니다.
- nano production_issuer.yaml
다음 줄을 추가합니다.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# Email address used for ACME registration
email: your_email_address
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Name of a secret used to store the ACME account private key
name: letsencrypt-prod-private-key
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
이 구성은 인증서를 발급하기 위해 Let’s Encrypt에 접속하는 ClusterIssuer
를 정의합니다. 인증서의 보안 및 만료에 관한 알림을 받으려면 your_email_address
를 이메일 주소로 바꿔야 합니다.
파일을 저장하고 닫습니다.
kubectl
로 롤아웃합니다.
- kubectl apply -f production_issuer.yaml
다음 출력을 받게 됩니다.
Outputclusterissuer.cert-manager.io/letsencrypt-prod created
Cert-Manager가 설치되면 이전 단계에서 정의한 인그레스 리소스에 인증서를 도입할 준비가 된 것입니다. 편집을 위해 hello-kubernetes-ingress.yaml
을 엽니다.
- nano hello-kubernetes-ingress.yaml
강조 표시된 줄을 추가합니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-kubernetes-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- hw1.your_domain
- hw2.your_domain
secretName: hello-kubernetes-tls
rules:
- host: "hw1.your_domain_name"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello-kubernetes-first
port:
number: 80
- host: "hw2.your_domain_name"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello-kubernetes-second
port:
number: 80
spec
아래의 tls
블록은 letsencrypt-prod
ClusterIssuer
문제. secretName
은 생성하는 Ingress마다 달라야 합니다.
hw1.your_domain
및 hw2.your_domain
을 자신의 도메인으로 교체해야 합니다. 편집이 끝나면 파일을 저장하고 닫습니다.
다음 명령을 실행하여 이 구성을 클러스터에 다시 적용합니다.
- kubectl apply -f hello-kubernetes-ingress.yaml
다음 출력을 받게 됩니다.
Outputingress.networking.k8s.io/hello-kubernetes-ingress configured
Let’s Encrypt 서버가 도메인에 대한 인증서를 발급할 때까지 몇 분 정도 기다려야 합니다. 그동안 다음 명령의 출력을 검사하여 진행 상황을 추적할 수 있습니다.
- kubectl describe certificate hello-kubernetes-tls
출력의 끝은 다음과 유사합니다.
OutputEvents:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Issuing 2m34s cert-manager-certificates-trigger Issuing certificate as Secret does not exist
Normal Generated 2m34s cert-manager-certificates-key-manager Stored new private key in temporary Secret resource "hello-kubernetes-tls-hxtql"
Normal Requested 2m34s cert-manager-certificates-request-manager Created new CertificateRequest resource "hello-kubernetes-tls-jnnwx"
Normal Issuing 2m7s cert-manager-certificates-issuing The certificate has been successfully issued
출력의 마지막 줄에 인증서가 성공적으로 발급되었습니다
라고 표시되면 CTRL + C
를 눌러 종료할 수 있습니다.
브라우저에서 도메인 중 하나로 이동합니다. 이제 연결이 안전하다는 것을 나타내는 자물쇠가 URL 옆에 나타납니다.
이 단계에서는 Helm을 사용하여 Cert-Manager를 설치하고 Let’s Encrypt ClusterIssuer
를 생성했습니다. 그런 다음 TLS 인증서 생성을 위해 Issuer
를 활용하도록 Ingress 리소스를 업데이트했습니다. 결국 브라우저에서 도메인 중 하나로 이동하여 HTTPS가 올바르게 작동함을 확인했습니다.
결론
이제 Helm을 사용하여 DigitalOcean Kubernetes 클러스터에서 Nginx Ingress Controller 및 Cert-Manager를 성공적으로 설정했습니다. 이제 Let’s Encrypt TLS 인증서를 사용하여 보호된 도메인의 인터넷에 앱을 노출할 수 있습니다.
Helm 패키지 관리자에 대한 자세한 내용은 이 Helm 소개를 참조하세요.