콘텐츠로 이동

Service Mesh 마이크로서비스 아키텍처 개발부터 카나리 배포까지 전체 프로세스 모범 사례(상)


개요

일반적으로 기업이 자체 컨테이너 환경을 구축한 후, 복잡한 배포 프로세스를 간소화하기 위해 GitlabCI, Jenkins를 사용하여 애플리케이션을 배포합니다. 동시에 Rancher를 사용하여 통합 리소스 오케스트레이션을 관리하고, Rancher 앱 스토어를 통해 애플리케이션 관리를 간소화합니다. 앱 스토어를 통해 DataKit을 원클릭으로 설치하면(자세한 내용은 DataKit 문서의 Helm 설치 방법 참조), Guance Rancher가 관리하는 Kubernetes 클러스터에 다양한 즉시 사용 가능한 관측 가능성 기능을 제공합니다. 이 문서에서는 잘 알려진 Bookinfo 사례를 통해 Guance를 활용하여 GitlabCI, Kubernetes 및 마이크로서비스의 관측 가능성을 구현하는 방법을 자세히 설명합니다.

시나리오 가정

한 회사가 Rancher를 사용하여 두 개의 Kubernetes 클러스터를 관리하고 있습니다. 하나는 개발/테스트용이고 다른 하나는 프로덕션용입니다. 회사는 개발/테스트 환경에 gitlab을 배포하여 CICD를 수행하며, BookInfo 프로젝트는 전자책 스토어로, 전형적인 다국어 마이크로서비스 프로젝트입니다. 현재 개발 중인 릴리스 버전이 개발/테스트 환경에 배포되고, 테스트를 통과하면 프로덕션 환경의 BookInfo에 대해 카나리 배포를 수행합니다. 이 회사의 관측 가능성 체계 구성 요소는 다음과 같습니다:
1.1 SRE는 두 환경의 Kubernetes 리소스 현황을 Guance에서 모니터링하여 용량 계획 및 장애 대응을 수행합니다.
2.1 개발자는 CI/CD 프로세스를 모니터링하여 소프트웨어 개발 주기 속도와 품질을 파악하고 오류가 발생한 파이프라인을 적시에 처리합니다.
2.2 SRE는 프로덕션 환경의 카나리 배포를 모니터링하여 버전 트래픽 전환 상태를 파악하고, 적시에 롤백하여 프로덕션 사용자에게 영향을 미치지 않도록 합니다.
3.1 SRE는 istio를 통해 전체 애플리케이션에 대한 분산 추적을 수행하고, Guance에서 애플리케이션의 주요 상태 지표를 확인하며, 비정상 요청을 적시에 처리합니다.
3.2 개발자는 자체 로그를 관리하고, 상태 이상 발생 시 Guance에서 분산 추적을 통해 로그 컨텍스트를 신속하게 찾아 문제를 해결합니다.
전체 실습 내용은 세 편으로 나누어 설명합니다.

사전 조건

배포 단계

1단계: Rancher를 사용하여 DataKit 설치

1.1 DataKit 배포

1.1.1 배포 파일 다운로드

Guance』에 로그인한 후, 『통합』 모듈을 클릭하고, 좌측 상단의 『DataKit』을 클릭한 후, 『Kubernetes』를 선택하여 datakit.yaml을 다운로드합니다.

1.1.2 토큰 구성

Guance』에 로그인하고, 『관리』 모듈로 이동한 후, 아래 그림에서 토큰을 찾아 datakit.yaml 파일의 ENV_DATAWAY 환경 변수 value 값에서 를 교체합니다.

        - name: ENV_DATAWAY
          value: https://openway.guance.com?token=<your-token>

image

1.1.3 글로벌 태그 설정

datakit.yaml 파일의 ENV_GLOBAL_HOST_TAGS 환경 변수 값 끝에 cluster_name_k8s=k8s-istio를 추가합니다. 여기서 k8s-istio는 클러스터 이름입니다. 이 단계는 클러스터에 글로벌 태그를 설정하는 것입니다.

        - name: ENV_GLOBAL_HOST_TAGS
          value: host=__datakit_hostname,host_ip=__datakit_ip,cluster_name_k8s=k8s-istio
1.1.4 네임스페이스 설정

DataKit이 선출 시 클러스터를 구분하기 위해 ENV_NAMESPACE 환경 변수를 설정해야 하며, 클러스터마다 값이 달라야 합니다. datakit.yaml 파일의 환경 변수 부분에 다음 내용을 추가합니다.

        - name: ENV_NAMESPACE
          value: k8s-istio
1.1.5 수집기 활성화

ddtrace 및 statsd 수집기를 활성화하려면 datakit.yaml 파일에서 ENV_DEFAULT_ENABLED_INPUTS 환경 변수를 찾아 마지막에 statsd,ddtrace를 추가합니다.

        - name: ENV_DEFAULT_ENABLED_INPUTS
          value: cpu,disk,diskio,mem,swap,system,hostobject,net,host_processes,container,statsd,ddtrace
1.1.6 DataKit 배포

『Rancher』에 로그인하고, 클러스터 탐색 탭에서 『k8s-solution-cluster』 클러스터를 선택한 후, datakit.yaml을 열고 리소스 파일 내용에 따라 k8s-solution-cluster 클러스터에서 해당 메뉴를 찾아 하나씩 리소스를 생성합니다.

image

『참고』다음 단계를 신속하게 수행하기 위해 이번 작업에서는 ConfigMap을 병합한 후 kubectl 명령을 직접 사용하여 DataKit을 배포합니다.

1.2 ConfigMap 생성

container 수집기와 zipkin 수집기를 활성화하려면 먼저 container.conf와 zipkin.conf를 정의해야 합니다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: datakit-conf
  namespace: datakit
data:
    #### container
    container.conf: |-  
      [inputs.container]
        docker_endpoint = "unix:///var/run/docker.sock"
        containerd_address = "/var/run/containerd/containerd.sock"

        enable_container_metric = true
        enable_k8s_metric = true
        enable_pod_metric = true

        ## Containers logs to include and exclude, default collect all containers. Globs accepted.
        container_include_log = []
        container_exclude_log = ["image:pubrepo.guance.com/datakit/logfwd*", "image:pubrepo.guance.com/datakit/datakit*"]

        exclude_pause_container = true

        ## Removes ANSI escape codes from text strings
        logging_remove_ansi_escape_codes = false

        kubernetes_url = "https://kubernetes.default:443"

        ## Authorization level:
        ##   bearer_token -> bearer_token_string -> TLS
        ## Use bearer token for authorization. ('bearer_token' takes priority)
        ## linux at:   /run/secrets/kubernetes.io/serviceaccount/token
        ## windows at: C:\var\run\secrets\kubernetes.io\serviceaccount\token
        bearer_token = "/run/secrets/kubernetes.io/serviceaccount/token"
        # bearer_token_string = "<your-token-string>"

        [inputs.container.tags]
          # some_tag = "some_value"
          # more_tag = "some_other_value"

    #### zipkin
    zipkin.conf: |-          
        [[inputs.zipkin]]
          pathV1 = "/api/v1/spans"
          pathV2 = "/api/v2/spans"

[inputs.container] 매개변수 설명

  • container_include_metric: 수집할 컨테이너 메트릭
  • container_exclude_metric: 수집하지 않을 컨테이너 메트릭
  • container_include_log: 수집할 컨테이너 로그
  • container_exclude_log: 수집하지 않을 컨테이너 로그
  • exclude_pause_container: true는 pause 컨테이너 제외
  • container_includecontainer_excludeimage로 시작해야 하며, 형식은 "image:<glob规则>"입니다. 이는 glob 규칙이 컨테이너 image에 적용됨을 의미합니다.
  • Glob 규칙은 경량 정규식으로, *, ? 등의 기본 일치 단위를 지원합니다.

그런 다음 『Rancher』에 로그인하고, 클러스터 탐색 탭에서 『k8s-solution-cluster』 클러스터를 선택한 후, 『추가 리소스』 -> 『Core』 -> 『ConfigMaps』로 차례로 이동하여 위에서 정의한 ConfigMap을 yaml 형식으로 생성합니다.

image

마지막으로 DataKit과 ConfigMap을 연결합니다. 『k8s-solution-cluster』 클러스터에서 『워크로드』 -> 『DaemonSets』로 이동하여 DataKit을 찾고, 오른쪽에서 『YAML 편집』을 선택한 후 다음 내용을 추가하고 『저장』을 클릭합니다.

image

        - mountPath: /usr/local/datakit/conf.d/container/container.conf
          name: datakit-conf
          subPath: container.conf
        - mountPath: /usr/local/datakit/conf.d/zipkin/zipkin.conf
          name: datakit-conf
          subPath: zipkin.conf

kubectl 명령을 사용하여 DataKit을 생성하는 경우 ConfigMap에 정의된 내용을 datakit.yaml 파일의 마지막에 추가한 후, 위의 구성을 파일의 volumeMounts 아래에 추가합니다.
『참고』---를 구분자로 사용합니다.

1.3 DataKit 실행 상태 확인

DataKit이 성공적으로 배포되면 아래 그림과 같은 실행 상태를 확인할 수 있습니다.

image

2단계: DataKit 서비스 매핑

Istio를 사용하여 추적 데이터를 전송하면 추적 데이터는 zipkin.istio-system의 Service로 전송되며, 포트는 9411입니다. DataKit 서비스의 네임스페이스는 datakit이고 포트는 9529이므로 변환이 필요합니다. 자세한 내용은 Kubernetes 클러스터에서 ExternalName을 사용하여 DataKit 서비스 매핑을 참조하세요.

3단계: DataFlux Function에서 DataKit 구성

Gitlab-CI를 사용하여 마이크로서비스를 배포할 때 Gitlab 실행 데이터를 수집하려면 DataFlux Function을 배포하고 DataKit을 구성해야 합니다. 자세한 단계는 Gitlab-CI 관측 가능성 모범 사례를 참조하세요.

4단계: Bookinfo 배포

2.1 소스 코드 다운로드

istio-1.13.2.zip을 다운로드합니다. 이후 사용되는 배포 파일은 모두 이 압축 파일에서 가져옵니다. 작업 편의를 위해 Rancher의 GUI 대신 kubectl 명령을 사용하여 리소스를 생성합니다.

2.2 RUM 활성화

웹사이트 호출 정보를 모니터링하려면 프론트엔드 데이터 수집을 활성화해야 합니다. 『Guance』에 로그인하고, 『실제 사용자 모니터링(RUM)』으로 이동하여 devops-bookinfo 애플리케이션을 새로 만든 후, 아래 JS를 복사합니다.

image

위 JS는 productpage 프로젝트의 모든 페이지에서 액세스할 수 있는 위치에 배치해야 합니다. 이 프로젝트에서는 위의 JS를 istio-1.13.2\samples\bookinfo\src\productpage\templates\productpage.html 파일에 복사합니다. 『참고』RUM 데이터 전송을 위한 DataKit 주소는 RUM 데이터 전송 DataKit 클러스터 모범 사례를 참조하세요.

image

그런 다음 productpage의 이미지를 다시 빌드하여 이미지 레지스트리에 업로드합니다.

cd istio-1.13.2\samples\bookinfo\src\productpage
docker build -t 172.16.0.238/df-demo/product-page:v1  .
docker push 172.16.0.238/df-demo/product-page:v1

2.3 Sidecar 주입 활성화

prod 네임스페이스를 생성하고, 해당 네임스페이스에서 Pod 생성 시 Sidecar가 자동으로 주입되어 Pod의 인바운드/아웃바운드 트래픽이 모두 Sidecar를 통해 처리되도록 설정합니다.

kubectl create ns prod 
kubectl label namespace prod istio-injection=enabled

2.4 productpage, details, ratings 배포

istio-1.13.2\samples\bookinfo\platform\kube\bookinfo.yaml 파일에서 reviews 마이크로서비스 배포 관련 부분을 제거하고, Service와 Deployment를 모두 prod 네임스페이스에 배포합니다. 모든 Deployment 컨트롤러의 Pod 템플릿에 annotations를 추가하여 Pod의 사용자 정의 수집을 활성화합니다. productpage 이미지는 이전 단계에서 생성한 이미지로 수정합니다. 전체 파일은 다음과 같습니다:

# Copyright Istio Authors
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

##################################################################################################
# This file defines the services, service accounts, and deployments for the Bookinfo sample.
#
# To apply all 4 Bookinfo services, their corresponding service accounts, and deployments:
#
#   kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
#
# Alternatively, you can deploy any resource separately:
#
#   kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l service=reviews # reviews Service
#   kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l account=reviews # reviews ServiceAccount
#   kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l app=reviews,version=v3 # reviews-v3 Deployment
##################################################################################################

##################################################################################################
# Details service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
  name: details
  namespace: prod
  labels:
    app: details
    service: details
spec:
  ports:
  - port: 9080
    name: http
  selector:
    app: details
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: bookinfo-details
  namespace: prod
  labels:
    account: details
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: details-v1
  namespace: prod
  labels:
    app: details
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: details
      version: v1
  template:
    metadata:
      labels:
        app: details
        version: v1
      annotations:
        datakit/prom.instances: |
          [[inputs.prom]]
            url = "http://$IP:15020/stats/prometheus"
            source = "bookinfo-istio-details"
            metric_types = ["counter", "gauge"]
            interval = "60s"
            tags_ignore = ["cache","cluster_type","component","destination_app","destination_canonical_revision","destination_canonical_service","destination_cluster","destination_principal","group","grpc_code","grpc_method","grpc_service","grpc_type","reason","request_protocol","request_type","resource","responce_code_class","response_flags","source_app","source_canonical_revision","source_canonical-service","source_cluster","source_principal","source_version","wasm_filter"]
            #measurement_prefix = ""
            metric_name_filter = ["istio_requests_total","pilot_k8s_cfg_events","istio_build","process_virtual_memory_bytes","process_resident_memory_bytes","process_cpu_seconds_total","envoy_cluster_assignment_stale","go_goroutines","pilot_xds_pushes","pilot_proxy_convergence_time_bucket","citadel_server_root_cert_expiry_timestamp","pilot_conflict_inbound_listener","pilot_conflict_outbound_listener_http_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_http","pilot_virt_services","galley_validation_failed","pilot_services","envoy_cluster_upstream_cx_total","envoy_cluster_upstream_cx_connect_fail","envoy_cluster_upstream_cx_active","envoy_cluster_upstream_cx_rx_bytes_total","envoy_cluster_upstream_cx_tx_bytes_total","istio_request_duration_milliseconds_bucket","istio_request_duration_seconds_bucket","istio_request_bytes_bucket","istio_response_bytes_bucket"]
            measurement_name = "istio_prom"
            #[[inputs.prom.measurements]]
            # prefix = "cpu_"
            # name = "cpu"         
            [inputs.prom.tags]
            namespace = "$NAMESPACE"
    spec:
      serviceAccountName: bookinfo-details
      containers:
      - name: details
        image: docker.io/istio/examples-bookinfo-details-v1:1.16.2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9080
        securityContext:
          runAsUser: 1000
---
##################################################################################################
# Ratings service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
  name: ratings
  namespace: prod
  labels:
    app: ratings
    service: ratings
spec:
  ports:
  - port: 9080
    name: http
  selector:
    app: ratings
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: bookinfo-ratings
  namespace: prod
  labels:
    account: ratings
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ratings-v1
  namespace: prod
  labels:
    app: ratings
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ratings
      version: v1
  template:
    metadata:
      labels:
        app: ratings
        version: v1
      annotations:
        datakit/prom.instances: |
          [[inputs.prom]]
            url = "http://$IP:15020/stats/prometheus"
            source = "bookinfo-istio-ratings"
            metric_types = ["counter", "gauge"]
            interval = "60s"
            tags_ignore = ["cache","cluster_type","component","destination_app","destination_canonical_revision","destination_canonical_service","destination_cluster","destination_principal","group","grpc_code","grpc_method","grpc_service","grpc_type","reason","request_protocol","request_type","resource","responce_code_class","response_flags","source_app","source_canonical_revision","source_canonical-service","source_cluster","source_principal","source_version","wasm_filter"]
            #measurement_prefix = ""
            metric_name_filter = ["istio_requests_total","pilot_k8s_cfg_events","istio_build","process_virtual_memory_bytes","process_resident_memory_bytes","process_cpu_seconds_total","envoy_cluster_assignment_stale","go_goroutines","pilot_xds_pushes","pilot_proxy_convergence_time_bucket","citadel_server_root_cert_expiry_timestamp","pilot_conflict_inbound_listener","pilot_conflict_outbound_listener_http_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_http","pilot_virt_services","galley_validation_failed","pilot_services","envoy_cluster_upstream_cx_total","envoy_cluster_upstream_cx_connect_fail","envoy_cluster_upstream_cx_active","envoy_cluster_upstream_cx_rx_bytes_total","envoy_cluster_upstream_cx_tx_bytes_total","istio_request_duration_milliseconds_bucket","istio_request_duration_seconds_bucket","istio_request_bytes_bucket","istio_response_bytes_bucket"]
            measurement_name = "istio_prom"
            #[[inputs.prom.measurements]]
            # prefix = "cpu_"
            # name = "cpu"         
            [inputs.prom.tags]
            namespace = "$NAMESPACE"
    spec:
      serviceAccountName: bookinfo-ratings
      containers:
      - name: ratings
        image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9080
        securityContext:
          runAsUser: 1000
---
##################################################################################################
# Productpage services
##################################################################################################
apiVersion: v1
kind: Service
metadata:
  name: productpage
  namespace: prod
  labels:
    app: productpage
    service: productpage
spec:
  ports:
  - port: 9080
    name: http
  selector:
    app: productpage
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: bookinfo-productpage
  namespace: prod
  labels:
    account: productpage
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: productpage-v1
  namespace: prod
  labels:
    app: productpage
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: productpage
      version: v1
  template:
    metadata:
      labels:
        app: productpage
        version: v1
      annotations:
        datakit/prom.instances: |
          [[inputs.prom]]
            url = "http://$IP:15020/stats/prometheus"
            source = "bookinfo-istio-product"
            metric_types = ["counter", "gauge"]
            interval = "60s"
            tags_ignore = ["cache","cluster_type","component","destination_app","destination_canonical_revision","destination_canonical_service","destination_cluster","destination_principal","group","grpc_code","grpc_method","grpc_service","grpc_type","reason","request_protocol","request_type","resource","responce_code_class","response_flags","source_app","source_canonical_revision","source_canonical-service","source_cluster","source_principal","source_version","wasm_filter"]
            metric_name_filter = ["istio_requests_total","pilot_k8s_cfg_events","istio_build","process_virtual_memory_bytes","process_resident_memory_bytes","process_cpu_seconds_total","envoy_cluster_assignment_stale","go_goroutines","pilot_xds_pushes","pilot_proxy_convergence_time_bucket","citadel_server_root_cert_expiry_timestamp","pilot_conflict_inbound_listener","pilot_conflict_outbound_listener_http_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_http","pilot_virt_services","galley_validation_failed","pilot_services","envoy_cluster_upstream_cx_total","envoy_cluster_upstream_cx_connect_fail","envoy_cluster_upstream_cx_active","envoy_cluster_upstream_cx_rx_bytes_total","envoy_cluster_upstream_cx_tx_bytes_total","istio_request_duration_milliseconds_bucket","istio_request_duration_seconds_bucket","istio_request_bytes_bucket","istio_response_bytes_bucket"]
            #measurement_prefix = ""
            measurement_name = "istio_prom"
            #[[inputs.prom.measurements]]
            # prefix = "cpu_"
            # name = "cpu"         
            [inputs.prom.tags]
            namespace = "$NAMESPACE"
    spec:
      serviceAccountName: bookinfo-productpage
      containers:
      - name: productpage
        #image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
        image: 172.16.0.238/df-demo/product-page:v1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9080
        volumeMounts:
        - name: tmp
          mountPath: /tmp
        securityContext:
          runAsUser: 1000
      volumes:
      - name: tmp
        emptyDir: {}
---
kubectl apply -f bookinfo.yaml

2.5 Gateway 리소스 및 가상 서비스 생성

istio-1.13.2\samples\bookinfo\networking\bookinfo-gateway.yaml 파일을 수정하여 prod 네임스페이스를 추가합니다.

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
  namespace: prod
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
  namespace: prod
spec:
  hosts:
  - "*"
  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
kubectl apply -f bookinfo-gateway.yaml 

2.6 productpage 접속

ingressgateway가 외부에 노출하는 포트를 확인합니다.

kubectl get svc -n istio-system

image

가상 서비스 규칙에 따라 브라우저에서 http://8.136.193.105:32156/productpage에 접속하면 productpage에 접속할 수 있습니다. 현재 reviews 서비스가 배포되지 않았으므로 Sorry, product reviews are currently unavailable for this book라는 메시지가 표시됩니다.

image

5단계: 자동화 배포

5.1 Gitlab 프로젝트 생성

Gitlab에 로그인하여 bookinfo-views 프로젝트를 생성합니다.

image

5.2 Gitlab과 DataKit 연결

gitlab 통합 문서를 참조하여 Gitlab과 DataKit을 연결합니다. 여기서는 Gitlab CI만 구성합니다.
『Gitlab』에 로그인하고, 『bookinfo-views』 -> 『Settings』 -> 『Webhooks』로 이동한 후, URL에 DataKit이 설치된 호스트 IP와 DataKit의 9529 포트를 입력하고 마지막에 /v1/gitlab을 추가합니다. 아래 그림을 참조하세요.

image

Job events와 Pipeline events를 선택하고, Add webhook을 클릭합니다.

image

방금 생성한 Webhooks 오른쪽의 Test를 클릭하고 Pipeline events를 선택하면 아래와 같이 HTTP 200이 표시되면 구성이 성공한 것입니다.

image

5.3 reviews 마이크로서비스에 Gitlab-CI 구성

『Gitlab』에 로그인하고, 『bookinfo-views』로 이동한 후, 루트 디렉터리에 deployment.yaml과 .gitlab-ci.yml 파일을 생성합니다. annotations에는 project, env, version 태그를 정의하여 프로젝트 및 버전별로 구분합니다.

apiVersion: v1
kind: Service
metadata:
  name: reviews
  namespace: prod
  labels:
    app: reviews
    service: reviews
spec:
  ports:
  - port: 9080
    name: http
  selector:
    app: reviews
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: bookinfo-reviews
  namespace: prod
  labels:
    account: reviews
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: reviews-__version__
  namespace: prod
  labels:
    app: reviews
    version: __version__
spec:
  replicas: 1
  selector:
    matchLabels:
      app: reviews
      version: __version__
  template:
    metadata:
      labels:
        app: reviews
        version: __version__
      annotations:
        datakit/prom.instances: |
          [[inputs.prom]]
            url = "http://$IP:15020/stats/prometheus"
            source = "bookinfo-istio-review"
            metric_types = ["counter", "gauge"]
            interval = "60s"
            tags_ignore = ["cache","cluster_type","component","destination_app","destination_canonical_revision","destination_canonical_service","destination_cluster","destination_principal","group","grpc_code","grpc_method","grpc_service","grpc_type","reason","request_protocol","request_type","resource","responce_code_class","response_flags","source_app","source_canonical_revision","source_canonical-service","source_cluster","source_principal","source_version","wasm_filter"]
            metric_name_filter = ["istio_requests_total","pilot_k8s_cfg_events","istio_build","process_virtual_memory_bytes","process_resident_memory_bytes","process_cpu_seconds_total","envoy_cluster_assignment_stale","go_goroutines","pilot_xds_pushes","pilot_proxy_convergence_time_bucket","citadel_server_root_cert_expiry_timestamp","pilot_conflict_inbound_listener","pilot_conflict_outbound_listener_http_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_http","pilot_virt_services","galley_validation_failed","pilot_services","envoy_cluster_upstream_cx_total","envoy_cluster_upstream_cx_connect_fail","envoy_cluster_upstream_cx_active","envoy_cluster_upstream_cx_rx_bytes_total","envoy_cluster_upstream_cx_tx_bytes_total","istio_request_duration_milliseconds_bucket","istio_request_duration_seconds_bucket","istio_request_bytes_bucket","istio_response_bytes_bucket"]
            #measurement_prefix = ""
            measurement_name = "istio_prom"
            #[[inputs.prom.measurements]]
            # prefix = "cpu_"
            # name = "cpu"
            [inputs.prom.tags]
            namespace = "$NAMESPACE"
        proxy.istio.io/config: |
          tracing:
            zipkin:
              address: zipkin.istio-system:9411
            custom_tags:
              project:
                literal:
                  value: "reviews"
              version:
                literal:
                  value: __version__
              env:
                literal:
                  value: "test"        
    spec:
      serviceAccountName: bookinfo-reviews
      containers:
      - name: reviews
        image: docker.io/istio/examples-bookinfo-reviews-__version__:1.16.2
        imagePullPolicy: IfNotPresent
        env:
        - name: LOG_DIR
          value: "/tmp/logs"
        ports:
        - containerPort: 9080
        volumeMounts:
        - name: tmp
          mountPath: /tmp
        - name: wlp-output
          mountPath: /opt/ibm/wlp/output
        securityContext:
          runAsUser: 1000
      volumes:
      - name: wlp-output
        emptyDir: {}
      - name: tmp
        emptyDir: {}
variables:
  APP_VERSION: "v1"

stages:
  - deploy

deploy_k8s:
  image: bitnami/kubectl:1.22.7
  stage: deploy
  tags:
    - kubernetes-runner
  script:
    - echo "deploy 실행"
    - ls
    - sed -i "s#__version__#${APP_VERSION}#g" deployment.yaml
    - cat deployment.yaml
    - kubectl apply -f deployment.yaml
  after_script:
    - sleep 10
    - kubectl get pod  -n prod

6단계: Gitlab CI 관측 가능성

6.1 reviews 마이크로서비스 배포

.gitlab-ci.yml 파일에서 APP_VERSION 값을 "v1"으로 변경하고 코드를 한 번 커밋한 후, "v2"로 변경하여 다시 커밋하고, "v3"로 변경하여 다시 한 번 커밋합니다.

image

이제 Pipeline이 3번 트리거됩니다.

image

6.2 Gitlab CI 파이프라인 관측 가능성

Guance』에 로그인하고, 『CI』로 이동한 후, 『개요』를 클릭하여 bookinfo-views 프로젝트를 선택하고 Pipeline 및 Job 실행 상태를 확인합니다.

image

image

Guance』에 로그인하고, 『CI』로 이동한 후, 『탐색기』를 클릭하고 gitlab_pipeline을 선택합니다.

image

image

Guance』에 로그인하고, 『CI』로 이동한 후, 『탐색기』를 클릭하고 gitlab_job을 선택합니다.

image

image

image

문서 평가

이 페이지가 도움이 되었나요?