Documentation ¶
Index ¶
- Constants
- Variables
- func Controller(ctx context.Context, config CloudConfig) (string, *http.Client, error)
- func HasTime(query wlogging.Query) (bool, error)
- func LogSource(config CloudConfig) (*gcpSource, error)
- func PrepareRollout(ctx context.Context, config CloudConfig, cfg *config.GKEConfig, ...) (*controller.RolloutRequest, error)
- func RunBabysitter(ctx context.Context) error
- func RunController(ctx context.Context, port int) error
- func RunDistributor(ctx context.Context, port int) error
- func RunManager(ctx context.Context, port int) error
- func Store(cluster *ClusterInfo) store.Store
- func Translate(project string, query wlogging.Query) (string, error)
- type CloudConfig
- type CloudLoggingClient
- type ClusterInfo
- type ContainerMetadata
- func (*ContainerMetadata) Descriptor() ([]byte, []int)deprecated
- func (x *ContainerMetadata) GetApp() string
- func (x *ContainerMetadata) GetClusterName() string
- func (x *ContainerMetadata) GetClusterRegion() string
- func (x *ContainerMetadata) GetContainerName() string
- func (x *ContainerMetadata) GetNamespace() string
- func (x *ContainerMetadata) GetNodeName() string
- func (x *ContainerMetadata) GetPodName() string
- func (x *ContainerMetadata) GetProject() string
- func (*ContainerMetadata) ProtoMessage()
- func (x *ContainerMetadata) ProtoReflect() protoreflect.Message
- func (x *ContainerMetadata) Reset()
- func (x *ContainerMetadata) String() string
- type KubeStore
- func (f *KubeStore) Delete(ctx context.Context, key string) error
- func (f *KubeStore) Get(ctx context.Context, key string, version *store.Version) (string, *store.Version, error)
- func (f *KubeStore) List(ctx context.Context) ([]string, error)
- func (f *KubeStore) Purge(ctx context.Context) error
- func (f *KubeStore) Put(ctx context.Context, key, value string, version *store.Version) (*store.Version, error)
- type MetricQuerent
- type TimeSeriesData
Constants ¶
const ( // Name of a Service Weaver configuration cluster. ConfigClusterName = "serviceweaver-config" // Region for the Service Weaver configuration cluster. ConfigClusterRegion = "us-central1" )
Variables ¶
var File_internal_gke_container_proto protoreflect.FileDescriptor
Functions ¶
func Controller ¶
Controller returns the HTTP address of the controller and an HTTP client that can be used to contact the controller.
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 RunBabysitter ¶
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
RunController creates and runs a controller.
func RunDistributor ¶ added in v0.18.0
RunDistributor creates and runs a distributor.
func RunManager ¶ added in v0.18.0
RunManager creates and runs a manager.
func Store ¶
func Store(cluster *ClusterInfo) store.Store
Store returns the Service Weaver store for the given cluster.
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.
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.
func GetClusterInfos ¶ added in v0.13.0
func GetClusterInfos(ctx context.Context, config CloudConfig) ([]*ClusterInfo, error)
GetClusterInfos returns information about all GKE clusters running in a given cloud project. 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 // 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) 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.
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
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.