Exercise 7.2: Service Mesh and Ingress Controller

  1. Linkerd 설치

    {
        curl -sL run.linkerd.io/install | sed -E 's/2.12.2/2.10.1/g' | sh
        export PATH=$PATH:/home/student/.linkerd2/bin
        echo "export PATH=$PATH:/home/student/.linkerd2/bin" >> $HOME/.bashrc
        linkerd check --pre
        linkerd install | kubectl apply -f -
        linkerd check
        linkerd viz install --set dashboard.enforcedHostRegexp=" " | kubectl apply -f -
        linkerd viz check
        linkerd viz dashboard &
    }
  2. 배포된 web Service를 외부 엑세스가 가능하도록 spec.type 값을 NodePort로 변경

    kubectl patch svc web --patch '{"spec":{"type":"NodePort"}}' -n linkerd-viz
  3. NodePort 확인 - 8084 포트에 맵핑된 NodePort

    kubectl get svc web -n linkerd-viz    
  4. 웹브라우저에서 ANY_NODE_IP:SERVICE_NODE_PORT 로 접속 - 아래 명령어로 주소 확인 가능

    echo "$(curl -s ifconfig.io):$(kubectl -n linkerd-viz get svc web -o=jsonpath='{.spec.ports[?(@.port==8084)].nodePort}')"
  5. 데모 애플리케이션 배포

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Namespace
    metadata:
      name: demo
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx
      labels:
        app: nginx
      namespace: demo
    spec:
      selector:
        matchLabels:
          app: nginx
      replicas: 1
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - image: nginx:1.20.1
            name: nginx
            ports:
            - containerPort: 80
              protocol: TCP
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      namespace: demo
    spec:
      type: NodePort
      selector:
        app: nginx
      ports:
        - port: 80
    EOF
  6. Linkerd 대시보드에 위에서 배포한 애플리케이션이 추가 되었는지 확인

  7. 배포된 Deployment에 Linkered 구성

    kubectl -n demo get deploy nginx -o yaml | linkerd inject - | kubectl apply -f -
  8. 배포된 Pod에 어떤 사항이 변경되었는지 확인

    kubectl get pod -n demo
  9. Linkerd 대시보드에서 어떤 사항이 변경되었는지 확인

  10. 생성된 Service의 Cluster IP 주소 확인

    kubectl get svc -n demo 
  11. 생성된 Service로 트래픽 생성

    watch -n 0.1 curl $(kubectl get svc nginx -o=jsonpath='{.spec.clusterIP}' -n demo)
  12. Linkerd 대시보드에서 해당 Service에 연결된 Deployment나 Pod의 지표 확인

  13. Deployment의 Replicas 갯수를 5개로 조정

    kubectl -n demo scale deploy nginx --replicas=5
  14. Service로 트래픽 생성

    watch -n 0.1 curl $(kubectl get svc nginx -o=jsonpath='{.spec.clusterIP}' -n demo)
  15. Linkerd 대시보드에서 해당 Service에 연결된 Deployment나 Pod의 지표 확인

  16. 생성된 데모 어플리케이션 삭제 - Namespace를 삭제하면 해당 Namespace에 포함된 모든 리소스가 삭제됨

    kubectl delete ns demo
  17. Helm Repository 추가 - NGINX Ingress

    {
        helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
        helm repo update
    }
  18. 위에서 추가한 Repository에서 Charts 파일 다운로드

    {
        helm fetch ingress-nginx/ingress-nginx --untar
        cd ingress-nginx && ls
    }
  19. values.yaml 파일 리뷰

    cat values.yaml
  20. 다운로드 받은 파일들을 이용해서 Helm Chart 설치

    helm install myingress . --set controller.kind=DaemonSet
  21. 클러스터에 생성된 Ingress가 있는지 확인

    kubectl get ing -A
  22. NGINX Ingress Controller가 설치 됐는지 확인

    kubectl get svc,pod -l app.kubernetes.io/instance=myingress
  23. 데모 애플리케이션 배포

    cat <<EOF | kubectl create -f -
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: web-one
      labels:
        app: web-one
    spec:
      selector:
        matchLabels:
          app: web-one
      replicas: 1
      template:
        metadata:
          labels:
            app: web-one
        spec:
          containers:
          - image: nginx
            name: nginx
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: web-one
    spec:
      type: ClusterIP
      selector:
        app: web-one
      ports:
        - port: 80
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: web-two
      labels:
        app: web-two
    spec:
      selector:
        matchLabels:
          app: web-two
      replicas: 1
      template:
        metadata:
          labels:
            app: web-two
        spec:
          containers:
          - image: httpd
            name: httpd
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: web-two
    spec:
      type: ClusterIP
      selector:
        app: web-two
      ports:
        - port: 80
    EOF
  24. Ingress 생성

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: ingress-test
      annotations:
        kubernetes.io/ingress.class: "nginx"
    spec:
      rules:
      - host: external.example.com
        http:
          paths:
          - backend:
              service:
                name: web-one
                port:
                  number: 80
            path: /
            pathType: ImplementationSpecific
    EOF
  25. 생성된 Ingress 확인

    kubectl get ingress
  26. 생성된 Ingress Controller Pod의 IP 주소 확인

    kubectl get pod -o wide -l app.kubernetes.io/instance=myingress
  27. CURL 명령어로 Ingress Controller Pod의 IP 주소 호출

    curl $(kubectl get pod -l app.kubernetes.io/name=ingress-nginx -o=jsonpath='{.items[0].status.podIP}')
  28. 생성된 Ingress Controller Service의 IP 주소 확인

    kubectl get svc -l app.kubernetes.io/instance=myingress
  29. CURL 명령어로 Ingress Controller Service의 IP 주소 호출

    curl $(kubectl get svc myingress-ingress-nginx-controller -o=jsonpath='{.spec.clusterIP}')
  30. Ingress에 명시한 Host 값을 포함해서 CURL 명령어로 Ingress Controller Service의 IP 주소 호출

    curl -H "Host: external.example.com" $(kubectl get svc myingress-ingress-nginx-controller -o=jsonpath='{.spec.clusterIP}')
  31. NGINX Ingress Controller에 Linkered 구성

    kubectl get ds myingress-ingress-nginx-controller -o yaml | linkerd inject --ingress - | kubectl apply -f -
  32. Linkerd 대시보드에 NGINX Ingress Controller DaemonSet의 Mesh가 활성 되었는지 확인

  33. Linkerd 대시보드 왼쪽 패널에서 Top에 들어가서 daemonset/myingress-ingress-nginx-controller로 들어오는 트래픽 모니터링

  34. 위에서 생성한 Ingress에 새로운 규칙 추가

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: ingress-test
      annotations:
        kubernetes.io/ingress.class: "nginx"
    spec:
      rules:
      - host: external.example.com
        http:
          paths:
          - backend:
              service:
                name: web-one
                port:
                  number: 80
            path: /
            pathType: ImplementationSpecific
      - host: internal.example.com
        http: 
          paths:
          - backend:
              service:
                name: web-two
                port:
                  number: 80
            path: /
            pathType: ImplementationSpecific
    EOF
  35. Ingress에 추가 Host 값을 포함해서 CURL 명령어로 Ingress Controller Service의 IP 주소 호출

    curl -H "Host: internal.example.com" $(kubectl get svc myingress-ingress-nginx-controller -o=jsonpath='{.spec.clusterIP}')
  36. Linkerd 대시보드에 위에서 호출한 HTTP 요청 기록 확인

  37. 리소스 삭제

    {
        kubectl delete deployment web-one web-two
        kubectl delete svc web-one web-two
        kubectl delete ing ingress-test
        helm uninstall myingress
        linkerd viz uninstall | kubectl delete -f -
        linkerd uninstall | kubectl delete -f -
    }

Last updated