add controllers
change kiali mux to go-restful add knative add health api
This commit is contained in:
@@ -68,8 +68,8 @@ func addWebService(c *restful.Container) error {
|
||||
To(metrics.GetWorkloadMetrics).
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Doc("Get workload metrics from a specific namespace").
|
||||
Param(webservice.PathParameter("namespace", "name of the namespace")).
|
||||
Param(webservice.PathParameter("workload", "name of the workload")).
|
||||
Param(webservice.PathParameter("namespace", "name of the namespace").Required(true)).
|
||||
Param(webservice.PathParameter("workload", "name of the workload").Required(true)).
|
||||
Param(webservice.QueryParameter("filters[]", "type of metrics type, e.g. request_count, request_duration, request_error_count")).
|
||||
Param(webservice.QueryParameter("queryTime", "from which UNIX time to extract metrics")).
|
||||
Param(webservice.QueryParameter("duration", "metrics duration, in seconds")).
|
||||
@@ -87,7 +87,7 @@ func addWebService(c *restful.Container) error {
|
||||
To(metrics.GetNamespaceMetrics).
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Doc("Get workload metrics from a specific namespace").
|
||||
Param(webservice.PathParameter("namespace", "name of the namespace")).
|
||||
Param(webservice.PathParameter("namespace", "name of the namespace").Required(true)).
|
||||
Param(webservice.QueryParameter("filters[]", "type of metrics type, e.g. request_count, request_duration, request_error_count")).
|
||||
Param(webservice.QueryParameter("queryTime", "from which UNIX time to extract metrics")).
|
||||
Param(webservice.QueryParameter("duration", "metrics duration, in seconds")).
|
||||
@@ -105,7 +105,7 @@ func addWebService(c *restful.Container) error {
|
||||
To(metrics.GetNamespaceGraph).
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Doc("Get service graph for a specific namespace").
|
||||
Param(webservice.PathParameter("namespace", "name of a namespace")).
|
||||
Param(webservice.PathParameter("namespace", "name of a namespace").Required(true)).
|
||||
Param(webservice.QueryParameter("graphType", "type of the generated service graph, eg. ")).
|
||||
Param(webservice.QueryParameter("groupBy", "group nodes by kind")).
|
||||
Param(webservice.QueryParameter("queryTime", "from which time point, default now")).
|
||||
@@ -118,7 +118,7 @@ func addWebService(c *restful.Container) error {
|
||||
To(metrics.GetNamespacesGraph).
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Doc("Get service graph for a specific namespace").
|
||||
Param(webservice.PathParameter("namespace", "name of a namespace")).
|
||||
Param(webservice.PathParameter("namespace", "name of a namespace").Required(true)).
|
||||
Param(webservice.QueryParameter("graphType", "type of the generated service graph, eg. ")).
|
||||
Param(webservice.QueryParameter("groupBy", "group nodes by kind")).
|
||||
Param(webservice.QueryParameter("queryTime", "from which time point, default now")).
|
||||
@@ -126,6 +126,39 @@ func addWebService(c *restful.Container) error {
|
||||
Param(webservice.QueryParameter("namespaces", "names of namespaces")).
|
||||
Writes(errors.Error{})).Produces(restful.MIME_JSON)
|
||||
|
||||
// Get workloads health
|
||||
webservice.Route(webservice.GET("/namespaces/{namespace}/workloads/{workload}/health").
|
||||
To(metrics.GetWorkloadHealth).
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Doc("Get workload health").
|
||||
Param(webservice.PathParameter("namespace", "name of a namespace").Required(true)).
|
||||
Param(webservice.PathParameter("workload", "workload name").Required(true)).
|
||||
Param(webservice.QueryParameter("rateInterval", "the rate interval used for fetching error rate").DefaultValue("10m").Required(true)).
|
||||
Param(webservice.QueryParameter("queryTime", "the time to use for query")).
|
||||
Writes(errors.Error{})).Produces(restful.MIME_JSON)
|
||||
|
||||
// Get app health
|
||||
webservice.Route(webservice.GET("/namespaces/{namespace}/apps/{app}/health").
|
||||
To(metrics.GetAppHealth).
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Doc("Get workload health").
|
||||
Param(webservice.PathParameter("namespace", "name of a namespace").Required(true)).
|
||||
Param(webservice.PathParameter("app", "app name").Required(true)).
|
||||
Param(webservice.QueryParameter("rateInterval", "the rate interval used for fetching error rate").DefaultValue("10m").Required(true)).
|
||||
Param(webservice.QueryParameter("queryTime", "the time to use for query")).
|
||||
Writes(errors.Error{})).Produces(restful.MIME_JSON)
|
||||
|
||||
// Get service health
|
||||
webservice.Route(webservice.GET("/namespaces/{namespace}/services/{service}/health").
|
||||
To(metrics.GetServiceHealth).
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Doc("Get workload health").
|
||||
Param(webservice.PathParameter("namespace", "name of a namespace").Required(true)).
|
||||
Param(webservice.PathParameter("service", "service name").Required(true)).
|
||||
Param(webservice.QueryParameter("rateInterval", "the rate interval used for fetching error rate").DefaultValue("10m").Required(true)).
|
||||
Param(webservice.QueryParameter("queryTime", "the time to use for query")).
|
||||
Writes(errors.Error{})).Produces(restful.MIME_JSON)
|
||||
|
||||
c.Add(webservice)
|
||||
|
||||
return nil
|
||||
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
ApiRootPath = "/apis"
|
||||
ApiRootPath = "/kapis"
|
||||
)
|
||||
|
||||
// container holds all webservice of apiserver
|
||||
|
||||
@@ -48,3 +48,18 @@ func GetNamespaceGraph(request *restful.Request, response *restful.Response) {
|
||||
func GetNamespacesGraph(request *restful.Request, response *restful.Response) {
|
||||
handlers.GraphNamespaces(request, response)
|
||||
}
|
||||
|
||||
// Get workload health
|
||||
func GetWorkloadHealth(request *restful.Request, response *restful.Response) {
|
||||
handlers.WorkloadHealth(request, response)
|
||||
}
|
||||
|
||||
// Get app health
|
||||
func GetAppHealth(request *restful.Request, response *restful.Response) {
|
||||
handlers.AppHealth(request, response)
|
||||
}
|
||||
|
||||
// Get service health
|
||||
func GetServiceHealth(request *restful.Request, response *restful.Response) {
|
||||
handlers.ServiceHealth(request, response)
|
||||
}
|
||||
|
||||
@@ -139,10 +139,6 @@ func (v *DestinationRuleController) Run(workers int, stopCh <-chan struct{}) {
|
||||
go wait.Until(v.worker, v.workerLoopPeriod, stopCh)
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer utilruntime.HandleCrash()
|
||||
}()
|
||||
|
||||
<-stopCh
|
||||
}
|
||||
|
||||
@@ -222,9 +218,9 @@ func (v *DestinationRuleController) syncService(key string) error {
|
||||
}
|
||||
|
||||
subset := v1alpha3.Subset{
|
||||
Name: util.NormalizeVersionName(name),
|
||||
Name: util.NormalizeVersionName(version),
|
||||
Labels: map[string]string{
|
||||
util.VersionLabel: name,
|
||||
util.VersionLabel: version,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -239,10 +235,15 @@ func (v *DestinationRuleController) syncService(key string) error {
|
||||
Name: service.Name,
|
||||
Labels: service.Labels,
|
||||
},
|
||||
Spec: v1alpha3.DestinationRuleSpec{
|
||||
Host: name,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
log.Error(err, "Couldn't get destinationrule for service", "key", key)
|
||||
return err
|
||||
}
|
||||
log.Error(err, "Couldn't get destinationrule for service", "key", key)
|
||||
return err
|
||||
|
||||
}
|
||||
|
||||
createDestinationRule := len(currentDestinationRule.Spec.Subsets) == 0
|
||||
|
||||
@@ -18,6 +18,7 @@ func getAppNameByStrategy(strategy *v1alpha2.Strategy) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// if virtualservice not specified with port number, then fill with service first port
|
||||
func fillDestinationPort(vs *v1alpha3.VirtualService, service *v1.Service) error {
|
||||
|
||||
if len(service.Spec.Ports) == 0 {
|
||||
@@ -27,14 +28,22 @@ func fillDestinationPort(vs *v1alpha3.VirtualService, service *v1.Service) error
|
||||
// fill http port
|
||||
for i := range vs.Spec.Http {
|
||||
for j := range vs.Spec.Http[i].Route {
|
||||
vs.Spec.Http[i].Route[j].Destination.Port.Number = uint32(service.Spec.Ports[0].Port)
|
||||
if vs.Spec.Http[i].Route[j].Destination.Port.Number == 0 {
|
||||
vs.Spec.Http[i].Route[j].Destination.Port.Number = uint32(service.Spec.Ports[0].Port)
|
||||
}
|
||||
}
|
||||
|
||||
if vs.Spec.Http[i].Mirror != nil && vs.Spec.Http[i].Mirror.Port.Number == 0 {
|
||||
vs.Spec.Http[i].Mirror.Port.Number = uint32(service.Spec.Ports[0].Port)
|
||||
}
|
||||
}
|
||||
|
||||
// fill tcp port
|
||||
for i := range vs.Spec.Tcp {
|
||||
for j := range vs.Spec.Tcp[i].Route {
|
||||
vs.Spec.Tcp[i].Route[j].Destination.Port.Number = uint32(service.Spec.Ports[0].Port)
|
||||
if vs.Spec.Tcp[i].Route[j].Destination.Port.Number == 0 {
|
||||
vs.Spec.Tcp[i].Route[j].Destination.Port.Number = uint32(service.Spec.Ports[0].Port)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ const (
|
||||
// resource with these following labels considered as part of servicemesh
|
||||
var ApplicationLabels = [...]string{
|
||||
ApplicationNameLabel,
|
||||
ApplicationVersionLabel,
|
||||
ServiceMeshEnabledLabel,
|
||||
AppLabel,
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ func NewVirtualServiceController(serviceInformer coreinformers.ServiceInformer,
|
||||
}
|
||||
|
||||
func (v *VirtualServiceController) Start(stopCh <-chan struct{}) error {
|
||||
v.Run(5, stopCh)
|
||||
v.Run(1, stopCh)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -147,10 +147,6 @@ func (v *VirtualServiceController) Run(workers int, stopCh <-chan struct{}) {
|
||||
go wait.Until(v.worker, v.workerLoopPeriod, stopCh)
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer utilruntime.HandleCrash()
|
||||
}()
|
||||
|
||||
<-stopCh
|
||||
}
|
||||
|
||||
@@ -202,7 +198,6 @@ func (v *VirtualServiceController) syncService(key string) error {
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -278,9 +273,7 @@ func (v *VirtualServiceController) syncService(key string) error {
|
||||
if len(vs.Spec.Http) > 0 || len(vs.Spec.Tcp) > 0 {
|
||||
_, err := v.virtualServiceClient.NetworkingV1alpha3().VirtualServices(namespace).Create(vs)
|
||||
if err != nil {
|
||||
|
||||
v.eventRecorder.Eventf(vs, v1.EventTypeWarning, "FailedToCreateVirtualService", "Failed to create virtualservice for service %v/%v: %v", service.Namespace, service.Name, err)
|
||||
|
||||
log.Error(err, "create virtualservice for service failed.", "service", service)
|
||||
return err
|
||||
}
|
||||
@@ -288,7 +281,6 @@ func (v *VirtualServiceController) syncService(key string) error {
|
||||
log.Info("service doesn't have a tcp port.")
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -328,7 +320,6 @@ func (v *VirtualServiceController) addDestinationRule(obj interface{}) {
|
||||
|
||||
func (v *VirtualServiceController) deleteStrategy(obj interface{}) {
|
||||
// nothing to do right now
|
||||
|
||||
}
|
||||
|
||||
func (v *VirtualServiceController) handleErr(err error, key interface{}) {
|
||||
@@ -343,7 +334,7 @@ func (v *VirtualServiceController) handleErr(err error, key interface{}) {
|
||||
return
|
||||
}
|
||||
|
||||
log.V(0).Info("Dropping service %q out of the queue: %v", "key", key, "error", err)
|
||||
log.V(4).Info("Dropping service out of the queue.", "key", key, "error", err)
|
||||
v.queue.Forget(key)
|
||||
utilruntime.HandleError(err)
|
||||
}
|
||||
|
||||
@@ -20,13 +20,10 @@ package k8s
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/mitchellh/go-homedir"
|
||||
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
@@ -37,10 +34,12 @@ var (
|
||||
k8sClient *kubernetes.Clientset
|
||||
k8sClientOnce sync.Once
|
||||
KubeConfig *rest.Config
|
||||
masterURL string
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&kubeConfigFile, "kubeconfig", fmt.Sprintf("%s/.kube/config", os.Getenv("HOME")), "path to kubeconfig file")
|
||||
flag.StringVar(&kubeConfigFile, "kubeconfig", "", "path to kubeconfig file")
|
||||
flag.StringVar(&masterURL, "master-url","", "kube-apiserver url, only needed when out of cluster")
|
||||
}
|
||||
|
||||
func Client() *kubernetes.Clientset {
|
||||
@@ -63,18 +62,8 @@ func Client() *kubernetes.Clientset {
|
||||
|
||||
func Config() (kubeConfig *rest.Config, err error) {
|
||||
|
||||
if kubeConfigFile == "" {
|
||||
if env := os.Getenv("KUBECONFIG"); env != "" {
|
||||
kubeConfigFile = env
|
||||
} else {
|
||||
if home, err := homedir.Dir(); err == nil {
|
||||
kubeConfigFile = fmt.Sprintf("%s/.kube/config", home)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if _, err = os.Stat(kubeConfigFile); err == nil {
|
||||
kubeConfig, err = clientcmd.BuildConfigFromFlags("", kubeConfigFile)
|
||||
kubeConfig, err = clientcmd.BuildConfigFromFlags(masterURL, kubeConfigFile)
|
||||
} else {
|
||||
kubeConfig, err = rest.InClusterConfig()
|
||||
}
|
||||
|
||||
@@ -19,9 +19,10 @@ package namespace
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/golang/glog"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
rbac "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -36,6 +37,8 @@ import (
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
)
|
||||
|
||||
var log = logf.Log.WithName("namespace-controller")
|
||||
|
||||
const threadiness = 2
|
||||
|
||||
var (
|
||||
@@ -54,18 +57,18 @@ type NamespaceController struct {
|
||||
}
|
||||
|
||||
func NewNamespaceController(
|
||||
kubeclientset kubernetes.Interface,
|
||||
clientset kubernetes.Interface,
|
||||
namespaceInformer coreinformers.NamespaceInformer,
|
||||
roleInformer rbacinformers.RoleInformer) *NamespaceController {
|
||||
|
||||
controller := &NamespaceController{
|
||||
clientset: kubeclientset,
|
||||
clientset: clientset,
|
||||
namespaceInformer: namespaceInformer,
|
||||
roleInformer: roleInformer,
|
||||
workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "namespaces"),
|
||||
}
|
||||
|
||||
glog.Info("setting up event handlers")
|
||||
log.V(3).Info("setting up event handlers")
|
||||
|
||||
namespaceInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: controller.handleObject,
|
||||
@@ -86,29 +89,24 @@ func NewNamespaceController(
|
||||
}
|
||||
|
||||
func (c *NamespaceController) Start(stopCh <-chan struct{}) error {
|
||||
go func() {
|
||||
defer utilruntime.HandleCrash()
|
||||
defer c.workqueue.ShutDown()
|
||||
defer utilruntime.HandleCrash()
|
||||
defer c.workqueue.ShutDown()
|
||||
|
||||
// Start the informer factories to begin populating the informer caches
|
||||
glog.Info("starting namespace controller")
|
||||
log.V(3).Info("starting namespace controller")
|
||||
defer glog.Info("shutting down namespace controller")
|
||||
|
||||
// Wait for the caches to be synced before starting workers
|
||||
glog.Info("waiting for informer caches to sync")
|
||||
if ok := cache.WaitForCacheSync(stopCh, c.namespaceInformer.Informer().HasSynced, c.roleInformer.Informer().HasSynced); !ok {
|
||||
glog.Fatalf("controller exit with error: failed to wait for caches to sync")
|
||||
}
|
||||
// Wait for the caches to be synced before starting workers
|
||||
log.Info("waiting for informer caches to sync")
|
||||
if ok := cache.WaitForCacheSync(stopCh, c.namespaceInformer.Informer().HasSynced, c.roleInformer.Informer().HasSynced); !ok {
|
||||
glog.Fatalf("controller exit with error: failed to wait for caches to sync")
|
||||
}
|
||||
|
||||
glog.Info("starting workers")
|
||||
log.V(3).Info("starting workers")
|
||||
for i := 0; i < threadiness; i++ {
|
||||
go wait.Until(c.runWorker, time.Second, stopCh)
|
||||
}
|
||||
|
||||
for i := 0; i < threadiness; i++ {
|
||||
go wait.Until(c.runWorker, time.Second, stopCh)
|
||||
}
|
||||
|
||||
glog.Info("started workers")
|
||||
<-stopCh
|
||||
glog.Info("shutting down workers")
|
||||
}()
|
||||
<-stopCh
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -142,7 +140,7 @@ func (c *NamespaceController) processNextWorkItem() bool {
|
||||
}
|
||||
|
||||
c.workqueue.Forget(obj)
|
||||
glog.Infof("successfully namespace synced '%s'", namespace)
|
||||
log.V(4).Info("successfully namespace synced ", "namespace", namespace)
|
||||
return nil
|
||||
}(obj)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user