전자책 출간 알림 [마이크로서비스패턴 쉽게 개발하기]

티스토리 뷰

Cloud/istio

04. Getting started

Happy@Cloud 2020. 3. 6. 11:18

istio 공식 사이트에서 제공하는 Bookinfo(https://istio.io/docs/examples/bookinfo/) 어플리케이션을 이용하여 실습해 보겠습니다.

1. Bookinfo 서비스 구성

Bookinfo 서비스의 실행 결과 화면입니다.
productpage, detail, review, rating의 4가지 마이크로서비스로 구성되어 있습니다.

 

 

각 마이크로서비스의 아키텍처는 아래와 같습니다.
마이크로서비스의 큰 특성중 하나인 Poly-glot(마이크로서비스별 상이한 기술 적용)으로 구성되어 있습니다.

2. 응용프로그램 배포

응용프로그램 배포 시 envoy proxy 컨테이너가 sidecar로 생성되도록 배포합니다.

1) auto sidecar injection

배포하려는 namespace에 istio sidecar injection이 자동으로 되도록 label을 수정합니다.

$ kubectl label ns <namespace> istio-injection=enabled
예) kubectl label ns test istio-injection=enabled

2) 배포

쉬운 이해를 위해 istio설치파일은 istio-1.4.6에 있고, 배포할 namespace는 test로 하겠습니다.\
~/istio-1.4.6/samples/bookinfo디렉토리에 배포를 위한 파일들이 모두 있습니다.

  1. 사전준비

    - namespace 생성 : kubectl create ns test
    - 현재 namespace를 test로 변경: kubectl config set-context $(kubectl config current-context) --namespace test
  2. 프로그램 배포

    $ cd ~/istio-1.4.6
    $ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
    $ kubectl get pod -w

3) istio gateway 생성

k8s 클러스터 외부(예: 웹브라우저)에서 접근하게 하기 위해 gateway를 생성합니다.

$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
$ kubectl get gateway

4) 테스트

웹브라우저에서 접근하기 위해서는 host와 PORT를 알아야 합니다. vanilla k8s에서는 아래와 같이 구하십시오.

-   IP구하기  
$ export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')

-   PORT구하기  
$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')

그외 k8s환경에서는 아래 링크를 참고하세요 : Determining the ingress IP and ports

여기서 INGRESS_HOST는 istio용 ingress POD가 설치된 NODE의 IP입니다. 

웹브라우저를 열고 http://아래 결과 IP와 PORT/productpage로 접근합니다.

$ echo $INGRESS_HOST:$INGRESS_PORT

3. Gateway, VirtualService 이해하기

예제를 조금 수정하면서 Gateway와 VirtualService에 대해 이해해 봅시다. 

먼저 istio는 namespace에 영향을 받지 않는다는 것을 기억하십시오. 현재 cluster의 모든 namespace에 있는 service들을 연결해야 하기 때문입니다.

Gateway의 yaml내용을 봅시다.

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

selector에서 istio KEY값이 ingressgateway인 POD를 지정했습니다. 

istio는 k8s의 ingress리소스 대신에 외부에서 연결을 위해 Gateway를 사용합니다. selector에 지정한 POD를 istio용 ingress gateway로 사용하겠다는 의미입니다. 

어떤 POD인지 찾아 봅시다.

$ kubectl get pod -l istio=ingressgateway --all-namespaces

 

 

istio-system에 있는 istio-ingressgateway-XXX POD입니다.  

위 Gateway의 내용은 80포트로 들어오는 모든 HOST에 대해 istio-ingressgateway-xxx POD를 이용하여 proxying하겠다는겁니다. 

80포트라는 번호는 아무렇게나 정한게 아닙니다. 어떻게 정해진걸까요 ? 

istio-ingressgateway-xxx POD가 연결이 되려면 해당하는 Service 리소스를 통해 연결되야 합니다.  어떤 Service인지 찾아 봅시다. 

istio-ingressgateway-xxx POD와 동일한 label을 갖고 있는 Service를 찾습니다. 

$ kubectl get svc -l istio=ingressgateway -n istio-system

 

 

YAML내용을 봅시다. 반드시 http2의 targetPort번호와 동일하게 Gateway의 포트번호를 지정해야 합니다. 

$ kubectl get svc istio-ingressgateway -n istio-system -o yaml

 

 

위 예로 본다면 외부에서는 http://$INGRESS_HOST:32746으로 접근하고, istio-ingressgateway SERVICE는 80포트로 수신하여 istio-ingressgateway-XXX POD를 80포트로 연결합니다. 
(INGRESS_HOST는 istio용 ingress POD가 설치된 NODE의 IP입니다.)

그 다음으로는 실제 bookinfo SERVICE가 연결이 되야 합니다. istio에서는 Service에 대한 routing을 VirtualService라는 리소스로 정의합니다.  bookinfo-gateway라는 GATEWAY를 이용하고, 모든 host에 대해서 특정 uri패턴으로 요청되면 productpage서비스를 9080포트로 연결합니다.  

$ kubectl get vs bookinfo -o yaml 

 

 

 요약하면 외부에서 istio를 이용하여 특정 서비스를 routing하는 순서는 아래와 같습니다. 

(Gateway 설정)->Service: istio-ingressgateway -> Pod: instio-ingressgateway-XXX ->

(VirtualService설정)-> Service: productpage ->

Container in productpage-XXX: istio envoy proxy -> Container in productpage-XXX: productpage

이해가 되었으면, 좀 더 확실한 이해를 위해 새로운 서비스를 추가하고 조금 바꿔 봅시다. 

- 수정사항: 모든 HOST가 아닌 http://bookinfo.<$INGRESS_HOST>.nip.io/productpage로 접근해야 productpage연결

- 추가:  http://users.<$INGRESS_HOST>.nip.io:18080/users로 요청되면 users-svc가 호출되어 아래와 같이 화면에 표시 

 

 

1) istio-ingressgateway SERVICE 수정 

$ mkdir ~/tmp/bookinfo && cd ~/tmp/bookinfo

$ kubectl get svc istio-ingressgateway -n istio-system -o yaml > iig.yaml 
아래와 같이 externalIPs를 $INGRESS_HOST로 하고 users-svc용 Gateway포트를 추가합니다.

(INGRESS_HOST는 istio용 ingress POD가 설치된 NODE의 IP입니다.)

 

 

전체 YAML예제는 아래와 같습니다. 

더보기

apiVersion: v1
kind: Service
metadata:
  labels:
    app: istio-ingressgateway
    istio: ingressgateway
    release: istio
  name: istio-ingressgateway
  namespace: istio-system
spec:
  clusterIP: 10.96.148.191
  externalTrafficPolicy: Cluster
  externalIPs:
  - 169.56.102.242
  ports:
  - name: status-port
    port: 15020
    protocol: TCP
    targetPort: 15020
  - name: http2
    port: 80
    protocol: TCP
    targetPort: 80
  - name: http
    port: 18080
    protocol: TCP
    targetPort: 18080
  - name: https
    port: 443
    protocol: TCP
    targetPort: 443
  - name: kiali
    port: 15029
    protocol: TCP
    targetPort: 15029
  - name: prometheus
    port: 15030
    protocol: TCP
    targetPort: 15030
  - name: grafana
    port: 15031
    protocol: TCP
    targetPort: 15031
  - name: tracing
    port: 15032
    protocol: TCP
    targetPort: 15032
  - name: tls
    port: 15443
    protocol: TCP
    targetPort: 15443
  selector:
    app: istio-ingressgateway
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer: {}

수정사항을 반영하고 확인합니다.

$ kubectl apply -f iig.yaml 

$ kubectl get svc istio-ingressgateway -n istio-system

 

 

External IP가 부여되었으므로 이제 http://<EXTERNAL-IP>:<SERVICE PORT>로 브라우저에서 접근할 수 있습니다. 

위 예제에서는 http://169.56.102.242/productpage로 접근할 수 있습니다. 

2) bookinfo-gateway수정

아래 예제를 참고하여 수정합니다. 

$ cd ~/tmp/bookinfo

$ vi gw.yaml

kind: Gateway
apiVersion: networking.istio.io/v1alpha3
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
    - hosts:
        - 'bookinfo.169.56.102.242.nip.io'
      port:
        name: http
        number: 80
        protocol: HTTP
    - hosts:
        - 'users.169.56.102.242.nip.io'
      port:
        name: http-users
        number: 18080
        protocol: HTTP

$ kubectl apply -f gw.yaml

 

3) VirtualService 수정 및 추가

- 기존에 있는 VirtualService 'bookinfo'를 아래 예제를 참고하여 수정합니다.

hosts를 '*'에서 'bookinfo.$INGRESS_HOST.nip.io'로 바꾸는 겁니다.

$ vi vs.yaml

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
    - 'bookinfo.169.56.102.242.nip.io'
  gateways:
    - bookinfo-gateway
  http:
    - match:
        - uri:
            exact: /productpage
        - uri:
            prefix: /static
        - uri:
            exact: /login
        - uri:
            exact: /logout
        - uri:
            prefix: /api/v1/products
      route:
        - destination:
            host: productpage
            port:
              number: 9080

- users-svc를 연결하기 위한 VirtualService를 추가합니다. 

$ vi vs-users.yaml

kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
  name: users
spec:
  hosts:
    - 'users.169.56.102.242.nip.io'
  gateways:
    - bookinfo-gateway
  http:
    - match:
        - uri:
            exact: /users
      route:
        - destination:
            host: users-svc
            port:
              number: 8888

- users-svc와 POD를 생성합니다. 아래 YAML을 이용하세요.

$ vi users.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: users-pod
spec:
  replicas: 1
  selector:
    matchLabels:
      app: users
  template:
    metadata:
      name: users-pod
      labels:
        app: users
    spec:
      containers:
      - name: users-container
        image: ondalk8s/users-img
        imagePullPolicy: Always
        ports:
          - containerPort: 10001
---
apiVersion: v1
kind: Service
metadata:
  name: users-svc
spec:
  selector:
    app: users
  type: ClusterIP
  ports:
    - name: users-port
      port: 8888
      protocol: TCP
      targetPort: 8080

 

4) 테스트

- productpage

$INGRSSS_HOST가 169.56.102.242이라면, 

http://169.56.102.242/productpage로 접근하면 연결이 안되야 합니다. 

http://bookinfo.169.56.102.242.nip.io/productpage 는 연결이 되야 합니다. 

 

 

 

- users

http://users.169.56.102.242.nip.io:18080/users로 연결이 되어야 합니다. 

 

 

5) istio proxy 설정 보기

세부적인 내용은 아래 참조하세요.

https://istio.io/docs/ops/diagnostic-tools/proxy-cmd/

 

Debugging Envoy and Istiod

Describes tools and techniques to diagnose Envoy configuration issues related to traffic management.

istio.io

proxy설정을 아래와 같이 파일로 만듭니다. 

$ istioctl proxy-config r istio-ingressgateway-8c9c9c9f5-stcj8 -n istio-system -o json > proxy-config.json

https://jsoneditoronline.org/ 로 이동합니다. 

왼쪽에서 proxy-config.json파일을 열고, 'COPY>' 버튼을 누릅니다.  

 

 

아래와 같이 YAML에 정의한대로 설정된것을 확인할 수 있습니다. 

 

 

 

 


4. Service간 연결 Visualize

kiali를 이용하여 service간 연결을 visualize해 보겠습니다. 

1) kiali 설치 : 설치 시 --set profile=demo로 했으면 이미 설치되어 있습니다. 

$ kubectl get svc -n istio-system

2) External IP 지정 

외부에서 연결하기 위해 External IP를 부여합니다. 

$ kubectl edit svc kiali -n istio-system

 

 

3) 웹브라우저 접근

아래 예제에서는 http://169.56.102.242:20001번으로 접근하면 됩니다.  기본 ID / PW는 admin / admin입니다.

 

 

 

4) Service 연결 보기

- bookinfo 페이지를 접근하여 대여섯번 정도 refresh하십시오. 예제에서는 http://bookinfo.169.56.102.242.nip.io/productpage입니다. 

- kiali 좌측 메뉴에서 Graph를 선택하고, 우측에서 옵션을 아래와 같이 조정합니다.  맨 우측 상단의 refresh 아이큰을 누르면 Service간 연결을 볼 수 있습니다. 

 

 

 

5) 테스트

Service간 라우팅을 변경하고 kiali에서 확인해 봅시다. 

$ cd ~/istio-1.4.6

- review 버전 v1을 호출하도록 virtual service를 생성합니다. virtual-service-all-v1.yaml내용은 다음장에서 설명합니다. 

$ kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

- destinationrule이라는 리소스를 먼저 만듭니다. destinationrule에 대해서는 이후 장에서 설명하겠습니다. 

$ kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml 

$ kubectl get destinationrule  또는 kubectl get dr

- productpage를 접근하여 대여섯번 refresh합니다. 그리고 kiali 페이지에서 맨 우측 상단의 refresh아이콘을 누릅니다.

 

 

 

- 이번에는 review v2-v3를 호출하도록 바꿉니다. 

$ cd ~/istio-1.4.6/samples/bookinfo/networking

$ kubectl apply -f virtual-service-reviews-v2-v3.yaml

- productpage를 접근하여 대여섯번 refresh합니다. v2가 호출되면 검은색 별점이 나타나고, v3가 호출되면 빨간색 별점이 표시됩니다. 

그리고 kiali 페이지에서 맨 우측 상단의 refresh아이콘을 누릅니다.

 

 

- 이번에는 review v3를 호출하도록 바꿉니다.

$ cd ~/istio-1.4.6/samples/bookinfo/networking

$ kubectl apply -f virtual-service-reviews-v3.yaml

- productpage를 접근하여 대여섯번 refresh합니다. 이번에는 항상 빨간색 별점이 표시됩니다.

그리고 kiali 페이지에서 맨 우측 상단의 refresh아이콘을 누릅니다.  v2쪽으로도 라우팅 되는게 보이다가 계속 refresh하면 v3로만 라우팅 되는걸로 나올겁니다. 지난 1분의 라우팅을 보여주기 때문에 약간 시간 차이가 발생합니다. 

 

 

 


5. Clean up

모든 리소스를 한꺼번에 정리하고 싶으면 아래 shell을 실행하십시오.

$ ~/istio-1.4.6/samples/bookinfo/platform/kube/cleanup.sh

 

 

 

수고하셨습니다.

이상으로 기본적인 실습을 했습니다.  이후 장에서는 istio의 각 feature를 학습하도록 하겠습니다. 

 

 

 

'Cloud > istio' 카테고리의 다른 글

05. Traffic Management: 서비스 Routing  (0) 2020.03.10
99. Trouble shooting  (0) 2020.03.03
03. istio sidecar injection  (0) 2020.03.03
02. istio 설치  (0) 2020.03.03
01. istio 란 ?  (0) 2020.02.04
댓글

전자책 출간 알림 [마이크로서비스패턴 쉽게 개발하기]