카테고리 없음

[2023-06-03 금] Ingress, matallb, volume

16비트 2023. 6. 3. 17:39

 

1.

Ingress

  • 앞서 service 로드밸런서는 L4(NLB)이고 인그레스는 L7(ALB)계층 로드밸런서다.
  • 들어온 트래픽의 목적지 경로를 redirect해줌
  • 클러스터 내의 서비스에 대한 외부 접근을 관리하는 API 오브젝트이며, 일반적으로 HTTP를 관리함.
  • 인그레스는 부하 분산, SSL 종료, 명칭 기반의 가상 호스팅을 제공할 수 있다.
  • 인그레스는 클러스터 외부에서 클러스터 내부 서비스로 HTTP와 HTTPS 경로를 노출한다. 트래픽 라우팅은 인그레스리소스에 정의된 규칙에 의해 컨트롤된다.

# docker ps  # 프라이빗 리포지토리 떠있는지 컨테이너 확인

 

 

# yum install -y rdate   

# rdate -s time.bora.net  # 서버 시간 맞추기

# kubectl delete all --all

 

master 세션에서 실행

# echo 'alias k=kubectl' >> ~/.bashrc

# echo 'complete -F __start_kubectl k' >> ~/.bashrc

# yum install -y git

# git clone https://github.com/hali-linux/_Book_k8sInfra.git
# kubectl apply -f /root/_Book_k8sInfra/ch3/3.3.2/ingress-nginx.yaml  # nginx가 제공하는 인그레스 스크립트
# kubectl get pods -n ingress-nginx    # 스크립트로 생성된 인그레스 namespace에 있는 system pod가 생성되었다

2. ingress에서 사용할 이미지 생성

첫 번째 서비스 라우팅에는 DNS/foods 로 식품회사 food 페이지

두 번째 서비스 라우팅은 DNS/sales 로 sales 페이지

세 번째 서비스 라우팅은 회사 홈페이지

ingress와 서비스를 연결할 rule을 스크립트로 생성해야한다

도커 세션에서 이미지 만들기

# mkdir test-home && cd $_    # 도커 서버 세션에서 작업 공간 생성

# vi /etc/docker/daemon.json   # 사설 리포지토리에 접근할 수 있도록 정보 등록

# systemctl restart docker

# docker pull 192.168.1.157:5000/nginx:latest   # 사설 리포지토리에서 이미지 가져오기

 

이미지를 만들기 위해 tar파일로 만들 재료 업로드

# vi index.html     # food 회사 웹페이지 만들기

# tar cvf food.tar index.html images    # 하나의 tar파일로 묶음

# vi Dockerfile  # 도커파일 생성
FROM 192.168.1.157:5000/nginx:latest    # 도커 허브에서 가져오려면 FROM nginx:latest 으로 적으면 된다
ADD food.tar /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]   # 생략 가능. nginx 이미지에 기본적으로 설정되어있음

FROM 192.168.1.157:5000/nginx:latest
ADD food.tar /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]

# docker build -t 192.168.1.157:5000/test-home:v1.0 .   # 이미지 생성

# docker push 192.168.1.157:5000/test-home:v1.0   # 사설 리포지토리에 이미지 등록

# docker run -d -p 80:80 --name test-home 192.168.1.157:5000/test-home:v1.0  # 이미지를 이용해서 test-home 컨테이너를 생성+실행

접속테스트

 

# vi index.html   # 배경색 green, sales-deploy로 변경

# tar cvf sale.tar images index.html

# vi Dockerfile   # sale.tar로 변경

FROM 192.168.1.157:5000/nginx:latest
ADD sale.tar /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]

# docker build -t 192.168.1.157:5000/test-home:v2.0 .

# docker push 192.168.1.157:5000/test-home:v2.0

 

# vi index.html   # 배경색 pink, home-deploy로 변경

# tar cvf home.tar images index.html

# vi Dockerfile   # home.tar로 변경

FROM 192.168.1.157:5000/nginx:latest
ADD home.tar /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]

# docker build -t 192.168.1.157:5000/test-home:v0.0 .

# docker push 192.168.1.157:5000/test-home:v0.0

 

 

# docker images   # 생성한 이미지 확인

pod에 들어갈 이미지는 다 준비가 되었다.

deployment yaml 스크립트로 service와 pod를 꾸밀 것이다.

deployment로 롤링업데이트, 복제가 수월함

master1 세션에서 실행

# mkdir ingress && cd $_

# kubectl get all   # 현재 상태

# vi ingress-deploy.yaml                  # 인그레스 depolyment 스크립트
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: foods-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: foods-deploy
  template:
    metadata:
      labels:
        app: foods-deploy
    spec:
      containers:
      - name: foods-deploy
        image: 192.168.1.157:5000/test-home:v1.0
---
apiVersion: v1
kind: Service
metadata:
  name: foods-svc
spec:
  type: ClusterIP # 서비스를 ClusterIP를 주면서 pod를 외부로 노출시키지 않겠다는 뜻. 퍼블릭 IP을 드러내지 않기 때문
  selector:
    app: foods-deploy # deployment의 labels랑 매핑해줘야한다
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sales-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sales-deploy
  template:
    metadata:
      labels:
        app: sales-deploy
    spec:
      containers:
      - name: sales-deploy
        image: 192.168.1.157:5000/test-home:v2.0
---
apiVersion: v1
kind: Service
metadata:
  name: sales-svc
spec:
  type: ClusterIP
  selector:
    app: sales-deploy
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: home-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: home-deploy
  template:
    metadata:
      labels:
        app: home-deploy
    spec:
      containers:
      - name: home-deploy
        image: 192.168.1.157:5000/test-home:v0.0
---
apiVersion: v1
kind: Service
metadata:
  name: home-svc
spec:
  type: ClusterIP
  selector:
    app: home-deploy
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

 


# kubectl apply -f ingress-deploy.yaml     # ingress-deploy 생성
# kubectl get all   # 3개의 pod, 3개의 service, 3개의 deployment, 3개의 replicaset 생성된다

3.

ingress controller

# vi ingress-config.yaml       # rule 기능을 하는 ingress controller pod 스크립트
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-nginx
  annotations: # nginx에서 만든 ingress contrller를 사용한다. rewirete-target이란 프론트엔드에서 신호를 받아서 백엔드로 넘겨주는 것. '/'뒤에 붙는 rule에 따라 경로로 이동을 하게 해준다
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules: # 라우팅 규칙
  - http:
      paths: # 경로에 따라서 해당 service로 보내준다
      - path: /foods
        backend: 
          serviceName: foods-svc
          servicePort: 80
      - path: /sales
        backend:
          serviceName: sales-svc
          servicePort: 80
      - path: # 경로를 주지 않았을 때는 home으로 보내준다
        backend:
          serviceName: home-svc
          servicePort: 80

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-nginx
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /foods
        backend:
          serviceName: foods-svc
          servicePort: 80
      - path: /sales
        backend:
          serviceName: sales-svc
          servicePort: 80
      - path:
        backend:
          serviceName: home-svc
          servicePort: 80


# kubectl apply -f ingress-config.yaml
# k get ingress ingress-nginx

# k get ingress ingress-nginx   # 인그레스 상세 정보

 

 

# vi ingress-service.yaml         # 제일 앞단에서 외부 트래픽을 받는 service 스크립트
apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress-controller
spec:
  ports:   # 외부 사용자가 접속해올 수 있는 포트 번호 지정
  - name: http
    protocol: TCP
    port: 80
    targetPort: 80
  - name: https
    protocol: TCP
    port: 443
    targetPort: 443
  selector:
    app.kubernetes.io/name: ingress-nginx   # ingress controller pod로 매핑
  type: LoadBalancer
  externalIPs:
  - 192.168.2.112  # mater1의 IP

apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress-controller
spec:
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 80
  - name: https
    protocol: TCP
    port: 443
    targetPort: 443
  selector:
    app.kubernetes.io/name: ingress-nginx
  type: LoadBalancer
  externalIPs:
  - 192.168.2.112



# kubectl apply -f ingress-service.yaml

# kubectl get svc -n ingress-nginx -o wide

접속 테스트

 

 

 

4.

metallb metallb는 로드밸런서에게 externalip를 dhcp처럼 자동으로 부여하는 기능

# kubectl apply -f /root/_Book_k8sInfra/ch3/3.3.4/metallb.yaml       # metallb 생성

# kubectl get pods -n metallb-system -o wide    # 이미지를 못가져오고 있다. 도커허브에서 이미지를 지웠음


# vi metallb-l2config.yaml
apiVersion: v1
kind: ConfigMap # ConfigMap에 환경 설정 값을 저장해놨다가 다른 pod가 쉽게 참조할 수 있도록 함
metadata:
  namespace: metallb-system
  name: config
data: # 등록된 externalIP대역에서 IP를 pod에게 부여해준다
  config: |
    address-pools:
    - name: nginx-ip-range
      protocol: layer2
      addresses:
      - 192.168.2.113-192.168.2.114   # worker1, worker2의 IP



# kubectl apply -f metallb-l2config.yaml      # metallb-l2config 생성
# kubectl describe configmaps -n metallb-system

// # kubectl delete -f metallb-l2config.yaml  

 

 


# vi metallb-test.yaml    # metallb의 pod, service 스크립트 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx-pod
spec:
  containers:
  - name: nginx-pod-container
    image: 192.168.1.157:5000/nginx.latest
---
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service-pod
spec:
  type: LoadBalancer
#  externalIPs:
#  -
  selector:
    app: nginx-pod
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

# kubectl apply -f metallb-test.yaml

# kubectl delete -f metallb-test.yaml

5.

kubectl delete -f /root/_Book_k8sInfra/ch3/3.3.4/metallb.yaml 

kubectl delete -f metallb-l2config.yaml  

kubectl delete -f metallb-test.yaml


# docker pull bitnami/metallb-speaker:0.9.3

# docker pull bitnami/metallb-controller:0.9.3

# docker tag bitnami/metallb-speaker:0.9.3 192.168.1.157:5000/metallb-speaker:0.9.3

# docker tag bitnami/metallb-controller:0.9.3 192.168.1.157:5000/metallb-controller:0.9.3

# docker push 192.168.1.157:5000/metallb-speaker:0.9.3

# docker push 192.168.1.157:5000/metallb-controller:0.9.3

 

vi  # 이미지 bitnami/metallb-speaker:0.9.3로 고치기. 두 군데

 

# vi /root/_Book_k8sInfra/ch3/3.3.4/metallb.yaml    

/image로 검색해서 192.168.1.157:5000/metallb-speaker:0.9.3, 192.168.1.157:5000/metallb-controller:0.9.3 로 수정

 

# kubectl apply -f /root/_Book_k8sInfra/ch3/3.3.4/metallb.yaml   

# kubectl get pod -n metallb-system -o wide

# kubectl apply -f metallb-l2config.yaml

# kubectl apply -f metallb-test.yaml

# kubectl get svc

# vi metallb-l2config.yaml

# kubectl apply -f metallb-12config.yaml

 

volume 관리   PV - persistent volume

컨테이너 내의 디스크에 있는 파일은 임시적이며, 컨테이너에서 실행될 때 애플리케이션에 적지 않은 몇 가지 문제가 발생합니다. 한 가지 문제는 컨테이너가 크래시될 때 파일이 손실된다는 것이다

k니belet은 컨테이너를 다시 시작하지만 초기화된 상태이다

두 번째 문제는 Pod에서 같이 실행되는 컨테이너 간에 파일을 공유할 때 발생한다

쿠버네티스는 다양한 유형의 볼륨을 지원합니다.

파드는 여러 볼륨 유형을 동시에 사용할 수 있습니다. 

임시 볼륨 유형은 파드의 수명을 갖지만, 퍼시스턴트 볼륨(PV)은 파드의 수명을 넘어 존재한다.(영구 저장)

 

 

 

 

PV는 Pod 밖에 저장소를 만들어 놓았다. 

PVC(Persistent Volume Claim) 은 pod가 PV에 얼만큼을 원하는지 요청하는 것. 그럼 PV가 원하는 만큼 떼어서 준다

1. PV 생성

2. PVC claim 생성 PV와 연결

3. pod 생성 PVC와 연결

 

 

 

6.

Volume

# mkdir volume && cd $_

# vi pv-pvc-pod.yaml
apiVersion: v1
kind: PersistentVolume   # PV 세팅
metadata: 
  name: task-pv-volume
  labels:
    type: local   # PV가 로컬
spec: # PV 세팅
  storageClassName: manual # 온프레미스 환경 옵션값. 퍼블릭 Cloud 스토리지로 활용할 수 있다
  capacity:
    storage: 10Mi
  accessModes:
    - ReadWriteOnce # 보안상 한 곳에서만 접근할 수 있게 설정. 한 곳에서 연결되면 다른 곳 연결 차단
  hostPath: # worker node의 경로
    path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim  # PVC 세팅
metadata:
  name: task-pv-claim
spec: 
  storageClassName: manual   # 'manual'은 온프레미스 값. 퍼블릭 Cloud도 연결할 수 있다
  accessModes:
    - ReadWriteOnce # 보안상 한 곳에서만 접근
  resources:
    requests: # 요청하는 공간
      storage: 1Mi
  selector: # pv의 label을 찾아갈 수 있도록 pv의 labels로 매핑
    matchLabels:
      type: local  # pv와 pvc 연결
---
apiVersion: v1
kind: Pod    #  pvc와 연결할 Pod 세팅
metadata:
  name: task-pv-pod
  labels:
    app: task-pv-pod
spec:
  volumes:
    - name: task-pv-storage # Pod가 PV를 사용하겠다
      persistentVolumeClaim:
        claimName: task-pv-claim # Claim할 PVC 매핑
  containers:
    - name: task-pv-container
      image: 192.168.1.157:5000/nginx:latest
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html" # 컨테이너에 마운트할 경로.  /mnt/data와 연결되는 위치
          name: task-pv-storage # 마운트할 PVC와 매핑. 

 

apiVersion: v1
kind: PersistentVolume
metadata:
  name: task-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 10Mi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Mi
  selector:
    matchLabels:
      type: local
---
apiVersion: v1
kind: Pod
metadata:
  name: task-pv-pod
  labels:
    app: task-pv-pod
spec:
  volumes:
    - name: task-pv-storage
      persistentVolumeClaim:
        claimName: task-pv-claim
  containers:
    - name: task-pv-container
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: task-pv-storage

# kubectl apply -f pv-pvc-pod.yaml

 

 

worker1 세션에서 데이터 넣어두기

# echo "HELLO" > /mnt/data/index.html    # 외부와 공유된다

 

master1 세션에서

# kubectl get svc

# kubectl expose pod task-pv-pod --name task-pv-pod --type=NodePort --port 80   # taks-pv-pod에게 노드포트를 준다. 클러스터 IP 포트 80

파드를 지워도 데이터가 남아있어야한다.

# kubectl delete pod task-pv-pod

# ls /mnt/data/    안지워짐

 

master1 세션에서

파드 다시 만들기

# vi task-pv-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: task-pv-pod
  labels:
    app: task-pv-pod
spec:
  volumes:
    - name: task-pv-storage
      persistentVolumeClaim:
        claimName: task-pv-claim
  containers:
    - name: task-pv-container
      image: 192.168.1.157:5000/nginx:latest
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: task-pv-storage

# kubectl apply -f task-pv-pod.yaml    # 파드 다시 생성

# kubectl get svc -o wide

# curl 10.100.121.255   # HELLO가 뜸. 지웠다가 다시 만들었는데도 마운트가 된다. PV, PVC만 보존이 되면 파드를 교체해도 데이터는 보존이 된다

# kubectl get pv, pvc  # PV 용량 10Mi, ACCESS MODES RWO, Retain이란 PVC가 지워지더라도 데이터를 유지한다는 뜻. 옵션이 Delete로 되어있으면 PVC가 지워지면 PV 데이터도 날라간다

Bound는 PV와 PVC가 잘 연결되어있다는 뜻.

CLAIM은 어느 PVC와 연결되어있는지 알 수 있다

 

# kubectl delete pvc task-pv-claim   # PVC 지우기

 

 


* rm -rf /mnt/data
* kubectl apply -f .
* echo "HELLO" > /mnt/data/index.html
* kubectl delete pod task-pv-pod
* kubectl delete pvc task-pv-claim
* Retain 동일한 스토리지 자산을 재사용하려는 경우, 동일한 스토리지 자산 정의로 새 퍼시스턴트볼륨을 생성한다.

 

7.

 

 

 

 

 

 

 

 

8.

 

# kubectl patch pvc pvc_name -p '{"metadata":{"finalizers":null}}'     # 데이터 보호를 위해 delete로 못지움. patch로 pvc 지우기

# kubectl patch pv pv_name -p '{"metadata":{"finalizers":null}}'    # pv 지우기

# kubectl patch pod pod_name -p '{"metadata":{"finalizers":null}}'    # pod 지우기

 

 

 

 

 

 

 

metallb  수정

# vi metallb-l2config.yaml

 

 

# kubectl delete configmaps config -n metallb-system    # 기존 것 지우기

# kubectl apply -f metallb-l2config.yaml

# kubectl get svc

 

# kubectl delete -f metallib-test.yaml

# vi metallb-test.yaml

# kubectl apply -f metallb-test.yaml   # 새로 생성

# kubectl get pod, svc    # metallb로 192.168.2.77 부여받았다

접속테스트

 

 

# vi metallb-test.yaml   # name이랑 식별자를  2로 해서 pod를 새로 만든다

 

안바꼈네

 

 

kubectl get pod -n metallb-system    # 파드 ID 확인

# kubectl logs -n metallb-system controller-78777cbb4b-dmmhl   # 파드 로그 확인