본문 바로가기

DevOps/쿠버네티스

INGRESS를 사용한 쿠버네티스 네트워크 설치 및 연결


## nginx와 INGRESS를 사용하여 쿠버네티스 내부의 어떤 Node에 해당하는 Service로 보낼지 규칙을 정할 수 있다. 예를 들면 zuul 처럼


## 기본적으로 host기반 그 뒤에 path 기반



ex) kubia.example.com/kubia -> service 1

ex) kubia.example.com/foo -> service 2

ex) foo.exmple.com -> service3


Namespace 생성하기

namespace.yml

apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx


$ k create -f namespace.yml


Namespace안에 서비스 생성하기

default-backend.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: default-http-backend
  labels:
    app: default-http-backend
  namespace: ingress-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: default-http-backend
  template:
    metadata:
      labels:
        app: default-http-backend
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - name: default-http-backend
        # Any image is permissible as long as:
        # 1. It serves a 404 page at /
        # 2. It serves 200 on a /healthz endpoint
        image: gcr.io/google_containers/defaultbackend:1.4 ##구글로부터 이미지를 가져오나보다
        livenessProbe: ## 헬스체크 하나보다
          httpGet:
            path: /healthz
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 30
          timeoutSeconds: 5
        ports:
        - containerPort: 8080
        resources:
          limits:
            cpu: 10m
            memory: 20Mi
          requests:
            cpu: 10m
            memory: 20Mi
---
apiVersion: v1
kind: Service ## 서비스 생성 yaml
metadata:
  name: default-http-backend
  namespace: ingress-nginx ## namespace안에서 생성된다. (반드시 namespace 먼저 생성필요)
  labels:
    app: default-http-backend
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: default-http-backend


$ k create -f default-backend.yaml


## 기타 등등 ingress에서 제공하는 yaml들을 실행한다.

## 자세한 ingress 셋팅은 github에서 확인 가능

## https://github.com/kubernetes/ingress-nginx/tree/master/deploy


$ k get po -n ingress-nginx

$ k svc -n ingress-nginx


## 추가로 pod를 띄울때는 반드시 같은 namespace에 올려야한다.

## namespace를 정의하지 않으면 default namespace에 묶인다.


$ k create -f test-rc.yaml -n ingress-nginx

## 상기와 같이 test-rc.yaml에 namespace정의가 없을때 cli에서 직접 옵션으로 정의 가능



## ingress controller가 앞단에 있고 nodejs pod 3개, kubia-test pod가 3개가 각각 clusterIP로 묶여서 떠있는것을 볼 수 있다.

## default-http-backend pod도 1개 떠있다.


nginx의 ingress controller 살펴보기

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx 
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ingress-nginx
  template:
    metadata:
      labels:
        app: ingress-nginx
      annotations:
        prometheus.io/port: '10254'
        prometheus.io/scrape: 'true'
    spec:
      serviceAccountName: nginx-ingress-serviceaccount
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.11.0
          args:
            - /nginx-ingress-controller ## nginx의 ingress controller가 아래와 같은 args를 가지고 실행을 하는구나 알수잇음
            - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
            - --annotations-prefix=nginx.ingress.kubernetes.io
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
          - name: http
            containerPort: 80
          - name: https
            containerPort: 443
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1

선언되지 않은 nginx controller에 요청하면?

$ k get svc -n ingress-nginx

curl -v <host>:port

## 선언되지 않은 ingress 호출이 올때는 default-http-backend로 보내면서 404를 보낸다.



## 상기 404 에러는 정상적이지 않게 ingress path가 적용된 경우라고 보면된다.

(혹은 아애 ingress path가 설정되지 않은 경우)


## ingress controller가 앞단에 있고 nodejs pod 3개, kubia-test pod가 3개가 각각 clusterIP로 묶여서 떠있는것을 볼 수 있지만, ingress rule이 정해지지 않아서 default-http-backend로 보내버림.(404)

INGRESS 설정하기

apiVersion: extensions/v1beta1
kind: Ingress ##ingress rule
metadata:
  name: ing-test
spec:
  rules:
  - host: host14-4.cloud.com ## 아무 host 설정
    http:
      paths:
      - path: /
        backend:
          serviceName: node-js ## path설정하고자 하는 serviceName 설정
          servicePort: 80 ## path설정하고자 하는 serviceName 설정


$ k create -f ing.yml -n ingress-nginx

## 추가로 hosts설정하여 내부망으로 들어오도록 설정한다.


hosts

10.10.12.141 host14-4.cloud.com


## nginx를 통해서 ingress path rule이 설정되었고 정상적으로 pod를 찾아감을 알 수 있다.



## ingress controller가 앞단에 있고 nodejs pod 3개, kubia-test pod가 3개가 각각 clusterIP로 묶여서 떠있는것 중에 nodejs pod이 설정되었음!!


추가로 rule 설정하기

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ing-test
spec:
  rules:
  - host: host14-4.cloud.com
    http:
      paths:
      - path: /
        backend:
          serviceName: node-js
          servicePort: 80
      - path: /test  ## 아까 ingress rule에 추가
        backend:  ## 아까 ingress rule에 추가
          serviceName: kubia-test ## 아까 ingress rule에 추가
          servicePort: 80 ## 아까 ingress rule에 추가


$ k apply -f ing.yml -n ingress-nginx

## 신규로 만든 yml파일을 바로 적용하기 위해서는 apply command를 사용하면 된다.



## cilent요청 / -> nginx ingress 판단 -> nodejs pod으로 보냄

## client요청 /test -> nginx ingress 판단 -> kubia-test로 보냄


## round robin은 nginx의 ingress가 해준다. 각각의 pod에 쏴줄 때 판단. session affinity도 가능(clientIP 서비스가 하는 동작인것 마냥 가능)