サービスメッシュ Linkerd
Linkerdとは
Linkerdはオープンソースのサービスメッシュで、Cloud Native Computing Foundationのメンバープロジェクトです。 現在では、Incubating projectとなっています。
Architecture
Linkerdはコントロールプレーンとデータプレーンで構成されます。
コントロールプレーンは、専用のnamespaceで実行されるサービスのセットです。 これらのサービスは、テレメトリデータの集計、ユーザー向けAPIの提供、データプレーンプロキシへの制御データの提供など、さまざまなことを実現します。
データプレーンは、各サービスインスタンスにて実行されている透過的なプロキシです。 コントロールプレーンにテレメトリを送信し、コントロールプレーンから制御信号を受信します。
tap
identity
proxy-injector
sp-validator
- バリデーターは、保存前に新しいサービスプロファイルを検証するアドミッションコントローラーです。
Step 1: Install the CLI
# curl -sL https://run.linkerd.io/install | sh Downloading linkerd2-cli-stable-2.6.0-linux... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 622 0 622 0 0 221 0 --:--:-- 0:00:02 --:--:-- 221 100 36.6M 100 36.6M 0 0 476k 0 0:01:18 0:01:18 --:--:-- 567k Download complete! Validating checksum... Checksum valid. Linkerd stable-2.6.0 was successfully installed 🎉 Add the linkerd CLI to your path with: export PATH=$PATH:/root/.linkerd2/bin Now run: linkerd check --pre # validate that Linkerd can be installed linkerd install | kubectl apply -f - # install the control plane into the 'linkerd' namespace linkerd check # validate everything worked! linkerd dashboard # launch the dashboard Looking for more? Visit https://linkerd.io/2/next-steps
では、使えるようにしていきます。
# vi .bash_profile 以下を追加 export PATH=$PATH:$HOME/.linkerd2/bin # source .bash_profile
Step 2: Validate your Kubernetes cluster
次のコマンドで、kubernetesがLinkerdを動かすうえで適した環境が作れているかの検証を行います。
# linkerd check --pre kubernetes-api -------------- √ can initialize the client √ can query the Kubernetes API kubernetes-version ------------------ √ is running the minimum Kubernetes API version √ is running the minimum kubectl version pre-kubernetes-setup -------------------- √ control plane namespace does not already exist √ can create Namespaces √ can create ClusterRoles √ can create ClusterRoleBindings √ can create CustomResourceDefinitions √ can create PodSecurityPolicies √ can create ServiceAccounts √ can create Services √ can create Deployments √ can create CronJobs √ can create ConfigMaps √ no clock skew detected pre-kubernetes-capability ------------------------- √ has NET_ADMIN capability √ has NET_RAW capability pre-linkerd-global-resources ---------------------------- √ no ClusterRoles exist √ no ClusterRoleBindings exist √ no CustomResourceDefinitions exist √ no MutatingWebhookConfigurations exist √ no ValidatingWebhookConfigurations exist √ no PodSecurityPolicies exist linkerd-version --------------- √ can determine the latest version √ cli is up-to-date Status check results are √
Step 3: Install Linkerd onto the cluster
それでは、Linkerdをデプロイしていきます。
# linkerd install | kubectl apply -f - namespace/linkerd created clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-identity created clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-identity created serviceaccount/linkerd-identity created clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-controller created clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-controller created serviceaccount/linkerd-controller created clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-destination created clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-destination created serviceaccount/linkerd-destination created role.rbac.authorization.k8s.io/linkerd-heartbeat created rolebinding.rbac.authorization.k8s.io/linkerd-heartbeat created serviceaccount/linkerd-heartbeat created clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-web-admin created serviceaccount/linkerd-web created customresourcedefinition.apiextensions.k8s.io/serviceprofiles.linkerd.io created customresourcedefinition.apiextensions.k8s.io/trafficsplits.split.smi-spec.io created clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-prometheus created clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-prometheus created serviceaccount/linkerd-prometheus created serviceaccount/linkerd-grafana created clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-proxy-injector created clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-proxy-injector created serviceaccount/linkerd-proxy-injector created secret/linkerd-proxy-injector-tls created mutatingwebhookconfiguration.admissionregistration.k8s.io/linkerd-proxy-injector-webhook-config created clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-sp-validator created clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-sp-validator created serviceaccount/linkerd-sp-validator created secret/linkerd-sp-validator-tls created validatingwebhookconfiguration.admissionregistration.k8s.io/linkerd-sp-validator-webhook-config created clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-tap created clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-tap-admin created clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-tap created clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-tap-auth-delegator created serviceaccount/linkerd-tap created rolebinding.rbac.authorization.k8s.io/linkerd-linkerd-tap-auth-reader created secret/linkerd-tap-tls created apiservice.apiregistration.k8s.io/v1alpha1.tap.linkerd.io created podsecuritypolicy.policy/linkerd-linkerd-control-plane created role.rbac.authorization.k8s.io/linkerd-psp created rolebinding.rbac.authorization.k8s.io/linkerd-psp created configmap/linkerd-config created secret/linkerd-identity-issuer created service/linkerd-identity created deployment.apps/linkerd-identity created service/linkerd-controller-api created service/linkerd-destination created deployment.apps/linkerd-controller created service/linkerd-dst created deployment.apps/linkerd-destination created cronjob.batch/linkerd-heartbeat created service/linkerd-web created deployment.apps/linkerd-web created configmap/linkerd-prometheus-config created service/linkerd-prometheus created deployment.apps/linkerd-prometheus created configmap/linkerd-grafana-config created service/linkerd-grafana created deployment.apps/linkerd-grafana created deployment.apps/linkerd-proxy-injector created service/linkerd-proxy-injector created service/linkerd-sp-validator created deployment.apps/linkerd-sp-validator created service/linkerd-tap created deployment.apps/linkerd-tap created
以下のコマンドで、正常にデプロイされたかを確認します。 出力は長かったので、省略します。
# linkerd check
deploymentの状態を見てみます。
# kubectl -n linkerd get deploy NAME READY UP-TO-DATE AVAILABLE AGE linkerd-controller 1/1 1 1 114s linkerd-destination 1/1 1 1 114s linkerd-grafana 1/1 1 1 114s linkerd-identity 1/1 1 1 114s linkerd-prometheus 1/1 1 1 114s linkerd-proxy-injector 1/1 1 1 113s linkerd-sp-validator 1/1 1 1 113s linkerd-tap 1/1 1 1 113s linkerd-web 1/1 1 1 114s
Step 4: Explore Linkerd
それでは、以下のコマンドでDashboardにアクセスできるようにします。
# nohup linkerd dashboard --address 127.0.0.1 -p 8000 & Linkerd dashboard available at: http://127.0.0.1:8000 Grafana dashboard available at: http://127.0.0.1:8000/grafana Opening Linkerd dashboard in the default browser Failed to open Linkerd dashboard automatically Visit http://127.0.0.1:8000 in your browser to view the dashboard
Step 5: Install the demo app
では、Linkerdの動きを見るために、デモのアプリケーションを動かしていきます。
# curl -sL https://run.linkerd.io/emojivoto.yml | kubectl apply -f - namespace/emojivoto created serviceaccount/emoji created serviceaccount/voting created serviceaccount/web created service/emoji-svc created service/voting-svc created service/web-svc created deployment.apps/emoji created deployment.apps/vote-bot created deployment.apps/voting created deployment.apps/web created # kubectl get pods -n emojivoto NAME READY STATUS RESTARTS AGE emoji-6b966565b5-nd59b 1/1 Running 0 73s vote-bot-67d8555767-2w5pp 1/1 Running 0 73s voting-675d89b7b8-w6hwb 1/1 Running 0 73s web-859cf8f695-l6pw5 1/1 Running 0 73s [root@gateway ~]# k get all -n emojivoto NAME READY STATUS RESTARTS AGE pod/emoji-6b966565b5-nd59b 1/1 Running 0 79s pod/vote-bot-67d8555767-2w5pp 1/1 Running 0 79s pod/voting-675d89b7b8-w6hwb 1/1 Running 0 79s pod/web-859cf8f695-l6pw5 1/1 Running 0 79s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/emoji-svc ClusterIP 10.100.200.127 <none> 8080/TCP 79s service/voting-svc ClusterIP 10.100.200.200 <none> 8080/TCP 79s service/web-svc LoadBalancer 10.100.200.5 <pending> 80:32716/TCP 79s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/emoji 1/1 1 1 79s deployment.apps/vote-bot 1/1 1 1 79s deployment.apps/voting 1/1 1 1 79s deployment.apps/web 1/1 1 1 79s NAME DESIRED CURRENT READY AGE replicaset.apps/emoji-6b966565b5 1 1 1 79s replicaset.apps/vote-bot-67d8555767 1 1 1 79s replicaset.apps/voting-675d89b7b8 1 1 1 79s replicaset.apps/web-859cf8f695 1 1 1 79s
では、デモアプリにアクセスしていきましょう。
http://[worker node の IP]: [LoadBalancerのport]
以下のコマンドで、このapplicationをlinkerdから監視できるようにしていきます。
# kubectl get -n emojivoto deploy -o yaml | linkerd inject - | kubectl apply -f - deployment "emoji" injected deployment "vote-bot" injected deployment "voting" injected deployment "web" injected deployment.extensions/emoji configured deployment.extensions/vote-bot configured deployment.extensions/voting configured deployment.extensions/web configured
このコマンドは、emojivoto ネームスペースで実行されているすべてのデプロイメントを取得し、linkerd inject
してから、クラスターに再適用します。
linkerd inject
はpodの中に以下のようなproxyコンテナを入れてくれます。
linkerd-proxy: Container ID: docker://f93e85b155827ffe8fdd06e2c689784ca103ba81eb5d259c82f37edb0f4c08e7 Image: gcr.io/linkerd-io/proxy:stable-2.6.0 Image ID: docker-pullable://gcr.io/linkerd-io/proxy@sha256:633b8b3434f4229b219274c7d452335e3f93300a30d01d465dd80102a7df3a50 Ports: 4143/TCP, 4191/TCP Host Ports: 0/TCP, 0/TCP State: Running Started: Sat, 07 Dec 2019 18:20:39 +0900 Ready: True Restart Count: 0 Liveness: http-get http://:4191/metrics delay=10s timeout=1s period=10s #success=1 #failure=3 Readiness: http-get http://:4191/ready delay=2s timeout=1s period=10s #success=1 #failure=3 Environment: LINKERD2_PROXY_LOG: warn,linkerd2_proxy=info LINKERD2_PROXY_DESTINATION_SVC_ADDR: linkerd-dst.linkerd.svc.cluster.local:8086 LINKERD2_PROXY_CONTROL_LISTEN_ADDR: 0.0.0.0:4190 LINKERD2_PROXY_ADMIN_LISTEN_ADDR: 0.0.0.0:4191 LINKERD2_PROXY_OUTBOUND_LISTEN_ADDR: 127.0.0.1:4140 LINKERD2_PROXY_INBOUND_LISTEN_ADDR: 0.0.0.0:4143 LINKERD2_PROXY_DESTINATION_GET_SUFFIXES: svc.cluster.local. LINKERD2_PROXY_DESTINATION_PROFILE_SUFFIXES: svc.cluster.local. LINKERD2_PROXY_INBOUND_ACCEPT_KEEPALIVE: 10000ms LINKERD2_PROXY_OUTBOUND_CONNECT_KEEPALIVE: 10000ms _pod_ns: emojivoto (v1:metadata.namespace) LINKERD2_PROXY_DESTINATION_CONTEXT: ns:$(_pod_ns) LINKERD2_PROXY_IDENTITY_DIR: /var/run/linkerd/identity/end-entity LINKERD2_PROXY_IDENTITY_TRUST_ANCHORS: -----BEGIN CERTIFICATE----- MIIBhDCCASmgAwIBAgIBATAKBggqhkjOPQQDAjApMScwJQYDVQQDEx5pZGVudGl0 eS5saW5rZXJkLmNsdXN0ZXIubG9jYWwwHhcNMTkxMjA2MDUxMTA3WhcNMjAxMjA1 MDUxMTI3WjApMScwJQYDVQQDEx5pZGVudGl0eS5saW5rZXJkLmNsdXN0ZXIubG9j YWwwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQHTUOU5YfGgDl87w3QU+e/Nag5 H3KVLk24Fp0uPSNB407gJ655kI+/W4M3f766aufGZR4UE6p6bo2TwcBxMGIHo0Iw QDAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC MA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAIfCEwHV0iBh3HBY JNchSjex3/EweFbzUBYX733GSrocAiEA4Kpl7iTGuSUARydgfXnMknVDNi1AHhv7 iUciHX8oFVw= -----END CERTIFICATE----- LINKERD2_PROXY_IDENTITY_TOKEN_FILE: /var/run/secrets/kubernetes.io/serviceaccount/token LINKERD2_PROXY_IDENTITY_SVC_ADDR: linkerd-identity.linkerd.svc.cluster.local:8080 _pod_sa: (v1:spec.serviceAccountName) _l5d_ns: linkerd _l5d_trustdomain: cluster.local LINKERD2_PROXY_IDENTITY_LOCAL_NAME: $(_pod_sa).$(_pod_ns).serviceaccount.identity.$(_l5d_ns).$(_l5d_trustdomain) LINKERD2_PROXY_IDENTITY_SVC_NAME: linkerd-identity.$(_l5d_ns).serviceaccount.identity.$(_l5d_ns).$(_l5d_trustdomain) LINKERD2_PROXY_DESTINATION_SVC_NAME: linkerd-destination.$(_l5d_ns).serviceaccount.identity.$(_l5d_ns).$(_l5d_trustdomain) LINKERD2_PROXY_TAP_SVC_NAME: linkerd-tap.$(_l5d_ns).serviceaccount.identity.$(_l5d_ns).$(_l5d_trustdomain) Mounts: /var/run/linkerd/identity/end-entity from linkerd-identity-end-entity (rw) /var/run/secrets/kubernetes.io/serviceaccount from emoji-token-whvv2 (ro)
これをすることで、DashboardのNamespace
paneでは通信の成功率や、mesh数を見ることができるようになります。
しっかり、データプレーンで機能しているのかを確認する場合は以下のコマンドを打ちます。
# linkerd -n emojivoto check --proxy kubernetes-api -------------- √ can initialize the client √ can query the Kubernetes API kubernetes-version ------------------ √ is running the minimum Kubernetes API version √ is running the minimum kubectl version linkerd-config -------------- √ control plane Namespace exists √ control plane ClusterRoles exist √ control plane ClusterRoleBindings exist √ control plane ServiceAccounts exist √ control plane CustomResourceDefinitions exist √ control plane MutatingWebhookConfigurations exist √ control plane ValidatingWebhookConfigurations exist √ control plane PodSecurityPolicies exist linkerd-existence ----------------- √ 'linkerd-config' config map exists √ heartbeat ServiceAccount exist √ control plane replica sets are ready √ no unschedulable pods √ controller pod is running √ can initialize the client √ can query the control plane API linkerd-api ----------- √ control plane pods are ready √ control plane self-check √ [kubernetes] control plane can talk to Kubernetes √ [prometheus] control plane can talk to Prometheus √ no invalid service profiles linkerd-version --------------- √ can determine the latest version √ cli is up-to-date linkerd-data-plane ------------------ √ data plane namespace exists √ data plane proxies are ready √ data plane proxy metrics are present in Prometheus √ data plane is up-to-date √ data plane and cli versions match Status check results are √
Step 6: Watch it run
GUI上に行きます。
Namespace
paneから、emojivotoを選択してみます。
各サービスの結びつきや、詳細情報を見ることができます。
Deploymentにある各componentを押すことで、個々の詳細な関係も見ることができます。
終わりに
とてもとっつきやすいservice meshツールなのではないかなと触っていて感じました。
この記事がLinkerdの最初のとっかかりの助けになればと思います。
読んでいただき、ありがとうございました。