반응형

트래픽을 클러스터로 가져오는 라우터/프록시의 역할을 한다.
라우팅하는 규칙을 가지고 있다.
Ingress를 관리하기 위해 Ingress Controller가 필요하다.

Ingress Controller는 Ingress 리소스를 관리한다.
Ingress에는 rule이 포함되어 있고 Ingress Controller는 rule을 적용한다.

ingress Controller에는 많은 종류가 있지만 nginx로 진행한다

 

Nginx ingress Controller

기존 클러스터를 삭제하자

kind delete cluster --name dev-cluster

그 이후 새로운 클러스터를 생성한다.

# 01-cluster.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: dev-cluster
nodes:
- role: control-plane
  kubeadmConfigPatches:
    - |
      kind: InitConfiguration
      nodeRegistration:
        kubeletExtraArgs:
          node-labels: "ingress-ready=true"
  extraPortMappings:
  - containerPort: 80
    hostPort: 80
    protocol: TCP
  - containerPort: 443
    hostPort: 443
    protocol: TCP
- role: worker
- role: worker


# metric-server 재설치
# 클러스터 생성
kind create cluster --config 01-cluster.yaml

이후 아래에서 ingress-nginx를 설치한다.

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml

 

Ingress demo

아래 2개의 파일을 생성하자

# 01-simple-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deploy
spec:
  selector:
    matchLabels:
      app: my-app
  replicas: 3
  template:
    metadata:
      labels:
        app: my-app
    spec:
      terminationGracePeriodSeconds: 1
      containers:
        - name: nginx
          image: vinsdocker/nginx-gke
---
apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  selector:
    app: my-app
  ports:
    - port: 80
      targetPort: 80

# 02-simple-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-app
                port:
                  number: 80

두개 다 적용해보자

kubectl apply -f .

ingress는 kubectl get all로 가져와지지 않는다.
대신 아래 명령어를 통해서 가져오자

kubectl get ing

# 결과
NAME         CLASS    HOSTS   ADDRESS     PORTS   AGE
my-ingress   <none>   *       localhost   80      49s

요청을 보내보면 요청이 각각 다른 파드로 제대로 전달되는것을 확인할 수 있다.

 ~/k8s-edu/sec10-ingress curl localhost
<H1>Hello my-deploy-5db6877498-7pbt2 </H1>
 ~/k8s-edu/sec10-ingress curl localhost
<H1>Hello my-deploy-5db6877498-k4bp7 </H1>
 ~/k8s-edu/sec10-ingress    curl localhost
<H1>Hello my-deploy-5db6877498-sc8st </H1>
 ~/k8s-edu/sec10-ingress  curl localhost
<H1>Hello my-deploy-5db6877498-sc8st </H1>
 ~/k8s-edu/sec10-ingress  curl localhost
<H1>Hello my-deploy-5db6877498-7pbt2 </H1>

 

Path Based Routing

이전 예시에서는 하나의 deployment에 대해서 적용했었다
이번에는 3개 각각에 ingress를 적용해보자
4개의 파일을 생성하자

# 01-product.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: product-app
spec:
  selector:
    matchLabels:
      app: product-app
  replicas: 2
  template:
    metadata:
      labels:
        app: product-app
    spec:
      terminationGracePeriodSeconds: 1
      containers:
        - name: product
          image: vinsdocker/k8s-ingress-product
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: product-service
spec:
  selector:
    app: product-app
  ports:
    - port: 80
      targetPort: 80


# 02-user.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-app
spec:
  selector:
    matchLabels:
      app: user-app
  replicas: 2
  template:
    metadata:
      labels:
        app: user-app
    spec:
      terminationGracePeriodSeconds: 1
      containers:
        - name: user
          image: vinsdocker/k8s-ingress-user
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: user-service
spec:
  selector:
    app: user-app
  ports:
    - port: 80
      targetPort: 80


# 03-home.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: home-app
spec:
  selector:
    matchLabels:
      app: home-app
  replicas: 1
  template:
    metadata:
      labels:
        app: home-app
    spec:
      terminationGracePeriodSeconds: 1
      containers:
        - name: home
          image: vinsdocker/k8s-ingress-home
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: home-service
spec:
  selector:
    app: home-app
  ports:
    - port: 80
      targetPort: 80


# 04-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
    - http:
        paths:
          - path: /product
            pathType: Prefix
            backend:
              service:
                name: product-service
                port:
                  number: 80
          - path: /user
            pathType: Prefix
            backend:
              service:
                name: user-service
                port:
                  number: 80
          - path: /
            pathType: Prefix
            backend:
              service:
                name: home-service
                port:
                  number: 80

폴더 전체를 적용하자

 kubectl apply -f 03-path-based-routing

이제 브라우저를 열어서 하나하나 들어가보자

localhost
localhost/product
localhost/user

각각의 파드에 도달하는 화면을 볼 수 있다.

 

Dev/Qa Deploy

폴더를 만들고 qa와 dev로 구분하자
이후 아래 파일들을 만들자

#dev
#deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deploy
spec:
  selector:
    matchLabels:
      app: my-app
  replicas: 2
  template:
    metadata:
      labels:
        app: my-app
    spec:
      terminationGracePeriodSeconds: 1
      containers:
        - name: nginx
          image: vinsdocker/k8s-app:v2
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  selector:
    app: my-app
  ports:
    - port: 80
      targetPort: 80


#ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-app
                port:
                  number: 80
#qa
#deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deploy
spec:
  selector:
    matchLabels:
      app: my-app
  replicas: 2
  template:
    metadata:
      labels:
        app: my-app
    spec:
      terminationGracePeriodSeconds: 1
      containers:
        - name: nginx
          image: vinsdocker/k8s-app:v1
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  selector:
    app: my-app
  ports:
    - port: 80
      targetPort: 80


#ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-app
                port:
                  number: 80

이제 2개의 namespace를 만들자

kubectl create ns dev
kubectl create ns qa

이후 생성한 파일들을 해당 네임스페이스에 적용해보자

kubectl apply -f 04-host-based-routing/dev-workload -n dev

kubectl apply -f 04-host-based-routing/qa-workload -n qa

# 결과
deployment.apps/my-deploy created
service/my-app created
Error from server (BadRequest): error when creating "04-host-based-routing/qa-workload/02-ingress.yaml": admission webhook "validate.nginx.ingress.kubernetes.io" denied the request: host "_" and path "/" is already defined in ingress dev/my-ingress

dev는 생성된것을확인할 수 있다. 하지만 ingress는 에러가 난 것을 확인할 수 있다.

 

Dev/QA routing issue

왜 이런일이 생길까? (아래는 Nginx 컨트롤러에 한한다. 다른 컨트롤러는 다를수도 있다.)
Ingress controller는 cluster 수준의 리소스이다.
또한 ingress controller는 등록된 ingress의 rule들을 가져와서 컨트롤러에서 관리하는데 이미 경로가 등록되어있기 때문이다.
그럼 해결하려면 어떻게 해야할까?

 

Host & Path based routing

ingress 파일들을 host 따라서 routing 하게 변경해보자

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
    - host: "dev.myapp.com"
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-app
                port:
                  number: 80



# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
    - host: "qa.myapp.com"
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-app
                port:
                  number: 80

이제 다시 생성해보면 제대로 생성되는 것을 확인할 수 있다

kubectl apply -f 04-host-based-routing/dev-workload -n dev
kubectl apply -f 04-host-based-routing/qa-workload -n qa

모든 환경에서 host를 건드려서 임의로 테스트 할 수 있다.
하지만 여기에서는 테스트 하지 않는다

반응형

'Kubernetes' 카테고리의 다른 글

[Kubernetes] HPA - Horizontal Pod Autoscaler  (0) 2024.12.30
[Kubernetes] Persistent Volume & StatefulSet  (0) 2024.12.30
[Kubernetes] Secret  (0) 2024.12.19
[Kubernetes] ConfigMap  (0) 2024.12.19
[Kubernetes] Probes  (0) 2024.12.19
얼은펭귄