mirror of
https://github.com/go-micro/go-micro.git
synced 2025-06-12 22:07:47 +02:00
[WIP] Micro Runtime (#947)
* Add Get() and GetOptions. * Removed watcher. Outline of client. YAML templates * Added default service and deployment templates and types * Added API tests and cleaned up errors. * Small refactoring. Template package is no more. * Ripped out existing code in preparation to small rework * Reshuffled the source code to make it organized better * Create service and deployment in kubernetes runtime * Major cleanup and refactoring of Kubernetes runtime * Service now handles low level K8s API calls across both K8s deployment an service API objects * Runtime has a task queue that serves for queueing runtime action requests * General refactoring * No need for Lock in k8s service * Added kubernetes runtime env var to default deployment * Enable running different versions of the same service * Can't delete services through labels * Proto cruft. Added runtime.CreateOptions implementation in proto * Removed proxy service from default env variables * Make service name mandatory param to Get method * Get Delete changes from https://github.com/micro/go-micro/pull/945 * Replaced template files with global variables * Validate service names before sending K8s API request * Refactored Kubernetes API client. Fixed typos. * Added client.Resource to make API resources more explicit in code
This commit is contained in:
@ -1,43 +1,132 @@
|
||||
// Package client provides an implementation of a restricted subset of kubernetes API client
|
||||
package client
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/micro/go-micro/util/log"
|
||||
)
|
||||
|
||||
const (
|
||||
// https://github.com/kubernetes/apimachinery/blob/master/pkg/util/validation/validation.go#L134
|
||||
dns1123LabelFmt string = "[a-z0-9]([-a-z0-9]*[a-z0-9])?"
|
||||
)
|
||||
|
||||
var (
|
||||
// DefaultImage is default micro image
|
||||
DefaultImage = "micro/micro"
|
||||
// ServiceRegexp is used to validate service name
|
||||
ServiceRegexp = regexp.MustCompile("^" + dns1123LabelFmt + "$")
|
||||
)
|
||||
|
||||
// Kubernetes client
|
||||
type Kubernetes interface {
|
||||
// UpdateDeployment patches deployment annotations with new metadata
|
||||
UpdateDeployment(string, interface{}) error
|
||||
// ListDeployments lists all micro deployments
|
||||
ListDeployments(labels map[string]string) (*DeploymentList, error)
|
||||
// Create creates new API resource
|
||||
Create(*Resource) error
|
||||
// Get queries API resrouces
|
||||
Get(*Resource, map[string]string) error
|
||||
// Update patches existing API object
|
||||
Update(*Resource) error
|
||||
// Delete deletes API resource
|
||||
Delete(*Resource) error
|
||||
// List lists API resources
|
||||
List(*Resource) error
|
||||
}
|
||||
|
||||
// Template is micro deployment template
|
||||
type Template struct {
|
||||
Metadata *Metadata `json:"metadata,omitempty"`
|
||||
// DefaultService returns default micro kubernetes service definition
|
||||
func DefaultService(name, version string) *Service {
|
||||
Labels := map[string]string{
|
||||
"name": name,
|
||||
"version": version,
|
||||
"micro": "service",
|
||||
}
|
||||
|
||||
svcName := name
|
||||
if len(version) > 0 {
|
||||
// API service object name joins name and version over "-"
|
||||
svcName = strings.Join([]string{name, version}, "-")
|
||||
|
||||
}
|
||||
|
||||
Metadata := &Metadata{
|
||||
Name: svcName,
|
||||
Namespace: "default",
|
||||
Version: version,
|
||||
Labels: Labels,
|
||||
}
|
||||
|
||||
Spec := &ServiceSpec{
|
||||
Type: "ClusterIP",
|
||||
Selector: Labels,
|
||||
Ports: []ServicePort{{
|
||||
name + "-port", 9090, "",
|
||||
}},
|
||||
}
|
||||
|
||||
return &Service{
|
||||
Metadata: Metadata,
|
||||
Spec: Spec,
|
||||
}
|
||||
}
|
||||
|
||||
// Spec defines micro deployment spec
|
||||
type Spec struct {
|
||||
Template *Template `json:"template,omitempty"`
|
||||
}
|
||||
// DefaultService returns default micro kubernetes deployment definition
|
||||
func DefaultDeployment(name, version string) *Deployment {
|
||||
Labels := map[string]string{
|
||||
"name": name,
|
||||
"version": version,
|
||||
"micro": "service",
|
||||
}
|
||||
|
||||
// Metadata defines api request metadata
|
||||
type Metadata struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
// API deployment object name joins name and version over "="
|
||||
depName := strings.Join([]string{name, version}, "-")
|
||||
|
||||
// DeploymentList
|
||||
type DeploymentList struct {
|
||||
Items []Deployment `json:"items"`
|
||||
}
|
||||
Metadata := &Metadata{
|
||||
Name: depName,
|
||||
Namespace: "default",
|
||||
Version: version,
|
||||
Labels: Labels,
|
||||
}
|
||||
|
||||
// Deployment is Kubernetes deployment
|
||||
type Deployment struct {
|
||||
Metadata *Metadata `json:"metadata"`
|
||||
Status *Status `json:"status"`
|
||||
}
|
||||
// TODO: we need to figure out this version stuff
|
||||
// might be worth adding Build to runtime.Service
|
||||
buildTime, err := strconv.ParseInt(version, 10, 64)
|
||||
if err == nil {
|
||||
buildUnixTimeUTC := time.Unix(buildTime, 0)
|
||||
Metadata.Annotations = map[string]string{
|
||||
"build": buildUnixTimeUTC.Format(time.RFC3339),
|
||||
}
|
||||
} else {
|
||||
log.Debugf("Runtime could not parse build: %v", err)
|
||||
}
|
||||
|
||||
// Status is Kubernetes deployment status
|
||||
type Status struct {
|
||||
Replicas int `json:"replicas"`
|
||||
AvailableReplicas int `json:"availablereplicas"`
|
||||
// TODO: change the image name here
|
||||
Spec := &DeploymentSpec{
|
||||
Replicas: 1,
|
||||
Selector: &LabelSelector{
|
||||
MatchLabels: Labels,
|
||||
},
|
||||
Template: &Template{
|
||||
Metadata: Metadata,
|
||||
PodSpec: &PodSpec{
|
||||
Containers: []Container{{
|
||||
Name: name,
|
||||
Image: DefaultImage,
|
||||
Env: []EnvVar{},
|
||||
Command: []string{"go", "run", "main.go"},
|
||||
Ports: []ContainerPort{{
|
||||
Name: name + "-port",
|
||||
ContainerPort: 8080,
|
||||
}},
|
||||
}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return &Deployment{
|
||||
Metadata: Metadata,
|
||||
Spec: Spec,
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user