클라우드 네이티브 애플리케이션 부트캠프 알림

티스토리 뷰

kubeadm으로 k8s를 설치한 후 ingress controller를 추가로 설치해야 합니다.

1. minikube에 설치

만약, minikube를 사용한다면 아래 명령으로 간단히 설치할 수 있습니다. 

$ minikube addons enable ingress

 

2. kubernetes 1.23.* 이상에 설치 

2021년 12월 현재 k8s 1.23.1에 설치하는 방법입니다. 

그전 버전에서 문제가 있었던 ingress설치 버그가 해결이 되어 공식 페이지에서 가이드하는 아래 방법으로 잘 설치 됩니다. 

아래 페이지에서 Baremetal 설치를 이용하여 설치 하십시오. 

https://kubernetes.github.io/ingress-nginx/deploy/

 

Installation Guide - NGINX Ingress Controller

Installation Guide There are multiple ways to install the NGINX ingress controller: with Helm, using the project repository chart; with kubectl apply, using YAML manifests; with specific addons (e.g. for minikube or MicroK8s). On most Kubernetes clusters,

kubernetes.github.io

 

nginx ingress controller는 NodePort로 동작합니다.

아래 예와 같이 외부에 노출된 NodePort(아래 예에서는 32686)는 생성시마다 달라집니다. 

만약, 고정하려면 deploy.yaml에서 지정하십시오. 

[root@ondal install]# kubectl get svc -n ingress-nginx
NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.107.23.205    <none>        80:32686/TCP,443:30539/TCP   31m
ingress-nginx-controller-admission   ClusterIP   10.100.133.234   <none>        443/TCP                      31m

 

NodePort를 사용하면 'http://{ingress address}:{ingress controller NodePort}'와 같이 서비스 호출 시 항상 인그레스 컨트롤러의 NodePort를 붙여줘야 합니다. 

NodePort를 사용하기 싫으면, 아래와 같이 Service에 External IP를 지정해도 됩니다. 이 ExternalIP는 클러스터 노드들의 IP를 추가해 주면 됩니다. 

$ kubectl edit svc ingress-nginx-controller -n ingress-nginx

...
spec:
  clusterIP: 10.107.23.205
  clusterIPs:
  - 10.107.23.205
  externalIPs:
  - 169.56.70.201
...

 

잘 동작 하는지 테스트 합니다. 

test-ingress.yaml파일을 만들고 배포합니다. 

주의할것은 ingress annotations에 아래와 같이 Ingress class가 반드시 지정되어 있어야 한다는 겁니다.

kubernetes.io/ingress.class: "nginx"

 참고로 이 IngressClass는 위 ngix controller 배포 시 'IngressClass'라는 Kind와 "nginx"라는 이름으로 생성됩니다. 

kind: Pod
apiVersion: v1
metadata:
  name: apple
  labels:
    app: apple
spec:
  containers:
    - name: apple
      image: hashicorp/http-echo
      imagePullPolicy: IfNotPresent
      args:
        - "-text=apple"
---
kind: Service
apiVersion: v1
metadata:
  name: apple
spec:
  selector:
    app: apple
  ports:
    - port: 5678 # Default port for image
---
kind: Pod
apiVersion: v1
metadata:
  name: banana
  labels:
    app: banana
spec:
  containers:
    - name: banana
      image: hashicorp/http-echo
      imagePullPolicy: IfNotPresent
      args:
        - "-text=banana"
---
kind: Service
apiVersion: v1
metadata:
  name: banana
spec:
  selector:
    app: banana
  ports:
    - port: 5678 # Default port for image
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: http-echo
  annotations:
    kubernetes.io/ingress.class: "nginx"
    ingress.kubernetes.io/rewrite-target: /
    kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - http:
      paths:
        - path: /apple
          pathType: Prefix
          backend:
            service:
              name: apple
              port:
                number: 5678
        - path: /banana
          pathType: Prefix
          backend:
            service:
              name: banana
              port:
                number: 5678

아래 예와 같이 default namespace에 배포합니다. 

kubectl apply -f test-ingress.yaml

 

ingress가 생성된것을 확인합니다. 

[root@ondal install]# kubectl get ing
NAME    CLASS    HOSTS   ADDRESS         PORTS   AGE
fruit   <none>   *       169.56.70.201   80      46m

 

이제 웹브라우저에서 아래와 같은 형식으로 접근합니다.

http://{ingress address}:{ingress controller NodePort}/apple[또는 banana]

ingress adress는 바로 위에서 구한값이고, ingress controller nodeport는 4)번 단계에서 구한 값입니다. 

Service 'ingress-nginx-controller'에 External IP를 지정한 경우는 아래와 같이 접근하면 됩니다. 

http://{External IP}/apple[또는 banana]

 

* Body size 와 Timeout 늘리기  

ingress 를 통해 데이터가 업로더/다운로드 될 때 일정 사이즈 이상이 되거나 Timeout을 초과하면 끊깁니다. 

이런 현상이 발생하면 아래와 같이 body size와 timeout을 늘이면 됩니다.  

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: 100m
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "60s"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "60s"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60s"

 

3. bastion 서버 통해 k8s cluster를 ingress를 이용하여 연결하기

외부에서 k8s cluster를 ingress로 직접 연결할 때는 이 작업은 필요 없습니다. 

그러나 실제 운영환경에서는 k8s cluster는 외부에 직접 노출 시키지 않고, L4/L7과 같은 Load balancer를 통해서 연결합니다.

이 글에서는 haproxy라는 S/W Load Balancer를 이용하여 연결하는 방법을 사용해 보겠습니다.

즉, User => haproxy서버 => ingress nginx 서버 => k8s Service => Pod로 연결되게 하는 겁니다. 

아래 글을 참고하여 haproxy서버를 bastion 서버에 설치 합니다.

https://kubepia.github.io/cloudpak/cp4app/install/infra05.html#haproxy%EC%84%9C%EB%B2%84-%EC%84%A4%EC%B9%98

 

Infra Servers-HAProxy서버 설치 | Kubepia Documents

Infra Servers-HAProxy서버 설치 HAProxy서버 설치 Terminal 또는 ssh명령으로 Network VM을 접근합니다. L/B 설정 api server에 대한 6443, 22623포트 L/B설정을 합니다. user services에 대한 80, 443포트 L/B설정을 합니다. L

kubepia.github.io

 

아래는 haproxy.cfg의 예제입니다. 

ingree-nginx Service객체의 포트는 30080과 30443으로 고정하여 지정하였습니다. 

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    #
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    #
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000

#---------------------------------------------------------------------
# api server
#---------------------------------------------------------------------
frontend apiserver
    bind *:6443
    default_backend apiserver
    mode tcp
    option tcplog
backend apiserver
    balance source
    mode tcp
    server worker1 10.193.24.196:6443 check
    server worker2 10.193.24.197:6443 check
#---------------------------------------------------------------------
# ingress-http
#---------------------------------------------------------------------
frontend ingress-http
    bind *:80
    default_backend ingress-http
    mode tcp
    option tcplog
backend ingress-http
    balance source
    mode tcp
    server worker1 10.193.24.196:30080 check
    server worker2 10.193.24.197:30080 check
#---------------------------------------------------------------------
# ingress-https
#---------------------------------------------------------------------
frontend ingress-https
    bind *:443
    default_backend ingress-https
    mode tcp
    option tcplog
backend ingress-https
    balance source
    mode tcp
    server worker1 10.193.24.196:30443 check
    server worker2 10.193.24.197:30443 check

 

설치 후에 외부에서 bastion서버를 통해 제대로 Pod 연결이 되는지 확인 합니다. 

http://{basion IP}/apple[또는 banana]

 

댓글

클라우드 네이티브 애플리케이션 부트캠프 알림