Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hubble: Use a single string to configure the server address #11330

Merged
merged 3 commits into from May 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Documentation/cmdref/cilium-agent.md
Expand Up @@ -99,7 +99,7 @@ cilium-agent [flags]
--http-retry-timeout uint Time after which a forwarded but uncompleted request is retried (connection failures are retried immediately); defaults to 0 (never)
--hubble-event-queue-size int Buffer size of the channel to receive monitor events.
--hubble-flow-buffer-size int Maximum number of flows in Hubble's buffer. The actual buffer size gets rounded up to the next power of 2, e.g. 4095 => 4096 (default 4095)
--hubble-listen-addresses strings List of additional addresses for Hubble server to listen to
--hubble-listen-address string An additional address for Hubble server to listen to, e.g. ":4244"
--hubble-metrics strings List of Hubble metrics to enable.
--hubble-metrics-server string Address to serve Hubble metrics on.
--hubble-socket-path string Set hubble's socket path to listen for connections (default "/var/run/cilium/hubble.sock")
Expand Down
4 changes: 2 additions & 2 deletions daemon/cmd/daemon_main.go
Expand Up @@ -752,8 +752,8 @@ func init() {
flags.String(option.HubbleSocketPath, defaults.HubbleSockPath, "Set hubble's socket path to listen for connections")
option.BindEnv(option.HubbleSocketPath)

flags.StringSlice(option.HubbleListenAddresses, []string{}, "List of additional addresses for Hubble server to listen to")
option.BindEnv(option.HubbleListenAddresses)
flags.String(option.HubbleListenAddress, "", `An additional address for Hubble server to listen to, e.g. ":4244"`)
option.BindEnv(option.HubbleListenAddress)

flags.Int(option.HubbleFlowBufferSize, 4095, "Maximum number of flows in Hubble's buffer. The actual buffer size gets rounded up to the next power of 2, e.g. 4095 => 4096")
option.BindEnv(option.HubbleFlowBufferSize)
Expand Down
17 changes: 6 additions & 11 deletions daemon/cmd/hubble.go
Expand Up @@ -16,7 +16,6 @@ package cmd

import (
"context"
"strings"
"time"

"github.com/cilium/cilium/api/v1/models"
Expand Down Expand Up @@ -84,13 +83,6 @@ func (d *Daemon) launchHubble() {
logger.Info("Hubble server is disabled")
return
}
addresses := option.Config.HubbleListenAddresses
for _, address := range addresses {
// TODO: remove warning once mutual TLS has been implemented
if !strings.HasPrefix(address, "unix://") {
logger.WithField("address", address).Warn("Hubble server will be exposing its API insecurely on this address")
}
}

payloadParser, err := parser.New(d, d, d, ipcache.IPIdentityCache, d)
if err != nil {
Expand Down Expand Up @@ -131,17 +123,20 @@ func (d *Daemon) launchHubble() {
}()

// configure another hubble instance that serve fewer gRPC services
if len(addresses) > 0 {
address := option.Config.HubbleListenAddress
if address != "" {
// TODO: remove warning once mutual TLS has been implemented
logger.WithField("address", address).Warn("Hubble server will be exposing its API insecurely on this address")
srv, err := server.NewServer(logger,
serveroption.WithListeners(addresses),
serveroption.WithTCPListener(address),
serveroption.WithHealthService(),
serveroption.WithObserverService(d.hubbleObserver),
)
if err != nil {
logger.WithError(err).Error("Failed to initialize Hubble server")
return
}
logger.WithField("addresses", addresses).Info("Starting Hubble server")
logger.WithField("address", address).Info("Starting Hubble server")
if err := srv.Serve(); err != nil {
logger.WithError(err).Error("Failed to start Hubble server")
return
Expand Down
19 changes: 0 additions & 19 deletions install/kubernetes/cilium/charts/agent/templates/svc.yaml
Expand Up @@ -17,25 +17,6 @@ spec:
selector:
k8s-app: cilium
{{- end }}
{{- if .Values.global.hubble.ui.enabled }}
---
kind: Service
apiVersion: v1
metadata:
name: hubble-grpc
namespace: {{ .Release.Namespace }}
labels:
k8s-app: hubble
spec:
type: ClusterIP
clusterIP: None
selector:
k8s-app: cilium
ports:
- targetPort: 50051
protocol: TCP
port: 50051
{{- end }}
{{- if and .Values.global.hubble.metrics.enabled (.Values.global.hubble.metrics.serviceMonitor.enabled) }}
---
kind: Service
Expand Down
Expand Up @@ -435,12 +435,8 @@ data:
{{.}}
{{- end }}
{{- end }}
# A space separated list of additional addresses for Hubble server to listen to (e.g. ":50051 :50052").
{{- if and .Values.global.hubble.ui.enabled (not (has "0.0.0.0:50051" .Values.global.hubble.listenAddresses)) }}
hubble-listen-addresses: {{ append .Values.global.hubble.listenAddresses "0.0.0.0:50051" | join " " | quote }}
{{- else }}
hubble-listen-addresses: {{ .Values.global.hubble.listenAddresses | join " " | quote }}
{{- end }}
# An additional address for Hubble server to listen to (e.g. ":4244").
hubble-listen-address: {{ .Values.global.hubble.listenAddress | quote }}
{{- end }}

# A space separated list of iptables chains to disable when installing feeder rules.
Expand Down
Expand Up @@ -26,9 +26,9 @@ spec:
- name: HUBBLE
value: "true"
- name: HUBBLE_SERVICE
value: "hubble-grpc.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }}"
value: "hubble-relay.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }}"
- name: HUBBLE_PORT
value: "50051"
value: "80"
ports:
- containerPort: 12000
name: http
Expand Down
13 changes: 5 additions & 8 deletions install/kubernetes/cilium/values.yaml
Expand Up @@ -432,16 +432,13 @@ global:
enabled: false
# Default unix domain socket path to listen to when Hubble is enabled. Default to "/var/run/cilium/hubble.sock".
socketPath: /var/run/cilium/hubble.sock
# List of additional addresses to listen to, for example:
# An additional address to listen to, for example:
#
# listenAddresses:
# - ":50051"
# - ":50052"
# listenAddress: ":4244"
#
# You can specify the list of metrics from the helm CLI:
#
# --set global.hubble.listenAddresses={:50051,:50052}
listenAddresses: []
# Set this field ":4244" if you are enabling hubble-relay, as it assumes that Hubble is listening
# on port 4244.
listenAddress: ""
# Buffer size of the channel Hubble uses to receive monitor events. If this value is not set,
# the queue size is set to the default monitor queue size.
eventQueueSize: ~
Expand Down
21 changes: 11 additions & 10 deletions pkg/hubble/server/server.go
Expand Up @@ -38,9 +38,7 @@ type Server struct {

// NewServer creates a new hubble gRPC server.
func NewServer(log *logrus.Entry, options ...serveroption.Option) (*Server, error) {
opts := serveroption.Options{
Listeners: make(map[string]net.Listener),
}
opts := serveroption.Options{}
for _, opt := range options {
if err := opt(&opts); err != nil {
return nil, fmt.Errorf("failed to apply option: %v", err)
Expand Down Expand Up @@ -68,13 +66,16 @@ func (s *Server) initGRPCServer() {
// listeners. Stop should be called to stop the server.
func (s *Server) Serve() error {
s.initGRPCServer()
for name, listener := range s.opts.Listeners {
go func(name string, listener net.Listener) {
s.log.WithField("listener", name).Info("Starting gRPC server on listener")
if err := s.srv.Serve(listener); err != nil {
s.log.WithError(err).Error("failed to close grpc server")
}
}(name, listener)
for _, listener := range []net.Listener{s.opts.UnixSocketListener, s.opts.TCPListener} {
if listener != nil {
go func(listener net.Listener) {
if err := s.srv.Serve(listener); err != nil {
s.log.WithError(err).
WithField("address", listener.Addr().String()).
Error("failed to start grpc server")
}
}(listener)
}
}
return nil
}
Expand Down
41 changes: 9 additions & 32 deletions pkg/hubble/server/serveroption/option.go
Expand Up @@ -33,51 +33,28 @@ import (

// Options stores all the configuration values for the hubble server.
type Options struct {
Listeners map[string]net.Listener
HealthService healthpb.HealthServer
ObserverService observerpb.ObserverServer
PeerService peerpb.PeerServer
TCPListener net.Listener
UnixSocketListener net.Listener
HealthService healthpb.HealthServer
ObserverService observerpb.ObserverServer
PeerService peerpb.PeerServer
}

// Option customizes then configuration of the hubble server.
type Option func(o *Options) error

// WithListeners configures listeners. Addresses that are prefixed with
// 'unix://' are assumed to be UNIX domain sockets, in which case appropriate
// permissions are tentatively set and the group owner is set to socketGroup.
// Otherwise, the address is assumed to be TCP.
func WithListeners(addresses []string) Option {
return func(o *Options) error {
var opt Option
for _, address := range addresses {
if strings.HasPrefix(address, "unix://") {
opt = WithUnixSocketListener(address)
} else {
opt = WithTCPListener(address)
}
if err := opt(o); err != nil {
for _, l := range o.Listeners {
l.Close()
}
return err
}
}
return nil
}
}

// WithTCPListener configures a TCP listener with the address.
func WithTCPListener(address string) Option {
return func(o *Options) error {
socket, err := net.Listen("tcp", address)
if err != nil {
return err
}
if _, exist := o.Listeners[address]; exist {
if o.TCPListener != nil {
socket.Close()
return fmt.Errorf("listener already configured: %s", address)
}
o.Listeners[address] = socket
o.TCPListener = socket
return nil
}
}
Expand All @@ -98,12 +75,12 @@ func WithUnixSocketListener(path string) Option {
return err
}
}
if _, exist := o.Listeners[path]; exist {
if o.UnixSocketListener != nil {
socket.Close()
unix.Unlink(socketPath)
return fmt.Errorf("listener already configured: %s", path)
}
o.Listeners[path] = socket
o.UnixSocketListener = socket
return nil
}
}
Expand Down
12 changes: 6 additions & 6 deletions pkg/option/config.go
Expand Up @@ -725,8 +725,8 @@ const (
// HubbleSocketPath specifies the UNIX domain socket for Hubble server to listen to.
HubbleSocketPath = "hubble-socket-path"

// HubbleListenAddresses specifies addresses for Hubble server to listen to.
HubbleListenAddresses = "hubble-listen-addresses"
// HubbleListenAddress specifies address for Hubble server to listen to.
HubbleListenAddress = "hubble-listen-address"

// HubbleFlowBufferSize specifies the maximum number of flows in Hubble's buffer.
HubbleFlowBufferSize = "hubble-flow-buffer-size"
Expand Down Expand Up @@ -968,7 +968,7 @@ var HelpFlagSections = []FlagsSection{
Flags: []string{
EnableHubble,
HubbleSocketPath,
HubbleListenAddresses,
HubbleListenAddress,
HubbleFlowBufferSize,
HubbleEventQueueSize,
HubbleMetricsServer,
Expand Down Expand Up @@ -1733,8 +1733,8 @@ type DaemonConfig struct {
// HubbleSocketPath specifies the UNIX domain socket for Hubble server to listen to.
HubbleSocketPath string

// HubbleListenAddresses specifies addresses for Hubble to listen to.
HubbleListenAddresses []string
// HubbleListenAddress specifies address for Hubble to listen to.
HubbleListenAddress string

// HubbleFlowBufferSize specifies the maximum number of flows in Hubble's buffer.
HubbleFlowBufferSize int
Expand Down Expand Up @@ -2422,7 +2422,7 @@ func (c *DaemonConfig) Populate() {
// Hubble options.
c.EnableHubble = viper.GetBool(EnableHubble)
c.HubbleSocketPath = viper.GetString(HubbleSocketPath)
c.HubbleListenAddresses = viper.GetStringSlice(HubbleListenAddresses)
c.HubbleListenAddress = viper.GetString(HubbleListenAddress)
c.HubbleFlowBufferSize = viper.GetInt(HubbleFlowBufferSize)
c.HubbleEventQueueSize = viper.GetInt(HubbleEventQueueSize)
if c.HubbleEventQueueSize == 0 {
Expand Down