[클라우드/K8S 기본(12) -Ingress, MetalLB 실습(3)]

SooYeon Yeon·2022년 9월 13일
0

클라우드 K8S

목록 보기
14/18

Quiz

디렉토리를 k8slab > rapalab 을 만들고 시작

  1. 모든 노드를 실행하고 master에서 토큰을 발행하여 각 노드에서 해당 토큰을 이용한 뒤, 클러스터에 조인한다.

  2. manager는 calico를 이용하여 네트워크 애드온을 설치한다. 이는 포드간 통신에 오버레이 네트워크를 제공할 수 있다. 또한, BGP를 이용하는 대규모 라우팅이 제공되는 환경이라면 이 역시 이용 가능한 플러그인으로 동작한다. 단, 우리 실습에서는 l2로 이용한다.

  3. 다음의 조건을 만족하는 웹서비스를 제공해 주세요

    • 외부로의 접속은 LB를 이용한다.(MetalLB)
    • LB에서 제공하는 주소 대역은 211.183.3.231-211.183.3.249까지이다.
    • Deployment
      • 3개의 웹서비스 제공(nginx 이용)

      • Pod는 각각 0.5개의 CPU, 32MB 메모리가 기본적으로 제공된다.

      • 만약, 각 Pod의 CPU 사용량이 80%를 넘어서게 되면 최대 10개까지 확장가능해야 한다.

      • nginx의 페이지는 ingress를 통해 라우팅 되어야 한다. 이는 nginx ingress controller을 이용하여 다음과 같이 구성한다.

                                                                                                                           vm port   pod

        211.183.3.20X → LB → Ingress Controller → Ingress → / → default 서비스 30001 3개

                                                                                       → /shop → shop 서비스 30002     3개
        
                                                                                       → /news → news 서비스 30003     3개
  4. nfs를 구성하여 각 pod에 공간을 제공할 수 있어야 한다.

    • 3의 연장선으로, default 서비스는 nfs 서버의 /default/index.html로 연결이 되도록
    • shop 서비스는 nfs 서버의 /shop/index.html 으로 연결이 되도록
    • news 서비스는 nfs 서버의 /news/index.html 로 연결이 되도록
    • 페이지의 내용은 자유롭게
  5. ingress controller는 LB와 연계하여 211.183.3.20X를 이용하고 있다. 이 IP 주소가 DNS를 통해 접속 할 수 있도록 했으면 좋겠지만

    www.gildong.com을 manager의 /etc/hosts에 등록하고, manager에서는 curl을 이용해 확인해본다. (curl http://www.gildong.com/shop) 그 외에 곳에서는 브라우저+IP로 확인 (211.183.3.20X/shop 이렇게)

  6. 이 모든 작업은 rapa 고객이 요청하는 것이다. (namespace=rapa)

구성하기

step1

모든 노드를 실행하고 master에서 토큰을 발행하여 각 노드에서 해당 토큰을 이용한 뒤, 클러스터에 조인한다.

루트로 전환 su 후 실행

master 토큰 발행 - 클러스터 조인

  • master
kubeadm init
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
export KUBECONFIG=/etc/kubernetes/admin.conf
  • worker에 붙여넣기
kubeadm join 211.183.3.100:6443 --token 121m84.60y2tf2sjlsbyk1v \
        --discovery-token-ca-cert-hash sha256:2c853acfd51fe383a325483cdd4e7d462ddceb05310863c2e23cfe1a535d7e98
  • master에서 확인하기
root@manager:~# kubectl get node
NAME      STATUS     ROLES                  AGE   VERSION
manager   NotReady   control-plane,master   65s   v1.21.0
worker1   NotReady   <none>                 13s   v1.21.0
worker2   NotReady   <none>                 12s   v1.21.0
worker3   NotReady   <none>                 11s   v1.21.0
  • docker login 해두기
docker login

step2

manager는 calico를 이용하여 네트워크 애드온을 설치한다. 이는 포드간 통신에 오버레이 네트워크를 제공할 수 있다. 또한, BGP를 이용하는 대규모 라우팅이 제공되는 환경이라면 이 역시 이용 가능한 플러그인으로 동작한다. 단, 우리 실습에서는 l2로 이용한다.

  • calico 배포
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
  • 확인
root@manager:~# kubectl get pod -n kube-system
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-867d8d6bd8-cjn62   1/1     Running   0          3m13s
calico-node-6wn2d                          1/1     Running   0          3m13s
calico-node-8hfpd                          1/1     Running   0          3m13s
calico-node-q7x4j                          1/1     Running   0          3m13s
calico-node-sf9fm                          1/1     Running   0          3m13s
coredns-558bd4d5db-vrdt7                   1/1     Running   0          5m48s
coredns-558bd4d5db-xtzvk                   1/1     Running   0          5m48s
etcd-manager                               1/1     Running   0          5m56s
...

step3

다음의 조건을 만족하는 웹서비스를 제공해 주세요

  • 외부로의 접속은 LB를 이용한다.(MetalLB)
  • LB에서 제공하는 주소 대역은 211.183.3.231-211.183.3.249까지이다.
  • Deployment
    • 3개의 웹서비스 제공(nginx 이용)

    • Pod는 각각 0.5개의 CPU, 32MB 메모리가 기본적으로 제공된다.

    • 만약, 각 Pod의 CPU 사용량이 80%를 넘어서게 되면 최대 10개까지 확장가능해야 한다.

    • nginx의 페이지는 ingress를 통해 라우팅 되어야 한다. 이는 nginx ingress controller을 이용하여 다음과 같이 구성한다.

                                                                                                                         vm port   pod

      211.183.3.20X → LB → Ingress Controller → Ingress → / → default 서비스 30001 3개

                                                                                     → /shop → shop 서비스 30002     3개
      
                                                                                     → /news → news 서비스 30003     3개

metalLB

  • metalLB 네임스페이스 생성
kubectl create ns metallb-system
  • 매니페스트 파일
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml
  • metalLB ConfigMap 적용하기’
root@manager:~# mkdir k8slab
root@manager:~# cd k8slab/
root@manager:~/k8slab# mkdir rapalab
root@manager:~/k8slab# cd rapalab/
root@manager:~/k8slab/rapalab# ls
root@manager:~/k8slab/rapalab# touch metallb.yaml
root@manager:~/k8slab/rapalab# vi metallb.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 211.183.3.231-211.183.3.249
kubectl apply -f metallb.yaml

Deployment

  • rapa namespace 만들기
root@manager:~/k8slab/rapalab# kubectl create ns rapa
namespace/rapa created

root@manager:~/k8slab/rapalab# kubectl get ns | grep rapa
rapa              Active   25s
  • 디렉토리 나누기
root@manager:~/k8slab/rapalab# mkdir default
root@manager:~/k8slab/rapalab# mkdir shop
root@manager:~/k8slab/rapalab# mkdir news
  • default-deploy-svc 파일 작성(default 디렉토리에서)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: default
  namespace: rapa
spec:
  replicas: 3
  selector:
    matchLabels:
      app: default
  template:
    metadata:
      name: default # pod 이름
      labels:
        app: default
    spec:
      containers:
      - name: default
        image: nginx
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 500m
            memory: 32Mi
---
apiVersion: v1
kind: Service
metadata:
  name: default
  namespace: rapa
spec:
  ports:
  - name: default-port
    port: 80 # 'service'의 port
    targetPort: 80 # Pod's port
    nodePort: 30001
  selector:
    app: default
  type: NodePort

배포하기

root@manager:~/k8slab/rapalab/default# kubectl apply -f default-deploy-svc.yaml
deployment.apps/default created
service/default created
  • shop-deploy-svc 파일 작성(shop 디렉토리에서)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: shop
  namespace: rapa
spec:
  replicas: 3
  selector:
    matchLabels:
      app: shop
  template:
    metadata:
      name: shop # pod 이름
      labels:
        app: shop
    spec:
      containers:
      - name: shop
        image: nginx
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 500m
            memory: 32Mi
---
apiVersion: v1
kind: Service
metadata:
  name: shop
  namespace: rapa
spec:
  ports:
  - name: shop-port
    port: 80 # 'service'의 port
    targetPort: 80 # Pod's port
    nodePort: 30002
  selector:
    app: shop
  type: NodePort

배포하기

root@manager:~/k8slab/rapalab/shop# kubectl apply -f shop-deploy-svc.yaml
deployment.apps/shop created
service/shop created
  • news-deploy-svc 파일 작성(news디렉토리에서)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: news
  namespace: rapa
spec:
  replicas: 3
  selector:
    matchLabels:
      app: news
  template:
    metadata:
      name: news # pod 이름
      labels:
        app: news
    spec:
      containers:
      - name: news
        image: nginx
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 500m
            memory: 32Mi
---
apiVersion: v1
kind: Service
metadata:
  name: news
  namespace: rapa
spec:
  ports:
  - name: news-port
    port: 80 # 'service'의 port
    targetPort: 80 # Pod's port
    nodePort: 30003
  selector:
    app: news
  type: NodePort

배포하기

root@manager:~/k8slab/rapalab/news# kubectl apply -f news-deploy-svc.yaml
deployment.apps/news created
service/news created

ingress

  • ingress-controller 배포
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.2/deploy/static/provider/cloud/deploy.yaml
  • ingress config

ingress-config.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx
  namespace: rapa
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - http:
      paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: default
              port:
                number: 80 # 서비스(nodeport)의 포트
        - path: /shop
          pathType: Prefix
          backend:
            service:
              name: shop
              port:
                number: 80
        - path: /news
          pathType: Prefix
          backend:
            service:
              name: news
              port:
                number: 80

배포하기

root@manager:~/k8slab/rapalab# kubectl apply -f ingress-config.yaml
ingress.networking.k8s.io/ingress-nginx created

확인하기

root@manager:~/k8slab/rapalab# kubectl get ingress
NAME            CLASS    HOSTS   ADDRESS         PORTS   AGE
ingress-nginx   <none>   *       211.183.3.231   80      3m40s

오토스케일링

  • metric server 배포
wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
vi components.yaml

136번째 줄 추가

  • 배포
root@manager:~/k8slab# kubectl apply -f components.yaml
  • HPA 통한 오토스케일링 구성 (test는 10으로 해보기)

default (default 디렉토리에서)

root@manager:~/k8slab/rapalab/default# kubectl autoscale deploy default -n rapa --cpu-percent=10 --min=3 --max=10
horizontalpodautoscaler.autoscaling/default autoscaled

shop (shop 디렉토리에서)

root@manager:~/k8slab/rapalab/shop# kubectl autoscale deploy shop -n rapa --cpu-percent=10 --min=3 --max=10
horizontalpodautoscaler.autoscaling/shop autoscaled

news(news 디렉토리에서)

root@manager:~/k8slab/rapalab/news# kubectl autoscale deploy news -n rapa --cpu-percent=8010 --min=3 --max=10
horizontalpodautoscaler.autoscaling/news autoscaled

지우고 다시하려면

kubectl get hpa -n rapa 해서 kubectl delete -n rapa 이름

  • 확인
root@manager:~/k8slab/rapalab/news# kubectl top no --use-protocol-buffers ; kubectl get hpa -n rapa
NAME      CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
manager   431m         10%    2326Mi          61%
worker1   192m         4%     1037Mi          56%
worker2   190m         4%     946Mi           51%
worker3   192m         4%     990Mi           53%
NAME      REFERENCE            TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
default   Deployment/default   0%/80%    3         10        3          2m
news      Deployment/news      0%/80%    3         10        3          23s
shop      Deployment/shop      0%/80%    3         10        3          68s
  • 부하 발생시키기
ab -c 1000 -n 200 -t 60 http://211.183.3.231/

ab -c 1000 -n 200 -t 60 http://211.183.3.231/shop/

ab -c 1000 -n 200 -t 60 http://211.183.3.231/news/
  • 확인
root@manager:~/k8slab/rapalab/news# kubectl top no --use-protocol-buffers ; kubectl get hpa -n rapa
NAME      CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
manager   537m         13%    2276Mi          60%
worker1   311m         7%     973Mi           52%
worker2   483m         12%    946Mi           51%
worker3   391m         9%     983Mi           53%
NAME      REFERENCE            TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
default   Deployment/default   0%/10%     3         10        10         108s
news      Deployment/news      0%/8010%   3         10        3          80s
shop      Deployment/shop      0%/10%     3         10        3          94s

step4

nfs를 구성하여 각 pod에 공간을 제공할 수 있어야 한다.

  • 3의 연장선으로, default 서비스는 nfs 서버의 /default/index.html로 연결이 되도록
  • shop 서비스는 nfs 서버의 /shop/index.html 으로 연결이 되도록
  • news 서비스는 nfs 서버의 /news/index.html 로 연결이 되도록
  • 페이지의 내용은 자유롭게
  • nfs server 구축

master

apt install -y nfs-server # manager에는 nfs 서버 설치
systemctl enable nfs-server --now
mkdir default
chmod 777 default/

mkdir shop
chmod 777 shop/

mkdir news
chmod 777 news/
  • 각 디렉토리에 index.html 각각 추가
<h3>Default Page @.@</h3>
<h3>Shop Page #_#</h3>
<h3>News Page -_-</h3>
vi /etc/exports
/root/default 211.183.3.0/24(rw,no_root_squash,sync)
/root/shop 211.183.3.0/24(rw,no_root_squash,sync)
/root/news 211.183.3.0/24(rw,no_root_squash,sync)
  • nfs-server 활성화/실행
ufw disable
systemctl restart nfs-server
  • worker1~3에 nfs client 설치
apt install -y nfs-common # worker에는 nfs client 설치

worker에서 확인

showmount -e 211.183.3.100
  • default-deploy-svc 파일 수정하기 (nfs 관련 추가)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: default
  namespace: rapa
spec:
  replicas: 3
  selector:
    matchLabels:
      app: default
  template:
    metadata:
      name: default # pod 이름
      labels:
        app: default
    spec:
      containers:
      - name: default
        image: nginx
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 500m
            memory: 32Mi
        volumeMounts:
        - name: default-volume
          mountPath: /usr/share/nginx/html
      volumes:
      - name: default-volume
        nfs:
          path: /root/default
          server: 211.183.3.100
---
apiVersion: v1
kind: Service
metadata:
  name: default
  namespace: rapa
spec:
  ports:
  - name: default-port
    port: 80 # 'service'의 port
    targetPort: 80 # Pod's port
    nodePort: 30001
  selector:
    app: default
  type: NodePort
root@manager:~/k8slab/rapalab/default# kubectl apply -f default-deploy-svc.yaml
deployment.apps/default created
service/default created
  • shop-deploy-svc 파일 수정 (nfs 관련 추가)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: shop
  namespace: rapa
spec:
  replicas: 3
  selector:
    matchLabels:
      app: shop
  template:
    metadata:
      name: shop # pod 이름
      labels:
        app: shop
    spec:
      containers:
      - name: shop
        image: nginx
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 500m
            memory: 32Mi
        volumeMounts:
        - name: shop-volume
          mountPath: /usr/share/nginx/html
      volumes:
      - name: shop-volume
        nfs:
          path: /root/shop
          server: 211.183.3.100
---
apiVersion: v1
kind: Service
metadata:
  name: shop
  namespace: rapa
spec:
  ports:
  - name: shop-port
    port: 80 # 'service'의 port
    targetPort: 80 # Pod's port
    nodePort: 30002
  selector:
    app: shop
  type: NodePort
root@manager:~/k8slab/rapalab/shop# kubectl apply -f shop-deploy-svc.yaml
deployment.apps/shop created
service/shop created
  • news-deploy-svc 파일 수정하기(nfs 관련 추가)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: news
  namespace: rapa
spec:
  replicas: 3
  selector:
    matchLabels:
      app: news
  template:
    metadata:
      name: news # pod 이름
      labels:
        app: news
    spec:
      containers:
      - name: news
        image: nginx
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 500m
            memory: 32Mi
        volumeMounts:
        - name: news-volume
          mountPath: /usr/share/nginx/html
      volumes:
      - name: news-volume
        nfs:
          path: /root/news
          server: 211.183.3.100
---
apiVersion: v1
kind: Service
metadata:
  name: news
  namespace: rapa
spec:
  ports:
  - name: news-port
    port: 80 # 'service'의 port
    targetPort: 80 # Pod's port
    nodePort: 30003
  selector:
    app: news
  type: NodePort
root@manager:~/k8slab/rapalab/news# kubectl apply -f news-deploy-svc.yaml
deployment.apps/news created
service/news created

step5

ingress controller는 LB와 연계하여 211.183.3.20X를 이용하고 있다. 이 IP 주소가 DNS를 통해 접속 할 수 있도록 했으면 좋겠지만

www.gildong.com을 manager의 /etc/hosts에 등록하고, manager에서는 curl을 이용해 확인해본다. (curl http://www.gildong.com/shop) 그 외에 곳에서는 브라우저+IP로 확인 (211.183.3.20X/shop 이렇게)

manager

vi /etc/hosts
211.183.3.231   www.gildong.com

0개의 댓글