Skip to content

Linkerd アーキテクチャ

対応バージョン: Linkerd 2.16+ 最終更新: February 22, 2026

概要

Linkerd は、control plane(制御プレーン)と data plane(データプレーン)で構成される service mesh アーキテクチャに従います。このドキュメントでは、各コンポーネントの役割、それらの相互作用、証明書階層、および proxy のライフサイクルについて詳しく説明します。

全体アーキテクチャ

Control Plane

control plane は linkerd namespace にデプロイされ、data plane proxy を設定および管理するコンポーネントで構成されます。

Destination Controller

Destination controller は、service discovery と policy 配布を担う中核コンポーネントです。

主な機能:

機能説明
Service DiscoveryKubernetes Service と Endpoint を監視し、リアルタイムの更新を proxy に提供します
Policy DistributionServiceProfile や TrafficSplit などの policy を proxy に配信します
Load Balancing InfoEWMA ベースの load balancing 用の Endpoint 重み情報
Service Profilesルートごとの retry、timeout、および metrics 設定

Destination API の動作:

go
// Destination API sends updates to proxies via gRPC streaming
// Proxy requests information about target service
service Destination {
    // Get returns update stream for a specific destination
    rpc Get(GetDestination) returns (stream Update);

    // GetProfile returns service profile update stream
    rpc GetProfile(GetDestination) returns (stream DestinationProfile);
}

Identity Controller

Identity controller は mTLS の証明書発行と管理を処理します。

証明書発行プロセス:

  1. Proxy は起動時に CSR(Certificate Signing Request)を生成します
  2. Identity controller は Pod の ServiceAccount を検証します
  3. Trust Anchor(Root CA)で証明書に署名します
  4. workload 証明書を proxy に配信します
  5. デフォルトの有効期間は 24 時間で、自動的に更新されます

Identity 設定:

yaml
# Identity settings in linkerd-config ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: linkerd-config
  namespace: linkerd
data:
  values: |
    identity:
      issuer:
        # Certificate issuance lifetime (default 24 hours)
        issuanceLifetime: 24h0m0s
        # Clock skew allowance
        clockSkewAllowance: 20s
        # Issuer scheme (kubernetes.io/tls)
        scheme: kubernetes.io/tls

Proxy Injector

Proxy Injector は Kubernetes Admission Webhook として動作し、Pod に sidecar を自動的に inject します。

Injection 条件:

yaml
# Namespace-level injection enablement
apiVersion: v1
kind: Namespace
metadata:
  name: my-app
  annotations:
    linkerd.io/inject: enabled

---
# Pod-level injection control
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  annotations:
    # Enable injection
    linkerd.io/inject: enabled
    # Or disable
    # linkerd.io/inject: disabled

Inject されるコンポーネント:

コンポーネント役割
linkerd-initInit container、iptables ルールを設定
linkerd-proxySidecar container、トラフィック proxy
VolumesIdentity token、設定
Environment VariablesProxy 設定、destination address

Policy Controller

Policy Controller は Linkerd の authorization policy を管理します。

yaml
# Server resource - defines inbound traffic
apiVersion: policy.linkerd.io/v1beta2
kind: Server
metadata:
  name: web-http
  namespace: my-app
spec:
  podSelector:
    matchLabels:
      app: web
  port: http
  proxyProtocol: HTTP/1

---
# ServerAuthorization - defines access permissions
apiVersion: policy.linkerd.io/v1beta2
kind: ServerAuthorization
metadata:
  name: web-authz
  namespace: my-app
spec:
  server:
    name: web-http
  client:
    meshTLS:
      serviceAccounts:
        - name: api-gateway
          namespace: my-app

Data Plane

Data Plane は、application Pod に inject される linkerd-proxy sidecar で構成されます。

linkerd2-proxy

Linkerd の data plane proxy は、Rust で記述された非常に軽量な micro-proxy です。

Proxy の特性:

特性
言語Rust
Memory 使用量~10MB
CPU overhead最小限
Latency overhead<1ms p99
ProtocolHTTP/1.1, HTTP/2, gRPC, TCP
TLSTLS 1.3 (rustls)

Istio Envoy との比較:

特性linkerd2-proxyEnvoy (Istio)
言語RustC++
Memory~10MB~50-100MB
Binary サイズ~10MB~60MB
Latency<1ms p992-5ms p99
Config の複雑さ低い(自動)高い(xDS)
拡張性制限ありWasm, Lua
Protocol サポートHTTP, gRPC, TCP非常に広範囲

Proxy のトラフィックフロー

linkerd-init(Init Container)

linkerd-init は、トラフィックを proxy に redirect する iptables ルールを設定します。

bash
# Example iptables rules set by linkerd-init
# Redirect outbound traffic (to port 4140)
iptables -t nat -A OUTPUT -p tcp -j REDIRECT --to-port 4140

# Redirect inbound traffic (to port 4143)
iptables -t nat -A PREROUTING -p tcp -j REDIRECT --to-port 4143

# Exclude proxy's own traffic
iptables -t nat -A OUTPUT -m owner --uid-owner 2102 -j RETURN

Inject された Pod 構造:

yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-app
  annotations:
    linkerd.io/inject: enabled
spec:
  initContainers:
  - name: linkerd-init
    image: cr.l5d.io/linkerd/proxy-init:v2.3.0
    args:
    - --incoming-proxy-port=4143
    - --outgoing-proxy-port=4140
    - --proxy-uid=2102
    securityContext:
      capabilities:
        add:
        - NET_ADMIN
        - NET_RAW

  containers:
  - name: my-app
    image: my-app:latest

  - name: linkerd-proxy
    image: cr.l5d.io/linkerd/proxy:stable-2.16.0
    ports:
    - containerPort: 4143  # Inbound
      name: linkerd-proxy
    - containerPort: 4191  # Admin/Metrics
      name: linkerd-admin
    env:
    - name: LINKERD2_PROXY_LOG
      value: warn,linkerd=info
    - name: LINKERD2_PROXY_DESTINATION_SVC_ADDR
      value: linkerd-dst.linkerd.svc.cluster.local:8086
    - name: LINKERD2_PROXY_IDENTITY_SVC_ADDR
      value: linkerd-identity.linkerd.svc.cluster.local:8080
    resources:
      requests:
        cpu: 100m
        memory: 64Mi
      limits:
        cpu: 1000m
        memory: 250Mi
    readinessProbe:
      httpGet:
        path: /ready
        port: 4191
    livenessProbe:
      httpGet:
        path: /live
        port: 4191

証明書階層

Linkerd は、階層型 PKI(Public Key Infrastructure)を使用して mTLS を実装します。

証明書階層構造

Trust Anchor(Root CA)

Trust Anchor は PKI の root であり、すべての証明書 chain における信頼の基盤です。

bash
# Create Trust Anchor (using step CLI)
step certificate create root.linkerd.cluster.local ca.crt ca.key \
  --profile root-ca \
  --no-password \
  --insecure \
  --not-after=87600h  # 10 years

# Verify Trust Anchor
openssl x509 -in ca.crt -text -noout

# Example output:
# Certificate:
#     Data:
#         Version: 3 (0x2)
#         Serial Number: ...
#         Signature Algorithm: ecdsa-with-SHA256
#         Issuer: CN = root.linkerd.cluster.local
#         Validity
#             Not Before: Feb 21 00:00:00 2026 GMT
#             Not After : Feb 21 00:00:00 2036 GMT
#         Subject: CN = root.linkerd.cluster.local
#         ...
#         X509v3 extensions:
#             X509v3 Key Usage: critical
#                 Certificate Sign, CRL Sign
#             X509v3 Basic Constraints: critical
#                 CA:TRUE

Trust Anchor の保存先:

yaml
# Stored as Kubernetes Secret
apiVersion: v1
kind: Secret
metadata:
  name: linkerd-identity-trust-roots
  namespace: linkerd
type: Opaque
data:
  ca-bundle.crt: <base64-encoded-ca.crt>

Identity Issuer(Intermediate CA)

Identity Issuer は workload 証明書を発行する intermediate CA です。

bash
# Create Identity Issuer certificate
step certificate create identity.linkerd.cluster.local issuer.crt issuer.key \
  --profile intermediate-ca \
  --ca ca.crt \
  --ca-key ca.key \
  --no-password \
  --insecure \
  --not-after=8760h  # 1 year

# Verify Issuer certificate
openssl x509 -in issuer.crt -text -noout

Identity Issuer Secret:

yaml
apiVersion: v1
kind: Secret
metadata:
  name: linkerd-identity-issuer
  namespace: linkerd
type: kubernetes.io/tls
data:
  tls.crt: <base64-encoded-issuer.crt>
  tls.key: <base64-encoded-issuer.key>
  ca.crt: <base64-encoded-ca.crt>

Workload 証明書

各 proxy は一意の workload 証明書を受け取ります。

SPIFFE ID 形式:

spiffe://root.linkerd.cluster.local/ns/<namespace>/sa/<service-account>

# Example:
spiffe://root.linkerd.cluster.local/ns/my-app/sa/web-service

証明書ローテーション

yaml
# Certificate lifetime configuration
identity:
  issuer:
    # Workload certificate lifetime (default 24 hours)
    issuanceLifetime: 24h0m0s
    # Clock skew allowance (default 20 seconds)
    clockSkewAllowance: 20s

# Proxy automatically renews certificates before expiration
# By default, renewal starts at 70% of certificate lifetime

Trust Anchor のローテーション:

bash
# Create new Trust Anchor
step certificate create root.linkerd.cluster.local ca-new.crt ca-new.key \
  --profile root-ca \
  --no-password \
  --insecure \
  --not-after=87600h

# Create bundle (existing + new)
cat ca.crt ca-new.crt > ca-bundle.crt

# Update ConfigMap
kubectl create configmap linkerd-identity-trust-roots \
  --from-file=ca-bundle.crt=ca-bundle.crt \
  -n linkerd \
  --dry-run=client -o yaml | kubectl apply -f -

# Then restart all proxies to apply new bundle
kubectl rollout restart deploy -n my-app

Sidecar Injection の詳細

Injection ワークフロー

Injection annotation

yaml
# Namespace level
metadata:
  annotations:
    linkerd.io/inject: enabled  # Inject into all Pods

# Pod/Deployment level
metadata:
  annotations:
    # Enable/disable injection
    linkerd.io/inject: enabled|disabled

    # Proxy configuration overrides
    config.linkerd.io/proxy-cpu-request: "100m"
    config.linkerd.io/proxy-memory-request: "64Mi"
    config.linkerd.io/proxy-cpu-limit: "1"
    config.linkerd.io/proxy-memory-limit: "250Mi"

    # Proxy log level
    config.linkerd.io/proxy-log-level: "warn,linkerd=info"

    # Skip ports (bypass proxy)
    config.linkerd.io/skip-inbound-ports: "25,587"
    config.linkerd.io/skip-outbound-ports: "25,587"

    # Opaque ports (bypass protocol detection)
    config.linkerd.io/opaque-ports: "3306,5432"

Proxy Readiness/Liveness

yaml
# Proxy health check endpoints
livenessProbe:
  httpGet:
    path: /live
    port: 4191
  initialDelaySeconds: 10
  periodSeconds: 10

readinessProbe:
  httpGet:
    path: /ready
    port: 4191
  initialDelaySeconds: 2
  periodSeconds: 10

コンポーネント間通信

Port の一覧:

コンポーネントPortProtocol用途
Destination8086gRPCService discovery API
Identity8080gRPC証明書発行 API
Policy8090gRPCPolicy API
Proxy Injector8443HTTPSAdmission Webhook
Proxy (Inbound)4143HTTP/gRPCInbound トラフィック
Proxy (Outbound)4140HTTP/gRPCOutbound トラフィック
Proxy (Admin)4191HTTPMetrics、health check

Istio アーキテクチャとの比較

Control Plane の比較

特性LinkerdIstio
Control Plane分散型(3 コンポーネント)統合型(istiod)
Proxylinkerd2-proxy(Rust)Envoy(C++)
Config ProtocolCustom gRPCxDS(複雑)
CRD 数~10~50+
学習曲線緩やか急峻
リソース使用量低い高い
拡張性制限ありWasm, Lua

Proxy の比較

yaml
# Linkerd Proxy Resources (typical)
resources:
  requests:
    cpu: 100m
    memory: 64Mi
  limits:
    cpu: 1000m
    memory: 250Mi

# Envoy Proxy Resources (typical)
resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 2000m
    memory: 1Gi

次のステップ

参考資料