이야기박스

Kubernetes. Ingress and TLS Setting 본문

Computer & Data/Orchestration

Kubernetes. Ingress and TLS Setting

박스님 2020. 1. 28. 11:18
반응형

 

쿠버네티스에서 제공하는 REST API 서비스에 https 통신을 제공하기 위하여 Ingress와 SSL 설정에 대한 기술 조사를 진행하게 되었습니다. 간략한 기술 소개 및 yaml 파일 예시를 소개하려고 합니다.

# Ingress란?

Ingress (명사) - 가거나 들어가는 행위; 들어갈 수 있는 권리; (어떤 장소에) 들어감; 입장권

보통 ingress는 서버 내부로 유입되는 트래픽을 나타내고 egress는 서버 외부로 나가는 트래픽을 의미합니다.

마찬가지로 Kubernetes Ingress는 외부에서 Kubernetes Service 및 다른 Resource에 접근하기 위한 게이트웨이라고 생각하시면 됩니다.

 

## Ingress가 필요한 이유

  • 하나의 공인된 주소로 다양한 서비스에 포워딩될 수 있음
  • HTTP Layer Control(Layer 7)이 가능

## Kubernetes Ingress 필요 구성 요소

  • Ingress : 규칙 정의
  • Ingress Controller : Deployment, 실제 Ingress가 실행되는 pod
  • Ingress Service : Ingress Controller를 외부에 제공하기 위한 서비스

# Ingress Controller

이제 Kubernetes에 Ingress를 적용하는 방법을 알아보려고 합니다. Ingress 또한 하나의 프로세스 이므로 Pod를 생성해 주어야 하고 이 Pod에 대한 Service 또한 생성해 주어야 합니다. 즉, Ingress는 규칙을 정의하는 것일 뿐이고 동작하기 위해서는 Ingress Controller(Deployment)가 필요하게 됩니다.

 

## Ingress 확인

 

현재 사용중인 클러스터에도 citrix로 되어 있는 ingress-controller가 있었습니다. 아무래도 LB 구성에 사용되는 것 같습니다.

kubectl get po --all-namespaces | grep "ingress"
kube-system    cic-k8s-ingress-controller-6fcdd6a576-jq46v            1/1     Running   1          7d23h

## Ingress 구성

그럼 이제 https 통신을 위하여 nginx의 ingress-controller를 구성해보려고 합니다. 아래 공식 링크를 참조하여 설치를 진행하면 됩니다.

Link. ingress-nginx github

 

kubernetes/ingress-nginx

NGINX Ingress Controller for Kubernetes. Contribute to kubernetes/ingress-nginx development by creating an account on GitHub.

github.com

위 github에서 ingress-nginx/deploy/static/mandatory.yaml 파일을 받아서 kubernetes에 제출하면 됩니다.

kubectl apply -f mandatory.yaml

 

이후 ingress 리소스를 생성해주면 자동으로 ingress-controller에 매핑되게 됩니다. 이 ingress에 대한 설명은 아래에서 다시 하도록 하겠습니다.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  namespace: test-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
    - http:
        paths:
          - path: /test
            backend:
              serviceName: test-service
              servicePort: 80

 

## Ingress Controller Service 등록

ingress-controller를 생성하고 ingress 규칙 또한 정의했지만 여기에 접근할 수 있는 수단이 아직 없네요. 그러므로 이제 Ingress Controller에 접근할 수 있는 Service를 만들어 주면 됩니다.

kind: Service
apiVersion: v1
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  externalTrafficPolicy: Local
  type: LoadBalancer
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: http
    - name: https
      port: 443
      protocol: TCP
      targetPort: https

그럼 이제 이 서비스를 통하여 위에서 정의했던 ingress 규칙의 효과를 볼 수 있습니다.

storyparks> kubectl get ingress   
NAME              HOSTS   ADDRESS         PORTS   AGE
tls-dev-ingress   *       10.106.***.***   80      103m

여기서 'ADDRESS'는 Ingress-Controller의 Service External IP가 됩니다. 이 공인 IP를 통하여 Ingess에 정의된 모든 서비스에 접근할 수 있습니다.

## 확인

curl {nginx-ingress-service 공인ip}/test

## 참고. Bypassing

Nginx Ingress Controller는 bypassing이라는 기능을 통하여 application pod에 트래픽을 직접 전달합니다. 해당 Pod의 Service를 경유해야 하는 네트워크 홉을 줄이게 되죠.

"[It routes to pods directly] in order to bypass kube-proxy to allow NGINX features like session affinity and custom load balancing algorithms. It also removes some overhead, such as conntrack entries for iptables DNAT."

# TLS Setting

다음은 TLS Setting을 해보려고 합니다. 우선 인증 정보를 담고 있는 Kubernetes Secret 생성이 필요합니다.

# tls-secret.yaml
apiVersion: v1
data:
  tls.crt: {your crt}
  tls.key: {your key}
kind: Secret
metadata:
  name: tls-secret
  namespace: test-namespace
type: kubernetes.io/tls

다음은 위 Secret 정보를 이용하여 ingress를 다시 구성합니다.

# tls-ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  namespace: test-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
    - hosts:
        - test.storyparks.com
      secretName: tls-secret
  rules:
    - host: test.storyparks.com
      http:
        paths:
          - path: /test
            backend:
              serviceName: test-service
              servicePort: 80

## 확인

curl https://test.storyparks.com/test

# Ingress Annotation

위 tls-ingress.yaml에서 사용했던 nginx.ingress.kubernetes.io/rewrite-target, kubernetes.io/ingress.class과 같이 Ingress Service의 동작 방식을 어노테이션을 통하여 컨트롤할 수 있습니다.

 

## nginx.ingress.kubernetes.io

Nginx의 설정을 위한 어노테이션입니다. nginx-ingress의 deployment를 보면 다음과 같은 설정이 있는 걸 볼 수 있습니다. 이 어노테이션을 통하여 nginx 설정을 컨트롤할 수 있고 커스텀 설정을 여러 개 지정할 수도 있습니다.

containers:
  - name: nginx-ingress-controller
    image: nos-gitlab-registry.nmn.io/kubernetes/base-images/nginx-ingress-controller:master
    args:
      - /nginx-ingress-controller
      - --configmap=$(POD_NAMESPACE)/nginx-configuration
      - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
      - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
      - --publish-service=$(POD_NAMESPACE)/ingress-nginx
      - --annotations-prefix=nginx.ingress.kubernetes.io

설정 예시 입니다.

  • nginx.ingress.kubernetes.io/rewrite-target : 지정된 경로로 Redirect를 한다. "/ (Root)"로 지정되어 있으면, 하위 context와 무관하게 항상 ROOT으로 Redirect 된다.
  • nginx.ingress.kubernetes.io/force-ssl-redirect : https로 강제 Redirect를 한다.
  • nginx.ingress.kubernetes.io/app-root : ROOT 경로를 재설정한다.

## kubernetes.io/ingress.class

한 클러스터에 여러 Ingress Controller가 정의되어 있는 경우, 어떠한 Ingress Controller를 사용할 것인지 정의하는 어노테이션입니다. 아까 nginx-ingress-controller를 설치하기 전, citrix-ingress-controller가 있는 것을 확인했었습니다. 때문에 지금 제가 테스트를 진행한 클러스터에는 ingress-controller가 두 개 이므로 어느 controller를 사용할지 지정이 필요합니다.

# Conclusion

  • Ingress Resource 자체는 하나의 규칙일 뿐입니다. 동작을 위해서는 Deployment, Service가 필요합니다.
  • 다양한 Ingress Controller가 있다면 kubernetes.io/ingress.class 어노테이션을 통하여 특정 Controller를 지정할 수 있습니다.
  • Nginx Controller는 다른 서비스들로 라우팅을 해줄 수 있습니다.

# Reference

## Kubernetes official docs

 

인그레스

 

kubernetes.io

## Matthewpalmer post

 

Kubernetes Ingress with Nginx Example - Kubernetes Book

Kubernetes Ingress with Nginx Example What is an Ingress? In Kubernetes, an Ingress is an object that allows access to your Kubernetes services from outside the Kubernetes cluster. You configure access by creating a collection of rules that define which in

matthewpalmer.net

## Alice_k106 blog, Ingress 주석 관련

 

163. [Kubernetes] 2편 : 쿠버네티스 Ingress의 ClusterIP Bypass, Annotation, SSL/TLS를 위한 인증서 적용

이번 포스트에서는 Ingress의 상세한 내용들, 예를 들어 Service의 ClusterIP의 Bypass, Ingress의 ...

blog.naver.com

반응형

'Computer & Data > Orchestration' 카테고리의 다른 글

Kubernetes. 고급 스케줄링  (1) 2022.01.12
Kubernetes. 소스 IP 주소 구하기  (0) 2020.06.29
Kubernetes. Helm3  (1) 2020.01.10
(작성중) Kubernetes. Pod AutoScaling  (0) 2019.12.06
Docker - SpringBoot JVM Option 이슈  (0) 2019.12.03