Kubernetes에서 Cert-Manager로 Nginx 인그레스를 설정하는 방법
소개
Kubernetes Ingress를 사용하면 Kubernetes 클러스터 외부에서 클러스터 내부의 서비스로 트래픽을 유연하게 라우팅할 수 있습니다. 이는 HTTP 및 HTTPS 트래픽을 Kubernetes Services로 라우팅하기 위한 규칙을 정의하는 Ingress 리소스와 트래픽 로드 밸런싱 및 라우팅을 통해 규칙을 구현하는 Ingress 컨트롤러를 사용하여 수행됩니다. 적절한 백엔드 서비스.
인기 있는 인그레스 컨트롤러에는 Traefik이 포함됩니다. Ingress는 각각 자체 전용 Load Balancer를 사용하는 여러 LoadBalancer 서비스 설정에 대한 보다 효율적이고 유연한 대안을 제공합니다.
이 가이드에서는 Kubernetes에서 유지하는 Helm을 사용하여 DigitalOcean Kubernetes에서 Nginx Ingress를 설정하는 방법을 설정합니다.
전제 조건
이 가이드를 시작하기 전에 다음을 사용할 수 있어야 합니다.
- 다른 방법을 사용하는 Kubernetes 1.15+ 클러스터.
- 로컬 시스템에 설치되고 클러스터에 연결하도록 구성된
kubectl
명령줄 도구.kubectl
DigitalOcean Kubernetes 클러스터에 연결하는 방법 설치에 대해 자세히 읽고kubectl
을 사용하여 클러스터에 연결하는 방법을 알아볼 수 있습니다. - Ingress에서 사용하는 DigitalOcean Load Balancer를 가리킬 수 있는 도메인 이름 및 DNS A 레코드. DigitalOcean을 사용하여 도메인의 DNS 레코드를 관리하는 경우 DNS 레코드 관리 방법을 참조하여
A
레코드를 만드는 방법을 알아보세요. - 로컬 시스템에 설치된
wget
명령줄 유틸리티. 운영 체제에 내장된 패키지 관리자를 사용하여wget
을 설치할 수 있습니다.
이러한 구성 요소를 설정했으면 이 가이드를 시작할 준비가 된 것입니다.
1단계 - 더미 백엔드 서비스 설정
인그레스 컨트롤러를 배포하기 전에 먼저 인그레스를 사용하여 외부 트래픽을 라우팅할 두 개의 더미 에코 서비스를 만들고 롤아웃합니다. 에코 서비스는 공식 Kubernetes 문서에서 서비스를 실행합니다.
로컬 컴퓨터에서 nano
또는 선호하는 편집기를 사용하여 echo1.yaml
이라는 파일을 만들고 편집합니다.
- nano echo1.yaml
다음 서비스 및 배포 매니페스트를 붙여넣습니다.
apiVersion: v1
kind: Service
metadata:
name: echo1
spec:
ports:
- port: 80
targetPort: 5678
selector:
app: echo1
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo1
spec:
selector:
matchLabels:
app: echo1
replicas: 2
template:
metadata:
labels:
app: echo1
spec:
containers:
- name: echo1
image: hashicorp/http-echo
args:
- "-text=echo1"
ports:
- containerPort: 5678
이 파일에서 우리는 app: echo1
레이블 선택기를 사용하여 포드로 트래픽을 라우팅하는 echo1
이라는 서비스를 정의합니다. 포트 80
에서 TCP 트래픽을 수락하고 http-echo
의 기본 포트인 포트 5678
로 라우팅합니다.
그런 다음 app: echo1
레이블 선택기로 포드를 관리하는 echo1
이라고도 하는 배포를 정의합니다. 배포에 2개의 포드 복제본이 있어야 하고 포드가 hashicorp/http-echo
이미지를 실행하는 echo1
이라는 컨테이너를 시작하도록 지정합니다. text
매개변수를 전달하고 echo1
로 설정하여 http-echo
웹 서버가 echo1
을 반환하도록 합니다. . 마지막으로 포드 컨테이너에서 포트 5678
을 엽니다.
더미 서비스 및 배포 매니페스트에 만족하면 파일을 저장하고 닫습니다.
그런 다음 -f
플래그와 함께 kubectl apply
를 사용하여 Kubernetes 리소스를 생성하고 매개변수로 방금 저장한 파일을 지정합니다.
- kubectl apply -f echo1.yaml
다음 출력이 표시되어야 합니다.
Outputservice/echo1 created
deployment.apps/echo1 created
서비스가 노출되는 내부 IP인 ClusterIP가 있는지 확인하여 서비스가 올바르게 시작되었는지 확인합니다.
- kubectl get svc echo1
다음 출력이 표시되어야 합니다.
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
echo1 ClusterIP 10.245.222.129 <none> 80/TCP 60s
이것은 echo1
서비스가 이제 포트 80
의 10.245.222.129
에서 내부적으로 사용 가능함을 나타냅니다. 선택한 Pod의 containerPort 5678
로 트래픽을 전달합니다.
이제 echo1
서비스가 실행 중이므로 echo2
서비스에 대해 이 프로세스를 반복합니다.
echo2.yaml
이라는 파일을 만들고 엽니다.
apiVersion: v1
kind: Service
metadata:
name: echo2
spec:
ports:
- port: 80
targetPort: 5678
selector:
app: echo2
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo2
spec:
selector:
matchLabels:
app: echo2
replicas: 1
template:
metadata:
labels:
app: echo2
spec:
containers:
- name: echo2
image: hashicorp/http-echo
args:
- "-text=echo2"
ports:
- containerPort: 5678
여기서는 기본적으로 위와 동일한 서비스 및 배포 매니페스트를 사용하지만 서비스 및 배포 echo2
의 이름을 지정하고 다시 레이블을 지정합니다. 또한 다양성을 제공하기 위해 포드 복제본을 1개만 생성합니다. 웹 서버가 텍스트 echo2
를 반환하도록 text
매개변수를 echo2
로 설정했는지 확인합니다.
파일을 저장하고 닫고 kubectl
을 사용하여 Kubernetes 리소스를 만듭니다.
- kubectl apply -f echo2.yaml
다음 출력이 표시되어야 합니다.
Outputservice/echo2 created
deployment.apps/echo2 created
다시 한 번 서비스가 실행 중인지 확인합니다.
- kubectl get svc
ClusterIP가 할당된 echo1
및 echo2
서비스가 모두 표시되어야 합니다.
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
echo1 ClusterIP 10.245.222.129 <none> 80/TCP 6m6s
echo2 ClusterIP 10.245.128.224 <none> 80/TCP 6m3s
kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 4d21h
더미 에코 웹 서비스가 실행 중이므로 Nginx 인그레스 컨트롤러를 롤아웃할 수 있습니다.
2단계 - Kubernetes Nginx 인그레스 컨트롤러 설정
이 단계에서는 Kubernetes에서 관리하는 설치 가이드의 v1.1.1
을 출시합니다.
Nginx 인그레스 컨트롤러는 Nginx 웹 서버를 실행하고 Kubernetes 컨트롤 플레인에서 새롭고 업데이트된 인그레스 리소스 객체를 감시하는 포드로 구성됩니다. 인그레스 리소스는 기본적으로 백엔드 서비스에 대한 트래픽 라우팅 규칙 목록입니다. 예를 들어 인그레스 규칙은 /web1
경로에 도착하는 HTTP 트래픽이 web1
백엔드 웹 서버로 향하도록 지정할 수 있습니다. Ingress 리소스를 사용하여 호스트 기반 라우팅을 수행할 수도 있습니다. 예를 들어 web1.your_domain.com
에 도달하는 요청을 백엔드 Kubernetes 서비스 web1
로 라우팅합니다.
이 경우 인그레스 컨트롤러를 DigitalOcean Kubernetes 클러스터에 배포하기 때문에 컨트롤러는 모든 외부 트래픽이 전달되는 DigitalOcean 로드 밸런서를 프로비저닝하는 로드 밸런서 서비스를 생성합니다. 이 로드 밸런서는 외부 트래픽을 Nginx를 실행하는 인그레스 컨트롤러 포드로 라우팅한 다음 적절한 백엔드 서비스로 트래픽을 전달합니다.
Nginx Ingress Controller Kubernetes 리소스를 생성하는 것으로 시작하겠습니다. 이는 컨트롤러의 구성, Kubernetes API에 대한 컨트롤러 액세스 권한을 부여하는 역할 기반 액세스 제어(RBAC) 역할, v1.1.1<을 사용하는 실제 수신 컨트롤러 배포를 포함하는 ConfigMap으로 구성됩니다. Nginx 인그레스 컨트롤러 이미지의 /code>. 이러한 필수 리소스의 전체 목록을 보려면 Kubernetes Nginx 수신 컨트롤러의 GitHub 리포지토리에서 매니페스트를 참조하세요.
참고: 이 튜토리얼에서는 DigitalOcean Provider의 공식 설치 지침을 따릅니다. Kubernetes 공급자에 따라 적절한 매니페스트 파일을 선택해야 합니다.
리소스를 생성하려면 kubectl apply
및 -f
플래그를 사용하여 GitHub에서 호스팅되는 매니페스트 파일을 지정합니다.
- kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/do/deploy.yaml
여기서는 적용
을 사용하여 향후 Ingress Controller 개체에 대한 변경 사항을 완전히 덮어쓰지 않고 점진적으로 적용
할 수 있습니다. 적용
에 대해 자세히 알아보려면 공식 Kubernetes 문서에서 리소스 관리를 참조하세요.
다음 출력이 표시되어야 합니다.
Outputnamespace/ingress-nginx created
serviceaccount/ingress-nginx created
configmap/ingress-nginx-controller created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
service/ingress-nginx-controller-admission created
service/ingress-nginx-controller created
deployment.apps/ingress-nginx-controller created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
serviceaccount/ingress-nginx-admission created
이 출력은 또한 deploy.yaml
매니페스트에서 생성된 모든 수신 컨트롤러 개체의 편리한 요약 역할을 합니다.
인그레스 컨트롤러 포드가 시작되었는지 확인합니다.
- kubectl get pods -n ingress-nginx \
- -l app.kubernetes.io/name=ingress-nginx --watch
OutputNAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-l2jhk 0/1 Completed 0 13m
ingress-nginx-admission-patch-hsrzf 0/1 Completed 0 13m
ingress-nginx-controller-c96557986-m47rq 1/1 Running 0 13m
프롬프트로 돌아가려면 CTRL+C
를 누르십시오.
이제 kubectl
로 서비스 세부 정보를 가져와 DigitalOcean 로드 밸런서가 성공적으로 생성되었는지 확인합니다.
- kubectl get svc --namespace=ingress-nginx
몇 분 후 DigitalOcean Load Balancer의 IP 주소에 해당하는 외부 IP 주소가 표시됩니다.
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.245.201.120 203.0.113.0 80:31818/TCP,443:31146/TCP 14m
ingress-nginx-controller-admission ClusterIP 10.245.239.119 <none> 443/TCP 14m
이후 단계에서 필요하므로 로드 밸런서의 외부 IP 주소를 기록해 둡니다.
참고: 기본적으로 Nginx Ingress LoadBalancer 서비스에는 service.spec.externalTrafficPolicy
가 Local
값으로 설정되어 모든 로드 밸런서 트래픽을 Nginx Ingress 포드를 실행하는 노드로 라우팅합니다. 다른 노드는 Ingress 트래픽이 노드로 라우팅되지 않도록 로드 밸런서 상태 확인에 의도적으로 실패합니다. 외부 트래픽 정책은 이 튜토리얼의 범위를 벗어나지만 자세한 내용은 공식 Kubernetes 문서에서 Type=LoadBalancer인 서비스의 소스 IP를 참조할 수 있습니다.
이 로드 밸런서는 HTTP 및 HTTPS 포트 80 및 443에서 트래픽을 수신하고 인그레스 컨트롤러 포드로 전달합니다. 수신 컨트롤러는 트래픽을 적절한 백엔드 서비스로 라우팅합니다.
이제 이 외부 로드 밸런서에서 DNS 레코드를 가리키고 일부 인그레스 리소스를 생성하여 트래픽 라우팅 규칙을 구현할 수 있습니다.
3단계 - 인그레스 리소스 생성
주어진 하위 도메인으로 향하는 트래픽을 해당 백엔드 서비스로 라우팅하기 위해 최소한의 인그레스 리소스를 생성하는 것부터 시작하겠습니다.
이 가이드에서는 테스트 도메인 example.com을 사용합니다. 소유하고 있는 도메인 이름으로 대체해야 합니다.
먼저 echo1.example.com으로 향하는 트래픽을 echo1
백엔드 서비스로 라우팅하고 echo2.example.com<으로 향하는 트래픽을 라우팅하는 간단한 규칙을 만듭니다. /mark>를 echo2
백엔드 서비스로 보냅니다.
좋아하는 편집기에서 echo_ingress.yaml
파일을 열어 시작합니다.
- nano echo_ingress.yaml
다음 인그레스 정의를 붙여넣습니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo-ingress
spec:
rules:
- host: echo1.example.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: echo1
port:
number: 80
- host: echo2.example.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: echo2
port:
number: 80
Ingress 규칙 편집을 마쳤으면 파일을 저장하고 닫습니다.
여기서는 echo-ingress
라는 수신 리소스를 생성하고 호스트 헤더를 기반으로 트래픽을 라우팅하도록 지정했습니다. HTTP 요청 호스트 헤더는 대상 서버의 도메인 이름을 지정합니다. 호스트 요청 헤더에 대해 자세히 알아보려면 Mozilla Developer Network example.com을 참조하십시오. 그러면 echo2
백엔드로 연결됩니다.
이제 kubectl
을 사용하여 인그레스를 생성할 수 있습니다.
- kubectl apply -f echo_ingress.yaml
Ingress 생성을 확인하는 다음 출력이 표시됩니다.
Outputingress.networking.k8s.io/echo-ingress created
Ingress를 테스트하려면 DNS 관리 서비스로 이동하여 DigitalOcean 로드 밸런서의 외부 IP를 가리키는 echo1.example.com
및 echo2.example.com
에 대한 A 레코드를 만듭니다. Load Balancer의 외부 IP는 이전 단계에서 가져온 ingress-nginx
서비스의 외부 IP 주소입니다. DigitalOcean을 사용하여 도메인의 DNS 레코드를 관리하는 경우 DNS 레코드 관리 방법을 참조하여 A
레코드를 만드는 방법을 알아보세요.
필요한 echo1.example.com
및 echo2.example.com
DNS 레코드를 생성했으면 < code>curl 명령줄 유틸리티.
로컬 컴퓨터에서 echo1
서비스를 curl
합니다.
- curl echo1.example.com
echo1
서비스에서 다음과 같은 응답을 받아야 합니다.
Outputecho1
이는 echo1.example.com
에 대한 요청이 Nginx 인그레스를 통해 echo1
백엔드 서비스로 올바르게 라우팅되고 있음을 확인합니다.
이제 echo2
서비스에 대해 동일한 테스트를 수행합니다.
- curl echo2.example.com
echo2
서비스에서 다음과 같은 응답을 받아야 합니다.
Outputecho2
이는 echo2.example.com
에 대한 요청이 Nginx 인그레스를 통해 echo2
백엔드 서비스로 올바르게 라우팅되고 있음을 확인합니다.
이 시점에서 가상 호스트 기반 라우팅을 수행하기 위해 최소 Nginx Ingress를 성공적으로 설정했습니다. 다음 단계에서는 cert-manager를 설치하여 Ingress용 TLS 인증서를 프로비저닝하고 보다 안전한 HTTPS 프로토콜을 활성화합니다.
4단계 - Cert-Manager 설치 및 구성
이 단계에서는 cert-manager의 v1.7.1을 클러스터에 설치합니다. cert-manager는 발급자의 TLS 인증서를 프로비저닝하는 Kubernetes 추가 기능입니다.
cert-manager 및 해당 설치 지침을 설치합니다. cert-manager 개체가 생성될 cert-manager
라는 네임스페이스가 생성됩니다.
- kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.7.1/cert-manager.yaml
다음 출력이 표시되어야 합니다.
Outputcustomresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created
. . .
deployment.apps/cert-manager-webhook created
mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created
validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created
설치를 확인하려면 실행 중인 포드의 cert-manager
네임스페이스를 확인하십시오.
- kubectl get pods --namespace cert-manager
OutputNAME READY STATUS RESTARTS AGE
cert-manager-578cd6d964-hr5v2 1/1 Running 0 99s
cert-manager-cainjector-5ffff9dd7c-f46gf 1/1 Running 0 100s
cert-manager-webhook-556b9d7dfd-wd5l6 1/1 Running 0 99s
이것은 cert-manager 설치가 성공했음을 나타냅니다.
echo1.example.com
및 echo2.example.com
도메인에 대한 인증서 발급을 시작하기 전에 서명된 x509의 인증 기관을 지정하는 발급자를 생성해야 합니다. 인증서를 얻을 수 있습니다. 이 가이드에서는 무료 TLS 인증서를 제공하고 인증서 구성을 테스트하기 위한 스테이징 서버와 확인 가능한 TLS 인증서를 롤아웃하기 위한 프로덕션 서버를 모두 제공하는 Let's Encrypt 인증 기관을 사용합니다.
인증서 프로비저닝 메커니즘이 올바르게 작동하는지 확인하기 위해 테스트 ClusterIssuer를 생성해 보겠습니다. ClusterIssuer는 네임스페이스 범위가 아니며 모든 네임스페이스의 인증서 리소스에서 사용할 수 있습니다.
원하는 텍스트 편집기에서 staging_issuer.yaml
파일을 엽니다.
nano staging_issuer.yaml
다음 ClusterIssuer 매니페스트를 붙여넣습니다.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
namespace: cert-manager
spec:
acme:
# The ACME server URL
server: https://acme-staging-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: your_email_address_here
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-staging
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
class: nginx
여기에서 letsencrypt-staging
이라는 ClusterIssuer를 생성하고 Let’s Encrypt 스테이징 서버를 사용하도록 지정합니다. 나중에 프로덕션 서버를 사용하여 인증서를 롤아웃할 것이지만 프로덕션 서버는 이에 대한 요청 속도를 제한하므로 테스트 목적으로 스테이징 URL을 사용해야 합니다.
그런 다음 인증서를 등록할 이메일 주소를 지정하고 Kubernetes 발급자를 만듭니다.
kubectl
을 사용하여 ClusterIssuer를 롤아웃합니다.
- kubectl create -f staging_issuer.yaml
다음 출력이 표시되어야 합니다.
Outputclusterissuer.cert-manager.io/letsencrypt-staging created
이제 이 프로세스를 반복하여 프로덕션 ClusterIssuer를 생성합니다. 인증서는 이전 단계에서 프로비저닝된 Ingress 리소스에 주석을 추가하고 업데이트한 후에만 생성됩니다.
원하는 편집기에서 prod_issuer.yaml
파일을 엽니다.
nano prod_issuer.yaml
다음 매니페스트를 붙여넣습니다.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
namespace: cert-manager
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: your_email_address_here
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
class: nginx
다른 ACME 서버 URL과 letsencrypt-prod
비밀 키 이름에 유의하십시오.
편집이 완료되면 파일을 저장하고 닫습니다.
kubectl
을 사용하여 이 발급자를 롤아웃합니다.
- kubectl create -f prod_issuer.yaml
다음 출력이 표시되어야 합니다.
Outputclusterissuer.cert-manager.io/letsencrypt-prod created
이제 Let's Encrypt 스테이징 및 prod ClusterIssuers를 만들었으므로 위에서 만든 Ingress 리소스를 수정하고 echo1.example.com
및 echo2에 대해 TLS 암호화를 활성화할 준비가 되었습니다. example.com
경로.
DigitalOcean Kubernetes를 사용하는 경우 먼저 6단계를 구현해야 합니다.
5단계 - 로드 밸런서를 통한 포드 통신 활성화(선택 사항)
Let's Encrypt에서 인증서를 프로비저닝하기 전에 cert-manager는 먼저 자가 검사를 수행하여 Let's Encrypt가 도메인을 검증하는 cert-manager 포드에 도달할 수 있는지 확인합니다. 이 검사가 DigitalOcean Kubernetes를 통과하려면 Nginx Ingress 로드 밸런서를 통해 Pod-Pod 통신을 활성화해야 합니다.
이를 위해 클라우드 로드 밸런서의 외부 IP를 가리키는 DNS A 레코드를 생성하고 이 하위 도메인으로 Nginx 인그레스 서비스 매니페스트에 주석을 추가합니다.
DNS 관리 서비스로 이동하여 시작하여 DigitalOcean 로드 밸런서의 외부 IP를 가리키는 workaround.example.com
에 대한 A 레코드를 만듭니다. 로드 밸런서의 외부 IP는 2단계에서 가져온 ingress-nginx
서비스의 외부 IP 주소입니다. DigitalOcean을 사용하여 도메인의 DNS 레코드를 관리하는 경우 DNS 레코드 관리 방법을 참조하여 A 레코드를 만드는 방법을 알아보세요. 여기서는 하위 도메인 해결 방법
을 사용하지만 원하는 하위 도메인을 자유롭게 사용할 수 있습니다.
이제 Ingress 로드 밸런서를 가리키는 DNS 레코드를 만들었으므로 do-loadbalancer-hostname
주석으로 Ingress LoadBalancer 서비스에 주석을 답니다. 선호하는 편집기에서 ingress_nginx_svc.yaml
파일을 열고 다음 LoadBalancer 매니페스트에 붙여넣습니다.
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/do-loadbalancer-enable-proxy-protocol: 'true'
service.beta.kubernetes.io/do-loadbalancer-hostname: "workaround.example.com"
labels:
helm.sh/chart: ingress-nginx-4.0.6
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
type: LoadBalancer
externalTrafficPolicy: Local
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
이 서비스 매니페스트는 2단계에서 설치한 전체 Nginx Ingress 매니페스트 파일에서 추출되었습니다. 설치한 Nginx Ingress 버전에 해당하는 서비스 매니페스트를 복사해야 합니다. 이 자습서에서는 1.1.1
입니다. 또한 do-loadbalancer-hostname
주석을 workaround.example.com
도메인으로 설정해야 합니다.
완료되면 파일을 저장하고 닫습니다.
kubectl apply
를 사용하여 실행 중인 ingress-nginx-controller
서비스를 수정합니다.
kubectl apply -f ingress_nginx_svc.yaml
다음 출력이 표시되어야 합니다.
Outputservice/ingress-nginx-controller configured
이를 통해 ingress-nginx-controller
서비스에 주석을 추가했으며 이제 클러스터의 포드가 이 ingress-nginx-controller
로드 밸런서를 사용하여 서로 통신할 수 있음을 확인합니다.
6단계 - 스테이징 및 프로덕션 Let's Encrypt 인증서 발급
도메인에 대한 스테이징 TLS 인증서를 발급하기 위해 4단계에서 생성한 ClusterIssuer로 echo_ingress.yaml
에 주석을 추가합니다. 이렇게 하면 ingress-shim
을 사용하여 자동으로 생성 및 발급됩니다. Ingress 매니페스트에 지정된 도메인에 대한 인증서.
선호하는 편집기에서 echo_ingress.yaml
을 엽니다.
- nano echo_ingress.yaml
Ingress 리소스 매니페스트에 다음을 추가합니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-staging"
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
- echo1.example.com
- echo2.example.com
secretName: echo-tls
rules:
- host: echo1.example.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: echo1
port:
number: 80
- host: echo2.example.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: echo2
port:
number: 80
여기에서 cert-manager ClusterIssuer를 4단계에서 생성한 테스트 인증서 ClusterIssuer인 letsencrypt-staging
으로 설정하는 주석을 추가합니다. 또한 수신 유형을 설명하는 주석을 추가합니다. 이 경우 nginx
.
또한 tls
블록을 추가하여 인증서를 획득하려는 호스트를 지정하고 secretName
을 지정합니다. 이 비밀에는 TLS 개인 키와 발급된 인증서가 포함됩니다. example.com
을 DNS 레코드를 생성한 도메인으로 바꿔야 합니다.
변경을 완료하면 파일을 저장하고 닫습니다.
이제 kubectl apply
를 사용하여 이 업데이트를 기존 Ingress 개체에 푸시합니다.
- kubectl apply -f echo_ingress.yaml
다음 출력이 표시되어야 합니다.
Outputingress.networking.k8s.io/echo-ingress configured
kubectl describe
를 사용하여 방금 적용한 Ingress 변경 사항의 상태를 추적할 수 있습니다.
- kubectl describe ingress
OutputEvents:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal UPDATE 6s (x3 over 80m) nginx-ingress-controller Ingress default/echo-ingress
Normal CreateCertificate 6s cert-manager Successfully created Certificate "echo-tls"
인증서가 성공적으로 생성되면 describe
를 실행하여 성공적인 생성을 추가로 확인할 수 있습니다.
- kubectl describe certificate
이벤트
섹션에 다음 출력이 표시되어야 합니다.
OutputEvents:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Requested 64s cert-manager Created new CertificateRequest resource "echo-tls-vscfw"
Normal Issuing 40s cert-manager The certificate has been successfully issued
이것은 TLS 인증서가 성공적으로 발급되었고 이제 구성된 두 도메인에 대해 HTTPS 암호화가 활성화되었음을 확인합니다.
이제 HTTPS가 올바르게 작동하는지 테스트하기 위해 백엔드 echo
서버에 요청을 보낼 준비가 되었습니다.
다음 wget
명령을 실행하여 echo1.example.com
에 요청을 보내고 응답 헤더를 STDOUT
에 인쇄합니다.
- wget --save-headers -O- echo1.example.com
다음 출력이 표시되어야 합니다.
Output. . .
HTTP request sent, awaiting response... 308 Permanent Redirect
. . .
ERROR: cannot verify echo1.example.com's certificate, issued by ‘ERROR: cannot verify echo1.example.com's certificate, issued by ‘CN=(STAGING) Artificial Apricot R3,O=(STAGING) Let's Encrypt,C=US’:
Unable to locally verify the issuer's authority.
To connect to echo1.example.com insecurely, use `--no-check-certificate'.
이는 HTTPS가 성공적으로 활성화되었음을 나타내지만 Let’s Encrypt 스테이징 서버에서 발급한 가짜 임시 인증서이므로 인증서를 확인할 수 없습니다.
이제 이 임시 가짜 인증서를 사용하여 모든 것이 작동하는지 테스트했으므로 두 호스트 echo1.example.com
및 echo2.example.com
에 대한 프로덕션 인증서를 롤아웃할 수 있습니다. . 이를 위해 letsencrypt-prod
ClusterIssuer를 사용합니다.
letsencrypt-prod
를 사용하도록 echo_ingress.yaml
을 업데이트합니다.
- nano echo_ingress.yaml
파일을 다음과 같이 변경합니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
- echo1.example.com
- echo2.example.com
secretName: echo-tls
rules:
- host: echo1.example.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: echo1
port:
number: 80
- host: echo2.example.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: echo2
port:
number: 80
여기에서 ClusterIssuer 이름을 letsencrypt-prod
로 업데이트합니다.
변경 사항에 만족하면 파일을 저장하고 닫습니다.
kubectl apply
를 사용하여 변경 사항을 롤아웃합니다.
- kubectl apply -f echo_ingress.yaml
Outputingress.networking.k8s.io/echo-ingress configured
Let’s Encrypt 프로덕션 서버가 인증서를 발급할 때까지 몇 분 정도 기다립니다. certificate
개체에서 kubectl describe
를 사용하여 진행 상황을 추적할 수 있습니다.
- kubectl describe certificate echo-tls
다음 출력이 표시되면 인증서가 성공적으로 발급된 것입니다.
Output Normal Issuing 28s cert-manager Issuing certificate as Secret was previously issued by ClusterIssuer.cert-manager.io/letsencrypt-staging
Normal Reused 28s cert-manager Reusing private key stored in existing Secret resource "echo-tls"
Normal Requested 28s cert-manager Created new CertificateRequest resource "echo-tls-49gmn"
Normal Issuing 2s (x2 over 4m52s) cert-manager The certificate has been successfully issued
이제 HTTPS가 올바르게 작동하는지 확인하기 위해 curl
을 사용하여 테스트를 수행합니다.
- curl echo1.example.com
다음이 표시되어야 합니다.
Output<html>
<head><title>308 Permanent Redirect</title></head>
<body>
<center><h1>308 Permanent Redirect</h1></center>
<hr><center>nginx/1.15.9</center>
</body>
</html>
이는 HTTP 요청이 HTTPS를 사용하도록 리디렉션되고 있음을 나타냅니다.
https://echo1.example.com
에서 curl
실행:
- curl https://echo1.example.com
이제 다음 출력이 표시됩니다.
Outputecho1
verbose -v
플래그와 함께 이전 명령을 실행하여 인증서 핸드셰이크에 대해 자세히 알아보고 인증서 정보를 확인할 수 있습니다.
이 시점에서 Nginx Ingress용 Let’s Encrypt 인증서를 사용하여 HTTPS를 성공적으로 구성했습니다.
결론
이 가이드에서는 부하를 분산하고 외부 요청을 Kubernetes 클러스터 내부의 백엔드 서비스로 라우팅하도록 Nginx Ingress를 설정합니다. 또한 cert-manager 인증서 프로비저너를 설치하고 두 호스트 경로에 대한 Let’s Encrypt 인증서를 설정하여 Ingress를 보호했습니다.
Nginx 인그레스 컨트롤러에 대한 많은 대안이 있습니다. 자세히 알아보려면 공식 Kubernetes 문서에서 Ingress 컨트롤러를 참조하세요.
Helm Kubernetes 패키지 관리자를 사용하여 Nginx 인그레스 컨트롤러를 롤아웃하는 방법에 대한 가이드는 Helm을 사용하여 DigitalOcean Kubernetes에서 Nginx 인그레스를 설정하는 방법을 참조하십시오.