개요
이전 시간에는 HTTP 트래픽에 대한 부하 분산기 구성에 대해 알아보았다. 이번 시간에는 HTTPS 트래픽에 대한 부하 분산기 구성에 대해서 알아 보도록 하자.
구성환경
kubernetes v1.17.4, docker-ce 19.03.8, nginx-ingress-controller 0.30.0
구성절차
1. ngninx-ingress-controller 설치 및 서비스 생성 2. 앱 배포 만들기 3. 인증서 및 키 만들기 4. 인그레스에 대한 인증서 지정 5. 부하 분산기 테스트 |
1. ingress-controller 설치 및 서비스 생성
1.1 nginx-ingress-controller 설치
shell> kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml namespace/ingress-nginx unchanged configmap/nginx-configuration unchanged configmap/tcp-services unchanged configmap/udp-services unchanged serviceaccount/nginx-ingress-serviceaccount unchanged clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole unchanged role.rbac.authorization.k8s.io/nginx-ingress-role unchanged rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding unchanged clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding unchanged deployment.apps/nginx-ingress-controller created limitrange/ingress-nginx configured shell> |
1.2 확인
shell> kubectl get pod -n ingress-nginx -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-ingress-controller-7f74f657bd-9zgfp 1/1 Running 0 3m15s 10.45.0.1 worker2 shell> kubectl get deploy -n ingress-nginx NAME READY UP-TO-DATE AVAILABLE AGE nginx-ingress-controller 1/1 1 1 4m19s shell> |
- nginx-ingress-controller 파드는 master 노드에서 실행되지 않기를 권고한다. nginx-ingress-controller는 DNS서브도메인의 IP를 가진 Worker Node에서 실행되도록한다. 특정 노드에서 nginx-igress-controller가 실행될수 있도록 아래의 예시를 참조하도록 한다..
- 예시 ) woker2 노드에서 실행중인 ingress-controller를 woker1로 변경
shell> kubectl get node NAME STATUS ROLES AGE VERSION master1 Ready master 16d v1.17.4 master2 Ready master 15d v1.17.4 master3 Ready master 16d v1.17.4 woker1 Ready <none> 16d v1.17.4 worker2 Ready <none> 22h v1.17.4 shell> kubectl get pod -n ingress-nginx -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-ingress-controller-7f74f657bd-9zgfp 1/1 Running 0 23m 10.45.0.1 worker2 shell> kubectl label nodes worker1 node-role.kubernetes.io/ingress="true" node/worker1 labeled shell> kubectl -n ingress-nginx patch deployment nginx-ingress-controller -p '{"spec": {"template": {"spec": {"nodeSelector": {"node-role.kubernetes.io/ingress": "true"}}}}}' deployment.apps/nginx-ingress-controller patched shell> kubectl get pod -n ingress-nginx -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-ingress-controller-844c7cd44f-s7xjr 1/1 Running 0 2m2s 10.38.0.3 worker1 shell> kubectl get node NAME STATUS ROLES AGE VERSION master1 Ready master 16d v1.17.4 master2 Ready master 31h v1.17.4 master2 Ready master 16d v1.17.4 worker1 Ready ingress 16d v1.17.4 worker2 Ready <none> 16d v1.17.4 shell> |
1.3 인그레스 서비스 생성
shell> kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/cloud-generic.yaml service/ingress-nginx created shell> kubectl get service -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx LoadBalancer 10.98.191.164 <pending> 80:30998/TCP,443:31101/TCP 89s shell> |
EXTERNAL-IP가 pending 상태로 지속된다면 아래 명령어로 EXTERNAL-IP를 추가해 주도록 한다. 여기서 EXTERNAL-IP는 DNS서브도메인의 IP이다.
shell> kubectl patch svc ingress-nginx -n ingress-nginx -p '{"spec": {"type": "LoadBalancer", "externalIPs":["192.168.0.148"]}}' service/ingress-nginx patched shell> kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx LoadBalancer 10.98.191.164 192.168.0.148 80:30998/TCP,443:31101/TCP 24m shell> |
1.4 참조 : ingress controller 버전 확인 방법
shell> POD_NAMESPACE=ingress-nginx shell> POD_NAME=$(kubectl get pods -n $POD_NAMESPACE -l app.kubernetes.io/name=ingress-nginx -o jsonpath='{.items[0].metadata.name}') shell> kubectl exec -it $POD_NAME -n $POD_NAMESPACE -- /nginx-ingress-controller --version ------------------------------------------------------------------------------- NGINX Ingress controller Release: 0.30.0 Build: git-7e65b90c4 Repository: https://github.com/kubernetes/ingress-nginx nginx version: nginx/1.17.8 ------------------------------------------------------------------------------- shell> |
2. 앱 배포 만들기
[kubernetes] 인그레스(Ingress)를 사용하여 HTTP(S) 부하 분산기 구성 #1 - HTTPS 부하 분산 의 2. 앱 배포 참조
3. 인증서(사설) 및 키 만들기
shell> openssl genrsa -out hoya.key 2048 Generating RSA private key, 2048 bit long modulus (2 primes) .....................................+++++ ........................................+++++ e is 65537 (0x010001) shell> openssl req -new -key hoya.key -out hoya.csr -subj "/CN=www.hoya.com" shell> openssl x509 -req -days 365 -in hoya.csr -signkey hoya.key -out hoya.crt Signature ok subject=CN = www.hoya.com Getting Private key shell> ls hoya.crt hoya.csr hoya.key nginx-ingress-controller.yaml static-ip-svc.yaml shell> |
4. 인그레스에 대한 인증서 지정
4.1 부하 분산기의 인증서 제공
shell> kubectl create secret tls hoya-com-secret --cert hoya.crt --key hoya.key secret/hoya-com-secret created shell> |
4.2 인그레스 만들기
- 인그레스 매니페스트(hoya-com-ingress.yaml)
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: hoya-com-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /$1 # 트래픽을 리디렉션해야하는대상 URI spec: tls: - secretName: hoya-com-secret rules: - host: www.hoya.com http: paths: - path: / backend: serviceName: web servicePort: 8080 - path: /v2/* backend: serviceName: web2 servicePort: 8080 |
* 인그레스 rewrite 설정 : https://kubernetes.github.io/ingress-nginx/examples/rewrite/
- 인그레스 리소스 생성 및 확인
shell> kubectl apply -f hoya-com-ingress.yaml ingress.extensions/hoya-com-ingress created shell> kubectl get ingress NAME HOSTS ADDRESS PORTS AGE hoya-com-ingress www.hoya.com 192.168.0.148 80, 443 33s shell> |
5. 부하 분산기 테스트
shell> curl -k https://www.hoya.com/ Hello, world! Version: 1.0.0 Hostname: web-9bbd7b488-rdmf2 shell> shell> curl -k https://www.hoya.com/v2/ Hello, world! Version: 2.0.0 Hostname: web2-74cf4946cc-m2bxg shell> |
참고
웹서버를 운영하다 보면 웹접속 로그를 분석할 경우가 많이 있다. 근데 인그레스 구성에서 클러스터 외부에서 컨테이너 접속을 할경우 컨테이너에서는 실제 접속하는 클라이언트의 IP를 확인할 수 없다. 그 이유는 nginx-ingress-controller에 패킷이 도착전 SNAT가 먼저 이루어지기 때문인데, 컨테이너에서 클러스터 외부에서의 웹접속 로그를 보면 모두 cni의 IP가 찍히는 것을 알수 있다. 이를 해결할 방법으로는 클러스터 외부에 proxy 서버를 구성하여 X-Forwarded-For 헤더를 추가해 주어야만 한다.
참조 문서 :
- 인그레스 컨트롤러 설치 : https://kubernetes.github.io/ingress-nginx/deploy/
- 인그레스 구성 : https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-multi-ssl?hl=ko
'가상화 > Kubernetes' 카테고리의 다른 글
[Docker] Priviate registry 구성 #4 - imagePullSecrets 작성 (0) | 2020.04.09 |
---|---|
[kubernetes] Pod 재시작 (1) | 2020.04.08 |
[Docker] 컨테이너와 로컬 파일 시스템간에 파일 / 폴더 복사 (0) | 2020.04.06 |
[kubernetes] 인그레스(Ingress)를 사용하여 HTTP(S) 부하 분산기 구성 #1 - HTTP 부하 분산 (0) | 2020.04.05 |
[Docker] docker-compose 활용 (0) | 2020.04.04 |