func (m *Master) installTunneler(nodeTunneler tunneler.Tunneler, nodeClient corev1client.NodeInterface) {
nodeTunneler.Run(nodeAddressProvider{nodeClient}.externalAddresses)
m.GenericAPIServer.AddHealthzChecks(healthz.NamedCheck("SSH Tunnel Check", tunneler.TunnelSyncHealthChecker(nodeTunneler)))
prometheus.NewGaugeFunc(prometheus.GaugeOpts{
Name: "apiserver_proxy_tunnel_sync_latency_secs",
Help: "The time since the last successful synchronization of the SSH tunnels for proxy requests.",
}, func() float64 { return float64(nodeTunneler.SecondsSinceSync()) })
}
func ExampleGaugeFunc() {
if err := prometheus.Register(prometheus.NewGaugeFunc(
prometheus.GaugeOpts{
Subsystem: "runtime",
Name: "goroutines_count",
Help: "Number of goroutines that currently exist.",
},
func() float64 { return float64(runtime.NumGoroutine()) },
)); err == nil {
fmt.Println("GaugeFunc 'goroutines_count' registered.")
}
// Note that the count of goroutines is a gauge (and not a counter) as
// it can go up and down.
// Output:
// GaugeFunc 'goroutines_count' registered.
}
// NewCollector returns a prometheus.Collector for a given stats var.
// It supports all stats var types except String, StringFunc and Rates.
// The returned collector still needs to be registered with prometheus registry.
func NewCollector(opts prometheus.Opts, v expvar.Var) prometheus.Collector {
switch st := v.(type) {
case *stats.Int:
return prometheus.NewGaugeFunc(prometheus.GaugeOpts(opts), func() float64 {
return float64(st.Get())
})
case stats.IntFunc:
return prometheus.NewGaugeFunc(prometheus.GaugeOpts(opts), func() float64 {
return float64(st())
})
case *stats.Duration:
return prometheus.NewGaugeFunc(prometheus.GaugeOpts(opts), func() float64 {
return st.Get().Seconds()
})
case stats.DurationFunc:
return prometheus.NewGaugeFunc(prometheus.GaugeOpts(opts), func() float64 {
return st().Seconds()
})
case *stats.Float:
return prometheus.NewGaugeFunc(prometheus.GaugeOpts(opts), st.Get)
case stats.FloatFunc:
return prometheus.NewGaugeFunc(prometheus.GaugeOpts(opts), st)
case *stats.Counters:
return newCountersCollector(opts, st, "tag")
case stats.CountersFunc:
return newCountersCollector(opts, st, "tag")
case *stats.MultiCounters:
return newCountersCollector(opts, st, st.Labels()...)
case *stats.MultiCountersFunc:
return newCountersCollector(opts, st, st.Labels()...)
case *stats.Histogram:
return newHistogramCollector(opts, st)
case *stats.Timings:
return newTimingsCollector(opts, st, "category")
case *stats.MultiTimings:
return newTimingsCollector(opts, &st.Timings, st.Labels()...)
case *stats.String:
// prometheus can't collect string values
return nil
case stats.StringFunc:
// prometheus can't collect string values
return nil
case *stats.Rates:
// Ignore these, because monitoring tools will calculate
// rates for us.
return nil
default:
log.Warningf("Unsupported type for %s: %T", opts.Name, v)
return nil
}
}
// TODO this needs to be refactored so we have a way to add general health checks to genericapiserver
// TODO profiling should be generic
func (m *Master) InstallGeneralEndpoints(c *Config) {
// Run the tunneler.
healthzChecks := []healthz.HealthzChecker{}
if c.Tunneler != nil {
c.Tunneler.Run(m.getNodeAddresses)
healthzChecks = append(healthzChecks, healthz.NamedCheck("SSH Tunnel Check", genericapiserver.TunnelSyncHealthChecker(c.Tunneler)))
prometheus.NewGaugeFunc(prometheus.GaugeOpts{
Name: "apiserver_proxy_tunnel_sync_latency_secs",
Help: "The time since the last successful synchronization of the SSH tunnels for proxy requests.",
}, func() float64 { return float64(c.Tunneler.SecondsSinceSync()) })
}
healthz.InstallHandler(&m.GenericAPIServer.HandlerContainer.NonSwaggerRoutes, healthzChecks...)
if c.GenericConfig.EnableProfiling {
routes.MetricsWithReset{}.Install(m.GenericAPIServer.HandlerContainer)
} else {
routes.DefaultMetrics{}.Install(m.GenericAPIServer.HandlerContainer)
}
}
//.........这里部分代码省略.........
// public keyfile is written last, so check for that.
publicKeyFile := c.SSHKeyfile + ".pub"
exists, err := util.FileExists(publicKeyFile)
if err != nil {
glog.Errorf("Error detecting if key exists: %v", err)
} else if !exists {
glog.Infof("Key doesn't exist, attempting to create")
err := m.generateSSHKey(c.SSHUser, c.SSHKeyfile, publicKeyFile)
if err != nil {
glog.Errorf("Failed to create key pair: %v", err)
}
}
m.tunnels = &util.SSHTunnelList{}
m.dialer = m.Dial
m.setupSecureProxy(c.SSHUser, c.SSHKeyfile, publicKeyFile)
m.lastSync = m.clock.Now().Unix()
// This is pretty ugly. A better solution would be to pull this all the way up into the
// server.go file.
httpKubeletClient, ok := c.KubeletClient.(*client.HTTPKubeletClient)
if ok {
httpKubeletClient.Config.Dial = m.dialer
transport, err := client.MakeTransport(httpKubeletClient.Config)
if err != nil {
glog.Errorf("Error setting up transport over SSH: %v", err)
} else {
httpKubeletClient.Client.Transport = transport
}
} else {
glog.Errorf("Failed to cast %v to HTTPKubeletClient, skipping SSH tunnel.", c.KubeletClient)
}
healthzChecks = append(healthzChecks, healthz.NamedCheck("SSH Tunnel Check", m.IsTunnelSyncHealthy))
m.lastSyncMetric = prometheus.NewGaugeFunc(prometheus.GaugeOpts{
Name: "apiserver_proxy_tunnel_sync_latency_secs",
Help: "The time since the last successful synchronization of the SSH tunnels for proxy requests.",
}, func() float64 { return float64(m.secondsSinceSync()) })
}
apiVersions := []string{}
if m.v1 {
if err := m.api_v1().InstallREST(m.handlerContainer); err != nil {
glog.Fatalf("Unable to setup API v1: %v", err)
}
apiVersions = append(apiVersions, "v1")
}
apiserver.InstallSupport(m.muxHelper, m.rootWebService, c.EnableProfiling, healthzChecks...)
apiserver.AddApiWebService(m.handlerContainer, c.APIPrefix, apiVersions)
defaultVersion := m.defaultAPIGroupVersion()
requestInfoResolver := &apiserver.APIRequestInfoResolver{APIPrefixes: util.NewStringSet(strings.TrimPrefix(defaultVersion.Root, "/")), RestMapper: defaultVersion.Mapper}
apiserver.InstallServiceErrorHandler(m.handlerContainer, requestInfoResolver, apiVersions)
if m.exp {
expVersion := m.expapi(c)
if err := expVersion.InstallREST(m.handlerContainer); err != nil {
glog.Fatalf("Unable to setup experimental api: %v", err)
}
apiserver.AddApiWebService(m.handlerContainer, c.ExpAPIPrefix, []string{expVersion.Version})
expRequestInfoResolver := &apiserver.APIRequestInfoResolver{APIPrefixes: util.NewStringSet(strings.TrimPrefix(expVersion.Root, "/")), RestMapper: expVersion.Mapper}
apiserver.InstallServiceErrorHandler(m.handlerContainer, expRequestInfoResolver, []string{expVersion.Version})
}
// Register root handler.
// We do not register this using restful Webservice since we do not want to surface this in api docs.
// Allow master to be embedded in contexts which already have something registered at the root
func (m *Master) InstallAPIs(c *Config) {
apiGroupsInfo := []genericapiserver.APIGroupInfo{}
// Install v1 unless disabled.
if c.APIResourceConfigSource.AnyResourcesForVersionEnabled(apiv1.SchemeGroupVersion) {
// Install v1 API.
m.initV1ResourcesStorage(c)
apiGroupInfo := genericapiserver.APIGroupInfo{
GroupMeta: *registered.GroupOrDie(api.GroupName),
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{
"v1": m.v1ResourcesStorage,
},
IsLegacyGroup: true,
Scheme: api.Scheme,
ParameterCodec: api.ParameterCodec,
NegotiatedSerializer: api.Codecs,
}
if autoscalingGroupVersion := (unversioned.GroupVersion{Group: "autoscaling", Version: "v1"}); registered.IsEnabledVersion(autoscalingGroupVersion) {
apiGroupInfo.SubresourceGroupVersionKind = map[string]unversioned.GroupVersionKind{
"replicationcontrollers/scale": autoscalingGroupVersion.WithKind("Scale"),
}
}
apiGroupsInfo = append(apiGroupsInfo, apiGroupInfo)
}
// Run the tunneler.
healthzChecks := []healthz.HealthzChecker{}
if m.tunneler != nil {
m.tunneler.Run(m.getNodeAddresses)
healthzChecks = append(healthzChecks, healthz.NamedCheck("SSH Tunnel Check", m.IsTunnelSyncHealthy))
prometheus.NewGaugeFunc(prometheus.GaugeOpts{
Name: "apiserver_proxy_tunnel_sync_latency_secs",
Help: "The time since the last successful synchronization of the SSH tunnels for proxy requests.",
}, func() float64 { return float64(m.tunneler.SecondsSinceSync()) })
}
healthz.InstallHandler(m.MuxHelper, healthzChecks...)
if c.EnableProfiling {
m.MuxHelper.HandleFunc("/metrics", MetricsWithReset)
} else {
m.MuxHelper.HandleFunc("/metrics", defaultMetricsHandler)
}
// Install third party resource support if requested
// TODO seems like this bit ought to be unconditional and the REST API is controlled by the config
if c.APIResourceConfigSource.ResourceEnabled(extensionsapiv1beta1.SchemeGroupVersion.WithResource("thirdpartyresources")) {
var err error
m.thirdPartyStorage, err = c.StorageFactory.New(extensions.Resource("thirdpartyresources"))
if err != nil {
glog.Fatalf("Error getting third party storage: %v", err)
}
m.thirdPartyResources = map[string]thirdPartyEntry{}
}
restOptionsGetter := func(resource unversioned.GroupResource) generic.RESTOptions {
return m.GetRESTOptionsOrDie(c, resource)
}
// stabilize order.
// TODO find a better way to configure priority of groups
for _, group := range sets.StringKeySet(c.RESTStorageProviders).List() {
if !c.APIResourceConfigSource.AnyResourcesForGroupEnabled(group) {
continue
}
restStorageBuilder := c.RESTStorageProviders[group]
apiGroupInfo, enabled := restStorageBuilder.NewRESTStorage(c.APIResourceConfigSource, restOptionsGetter)
if !enabled {
continue
}
apiGroupsInfo = append(apiGroupsInfo, apiGroupInfo)
}
if err := m.InstallAPIGroups(apiGroupsInfo); err != nil {
glog.Fatalf("Error in registering group versions: %v", err)
}
}
func (m *Master) InstallAPIs(c *Config) {
restOptionsGetter := func(resource unversioned.GroupResource) generic.RESTOptions {
return m.restOptionsFactory.NewFor(resource)
}
apiGroupsInfo := []genericapiserver.APIGroupInfo{}
// Install v1 unless disabled.
if c.GenericConfig.APIResourceConfigSource.AnyResourcesForVersionEnabled(apiv1.SchemeGroupVersion) {
legacyRESTStorage, apiGroupInfo, err := m.legacyRESTStorageProvider.NewLegacyRESTStorage(restOptionsGetter)
if err != nil {
glog.Fatalf("Error building core storage: %v", err)
}
m.legacyRESTStorage = legacyRESTStorage
apiGroupsInfo = append(apiGroupsInfo, apiGroupInfo)
}
// Run the tunneler.
healthzChecks := []healthz.HealthzChecker{}
if m.tunneler != nil {
m.tunneler.Run(m.getNodeAddresses)
healthzChecks = append(healthzChecks, healthz.NamedCheck("SSH Tunnel Check", m.IsTunnelSyncHealthy))
prometheus.NewGaugeFunc(prometheus.GaugeOpts{
Name: "apiserver_proxy_tunnel_sync_latency_secs",
Help: "The time since the last successful synchronization of the SSH tunnels for proxy requests.",
}, func() float64 { return float64(m.tunneler.SecondsSinceSync()) })
}
healthz.InstallHandler(&m.HandlerContainer.NonSwaggerRoutes, healthzChecks...)
if c.GenericConfig.EnableProfiling {
routes.MetricsWithReset{}.Install(m.HandlerContainer)
} else {
routes.DefaultMetrics{}.Install(m.HandlerContainer)
}
// Install third party resource support if requested
// TODO seems like this bit ought to be unconditional and the REST API is controlled by the config
if c.GenericConfig.APIResourceConfigSource.ResourceEnabled(extensionsapiv1beta1.SchemeGroupVersion.WithResource("thirdpartyresources")) {
var err error
m.thirdPartyStorageConfig, err = c.StorageFactory.NewConfig(extensions.Resource("thirdpartyresources"))
if err != nil {
glog.Fatalf("Error getting third party storage: %v", err)
}
m.thirdPartyResources = map[string]*thirdPartyEntry{}
}
// stabilize order.
// TODO find a better way to configure priority of groups
for _, group := range sets.StringKeySet(c.RESTStorageProviders).List() {
if !c.GenericConfig.APIResourceConfigSource.AnyResourcesForGroupEnabled(group) {
glog.V(1).Infof("Skipping disabled API group %q.", group)
continue
}
restStorageBuilder := c.RESTStorageProviders[group]
apiGroupInfo, enabled := restStorageBuilder.NewRESTStorage(c.GenericConfig.APIResourceConfigSource, restOptionsGetter)
if !enabled {
glog.Warningf("Problem initializing API group %q, skipping.", group)
continue
}
glog.V(1).Infof("Enabling API group %q.", group)
if postHookProvider, ok := restStorageBuilder.(genericapiserver.PostStartHookProvider); ok {
name, hook, err := postHookProvider.PostStartHook()
if err != nil {
glog.Fatalf("Error building PostStartHook: %v", err)
}
if err := m.GenericAPIServer.AddPostStartHook(name, hook); err != nil {
glog.Fatalf("Error registering PostStartHook %q: %v", name, err)
}
}
apiGroupsInfo = append(apiGroupsInfo, apiGroupInfo)
}
for i := range apiGroupsInfo {
if err := m.InstallAPIGroup(&apiGroupsInfo[i]); err != nil {
glog.Fatalf("Error in registering group versions: %v", err)
}
}
}
availFS = flag.String("varz_avail_fs",
"/dcs-ssd",
"If non-empty, /varz will contain the number of available bytes on the specified filesystem")
)
const (
bytesPerSector = 512
)
var (
memAllocBytesGauge = prometheus.NewGaugeFunc(
prometheus.GaugeOpts{
Subsystem: "process",
Name: "mem_alloc_bytes",
Help: "Bytes allocated and still in use.",
},
func() float64 {
var m runtime.MemStats
runtime.ReadMemStats(&m)
return float64(m.Alloc)
},
)
availFSGauge = prometheus.NewGaugeFunc(
prometheus.GaugeOpts{
Name: "avail_fs_bytes",
Help: "Number of available bytes on -varz_avail_fs.",
},
func() float64 {
if *availFS != "" {
var stat syscall.Statfs_t
if err := syscall.Statfs(*availFS, &stat); err != nil {
开发者ID:jamessan,项目名称:dcs,代码行数:32,代码来源:varz.go
示例14:
peerStore *raft.JSONPeers
ircStore *raft_store.LevelDBStore
ircServer *ircserver.IRCServer
executablehash = executableHash()
// Version is overwritten by Makefile.
Version = "unknown"
isLeaderGauge = prometheus.NewGaugeFunc(
prometheus.GaugeOpts{
Subsystem: "raft",
Name: "isleader",
Help: "1 if this node is the raft leader, 0 otherwise",
},
func() float64 {
if node.State() == raft.Leader {
return 1
}
return 0
},
)
sessionsGauge = prometheus.NewGaugeFunc(
prometheus.GaugeOpts{
Subsystem: "irc",
Name: "sessions",
Help: "Number of IRC sessions",
},
func() float64 {
return float64(ircServer.NumSessions())
请发表评论