Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Bootes - Envoy Control Plane Kubernetes Control...
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Yuki Ito
June 20, 2020
Technology
1.1k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Bootes - Envoy Control Plane Kubernetes Controller -
Yuki Ito
June 20, 2020
More Decks by Yuki Ito
See All by Yuki Ito
newmo の創業を支える Software Architecture と Platform Engineering
110y
5
3.8k
Modular Monolith Go Server with GraphQL Federation + gRPC
110y
1
1.2k
Modular Monolith + Go @ newmo
110y
1
1.3k
Go + GraphQL @ newmo
110y
3
1k
Architect / Platform Team at KAUCHE
110y
1
740
Cloud Run + Observability / Reliability @ KAUCHE
110y
0
710
Cloud Run CI/CD + QA @ KAUCHE
110y
1
700
Microservices on Cloud Run @ KAUCHE
110y
0
350
KAUCHE Loves Go
110y
0
560
Other Decks in Technology
See All in Technology
デザインレビューは自動化できるのか?─ Flutter × Figma で UI 品質保証を考える
techiro
0
150
AIコーディングエージェント開発_全体像
happysamurai294
0
110
200人の配信コメント、 全部Jevが仕分けます 〜 マサカリガードを作ってみた 〜
katayamatg
1
340
Draft AIエージェントの トークン消費を最小化する 8つの原則
kinopeee
6
1.8k
Agent 活用環境の構築・運用のための AWS サービスのご紹介/agentcore-for-building-and-operating-agents
ren8k
1
210
Filter What the LLM Reads: RAG Governance with AgentCore Gateway
yakumo
1
110
AIをリアル世界に解き放つ 〜M5Stack×AIであなたのアイディアを手の平に〜
hamadakoji
1
570
Claude for Google Workspaces ポン出し/claude-for-google-workspace-slide-conversion
emiki
0
13k
渡米前の準備を制す!re:Invent 2026徹底準備術 / The Ultimate Preparation Guide for re:Invent 2026
yuj1osm
1
330
Patterns in AI Driven Software Development
akosma
PRO
0
200
生成AI時代、PMは事業責任者に進化するともっと面白い〜PMだからこそ事業構造を動かせる時代に〜
kakehashi
PRO
1
920
キヨさん、67歳。AIコーディングエージェントに挑む
happysamurai294
0
110
Featured
See All Featured
Darren the Foodie - Storyboard
khoart
PRO
4
4k
Git: the NoSQL Database
bkeepers
PRO
433
67k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
430
Visualization
eitanlees
153
17k
Designing Experiences People Love
moore
143
24k
Color Theory Basics | Prateek | Gurzu
gurzu
1
500
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
330
My Coaching Mixtape
mlcsv
0
370
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.7k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
Balancing Empowerment & Direction
lara
6
1.3k
Building the Perfect Custom Keyboard
takai
2
920
Transcript
Bootes - Envoy Control Plane Kubernetes Controller - Envoy Meetup
Tokyo #2 Yuki Ito
Merpay Architect Team Backend Engineer Yuki Ito
Agenda •What is Bootes? •Implementation •Use Case
Agenda •What is Bootes? •Implementation •Use Case
Bootes https://github.com/110y/bootes
Bootes Envoy Control Plane implemented as a... Kubernetes Custom Controller
Bootes: Overview Bootes Config Config Config
Bootes: Overview Bootes Config Config Config kube-apiserver ! kubectl
Motivation •Simple Control Plane •Full Envoy features •Kubernetes Custom Resource
Movement
e.g. Service Mesh Interface kind: TrafficSplit metadata: name: canary spec:
service: website backends: - service: website-v1 weight: 90 - service: website-v2 weight: 10
e.g. Crossplane apiVersion: database.gcp.crossplane.io/v1beta1 kind: CloudSQLInstance metadata: name: cloudsqlpostgresql spec:
forProvider: databaseVersion: POSTGRES_9_6 region: us-central1 settings: tier: db-custom-1-3840 dataDiskType: PD_SSD dataDiskSizeGb: 10
Agenda •What is Bootes? •Implementation •Use Case
Agenda •What is Bootes? •Implementation •Use Case
Implementation Envoy Control Plane Kubernetes Custom Controller " How Bootes
works
Implementation Envoy Control Plane Kubernetes Custom Controller " How Bootes
works
Envoy Control Plane Control Plane Config Config Config xDS API
Envoy Configurations •Listener •Route •Cluster •Endpoint
Envoy Configurations Listener Route Cluster Endpoint Endpoint Endpoint Endpoint Cluster
Envoy Configurations 0.0.0.0:5000 Listener Route Service-1 Cluster 10.28.1.11 10.28.1.12 10.28.1.13
10.28.1.14 Service-2 Cluster Path: /service-1 Path: /service-2
Static Configurations static_resources: listeners: - address: socket_address: protocol: TCP address:
0.0.0.0 port_value: 5000 #... clusters: - name: service-1 connect_timeout: 1s type: STRICT_DNS lb_policy: ROUND_ROBIN #... envoy.yaml
Static Configurations > envoy -c envoy.yaml
Problem of Static Configurations Though simplistic, fairly complicated deployments can
be created using static configurations and graceful hot restarts. https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/operations/dynamic_configuration
Dynamic Configurations Control Plane Route Listener Cluster xDS API
x Discovery Service API •Listener Discovery Service •Route Discovery Service
•Cluster Discovery Service •Endpoint Discovery Service
x Discovery Service API •Listener Discovery Service •Route Discovery Service
•Cluster Discovery Service •Endpoint Discovery Service
x Discovery Service API Control Plane Listener Listener Listener Listener
Discovery Service
x Discovery Service API Control Plane Cluster Cluster Cluster Cluster
Discovery Service
e.g. Cluster Discovery Service service ClusterDiscoveryService { rpc StreamClusters(stream discovery.v3.DiscoveryRequest)
returns (stream discovery.v3.DiscoveryResponse) { } rpc DeltaClusters(stream discovery.v3.DeltaDiscoveryRequest) returns (stream discovery.v3.DeltaDiscoveryResponse) { } rpc FetchClusters(discovery.v3.DiscoveryRequest) returns (discovery.v3.DiscoveryResponse) { } } https://github.com/envoyproxy/envoy/blob/master/api/envoy/service/cluster/v3/cds.proto cds.proto
x Discovery Service API •Listener Discovery Service •Route Discovery Service
•Cluster Discovery Service •Endpoint Discovery Service
Dynamic Configurations dynamic_resources: lds_config: api_config_source: api_type: GRPC grpc_services: - envoy_grpc:
cluster_name: lds-server cds_config: #... envoy.yaml
Dynamic Configurations dynamic_resources: lds_config: api_config_source: api_type: GRPC grpc_services: - envoy_grpc:
cluster_name: lds-server cds_config: #... envoy.yaml
Dynamic Configurations envoy.yaml static_resources: clusters: - name: lds-server connect_timeout: 1s
type: STRICT_DNS http2_protocol_options: {} load_assignment: cluster_name: lds-server endpoints: - lb_endpoints: - endpoint: address: socket_address: address: ... port_value: ...
Dynamic Configurations dynamic_resources: lds_config: api_config_source: api_type: gRPC grpc_services: - envoy_grpc:
cluster_name: lds-server cds_config: #... static_resources: clusters: - name: lds-server connect_timeout: 1s type: LOGICAL_DNS http2_protocol_options: {} load_assignment: cluster_name: lds-server endpoints: - lb_endpoints: - endpoint: address: socket_address: address: ... port_value: ... envoy.yaml
x Discovery Service API Control Plane Route Listener CDS LDS
RDS CDS
Problem of xDS API 0.0.0.0:5000 Listener Route Service-1 Cluster 10.28.1.11
10.28.1.12
Problem of xDS API 0.0.0.0:5000 Listener Route Service-1 Cluster 10.28.1.11
10.28.1.12 10.28.1.13 10.28.1.14 Service-2 Cluster
Problem of xDS API 0.0.0.0:5000 Listener Route Service-1 Cluster 10.28.1.11
10.28.1.12 10.28.1.13 10.28.1.14 Service-2 Cluster RDS CDS
Problem of xDS API 0.0.0.0:5000 Listener Route Service-1 Cluster 10.28.1.11
10.28.1.12 ❌ RDS
Problem of xDS API 0.0.0.0:5000 Listener Route Service-1 Cluster 10.28.1.11
10.28.1.12 10.28.1.13 10.28.1.14 Service-2 Cluster CDS
Problem of xDS API 0.0.0.0:5000 Listener Route Service-1 Cluster 10.28.1.11
10.28.1.12 10.28.1.13 10.28.1.14 Service-2 Cluster CDS RDS
Problem of xDS API To avoid downtime... 1. Cluster 2.
Endpoint 3. Listener 4. Route
Problem of xDS API Control Plane Route Listener CDS LDS
RDS CDS
Aggregated Discovery Service Control Plane Listener / Route / Cluster
/ Endpoint Aggregated Discovery Service
Aggregated Discovery Service service AggregatedDiscoveryService { rpc StreamAggregatedResources(stream DiscoveryRequest) returns
(stream DiscoveryResponse) { } rpc DeltaAggregatedResources(stream DeltaDiscoveryRequest) returns (stream DeltaDiscoveryResponse) { } } ads.proto https://github.com/envoyproxy/envoy/blob/master/api/envoy/service/discovery/v3/ads.proto
Aggregated Discovery Service dynamic_resources: cds_config: ads: {} lds_config: ads: {}
ads_config: api_type: GRPC grpc_services: - envoy_grpc: cluster_name: ads-server envoy.yaml
Aggregated Discovery Service dynamic_resources: cds_config: ads: {} lds_config: ads: {}
ads_config: api_type: GRPC grpc_services: - envoy_grpc: cluster_name: ads-server envoy.yaml
Aggregated Discovery Service Control Plane Listener / Route / Cluster
/ Endpoint Aggregated Discovery Service
Bootes uses ADS Bootes Route Listener Cluster kube-apiserver Aggregated Discovery
Service
go-control-plane envoyproxy/go-control-plane
go-control-plane import ( cache ".../go-control-plane/pkg/cache/v3" server ".../go-control-plane/pkg/server/v3" discovery ".../go-control-plane/envoy/service/discovery/v3" "google.golang.org/grpc"
) // ... snapshotCache := cache.NewSnapshotCache(...) server := server.NewServer(ctx, snapshotCache, ...) grpcServer := grpc.NewServer() lis, _ := net.Listen("tcp", ":8081") discovery.RegisterAggregatedDiscoveryServiceServer(grpcServer, server) grpcServer.Serve(lis) Minimum Implementation
go-control-plane import ( cache ".../go-control-plane/pkg/cache/v3" server ".../go-control-plane/pkg/server/v3" discovery ".../go-control-plane/envoy/service/discovery/v3" "google.golang.org/grpc"
) // ... snapshotCache := cache.NewSnapshotCache(...) server := server.NewServer(ctx, snapshotCache, ...) grpcServer := grpc.NewServer() lis, _ := net.Listen("tcp", ":8081") discovery.RegisterAggregatedDiscoveryServiceServer(grpcServer, server) grpcServer.Serve(lis) Minimum Implementation
go-control-plane Package "go-control-plane/envoy" envoy/config/cluster/v3/ ├── circuit_breaker.pb.go ├── circuit_breaker.pb.validate.go ├── cluster.pb.go
├── cluster.pb.validate.go ├── filter.pb.go ├── filter.pb.validate.go ├── outlier_detection.pb.go └── outlier_detection.pb.validate.go Go files generated from .proto
go-control-plane import ( cache ".../go-control-plane/pkg/cache/v3" server ".../go-control-plane/pkg/server/v3" discovery ".../go-control-plane/envoy/service/discovery/v3" "google.golang.org/grpc"
) // ... snapshotCache := cache.NewSnapshotCache(...) server := server.NewServer(ctx, snapshotCache, ...) grpcServer := grpc.NewServer() lis, _ := net.Listen("tcp", ":8081") discovery.RegisterAggregatedDiscoveryServiceServer(grpcServer, server) grpcServer.Serve(lis) Minimum Implementation
go-control-plane Package "go-control-plane/pkg/server" Server Implementation import ( server ".../go-control-plane/pkg/server/v3" discovery
".../go-control-plane/envoy/service/discovery/v3" "google.golang.org/grpc" // ... ) // ... server := server.NewServer(ctx, snapshotCache, ...) grpcServer := grpc.NewServer() discovery.RegisterAggregatedDiscoveryServiceServer(grpcServer, server) grpcServer.Serve(lis)
go-control-plane import ( cache ".../go-control-plane/pkg/cache/v3" server ".../go-control-plane/pkg/server/v3" discovery ".../go-control-plane/envoy/service/discovery/v3" "google.golang.org/grpc"
) // ... snapshotCache := cache.NewSnapshotCache(...) server := server.NewServer(ctx, snapshotCache, ...) grpcServer := grpc.NewServer() lis, _ := net.Listen("tcp", ":8081") discovery.RegisterAggregatedDiscoveryServiceServer(grpcServer, server) grpcServer.Serve(lis) Minimum Implementation
go-control-plane Package "go-control-plane/pkg/cache" { "envoy-1": { "clusters": [ "service-1": {...},
"service-2": {...} ], "listeners": [...], "routes": [...], "endpoints": [...], }, "envoy-2": {...}, ... } Configurations Cache for each Envoys
go-control-plane Package "go-control-plane/pkg/cache" snapshot := cache.NewSnapshot( "version-xxx", endpoints, clusters, routes,
listeners, //... ) snapshotCache.SetSnapshot("envoy-1", snapshot)
go-control-plane Config Config Config Cache (pkg/cache) Aggregated Discovery Service gRPC
Server (pkg/server) Update (cache.SetSnapshot)
go-control-plane Config Config Config Cache (pkg/cache) Aggregated Discovery Service gRPC
Server (pkg/server) Update (cache.SetSnapshot)
Implementation Envoy Control Plane Kubernetes Custom Controller " How Bootes
works
Implementation Envoy Control Plane Kubernetes Custom Controller " How Bootes
works
Kubernetes Custom Controller Bootes Config Config Config kube-apiserver Aggregated Discovery
Service ! kubectl apply -f cluster.yaml
Custom Resource Definition (CRD) ɾPod ɾReplicaSet ɾDeployment ɾService ɾIngress ɾHorizontalPodAutoscaler
ɾPodDisruptionBudget ... e.g. Istio ɾVirtualService ... e.g. SMI ɾTrafficSplit ... e.g. CrossPlane ɾCloudSQLInstance ... Native Resources Custom Resources + Extends Kubernetes using CRD
Bootes uses CRD ɾPod ɾReplicaSet ɾDeployment ɾService ɾIngress ɾHorizontalPodAutoscaler ɾPodDisruptionBudget
... ɾListener ɾRoute ɾCluster ɾEndpoint Native Resources Custom Resources + Extends Kubernetes using CRD
Bootes uses CRD cluster.yaml apiVersion: bootes.io/v1 kind: Cluster metadata: name:
example-cluster namespace: foo spec: config: name: example-cluster connect_timeout: 1s type: EDS lb_policy: ROUND_ROBIN http2_protocol_options: {} eds_cluster_config: eds_config: ads: {}
Bootes uses CRD cluster.yaml apiVersion: bootes.io/v1 kind: Cluster metadata: name:
example-cluster namespace: foo spec: config: name: example-cluster connect_timeout: 1s type: EDS lb_policy: ROUND_ROBIN http2_protocol_options: {} eds_cluster_config: eds_config: ads: {}
Bootes uses CRD cluster.yaml apiVersion: bootes.io/v1 kind: Cluster metadata: name:
example-cluster namespace: foo spec: config: name: example-cluster connect_timeout: 1s type: EDS lb_policy: ROUND_ROBIN http2_protocol_options: {} eds_cluster_config: eds_config: ads: {}
Bootes uses CRD cluster.yaml Any Envoy Cluster Config apiVersion: bootes.io/v1
kind: Cluster metadata: name: example-cluster namespace: foo spec: config: name: example-cluster connect_timeout: 1s type: EDS lb_policy: ROUND_ROBIN http2_protocol_options: {} eds_cluster_config: eds_config: ads: {}
Kubernetes Custom Controller Bootes Config Config Config kube-apiserver Aggregated Discovery
Service ! kubectl apply -f cluster.yaml
Kubernetes Custom Controller We can use any Kubernetes Ecosystem Tools
$
e.g. kustomize kustomize base-cluster.yaml dev-cluster.yaml prod-cluster.yaml
e.g. kpt ! awesome-cluster.yaml kpt pkg get ... !
Implementation Envoy Control Plane Kubernetes Custom Controller " How Bootes
works
Implementation Envoy Control Plane Kubernetes Custom Controller " How Bootes
works
How Bootes Works Bootes kube-apiserver ! kubectl apply -f example-cluster.yaml
Aggregated Discovery Service
How Bootes Works ! kubectl apply -f example-cluster.yaml
How Bootes Works apiVersion: bootes.io/v1 kind: Cluster metadata: name: example-cluster
namespace: a spec: workloadSelector: labels: app: foo config: # ... example-cluster.yaml
How Bootes Works apiVersion: bootes.io/v1 kind: Cluster metadata: name: example-cluster
namespace: a spec: workloadSelector: labels: app: foo config: # ... example-cluster.yaml
How Bootes Works example-cluster.yaml config: name: example-cluster connect_timeout: 1s type:
EDS lb_policy: ROUND_ROBIN http2_protocol_options: {} eds_cluster_config: eds_config: ads: {} # ...
How Bootes Works Bootes kube-apiserver ! kubectl apply -f example-cluster.yaml
JSON
How Bootes Works proto := &cluster.Cluster{} (&protojson.UnmarshalOptions{}).Unmarshal(json, proto) JSON (Proto)
google.golang.org/protobuf/encoding/protojson
How Bootes Works Bootes kube-apiserver ! kubectl apply -f example-cluster.yaml
JSON Aggregated Discovery Service
How Bootes Works Bootes Namespace: a Namespace: b app: foo
app: bar app: foo app: bar app: foo app: bar Namespace: c Looking up target Envoy (Pod)
How Bootes Works apiVersion: bootes.io/v1 kind: Cluster metadata: name: example-cluster
namespace: a spec: workloadSelector: labels: app: foo config: # ... example-cluster.yaml
How Bootes Works Bootes Namespace: a Namespace: b app: foo
app: bar app: foo app: bar app: foo app: bar Namespace: c Looking up target Envoy (Pod)
How Bootes Works apiVersion: bootes.io/v1 kind: Cluster metadata: name: example-cluster
namespace: a spec: workloadSelector: labels: app: foo config: # ... example-cluster.yaml
How Bootes Works Bootes Namespace: a Namespace: b app: foo
app: bar app: foo app: bar app: foo app: bar Namespace: c Looking up target Envoy (Pod)
How Bootes Works Bootes Namespace: a app: foo pod-xxx-333 app:
foo pod-xxx-222 app: foo pod-xxx-111
How Bootes Works Bootes kube-apiserver ! kubectl apply -f example-cluster.yaml
JSON Aggregated Discovery Service
Agenda •What is Bootes? •Implementation •Use Case
Agenda •What is Bootes? •Implementation •Use Case
Envoy Reverse Proxy Use case Pod microservice B Service Pod
Service Pod Service Pod microservice A !
Envoy Reverse Proxy Use case Pod microservice B Service Pod
Service Pod Service Pod microservice A ! CDS CDS CDS LDS RDS RDS RDS
Custom HTTP Filter { "microservice-A": "PR-1", "microservice-B": "PR-2" } microservice-A:
PR-1 microservice-B: PR-2 Request from APP Request to Upstream JWT Payload HTTP Header ɾɾɾ ɾɾɾ
Envoy Reverse Proxy Use case Pod microservice B Service Pod
Service Pod Service Pod microservice A ! CDS CDS CDS LDS RDS RDS RDS
Agenda •What is Bootes? •Implementation •Use Case