xds

package module
v1.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 25, 2024 License: Apache-2.0 Imports: 46 Imported by: 0

README

example-envoy-xds

Apache License GoDoc Go Report Card Releases

example-envoy-xds is an example of implementation of envoy and control-plane using v3 xDS API.

Features:

  • xDS (EDS/CDS/LDS/RDS/ALS)
  • Dynamic update of yaml files (using fsnotify)
  • Access log storage using ALS
  • Configuration examples of various settings
  • Configuration of Weighted Round Robin LoadBalancer

Bootstrapping

As bootstrap, in envoy/envoy.yaml, specify example-envoy-xds in xds_cluster and als_cluster
This will allow xDS communication with grpc.

For general use, envoy.yaml is used as a template file and replaced by sed in docker-entrypoint.sh.

node:
  cluster: @ENVOY_XDS_CLUSTER@
  id: @ENVOY_XDS_NODE_ID@
  locality:
    region: @ENVOY_XDS_LOCALITY_REGION@
    zone: @ENVOY_XDS_LOCALITY_ZONE@

admin:
  access_log_path: /dev/null
  address:
    socket_address: { protocol: TCP, address: @ENVOY_ADMIN_LISTEN_HOST@, port_value: @ENVOY_ADMIN_LISTEN_PORT@ }

dynamic_resources:
  lds_config:
    resource_api_version: V3
    api_config_source:
      api_type: GRPC
      transport_api_version: V3
      grpc_services:
      - envoy_grpc: { cluster_name: xds_cluster }
      set_node_on_first_message_only: true
  cds_config:
    resource_api_version: V3
    api_config_source:
      api_type: GRPC
      transport_api_version: V3
      grpc_services:
      - envoy_grpc: { cluster_name: xds_cluster }
      set_node_on_first_message_only: true

static_resources:
  clusters:
  - name: xds_cluster
    connect_timeout: 1s
    type: STATIC
    lb_policy: ROUND_ROBIN
    http2_protocol_options: {}
    load_assignment:
      cluster_name: xds_cluster
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address: { protocol: TCP, address: @ENVOY_XDS_HOST@, port_value: @ENVOY_XDS_PORT@ }
  - name: als_cluster
    connect_timeout: 1s
    type: STATIC
    lb_policy: ROUND_ROBIN
    http2_protocol_options: {}
    upstream_connection_options:
      tcp_keepalive: {}
    load_assignment:
      cluster_name: als_cluster
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address: { protocol: TCP, address: @ENVOY_ALS_HOST@, port_value: @ENVOY_ALS_PORT@ }

layered_runtime:
  layers:
    - name: runtime0
      rtds_layer:
        rtds_config:
          resource_api_version: V3
          api_config_source:
            transport_api_version: V3
            api_type: GRPC
            grpc_services:
              envoy_grpc:
                cluster_name: xds_cluster
        name: runtime0

When you start envoy with docker, you can specify IP and port of example-envoy-xds with environment variables.

$ docker run --net=host                          \
  -e ENVOY_XDS_CLUSTER=example0                  \
  -e ENVOY_XDS_NODE_ID=envoy-node1               \
  -e ENVOY_XDS_HOST=10.10.0.101                  \
  -e ENVOY_XDS_PORT=5000                         \
  -e ENVOY_XDS_LOCALITY_REGION=asia-northeast1   \
  -e ENVOY_XDS_LOCALITY_ZONE=asia-northeast1-a   \
  -e ENVOY_ALS_HOST=10.10.0.101                  \
  -e ENVOY_ALS_PORT=5001                         \
  docker.pkg.github.com/octu0/example-envoy-xds/envoy:1.21.6

Configure xDS with grpc, example-envoy-xds will be started so that envoy can communicate with it.
At this time, node.id of envoy (specified by ENVOY_XDS_NODE_ID) must be the same value,
otherwise the Snapshot will not be changed.

$ docker run --net=host           \
  -e XDS_NODE_ID=envoy-node1      \
  -e XDS_LISTEN_ADDR=0.0.0.0:5000 \
  -e ALS_LISTEN_ADDR=0.0.0.0:5001 \
  -e CDS_YAML=/app/vol/cds.yaml   \
  -e EDS_YAML=/app/vol/eds.yaml   \
  -e RDS_YAML=/app/vol/rds.yaml   \
  -e LDS_YAML=/app/vol/lds.yaml   \
  -v $(pwd):/app/vol              \
  docker.pkg.github.com/octu0/example-envoy-xds/example-envoy-xds:1.0.3 server

Edit eds.yaml in current directory to make sure EDS are updated.

Execution example

Using docker-compose to check the behavior.

$ docker-compose up -d

and curl it.

$ curl -H 'Host:example.com' localhost:8080
legacy node-003

$ curl -H 'Host:example.com' localhost:8080
new node-102

License

Apache 2.0, see LICENSE file for details.

Documentation

Index

Constants

View Source
const (
	AccesslogLinefeed  string = "\n"
	AccesslogDelimiter string = "\t"
)
View Source
const (
	AppName string = "example-envoy-xds"
	Version string = "1.0.4"
	UA      string = AppName + "/" + Version
)
View Source
const (
	BootstrapXdsClusterName string        = "xds_cluster"
	BootstrapAlsClusterName string        = "als_cluster"
	EnvoyRESTRefreshDelay   time.Duration = 10 * time.Second
	EnvoyRESTRequestTimeout time.Duration = 10 * time.Second
	EnvoyGRPCRequestTimeout time.Duration = 10 * time.Second
)

Variables

This section is empty.

Functions

func AlsListenAddr

func AlsListenAddr(addr string) serverOptFunc

func CdsClusterConnectionTimeout

func CdsClusterConnectionTimeout(dur time.Duration) cdsOptFunc

func CdsClusterRefreshIntervalBase

func CdsClusterRefreshIntervalBase(dur time.Duration) cdsOptFunc

func CdsClusterRefreshIntervalMax

func CdsClusterRefreshIntervalMax(dur time.Duration) cdsOptFunc

func CdsClusterUpstreamKeepAliveIntervalSeconds

func CdsClusterUpstreamKeepAliveIntervalSeconds(seconds uint32) cdsOptFunc

func CdsClusterUpstreamKeepAliveTimeSeconds

func CdsClusterUpstreamKeepAliveTimeSeconds(seconds uint32) cdsOptFunc

func CdsHealthCheckInitialIntervalOnAddCluster

func CdsHealthCheckInitialIntervalOnAddCluster(dur time.Duration) cdsOptFunc

func CdsHealthCheckInitialJitter

func CdsHealthCheckInitialJitter(dur time.Duration) cdsOptFunc

func CdsOutlierBaseEjectionTime

func CdsOutlierBaseEjectionTime(dur time.Duration) cdsOptFunc

func CdsOutlierConsecutiveCount5xx

func CdsOutlierConsecutiveCount5xx(times uint32) cdsOptFunc

func CdsOutlierConsecutiveGatewayFailure

func CdsOutlierConsecutiveGatewayFailure(times uint32) cdsOptFunc

func CdsOutlierInterval

func CdsOutlierInterval(dur time.Duration) cdsOptFunc

func CdsOutlierSuccessRateMinHosts

func CdsOutlierSuccessRateMinHosts(size uint32) cdsOptFunc

func EdsLbEndpointHealthStatus added in v1.0.1

func EdsLbEndpointHealthStatus(status corev3.HealthStatus) edsOptFunc

func EdsLoadBalancingWeight

func EdsLoadBalancingWeight(weight uint32) edsOptFunc

func LdsStatPrefix

func LdsStatPrefix(prefix string) ldsOptFunc

func MaxConcurrentStreams

func MaxConcurrentStreams(n uint32) serverOptFunc

func NewServer

func NewServer(ctx context.Context, cache cachev3.Cache, funcs ...serverOptFunc) *server

func RdsRetryBackOffIntervalBase

func RdsRetryBackOffIntervalBase(dur time.Duration) rdsOptFunc

func RdsRetryBackOffIntervalMax

func RdsRetryBackOffIntervalMax(dur time.Duration) rdsOptFunc

func RdsRetryHostSelectionAttempts

func RdsRetryHostSelectionAttempts(times int64) rdsOptFunc

func RdsRetryPerTryTimeout

func RdsRetryPerTryTimeout(dur time.Duration) rdsOptFunc

func WatchCdsConfigFile

func WatchCdsConfigFile(path string) watchOptFunc

func WatchEdsConfigFile

func WatchEdsConfigFile(path string) watchOptFunc

func WatchLdsConfigFile

func WatchLdsConfigFile(path string) watchOptFunc

func WatchRdsConfigFile

func WatchRdsConfigFile(path string) watchOptFunc

func XdsListenAddr

func XdsListenAddr(addr string) serverOptFunc

Types

type AccessLog

type AccessLog struct {
	Route                     string
	ClientAddress             string
	RemoteAddress             string
	RequestTime               time.Time
	Protocol                  string
	RequestMethod             string
	RequestPath               string
	UserAgent                 string
	Referer                   string
	ForwardedFor              string
	ResponseStatus            uint32
	RequestReceiveDuration    time.Duration // TimeToLastRxByte
	ResponseReceivingDuration time.Duration // TimeToFirstUpstreamRxByte
	ResponseCompleteDuration  time.Duration // TimeToLastUpstreamRxByte
	ClientReceivingDuration   time.Duration // TimeToFirstDownstreamTxByte
	ClientCompleteDuration    time.Duration // TimeToLastDownstreamTxByte
}

func (AccessLog) WriteTo

func (a AccessLog) WriteTo(logId string, buf *bytes.Buffer)

write to buffer

type CDSConfig

type CDSConfig struct {
	ClusterName string               `yaml:"name"         validate:"required"`
	LbPolicy    string               `yaml:"lb-policy"    validate:"required"`
	HealthCheck CDSHealthCheckConfig `yaml:"health-check" validate:"required"`
}

type CDSHealthCheckConfig

type CDSHealthCheckConfig struct {
	Host           string   `yaml:"host"         validate:""`
	Path           string   `yaml:"path"         validate:"required"`
	Status         []string `yaml:"status"       validate:"required,unique"`
	Timeout        uint32   `yaml:"timeout"      validate:"gte=1,lte=900"`
	Interval       uint32   `yaml:"interval"     validate:"gte=1,lte=180"`
	HealthyCount   uint32   `yaml:"healthy"      validate:"gte=1,lte=10"`
	UnhealthyCount uint32   `yaml:"unhealthy"    validate:"gte=1,lte=10"`
}

func (CDSHealthCheckConfig) IntervalSecond

func (c CDSHealthCheckConfig) IntervalSecond() time.Duration

func (CDSHealthCheckConfig) TimeoutSecond

func (c CDSHealthCheckConfig) TimeoutSecond() time.Duration

type EDSConfig

type EDSConfig struct {
	ClusterName     string              `yaml:"name"             validate:"required"`
	BalancingPolicy string              `yaml:"balancing-policy" validate:"required"`
	Instances       []EDSInstanceConfig `yaml:"instances"        validate:"required"`
}

type EDSInstanceConfig

type EDSInstanceConfig struct {
	InstanceName string `yaml:"instance-name"  validate:"required"`
	IP           string `yaml:"ip"             validate:"required,ip"`
	Port         uint32 `yaml:"port"           validate:"required,gte=1,lte=65535"`
	Region       string `yaml:"region"         validate:"required"`
	Zone         string `yaml:"zone"           validate:"zone"`
	Protocol     string `yaml:"protocol"       validate:"required"`
	Weight       uint32 `yaml:"weight"`
}

func (EDSInstanceConfig) Address

func (c EDSInstanceConfig) Address() *corev3.Address

type LDSAccessLogConfig

type LDSAccessLogConfig struct {
	LogId         string `yaml:"log-id"          validate:"required"`
	FlushInterval uint32 `yaml:"flush-interval"  validate:"required,gte=1"`
	BufferSize    uint32 `yaml:"buffer-size"     validate:"required,gte=1"`
}

func (LDSAccessLogConfig) FlushIntervalSecond

func (c LDSAccessLogConfig) FlushIntervalSecond() time.Duration

type LDSConfig

type LDSConfig struct {
	Listen    LDSListenConfig    `yaml:"listen"           validate:"required"`
	Server    LDSServerConfig    `yaml:"server"           validate:"required"`
	Timeout   LDSTimeoutConfig   `yaml:"timeout"          validate:"required"`
	AccessLog LDSAccessLogConfig `yaml:"accesslog"        validate:"required"`
}

type LDSListenConfig

type LDSListenConfig struct {
	Protocol string `yaml:"protocol"         validate:"required"`
	IP       string `yaml:"ip"               validate:"required,ip"`
	Port     uint32 `yaml:"port"             validate:"required,gte=1,lte=65535"`
}

func (LDSListenConfig) Address

func (c LDSListenConfig) Address() *corev3.Address

type LDSServerConfig

type LDSServerConfig struct {
	ServerName     string `yaml:"name"             validate:"required,ascii"`
	UseRemoteAddr  bool   `yaml:"use-remote-addr"  validate:"required"`
	SkipXffAppend  bool   `yaml:"skip-xff-append"  validate:"required"`
	XffTrustedHops uint32 `yaml:"xff-trusted-hops" validate"required"`
}

type LDSTimeoutConfig

type LDSTimeoutConfig struct {
	RequestTimeout uint32 `yaml:"request-timeout"  validate:"required,gte=1"`
	DrainTimeout   uint32 `yaml:"drain-timeout"    validate:"required,gte=1"`
	IdleTimeout    uint32 `yaml:"idle-timeout"     validate:"required,gte=1"`
	MaxDuration    uint32 `yaml:"max-duration"     validate:"required,gte=1"`
}

func (LDSTimeoutConfig) DrainTimeoutSecond

func (c LDSTimeoutConfig) DrainTimeoutSecond() time.Duration

func (LDSTimeoutConfig) IdleTimeoutSecond

func (c LDSTimeoutConfig) IdleTimeoutSecond() time.Duration

func (LDSTimeoutConfig) MaxDurationSecond

func (c LDSTimeoutConfig) MaxDurationSecond() time.Duration

func (LDSTimeoutConfig) RequestTimeoutSecond

func (c LDSTimeoutConfig) RequestTimeoutSecond() time.Duration

type RDSActionConfig

type RDSActionConfig struct {
	Timeout     uint32 `yaml:"timeout"      validate:"required"`
	IdleTimeout uint32 `yaml:"idle-timeout" validate:"required"`
	RetryPolicy string `yaml:"retry-policy" validate:"required"`
}

func (RDSActionConfig) IdleTimeoutSecond

func (c RDSActionConfig) IdleTimeoutSecond() time.Duration

func (RDSActionConfig) TimeoutSecond

func (c RDSActionConfig) TimeoutSecond() time.Duration

type RDSClusterConfig

type RDSClusterConfig struct {
	Prefix  string                   `yaml:"prefix"  validate:"required"`
	Target  []RDSClusterWeightConfig `yaml:"target"  validate:"required"`
	Headers []RDSClusterHeaderConfig `yaml:"headers" validate:""`
}

type RDSClusterHeaderConfig added in v1.0.2

type RDSClusterHeaderConfig struct {
	HeaderName  string           `yaml:"name"          validate:""`
	StringMatch RDSStringMatcher `yaml:"string_match"  validate:""`
}

type RDSClusterWeightConfig

type RDSClusterWeightConfig struct {
	ClusterName string `yaml:"name"   validate:"required"`
	Weight      uint32 `yaml:"weight" validate:"gte=0,lte=100"`
}

type RDSConfig

type RDSConfig struct {
	VHostName string             `yaml:"vhost"   validate:"required"`
	Domain    []string           `yaml:"domain"  validate:"required,unique"`
	Cluster   []RDSClusterConfig `yaml:"cluster" validate:"required"`
	Action    RDSActionConfig    `yaml:"action"  validate:"required"`
}

type RDSStringMatcher added in v1.0.2

type RDSStringMatcher struct {
	Exact string `yaml:"exact" validate:""`
}

type WatchFile

type WatchFile struct {
	// contains filtered or unexported fields
}

func NewWatchFile

func NewWatchFile(ctx context.Context, nodeId string, funcs ...watchOptFunc) *WatchFile

func (*WatchFile) Cache

func (w *WatchFile) Cache() cachev3.Cache

func (*WatchFile) ReloadAll

func (w *WatchFile) ReloadAll() error

all or nothing reload

func (*WatchFile) Watch

func (w *WatchFile) Watch(ctx context.Context) error

Directories

Path Synopsis
cli

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL