mesh

package
v0.0.0-...-cac5726 Latest Latest
Warning

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

Go to latest
Published: Jan 28, 2022 License: Apache-2.0 Imports: 35 Imported by: 7

Documentation

Index

Constants

View Source
const (
	WorkloadCertDir = "./var/run/secrets/workload-spiffe-credentials"

	// This is derived from CA certs plus all TrustAnchors.
	// In GKE, it is expected that Citadel roots will be configure using TrustConfig - so they are visible
	// to all workloads including TD proxyless GRPC.
	//
	// Outside of GKE, this is loaded from the mesh.env - the mesh gate is responsible to keep it up to date.
	WorkloadRootCAs = "ca_certificates.pem"
)
View Source
const (
	ServerListenerNamePrefix = "xds.istio.io/grpc/lds/inbound/"
	// ServerListenerNameTemplate for the name of the Listener resource to subscribe to for a gRPC
	// server. If the token `%s` is present in the string, all instances of the
	// token will be replaced with the server's listening "IP:port" (e.g.,
	// "0.0.0.0:8080", "[::]:8080").
	ServerListenerNameTemplate = ServerListenerNamePrefix + "%s"
)
View Source
const FileWatcherCertProviderName = "file_watcher"

Variables

View Source
var Debug = false

Functions

func CheckFiles

func CheckFiles()

func GenCSRTemplate

func GenCSRTemplate(trustDomain, san string) *x509.CertificateRequest

func SaveFiles

func SaveFiles()

Types

type Bootstrap

type Bootstrap struct {
	XDSServers                 []XdsServer                    `json:"xds_servers,omitempty"`
	Node                       *Node                          `json:"node,omitempty"`
	CertProviders              map[string]CertificateProvider `json:"certificate_providers,omitempty"`
	ServerListenerNameTemplate string                         `json:"server_listener_resource_name_template,omitempty"`
}

Bootstrap contains the general structure of what's expected by GRPC's XDS implementation. See https://github.com/grpc/grpc-go/blob/master/xds/internal/xdsclient/bootstrap/bootstrap.go TODO use structs from gRPC lib if created/exported

func GenerateBootstrap

func GenerateBootstrap(opts GenerateBootstrapOptions, meta map[string]string) (*Bootstrap, error)

GenerateBootstrap generates the bootstrap structure for gRPC XDS integration.

func GenerateBootstrapFile

func GenerateBootstrapFile(opts GenerateBootstrapOptions, path string) (*Bootstrap, error)

GenerateBootstrapFile generates and writes atomically as JSON to the given file path.

func LoadBootstrap

func LoadBootstrap(file string) (*Bootstrap, error)

LoadBootstrap loads a Bootstrap from the given file path.

func (*Bootstrap) FileWatcherProvider

func (b *Bootstrap) FileWatcherProvider() *FileWatcherCertProviderConfig

FileWatcherProvider returns the FileWatcherCertProviderConfig if one exists in CertProviders

type CSRSigner

type CSRSigner interface {
	CSRSign(ctx context.Context, csrPEM []byte, certValidTTLInSec int64) ([]string, error)
}

type CertificateAuthorityConfig

type CertificateAuthorityConfig struct {
	MeshCAConfig                      *MeshCAConfig                      `json:"meshCAConfig,omitempty"`
	CertificateAuthorityServiceConfig *CertificateAuthorityServiceConfig `json:"certificateAuthorityServiceConfig,omitempty"`
}

type CertificateAuthorityServiceConfig

type CertificateAuthorityServiceConfig struct {
	// Format: //privateca.googleapis.com/projects/PROJECT_ID/locations/SUBORDINATE_CA_LOCATION/caPools/SUBORDINATE_CA_POOL_NAME
	EndpointURI string `json:"endpointURI"`
}

type CertificateProvider

type CertificateProvider struct {
	PluginName string      `json:"plugin_name,omitempty"`
	Config     interface{} `json:"config,omitempty"`
}

type Cfg

type Cfg interface {
	GetSecret(ctx context.Context, ns string, name string) (map[string][]byte, error)
	GetCM(ctx context.Context, ns string, name string) (map[string]string, error)
}

type ChannelCreds

type ChannelCreds struct {
	Type   string      `json:"type,omitempty"`
	Config interface{} `json:"config,omitempty"`
}

type ECDSA

type ECDSA struct {
	Curve string `json:"curve"`
}

type FileWatcherCertProviderConfig

type FileWatcherCertProviderConfig struct {
	CertificateFile   string          `json:"certificate_file,omitempty"`
	PrivateKeyFile    string          `json:"private_key_file,omitempty"`
	CACertificateFile string          `json:"ca_certificate_file,omitempty"`
	RefreshDuration   json.RawMessage `json:"refresh_interval,omitempty"`
}

func (*FileWatcherCertProviderConfig) FilePaths

func (c *FileWatcherCertProviderConfig) FilePaths() []string

type GenerateBootstrapOptions

type GenerateBootstrapOptions struct {
	Node             *Node
	XdsUdsPath       string
	DiscoveryAddress string
	CertDir          string
}

type KRun

type KRun struct {
	// BaseDir is the root directory for all created files and all lookups.
	// If empty, will default to "/" when running as root, and "./" when running as regular user.
	// MESH_BASE_DIR will override it.
	BaseDir string

	// Config maps to 'mount'. Key is the config map name, value is a path.
	// Config mounts are optional (for now)
	CM2Dirs map[string]string

	// Audience to files. For each key, a k8s token with the given audience
	// will be created. Files should be under /var/run/secrets
	Aud2File map[string]string

	// ProxyConfig is a subset of istio ProxyConfig
	ProxyConfig *ProxyConfig

	// Address of the XDS server. If not specified, MCP is used.
	XDSAddr string

	// MeshTenant. Only set if using MCP or external Istiod.
	// Opaque, internal string that identifies the mesh to the XDS server.
	// Different from meshID - which is the user-visible form.
	MeshTenant string

	// External address of the mesh connector
	// Not used for internal workloads.
	MeshConnectorAddr string

	// Internal (ILB) address.
	MeshConnectorInternalAddr string

	// Canonical name for the application.
	// Will be set as "app" and "service.istio.io/canonical-name" labels
	//
	// If not set "default" will be used.
	// TODO: use service name as default
	Name string

	// Revision
	Rev string

	// If not empty, will run Istio-agent as a gateway (router instead of sidecar)
	// with the "istio: $Gateway" label.
	Gateway string

	// Agent debug config (example dns:debug).
	// Based on ISTIO_DEBUG
	AgentDebug string

	// Namespace for the application. The user running the command must have
	// the appropriate Token, Secret, ConfigMap permissions in the namespace.
	//
	// If not set, "default" will be used.
	// TODO: use the GSA name as default namespace.
	Namespace string

	// KSA is the k8s service account for getting tokens.
	//
	// If not set, "default" will be used.
	// TODO: use service name as default
	KSA string

	// ProjectId is the name of the project where config cluster is running
	// The workload may be in a different project.
	ProjectId string

	// ProjectNumber is used for GCP federated token exchange.
	// It is populated from the mesh-env PROJECT_NUMBER setting to construct the federated P4SA
	//    "service-" + s.kr.ProjectNumber + "@gcp-sa-meshdataplane.iam.gserviceaccount.com"
	// This is used for MeshCA and Stackdriver access.
	ProjectNumber string

	// Deprecated - ClusterAddress used instead.
	ClusterName string

	// TODO: replace with Workloadlocation. Config cluster location not used.
	ClusterLocation string

	Children []*exec.Cmd

	TrustDomain string

	StartTime      time.Time
	EnvoyStartTime time.Time
	EnvoyReadyTime time.Time
	AppReadyTime   time.Time

	Labels     map[string]string
	VendorInit func(context.Context, *KRun) error

	// WhiteboxMode indicates no iptables capture
	WhiteboxMode bool
	InCluster    bool

	// PEM cert roots detected in the cluster - Citadel, custom CAs from mesh config.
	// Will be saved to a file.
	CARoots []string

	// Citadel root(s) - PEM format, may have multiple roots.
	//
	CitadelRoot string

	// MeshAddr is the location of the mesh environment file.
	// This will be loaded at startup (TODO: and periodically or on demand for dynamic changes - XDS may also
	// push configs)
	//
	//
	//
	// Supported formats:
	// - https://.... - regular URL, using system certificates. Will return the mesh env directly.
	// - file://... - load from file
	// - gke://CONFIG_PROJECT_ID[/CLUSTER_LOCATION/CLUSTER_NAME/WORKLOAD_NAMESPACE] - GKE Container API.
	MeshAddr *url.URL

	// Config cluster address - https://container.googleapis.com/v1/projects/%s/locations/%s/clusters/%s
	// Used in the identitynamespace config for STS exchange.
	ClusterAddress string

	InstanceID string

	// Content of the 'mesh environment' - loaded from the config file in istio-system (or the address of the mesh).
	// Additional entries may be merged from env or app specific config file.
	MeshEnv map[string]string

	CSRSigner CSRSigner

	// Interface to abstract k8s implementation
	TokenProvider    TokenProvider
	Cfg              Cfg
	TransportWrapper func(transport http.RoundTripper) http.RoundTripper

	// Function to call after config has been loaded, before init certs.
	PostConfigLoad func(ctx context.Context, kr *KRun) error

	X509KeyPair     *tls.Certificate
	TrustedCertPool *x509.CertPool

	// Holds Traffic Director sidecar environment.
	TdSidecarEnv *TdSidecarEnv

	// Network Name for which the envoy configs will be requested. For TD, this refers to VPC network name
	// in the forwarding rule.
	NetworkName string
	// contains filtered or unexported fields
}

KRun allows running an app in an Istio and K8S environment.

func New

func New() *KRun

New creates an uninitialized mesh launcher.

func (*KRun) Config

func (kr *KRun) Config(name, def string) string

Config returns a mesh setting, from env variable or the loaded mesh-env.

func (*KRun) Exit

func (kr *KRun) Exit(code int)

func (*KRun) FindXDSAddr

func (kr *KRun) FindXDSAddr() string

FindXDSAddr will determine which discovery address to use.

The logic is: - if "mesh tenant" is set - use MCP. This is the main case. - if "mesh tehant" is not set - use the mesh connector for ASM/OSS - if an XDS_ADDR is explicitly set, use it - unless it is invalid ( MCP without tenant ID)

func (*KRun) GetRequestMetadata

func (kr *KRun) GetRequestMetadata(ctx context.Context, aud ...string) (map[string]string, error)

GetRequestMetadata implements credentials.PerRPCCredentials with normal audience semantics, returning tokens signed by K8S APIserver. For GCP tokens, use 'sts' package.

func (*KRun) GetToken

func (kr *KRun) GetToken(ctx context.Context, aud string) (string, error)

GetToken returns a token with the given audience for the current KSA, using CreateToken request. Used by the STS token exchanger.

func (*KRun) GetTrafficDirectorIPTablesEnvVars

func (kr *KRun) GetTrafficDirectorIPTablesEnvVars() []string

GetTrafficDirectorIPTablesEnvVars returns env vars needed for iptables interception for TD

func (*KRun) InitCertificates

func (kr *KRun) InitCertificates(ctx context.Context, outDir string) error

Common setup for cert management. After the 'mesh-env' is loaded (from env, k8s, URL) the next step is to init the workload identity. This must happen before connecting to XDS - since certs is one of the possible auth methods.

The logic is:

  • (best case) certificates already provisioned by platform. Detects GKE paths (CAS), old Istio, CertManager style If workload certs are platform-provisioned: extract trust domain, namespace, name, pod id from cert.

- Detect the WORKLOAD_SERVICE_ACCOUNT, trust domain from JWT or mesh-env - Use WORKLOAD_CERT json to load the config for the CSR, create a CSR - Call CSRSigner. - Save the certificates if running as root or an output dir is set. This will use CAS naming convention.

If envoy + pilot-agent are used, they should be configured to use the cert files. This is done by setting "CA_PROVIDER=GoogleGkeWorkloadCertificate" when starting pilot-agent

func (*KRun) InitForTD

func (kr *KRun) InitForTD()

func (*KRun) InitForTDFromMeshEnv

func (kr *KRun) InitForTDFromMeshEnv() bool

func (*KRun) InitRoots

func (kr *KRun) InitRoots(ctx context.Context, outDir string) error

InitRoots will find the mesh roots.

  • if Zatar or another CSI provider are enabled, we do nothing - Zatar config is the root of trust for everything
  • otherwise the roots are expected to be part of mesh-env. The mesh connector or other tools will populate it - ideally from the CSI/Zatar or TrustConfig CRD.

func (*KRun) LoadConfig

func (kr *KRun) LoadConfig(ctx context.Context) error

func (*KRun) NewCSR

func (a *KRun) NewCSR(kty string, trustDomain, san string) (privPEM []byte, csrPEM []byte, err error)

func (*KRun) PrepareTrafficDirectorBootstrap

func (kr *KRun) PrepareTrafficDirectorBootstrap(templatePath string, outputPath string) error

func (*KRun) RefreshAndSaveTokens

func (kr *KRun) RefreshAndSaveTokens()

RefreshAndSaveTokens is run periodically to create token, secrets, config map files. The primary use is istio token expected by pilot agent. This should not be called unless pilot-agent/envoy or proxyless gRPC without library are used. pilot-agent is currently refreshing the certificates - WIP to move that here.

Certs for 'direct' (library) use can be created without saving the tokens. 'library' means linking this or a similar package with the application.

func (*KRun) Region

func (kr *KRun) Region() string

Extract Region from ClusterLocation

func (*KRun) RequireTransportSecurity

func (kr *KRun) RequireTransportSecurity() bool

RequireTranportSecurity is part of gRPC interface, returning false because we also support secure networks (low-level)

func (*KRun) Signals

func (kr *KRun) Signals()

Signals handles the special signals.

SIGTERM - send by docker on 'docker stop'. See https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-terminating-with-grace

func (*KRun) StartApp

func (kr *KRun) StartApp()

StartApp uses the reminder of the command line to exec an app, using K8S_UID as UID, if present.

func (*KRun) StartEnvoy

func (kr *KRun) StartEnvoy() error

StartEnvoy does iptables interception, envoy bootstrap preparation and runs envoy.

func (*KRun) StartIPTablesInterception

func (kr *KRun) StartIPTablesInterception() error

StartIPTablesInterception intercepts traffic via iptables script.

func (*KRun) StartIstioAgent

func (kr *KRun) StartIstioAgent() error

StartIstioAgent creates the env and starts istio agent. If running as root, will also init iptables and change UID to 1337.

func (*KRun) WaitAppStartup

func (kr *KRun) WaitAppStartup() error

WaitAppStartup waits for app to be ready to accept requests. - default is KNative 'listen on the app port' ( 8080 default, PORT_http overrides ) - startupProbe.tcp and startupProbe.http can define alternate port and using http ready.

func (*KRun) WaitEnvoyReady

func (kr *KRun) WaitEnvoyReady(addr string, max time.Duration) error

WaitEnvoyReady waits for envoy to be ready until max is reached, otherwise returns a non-nil error.

func (*KRun) WaitHTTPReady

func (kr *KRun) WaitHTTPReady(url string, max time.Duration) error

func (*KRun) WaitTCPReady

func (kr *KRun) WaitTCPReady(addr string, max time.Duration) error

WaitTCPReady uses the same detection as CloudRun, i.e. TCP connect.

type KeyAlgorithm

type KeyAlgorithm struct {
	RSA   *RSA   `json:"rsa,omitempty"`
	ECDSA *ECDSA `json:"ecdsa,omitempty"`
}

type Locality

type Locality struct {
	// Region this :ref:`zone <envoy_api_field_config.core.v3.Locality.zone>` belongs to.
	Region string `protobuf:"bytes,1,opt,name=region,proto3" json:"region,omitempty"`
	// Defines the local service zone where Envoy is running. Though optional, it
	// should be set if discovery service routing is used and the discovery
	// service exposes :ref:`zone data <envoy_api_field_config.endpoint.v3.LocalityLbEndpoints.locality>`,
	// either in this message or via :option:`--service-zone`. The meaning of zone
	// is context dependent, e.g. `Availability Zone (AZ)
	// <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html>`_
	// on AWS, `Zone <https://cloud.google.com/compute/docs/regions-zones/>`_ on
	// GCP, etc.
	Zone string `protobuf:"bytes,2,opt,name=zone,proto3" json:"zone,omitempty"`
	// When used for locality of upstream hosts, this field further splits zone
	// into smaller chunks of sub-zones so they can be load balanced
	// independently.
	SubZone string `protobuf:"bytes,3,opt,name=sub_zone,json=subZone,proto3" json:"sub_zone,omitempty"`
}

type MeshCAConfig

type MeshCAConfig struct {
}

type MeshConfig

type MeshConfig struct {
	TrustDomain   string      `yaml:"trustDomain,omitempty"`
	DefaultConfig ProxyConfig `yaml:"defaultConfig,omitempty"`
}

MeshConfig is a minimal mesh config - used to load in-cluster settings used in injection.

type Node

type Node struct {
	Id       string           `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
	Locality *Locality        `protobuf:"bytes,4,opt,name=locality,proto3" json:"locality,omitempty"`
	Metadata *structpb.Struct `protobuf:"bytes,3,opt,name=metadata,proto3" json:"metadata,omitempty"`
}

Duplicated from github.com/envoyproxy/go-control-plane/envoy/config/core/v3 to avoid deps to large package. Only what we use.

type ProxyConfig

type ProxyConfig struct {
	DiscoveryAddress  string            `yaml:"discoveryAddress,omitempty"`
	MeshId            string            `yaml:"meshId,omitempty"`
	ProxyMetadata     map[string]string `yaml:"proxyMetadata,omitempty"`
	CaCertificatesPem []string          `yaml:"caCertificatesPem,omitempty"`
}

type RSA

type RSA struct {
	ModulusSize int `json:"modulusSize"`
}

type TdSidecarEnv

type TdSidecarEnv struct {
	// Scope specifies the mesh in a project.
	Scope string
	// List of comma seperated IP ranges that will have their traffic intercepted
	// and redirected to Envoy. Set it to '*' to intercept all traffic.
	ServiceCidr string
	// Envoy listening port. Outbound traffic will be redirected to this port.
	EnvoyPort string
	// Envoy admin interface listening port. Admin interface will only be available on
	// localhost.
	EnvoyAdminPort string
	// Location for envoy output.
	LogDirectory string
	// Envoy log level. Must be one of [trace][debug][info][warning][error][critical][off]
	LogLevel string
	// If set to "true", enables generation of tracing for inbound and outbound.
	TracingEnabled bool
	// Port on which Envoy listener will resolve DNS requests. Outbound DNS requests
	// will be intercepted and forwarded to Envoy on this port.
	EnvoyDnsPort string
	// Zone of the current CloudRun service.
	EnvoyZone string
	// NodeId that this envoy client will use with TD control plane.
	NodeID string
	// Location of public server cert for GCP Traffic Director over HTTPS
	XdsServerCert string
	// Location of envoy template file and script associated with setting up envoy for TD support.
	PackageDirectory string
}

TDSidecarEnv contains environment files that controls how an envoy proxy will be set up and interact with Traffic Director control plane.

func NewTdSidecarEnv

func NewTdSidecarEnv() *TdSidecarEnv

NewTdSidecarEnv sets up TdSideCarEnv with defaults.

type TokenProvider

type TokenProvider interface {
	GetToken(ctx context.Context, aud string) (string, error)
}

type TrustAnchor

type TrustAnchor struct {
	SPIFFETrustBundleEndpoint string `json:"spiffeTrustBundleEndpoint,omitempty"`

	// Format: //privateca.googleapis.com/projects/PROJECT_ID/locations/ROOT_CA_POOL_LOCATION/caPools/ROOT_CA_POOL_NAME
	CertificateAuthorityServiceURI string `json:"certificateAuthorityServiceURI,omitempty"`

	PEMCertificate string `json:"pemCertificate,omitempty"`
}

type TrustConfigSpec

type TrustConfigSpec struct {
	TrustStores []TrustStore `json:"trustStores"`
}

TrustConfig is the GKE config - when used outside GKE this is passed in the mesh-env

type TrustStore

type TrustStore struct {
	TrustDomain  string        `json:"trustDomain"`
	TrustAnchors []TrustAnchor `json:"trustAnchors,omitempty"`
}

type WorkloadCertificateConfigSpec

type WorkloadCertificateConfigSpec struct {
	CertificateAuthorityConfig CertificateAuthorityConfig `json:"certificateAuthorityConfig"`
	ValidityDurationSeconds    int64                      `json:"validityDurationSeconds,omitempty"`
	RotationWindowPercentage   int64                      `json:"rotationWindowPercentage,omitempty"`
	KeyAlgorithm               *KeyAlgorithm              `json:"keyAlgorithm,omitempty"`
}

type XdsServer

type XdsServer struct {
	ServerURI      string         `json:"server_uri,omitempty"`
	ChannelCreds   []ChannelCreds `json:"channel_creds,omitempty"`
	ServerFeatures []string       `json:"server_features,omitempty"`
}

Jump to

Keyboard shortcuts

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