Infra/Kubernetes

[K8s] Kubernetes Ingress 및 Helm

혬수 2024. 11. 5. 10:49

 

본 글은 한 권으로 배우는 도커&쿠버네티스 책에 대한 정리와 실습 내용입니다.

 

📌 인그레스 Ingress 

클러스터 외부에서 내부에 존재하는 서비스에 접근하기 위해 HTTP(S) 활용한 라우팅 규칙 제공하는 오브젝트

→ 여러 서비스를 다수의 LoadBalancer 없이도 외부에 노출

 

 

 

📌 헬름 Helm 

배포를 위해 필요한 파일들을 하나의 패키지 형태로 관리

yaml 파일 만들지 않고도 쿠버네티스 환경에서 애플리케이션을 쉽고 편하게 설치 가능

 

https://helm.sh/docs/intro/install/

 

Installing Helm

Learn how to install and get running with Helm.

helm.sh

# 마스터 노드에만 설치

cd ~/work/app/helm
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

helm version

helm repo add bitnami https://charts.bitnami.com/bitnami

helm repo update
helm repo list
## NAME   	URL
## bitnami	https://charts.bitnami.com/bitnami

 

 

📌 실습 

Ingress와 Helm을 통해 두개의 서비스 배포하는 실습 진행!!

 

  • 헬름 활용한 nginx ingress controller 설치
    • nginx ingress controller: 트래픽 관리할 수 있도록 도와주는 애플리케이션
# 마스터 노드에만 설치

cd ~/work/app/nginx-ingress-controller

helm search repo nginx
## nginx 포함하는 헬름차트 볼 수 있음
helm pull bitnami/nginx-ingress-controller

tar xvfz nginx-ingress-controller-11.5.1.tgz # 압축 풀기
ls
## nginx-ingress-controller  nginx-ingress-controller-11.5.1.tgz

mv nginx-ingress-controller nginx-ingress-controller-11.5.1

cd nginx-ingress-controller-11.5.1
cp values.yaml my-values.yaml # 설정 변경을 원하는 경우, my-values.yaml에서 변경


k create namespace mynginx # 각 애플리케이션 용도에 맞춰 전용 네임스페이스를 통해 관리
helm install --namespace mynginx --generate-name bitnami/nginx-ingress-controller -f my-values.yaml
helm --namespace mynginx ls
k get all --namespace mynginx
## service LoadBalancer 타입이 Pending 상태
## EXTERNAL-IP 할당을 위해 추후 metallb 설치

 

  • metalLB을 통한 베어메탈 LoadBalancer 구성
k get configmap kube-proxy -n kube-system -o yaml | grep strictARP # kube-proxy의 strictARP 확인
## strictARP: false -> true로 바꿔줘야함
kubectl get configmap kube-proxy -n kube-system -o yaml | sed -e "s/strictARP: false/strictARP: true/" | kubectl apply -f - -n kube-system

helm repo add metallb https://metallb.github.io/metallb
helm repo update
helm search repo metallb

helm pull metallb/metallb
tar xvfz metallb-0.14.8.tgz

mv metallb metallb-0.14.8
cd metallb-0.14.8
cp values.yaml my-values.yaml

k create namespace mymetallb

helm install --namespace mymetallb --generate-name metallb/metallb -f my-values.yaml
## Now you can configure it via its CRs. Please refer to the metallb official docs
## on how to use the CRs.
# -> CRs를 통해 설정 가능; metallb가 관리할 IP 주소 범위 설정

k get all --namespace mymetallb
# speaker와 controller가 정상적으로 작동중. running
# service의 EXTERNAL-IP가 none인 것은 정상 -> 클러스터 내부에서만 사용하기 때문

k get configmap --namespace mymetallb # metallb 추가된 것 확인
# ~/work/app/metallb/metallb-0.14.8/my-config.yaml

---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: my-metallb-config
  namespace: mymetallb
spec:
  addresses:
    - 192.168.64.100-192.168.64.200 # k8s 클러스터 IP 범위 포함 X
  autoAssign: true
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: my-metallb-config
  namespace: mymetallb
spec:
  ipAddressPools:
    - my-metallb-config
k apply -f my-config.yaml
## ipaddresspool.metallb.io/my-metallb-config created
## l2advertisement.metallb.io/my-metallb-config created

k get ipaddresspool.metallb.io --namespace mymetallb

k describe ipaddresspool.metallb.io my-metallb-config --namespace mymetallb
# IP 주소 범위 설정된 것 확인

k get all --namespace mynginx
# 서비스에서 ingress-controller의 EXTERNAL-IP가 설정된 것 확인

k describe service/nginx-ingress-controller-1730253917 --namespace mynginx
## Events:
##  Type    Reason        Age    From                Message
##  ----    ------        ----   ----                -------
##  Normal  IPAllocated   6m36s  metallb-controller  Assigned IP ["192.168.64.100"]
# metallb를 통해 IP 주소 할당 받은것 확인

# 80포트 열어주기

 

  • 인그레스로 두개의 서비스 배포

# ~/work/ch09/ex13/ingress01-deploy.yml
                                                                        
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ingress-deploy-test01
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: web-deploy01
  template:
    metadata:
      labels:
        app.kubernetes.io/name: web-deploy01
    spec:
      containers:
        - name: nginx
          image: nginx:latest
# ~/work/ch09/ex13/ingress01-service.yml

apiVersion: v1
kind: Service
metadata:
  name: ingress-service-test01
spec:
  selector:
    app.kubernetes.io/name: web-deploy01
  type: ClusterIP
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
# ~/work/ch09/ex14/ingress02-deploy.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ingress-deploy-test02
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: web-deploy02
  template:
    metadata:
      labels:
        app.kubernetes.io/name: web-deploy02
    spec:
      containers:
        - name: nginx
          image: nginx:1.25
# ~/work/ch09/ex14/ingress02-service.yml

apiVersion: v1
kind: Service
metadata:
  name: ingress-service-test02
spec:
  selector:
    app.kubernetes.io/name: web-deploy02
  type: ClusterIP
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
# ~/work/ch09/ex14/ingress02-ingress.yml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-test02
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - http:
        paths:
          - path: /test01
            pathType: Prefix
            backend:
              service:
                name: ingress-service-test01
                port:
                  number: 80
          - path: /test02 # 추가
            pathType: Prefix
            backend:
              service:
                name: ingress-service-test02
                port:
                  number: 80
k apply -f ingress01-deploy.yml
k apply -f ingress01-service.yml
k apply -f ingress02-deploy.yml
k apply -f ingress02-service.yml

k get all 

k apply -f ingress02-ingress.yml

k port-forward -n mynginx service/nginx-ingress-controller-1730253917 2000:80 --address 0.0.0.0
# 호스트 머신

curl http://192.168.64.100/test01 # ingress-controller의 외부IP에 직접 접근
curl http://192.168.64.100/test02

curl http://192.168.64.8:2000/test01 # 포트포워딩
curl http://192.168.64.8:2000/test02

 

트러블 슈팅

k port-forward 2000:80로 해도 2000 → 8080

k get service -n mynginx nginx-ingress-controller-1730253917 -o yaml
spec:
  ports:
    - name: http
      nodePort: 31503
      port: 80
      protocol: TCP
      targetPort: http

⇒ 서비스의 80 포트는 실제로 컨테이너의 8080 포트로 트래픽을 전달

  • 컨테이너 포트 확인
k get deployment -n mynginx -l app.kubernetes.io/name=nginx-ingress-controller -o yaml
          ports:
          - containerPort: 80
            name: http
            protocol: TCP
  • Helm 차트의 values.yaml 수정 → my-values.yaml로
    • controller.service.ports.http.targetPort 값을 80으로 변경
  • Helm 차트 업데이트
helm list --namespace mynginx # release-name 확인
helm upgrade <release-name> bitnami/nginx-ingress-controller -n mynginx -f my-values.yaml
  • kubectl port-forward → 서비스 포트(port)는 타겟 포트(targetPort)로 트래픽을 전달