gke

package
v0.24.4 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2024 License: Apache-2.0 Imports: 123 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var File_internal_gke_container_proto protoreflect.FileDescriptor

Functions

func Controller

func Controller(ctx context.Context, config CloudConfig) (string, *http.Client, error)

Controller returns the HTTP address of the controller and an HTTP client that can be used to contact the controller.

func HasTime

func HasTime(query wlogging.Query) (bool, error)

HasTime returns whether the provided query contains a predicate on the "time" field.

func LogLevelFromName added in v0.24.2

func LogLevelFromName(name string) (slog.Level, error)

LogLevelFromName returns the log level corresponding to a level, based on its name.

func LogSource

func LogSource(config CloudConfig) (*gcpSource, error)

LogSource returns a new dlogging.Source that reads log entries written by Service Weaver applications deployed on Google Cloud.

func PrepareRollout

func PrepareRollout(ctx context.Context, config CloudConfig, cfg *config.GKEConfig, toolVersion string) (*controller.RolloutRequest, error)

PrepareRollout returns a new rollout request for the given application version, along with the HTTP client that should be used to reach it. May mutate the passed-in deployment. REQUIRES: Called by the weaver-gke command.

func Purge added in v0.22.3

func Purge(ctx context.Context, config CloudConfig) error

Purge deletes all resources created by Service Weaver in the given GCP project. It returns an error if there are some resources that cannot be deleted. TODO: Update IAM permissions to not point to the deleted resources.

func RunBabysitter

func RunBabysitter(ctx context.Context) error

RunBabysitter creates and runs a GKE babysitter.

The GKE babysitter starts and manages a weavelet. If the weavelet crashes, the babysitter will crash as well, causing the kubernetes manager to re-run the container.

The following environment variables must be set before this method is called:

  • configEnvKey
  • replicaSetEnvKey
  • containerMetadataEnvKey
  • nodeNameEnvKey
  • podNameEnvKey

This call blocks until the provided context is canceled or an error is encountered.

func RunController added in v0.18.0

func RunController(ctx context.Context, port int) error

RunController creates and runs a controller.

func RunDistributor added in v0.18.0

func RunDistributor(ctx context.Context, port int) error

RunDistributor creates and runs a distributor.

func RunManager added in v0.18.0

func RunManager(ctx context.Context, port int) error

RunManager creates and runs a manager.

func Store

func Store(cluster *ClusterInfo) store.Store

Store returns the Service Weaver store for the given cluster.

func ToolVersion added in v0.21.0

func ToolVersion() (string, bool, error)

ToolVersion returns the version of the running tool binary, along with an indication whether the tool was built manually, i.e., not via go install.

func Translate

func Translate(project string, query wlogging.Query) (string, error)

Translate translates a log query into a Google Cloud Logging query 1.

Types

type CloudConfig

type CloudConfig struct {
	Project       string // Cloud project.
	ProjectNumber string // Cloud project number

	// TokenSource used for accessing the cloud project.
	TokenSource oauth2.TokenSource

	// Account name associated with the project. This value is filled as
	// best-effort and may be empty (e.g., if token is used for access).
	Account string
}

CloudConfig stores the configuration information for a cloud project.

func SetupCloudConfig

func SetupCloudConfig(project, token, account string) (CloudConfig, error)

SetupCloudConfig sets up the cloud configuration for the given project, using the provided account name and access token. If the project name is empty, its value is retrieved from the active gcloud configuration on the local machine. If access token is empty, and if the CLOUDSDK_AUTH_ACCESS_TOKEN environment variable is set, the environment variable value is used. Otherwise, a new access token is generated for the provided account name. If the account name is also empty, its value is retrieved from the active gcloud configuration on the local machine.

REQUIRES: The caller is running on a user machine.

func (*CloudConfig) ClientOptions

func (c *CloudConfig) ClientOptions() []option.ClientOption

ClientOptions returns the client options that should be passed to cloud clients for proper authentication.

type CloudLoggingClient

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

CloudLoggingClient is a Google Cloud Logging client. Code running on GKE can use a CloudLoggingClient to create loggers that log to Google Cloud Logging. These logs will also correctly show up in the "LOGS" tab on the GKE console.

func (*CloudLoggingClient) Close

func (cl *CloudLoggingClient) Close() error

Close closes the CloudLoggingClient.

func (*CloudLoggingClient) Log

func (cl *CloudLoggingClient) Log(entry *protos.LogEntry)

Log logs the provided entry to Google Cloud Logging.

func (*CloudLoggingClient) Logger

func (cl *CloudLoggingClient) Logger(opts wlogging.Options) *slog.Logger

Logger returns a new slog.Logger that logs to Google Cloud Logging.

type ClusterInfo

type ClusterInfo struct {
	// Cluster name.
	Name string

	// Cluster region (e.g., us-east1, europe-west1). This value is static for
	// the lifetime of the cluster.
	Region string

	// Cluster multi-region (e.g., us, europe, asia).  May be empty if the
	// cluster isn't part of a multi-region (e.g., northamerica-northeast1).
	MultiRegion string

	// Configuration information for a cloud
	CloudConfig CloudConfig

	// Kubernetes clientset for the core API.
	Clientset *kubernetes.Clientset
	// contains filtered or unexported fields
}

ClusterInfo stores information about a GKE cluster.

func GetClusterInfo

func GetClusterInfo(ctx context.Context, config CloudConfig, cluster, region string) (*ClusterInfo, error)

GetClusterInfo returns information about a GKE cluster running in a given cloud region. REQUIRES: The caller is running on the user machine.

type ContainerMetadata

type ContainerMetadata struct {
	Project       string            `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`                                  // GCP project
	ClusterName   string            `protobuf:"bytes,2,opt,name=cluster_name,json=clusterName,proto3" json:"cluster_name,omitempty"`       // GKE cluster name
	ClusterRegion string            `protobuf:"bytes,3,opt,name=cluster_region,json=clusterRegion,proto3" json:"cluster_region,omitempty"` // GKE cluster region (e.g., us-east1)
	Namespace     string            `protobuf:"bytes,4,opt,name=namespace,proto3" json:"namespace,omitempty"`                              // Kubernetes namespace (e.g., default)
	NodeName      string            `protobuf:"bytes,5,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"`                // GCP node name
	PodName       string            `protobuf:"bytes,6,opt,name=pod_name,json=podName,proto3" json:"pod_name,omitempty"`                   // Kubernetes pod name
	ContainerName string            `protobuf:"bytes,7,opt,name=container_name,json=containerName,proto3" json:"container_name,omitempty"` // Kubernetes container name
	App           string            `protobuf:"bytes,8,opt,name=app,proto3" json:"app,omitempty"`                                          // Kubernetes app label
	Telemetry     *config.Telemetry `protobuf:"bytes,9,opt,name=telemetry,proto3" json:"telemetry,omitempty"`                              // Options to configure the telemetry
	// contains filtered or unexported fields
}

ContainerMetadata contains metadata about a container running on GKE.

Typically, when Service Weaver launches a container, it places the container's ContainerMetadata in an environment variable (see container.go). The running container can then parse the ContainterMetadata from the environment and use the metadata for various things.

For example, the stdout and stderr of a container run on GKE are captured and logged to Google Cloud Logging 1. Every one of these log entries contains a "labels" and "resource" field that looks something like this:

labels: {
  compute.googleapis.com/resource_name:
  "gke-serviceweaver-default-pool-05ad7bcf-55vd" k8s-pod/app: "todo-main-ac9156"
  k8s-pod/pod-template-hash: "56ffc498d"
}
resource: {
  labels: {
    cluster_name: "serviceweaver"
    container_name: "serviceweaver"
    region: "us-east1"
    namespace_name: "serviceweaver"
    pod_name: "todo-main-ac9156-56ffc498d-l57rm"
    project_id: "serviceweaver-gke-dev"
  }
  type: "k8s_container"
}

When you click on the "LOGS" tab on the page for a pod, deployment, or stateful set, the Google Cloud Console forms a query over these fields and shows you the resulting log entries. We're logging entries directly to Google Cloud Logging---not printing them to stdout or stderr---so in order for the logs to appear in the "LOGS" tab, we have to embed the same "labels" and "resource" fields. These fields are populated using a ContainerMetadata.

func (*ContainerMetadata) Descriptor deprecated

func (*ContainerMetadata) Descriptor() ([]byte, []int)

Deprecated: Use ContainerMetadata.ProtoReflect.Descriptor instead.

func (*ContainerMetadata) GetApp

func (x *ContainerMetadata) GetApp() string

func (*ContainerMetadata) GetClusterName

func (x *ContainerMetadata) GetClusterName() string

func (*ContainerMetadata) GetClusterRegion

func (x *ContainerMetadata) GetClusterRegion() string

func (*ContainerMetadata) GetContainerName

func (x *ContainerMetadata) GetContainerName() string

func (*ContainerMetadata) GetNamespace

func (x *ContainerMetadata) GetNamespace() string

func (*ContainerMetadata) GetNodeName

func (x *ContainerMetadata) GetNodeName() string

func (*ContainerMetadata) GetPodName

func (x *ContainerMetadata) GetPodName() string

func (*ContainerMetadata) GetProject

func (x *ContainerMetadata) GetProject() string

func (*ContainerMetadata) GetTelemetry added in v0.24.1

func (x *ContainerMetadata) GetTelemetry() *config.Telemetry

func (*ContainerMetadata) ProtoMessage

func (*ContainerMetadata) ProtoMessage()

func (*ContainerMetadata) ProtoReflect

func (x *ContainerMetadata) ProtoReflect() protoreflect.Message

func (*ContainerMetadata) Reset

func (x *ContainerMetadata) Reset()

func (*ContainerMetadata) String

func (x *ContainerMetadata) String() string

type KubeStore added in v0.10.0

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

KubeStore is a Kubernetes ConfigMap backed implementation of a Store.

Overview

Every key-value pair is stored in its own ConfigMap. Kubernetes requires that ConfigMap names are valid DNS subdomain names 1, so we cannot name a ConfigMap with the key it stores. Instead, the SHA-265 hash of a key serves as the name of the ConfigMap that stores it (with a "store-" prefix). For example, the ConfigMap that maps key "a key" to value "a value" looks something like this:

ConfigMap{
    ObjectMeta: metav1.ObjectMeta{
        Name: "store-" + SHA-256("a key")
    },
    BinaryData: map[string][]byte{
        "key":   []byte("a key"),
        "value": []byte("a value"),
    },
}

Note that the key and value are stored in the BinaryData section of the ConfigMap. In theory, we could only store the value and not store the key, but practically we choose to store the key along with the value to make ConfigMaps more interpretable.

Versions

KubeStore implements `store.Version`s using ConfigMap resource versions. We omitted the ResourceVersion field in the ConfigMap above to keep things simple, but in reality, Kubernetes assigns the ConfigMap a resource version. That looks something like this:

ConfigMap{
    ObjectMeta: metav1.ObjectMeta{
        Name: "store-" + SHA-256("a key")
        ResourceVersion: "111111111",
    },
    BinaryData: map[string][]byte{
        "key":   []byte("a key"),
        "value": []byte("a value"),
    },
}

Here, the ConfigMap's resource version is "111111111". If we call KubeStore.Get(ctx, "a key", nil), we get a store.Version{Opaque: "111111111"}.

Listing

A Kubernetes cluster will have many ConfigMaps besides those managed by a KubeStore. In order to differentiate a KubeStore managed ConfigMap from some other ConfigMap, the KubeStore also labels every key-value pair with the label "serviceweaver/store=true". So, the ConfigMap above looks something like this:

ConfigMap{
    ObjectMeta: metav1.ObjectMeta{
        Name: "store-" + SHA-256("a key")
        ResourceVersion: "111111111",
        Labels: map[string]string{"serviceweaver/store": "true"},
    },
    BinaryData: map[string][]byte{
        "key":   []byte("a key"),
        "value": []byte("a value"),
    },
}

KubeStore also uses this label to implement the List method, fetching every ConfigMap that has the "serviceweaver/store=true" label.

Kubernetes Consistency

Note that it is a little unclear what level of consistency ConfigMaps provide, but we think that the operations we use to implement KubeStore are all linearizable. 2 discusses how resource versions can be used to implement optimistic concurrency control and suggests that versioned writes are linearizable. 3 says that gets with an unset resource version return the "most recent" data, which we interpret to be linearizable. This is also backed by 4, which states:

> Kubernetes Get and List requests are guaranteed to be "consistent reads" > if the resourceVersion parameter is not provided. Consistent reads are > served from etcd using a "quorum read".

There is a possibility that we misunderstood Kubernetes' documentation or the Kubernetes implementation does not properly implement its promised consistency guarantees, but the implementation of KubeStore is written under the assumption that all of the underlying ConfigMap operations it calls are linearizable.

func (*KubeStore) Delete added in v0.10.0

func (f *KubeStore) Delete(ctx context.Context, key string) error

func (*KubeStore) Get added in v0.10.0

func (f *KubeStore) Get(ctx context.Context, key string, version *store.Version) (string, *store.Version, error)

func (*KubeStore) List added in v0.10.0

func (f *KubeStore) List(ctx context.Context, opts store.ListOptions) ([]string, error)

func (*KubeStore) Purge added in v0.10.0

func (f *KubeStore) Purge(ctx context.Context) error

Purge deletes everything from the store. Unlike operations like [Put] and [Get], Purge is not guaranteed to be linearizable.

func (*KubeStore) Put added in v0.10.0

func (f *KubeStore) Put(ctx context.Context, key, value string, version *store.Version) (*store.Version, error)

type MetricQuerent

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

MetricQuerent run queries against the Google Cloud Monitoring service.

It can currently only be used to access metrics exported by the Service Weaver runtime.

func NewMetricQuerent

func NewMetricQuerent(config CloudConfig) *MetricQuerent

NewMetricQuerent creates a new MetricQuerent with the given cloud configuration.

func (*MetricQuerent) Exists added in v0.5.1

func (mq *MetricQuerent) Exists(ctx context.Context, metric string) (bool, error)

Exists returns true iff the metric with the given name exists.

func (*MetricQuerent) QueryTimeSeries

func (mq *MetricQuerent) QueryTimeSeries(ctx context.Context, queryMQL string) ([]TimeSeriesData, error)

QueryTimeSeries runs the given MQL 1 query and returns the resulting time series.

Here is an example MQL query:

fetch k8s_container
| metric 'custom.googleapis.com/my_metric'
| filter metric.my_label == 'bar'
| align rate(1m)
| within 10m

The "within" table operator in the above query ensures that the query applies only to the last 10 minutes of data points. If we didn't add this operator, the query would have resulted in an unbounded amount of data points, which could lead to OOMs. Therefore, make sure that all your queries have a limiting factor such as "within".

type TimeSeriesData

type TimeSeriesData struct {
	Labels []string // Labels associated with the time series.

	// Time series points at various time intervals, from the most recent to the
	// least recent. Each time interval corresponds to the alignment period
	// specified in the query.
	//
	// Primitive data points (e.g., double, integer) consist of a single typed
	// value, while distributions consist of multiple typed values.
	Points [][]*monitoringpb.TypedValue
}

TimeSeriesData stores information about a queried time series.

Jump to

Keyboard shortcuts

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