Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
2
Help us understand the problem. What is going on with this article?
@sota0113

サービスメッシュのLinkerdで取得したデータをZipkinで分散トレーシングする

More than 1 year has passed since last update.

前書き

首題の通り、マイクロサービスを実現する上で欠かせないサービスメッシュをLinkerdで実現し、各マイクロサービスの分散トレースをZipkinで実現します。
説明もそこそこに、とにかく早く構築してみたい方は、「構築手順」の章から進めてください。

Linkerdについて

Linkerdとは、buoyant社が開発したサービスメッシュOSSツールで、「本番環境として世界で最も使われているサービスメッシュ」と言われています。(ソース)

buoyant社はLinkerdとは別に、kubernetes専用のサービスメッシュConduitを発表しました。
ConduitはLinkerdの後継ではなく、Linkerdの開発とサポートは継続されるものの、いずれはConduitがメインとなると言われています。(ソース同上)

サービスメッシュの構成方法は主に、per nodeとper pod(サイドカー)方式があります。
Linkerdは両方対応可能ですが、今回はper nodeで実装します。
per nodeの場合、多数のpodを配置してもコンポーネントが増加することはないため、一般的にはper podよりもリソースを抑えることが出来ると言われています(が、per nodeのLinkerd自体のリソース使用量は小さくなく(ソース同上)、ultra-low-resourceな環境では別の選択肢を考える必要があります。)

image.png

上図では、pod4にあるサービスからpod8にあるサービスへリクエストを送る様子を描いています。
pod4はnode 1のLinkerdにリクエストを送ります。node1のLinkerdはdtabルールに従って、node2のLinkerdにリクエストを送りnode2のLinkerdはpod8のサービスに送ります。

※node1のLinkerdとnode2のLinkerdを繋ぐnamerdについて
manerdはdtabs(Delegation tables)によるルーティング情報を中央管理し、Linkerdからルーティング情報が参照されます。
上図のようにnodeまたぎでLinkerdのサービスメッシュを実現するためには、namerdが必要です。

Zipkinについて

zipkinは分散トレーシングツールで、マイクロサービス間のレイテンシーを収集/可視化することができます。(Zipkin公式ホームページ)
Zipkinは以下のアーキテクチャーで動作します。
Zipkinをkubernetesのpodとして動作させるために、serviceとしてcollectorとUIの2つが必要であることがわかります。

image.png

構築手順

GCP(GKE)の設定

GCP(GKE)のクラスターが作成されている前提で、以下コマンドを実行し、認証/kubectlとdockerの向き先を設定します。

##ログイン
$ gcloud auth login

##プロジェクト一覧
$ gcloud projects list

##プロジェクト変更
$ gcloud config set project soty-naky-0113

## クラスター一覧
$ gcloud container clusters list

## クラスター設定
$ gcloud container clusters get-credentials NAME --zone ZONE

## kubectlの構成の確認
$ kubectl config current-context

## dockerの構成
$ gcloud auth configure-docker

Zipkinの導入

以下のファイルを用意します。

・zipkin-replicationcontroller.yaml :podのyaml
・zipkin-collecter-service.yaml :Zipkinのcollecterのservice.yaml
・zipkin-ui-service.yaml :UIのservice.yaml
・zipkin-ingress.yaml :ZipkinのUIへ(httpsで)アクセスするためのingress.yaml
・各種tlsファイル :ingressへhttpsプロトコルで接続するために作成する自己証明のファイル群
・zipkin-secret.yaml :Ingressの自己証明書のsecret.yaml

それぞれのyamlファイルの中身は以下の通りです。

zipkin-replicationcontroller.yaml
apiVersion: v1
kind: ReplicationController
metadata:
  name: zipkin
spec:
  replicas: 1
  selector:
    app: zipkin
  template:
    metadata:
      name: zipkin
      labels:
        app: zipkin
    spec:
      containers:
      - name: zipkin
        image: openzipkin/zipkin:1.20
        env:
        - name: SCRIBE_ENABLED
          value: "true"
        ports:
        - name: scribe
          containerPort: 9410
        - name: http
          containerPort: 9411
zipkin-collecter-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    name: zipkin-collector
  name: zipkin-collector
spec:
  type: ClusterIP
  selector:
    app: zipkin
  ports:
  - name: scribe
    port: 9410
    targetPort: 9410
zipkin-ui-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: zipkin-ui
  labels:
    name: zipkin
spec:
  type: NodePort
  selector:
    app: zipkin
  ports:
  - name: https
    port: 443
    targetPort: 9411
zipkin-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: zipkin-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: zipkin-tls
  backend:
    serviceName: zipkin-ui
    servicePort: 443
zipkin-secret.yaml
apiVersion: v1
data:
  tls.crt: LS0tLS1...... #生成した.crtをbase64でエンコードした値を入力
  tls.key: LS0tLS1...... #生成した.keyをbase64でエンコードした値を入力
kind: Secret
metadata:
  name: zipkin-tls
  namespace: default
type: Opaque

上記tls.crt:tls.key:については、以下の手順で作成します。
・自己証明ファイル群を作成します。どの方法でも構いませんが、私はこちらのwebサイトを参考に、自己証明ファイル群を作成しました。
・作成した.crtファイルと.keyファイル(以下例ではそれぞれserver.crtとserver.key)をbase64でエンコードします。以下コマンドを実行して、その標準出力をそれぞれtls.crt:tls.key:の値として貼り付けます。

## server.crtとserver.keyファイルを、それぞれbase64エンコードするコマンド
$ cat server.crt | base64
$ cat server.key | base64

ここまで作成したファイル群をGKEに適用します。
まず以下コマンドを実行して、先にSecretを作成します。

$ kubectl create -f zipkin-secret.yaml
secret "zipkin-tls" created

pod(replicationcontroller)を作成します。

$ kubectl create -f zipkin-replicationcontroller.yaml

serviceを作成します。

$ kubectl create -f zipkin-ui-service.yaml zipkin-collecter-service.yaml

ingressを作成します。

$ kubectl create -f zipkin-ingress.yaml

アクセスポイントを確認します。以下コマンドでingressに割り振られているIPアドレスを確認します。(IPアドレスの割り振りには時間がかかる場合があります)

$ kubectl get ingress zipkin-ingress
NAME             HOSTS     ADDRESS          PORTS     AGE
zipkin-ingress   *         35.xxx.xxx.xxx   80, 443   10m

割り振られたアドレス(35.xxx.xxx.xxx)にhttpsでアクセスします。
(Ingressのannotations:の設定でkubernetes.io/ingress.allow-http: "false"としているため、httpプロトコルではアクセスできないことも併せて確認します)

httpsプロトコルでのアクセス
image.png

httpプロトコルでのアクセス
image.png

以上でZipkinの導入は完了です。

Linkerdの導入

Linkerdを導入するにあたり、以下のファイルを用意します。
・linkerd-daemonset.yaml :linkerdをdaemonsetとしてデプロイするyaml
・linkerd-configmap.yaml :linkerdの設定ファイルとなるconfig.yaml

linkerd-daemonset.yaml
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  labels:
    app: l5d
  name: l5d
spec:
  template:
    metadata:
      labels:
        app: l5d
    spec:
      volumes:
      - name: l5d-config
        configMap:
          name: "l5d-config"
      containers:
      - name: l5d
        image: mycluster.icp:8500/default/linkerd:1.3.6
        env:
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        args:
        - /io.buoyant/linkerd/config/config.yaml
        ports:
        - name: outgoing
          containerPort: 4140
          hostPort: 4140
        - name: incoming
          containerPort: 4141
        - name: admin
          containerPort: 9990
        volumeMounts:
        - name: "l5d-config"
          mountPath: "/io.buoyant/linkerd/config"
          readOnly: true

      - name: kubectl
        image: mycluster.icp:8500/default/kubectl:v1.8.5
        args:
        - "proxy"
        - "-p"
        - "8001"
linkerd-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: l5d-config
data:
  config.yaml: |-
    admin:
      ip: 0.0.0.0
      port: 9990

    namers:
    - kind: io.l5d.k8s
      host: localhost
      port: 8001

    telemetry:
    - kind: io.l5d.prometheus
    - kind: io.l5d.zipkin
      host: zipkin-collector.default.svc.cluster.local
      port: 9410
      sampleRate: 1.0
    - kind: io.l5d.recentRequests
      sampleRate: 0.25

    usage:
      orgId: linkerd-examples-daemonset-zipkin

    routers:
    - protocol: http
      label: outgoing
      dtab: |
        /srv        => /#/io.l5d.k8s/default/http;
        /host       => /srv;
        /svc        => /host;
        /host/world => /srv/world-v1;
      interpreter:
        kind: default
        transformers:
        - kind: io.l5d.k8s.daemonset
          namespace: default
          port: incoming
          service: l5d
      servers:
      - port: 4140
        ip: 0.0.0.0
      service:
        responseClassifier:
          kind: io.l5d.http.retryableRead5XX

    - protocol: http
      label: incoming
      dtab: |
        /srv        => /#/io.l5d.k8s/default/http;
        /host       => /srv;
        /svc        => /host;
        /host/world => /srv/world-v1;
      interpreter:
        kind: default
        transformers:
        - kind: io.l5d.k8s.localnode
      servers:
      - port: 4141
        ip: 0.0.0.0

Linkerdが取得したサービスメッシュのデータは、config.yaml内で定義した以下の箇所でzipkinに渡しています。

    telemetry:
    - kind: io.l5d.prometheus
    - kind: io.l5d.zipkin
      host: zipkin-collector.default.svc.cluster.local
      port: 9410
      sampleRate: 1.0

configmapを作成します。

$ kubectl create -f linkerd-configmap.yaml

Linkerdをdaemonsetとしてデプロイします。

$ kubectl create -f linkerd-daemonset.yaml

デプロイしたpodが正常に稼働していることを確認します。

$ kubectl get po -o wide -l app=l5d
NAME        READY     STATUS    RESTARTS   AGE       IP         NODE
l5d-22rkl   2/2       Running   0          5m        10.8.2.8   gke-cluster-1-default-pool-c4146799-hc7z
l5d-tcfhc   2/2       Running   0          5m        10.8.1.8   gke-cluster-1-default-pool-c4146799-69xf
l5d-xmv7z   2/2       Running   0          5m        10.8.0.9   gke-cluster-1-default-pool-c4146799-tps1

以上でLinkerdの導入は完了です。

サンプルアプリケーションの導入

あとはアプリケーションをデプロイし、動作させることでZipkinのインターフェースから分散トレースを可視化することができます。
※6/8までに詳しい手順をアップデート予定です

2
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
sota0113
クラウド/サポート/内容に誤りがございましたらお知らせ頂ければ幸いです。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
2
Help us understand the problem. What is going on with this article?