proxy

package
v1.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 13, 2018 License: MPL-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package proxy contains logic for agent interaction with proxies, primarily "managed" proxies. Managed proxies are proxy processes for Connect-compatible endpoints that Consul owns and controls the lifecycle for.

This package does not contain the built-in proxy for Connect. The source for that is available in the "connect/proxy" package.

Index

Constants

View Source
const (
	DaemonRestartHealthy    = 10 * time.Second // time before considering healthy
	DaemonRestartBackoffMin = 3                // 3 attempts before backing off
	DaemonRestartMaxWait    = 1 * time.Minute  // maximum backoff wait time
)

Constants related to restart timers with the daemon mode proxies. At some point we will probably want to expose these knobs to an end user, but reasonable defaults are chosen.

View Source
const (
	// ManagerCoalescePeriod and ManagerQuiescentPeriod relate to how
	// notifications in updates from the local state are colaesced to prevent
	// lots of churn in the manager.
	//
	// When the local state updates, the manager will wait for quiescence.
	// For each update, the quiscence timer is reset. If the coalesce period
	// is reached, the manager will update proxies regardless of the frequent
	// changes. Then the whole cycle resets.
	ManagerCoalescePeriod  = 5 * time.Second
	ManagerQuiescentPeriod = 500 * time.Millisecond

	// ManagerSnapshotPeriod is the interval that snapshots are taken.
	// The last snapshot state is preserved and if it matches a file isn't
	// written, so its safe for this to be reasonably frequent.
	ManagerSnapshotPeriod = 1 * time.Second
)
View Source
const (
	// EnvProxyID is the name of the environment variable that is set for
	// managed proxies containing the proxy service ID. This is required along
	// with the token to make API requests related to the proxy.
	EnvProxyID = "CONNECT_PROXY_ID"

	// EnvProxyToken is the name of the environment variable that is passed
	// to managed proxies containing the proxy token.
	EnvProxyToken = "CONNECT_PROXY_TOKEN"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Daemon

type Daemon struct {
	// Command is the command to execute to start this daemon. This must
	// be a Cmd that isn't yet started.
	Command *exec.Cmd

	// ProxyID is the ID of the proxy service. This is required for API
	// requests (along with the token) and is passed via env var.
	ProxyID string

	// ProxyToken is the special local-only ACL token that allows a proxy
	// to communicate to the Connect-specific endpoints.
	ProxyToken string

	// Logger is where logs will be sent around the management of this
	// daemon. The actual logs for the daemon itself will be sent to
	// a file.
	Logger *log.Logger

	// PidPath is the path where a pid file will be created storing the
	// pid of the active process. If this is empty then a pid-file won't
	// be created. Under erroneous conditions, the pid file may not be
	// created but the error will be logged to the Logger.
	PidPath string
	// contains filtered or unexported fields
}

Daemon is a long-running proxy process. It is expected to keep running and to use blocking queries to detect changes in configuration, certs, and more.

Consul will ensure that if the daemon crashes, that it is restarted.

func (*Daemon) Close

func (p *Daemon) Close() error

Close implements Proxy by stopping the run loop but not killing the process. One Close is called, Stop has no effect.

func (*Daemon) Equal

func (p *Daemon) Equal(raw Proxy) bool

Equal implements Proxy to check for equality.

func (*Daemon) MarshalSnapshot

func (p *Daemon) MarshalSnapshot() map[string]interface{}

MarshalSnapshot implements Proxy

func (*Daemon) Start

func (p *Daemon) Start() error

Start starts the daemon and keeps it running.

This function returns after the process is successfully started.

func (*Daemon) Stop

func (p *Daemon) Stop() error

Stop stops the daemon.

This will attempt a graceful stop (SIGINT) before force killing the process (SIGKILL). In either case, the process won't be automatically restarted unless Start is called again.

This is safe to call multiple times. If the daemon is already stopped, then this returns no error.

func (*Daemon) UnmarshalSnapshot

func (p *Daemon) UnmarshalSnapshot(m map[string]interface{}) error

UnmarshalSnapshot implements Proxy

type Manager

type Manager struct {
	// State is the local state that is the source of truth for all
	// configured managed proxies.
	State *local.State

	// Logger is the logger for information about manager behavior.
	// Output for proxies will not go here generally but varies by proxy
	// implementation type.
	Logger *log.Logger

	// DataDir is the path to the directory where data for proxies is
	// written, including snapshots for any state changes in the manager.
	// Within the data dir, files will be written in the following locatins:
	//
	//   * logs/ - log files named <service id>-std{out|err}.log
	//   * pids/ - pid files for daemons named <service id>.pid
	//   * snapshot.json - the state of the manager
	//
	DataDir string

	// Extra environment variables to set for the proxies
	ProxyEnv []string

	// SnapshotPeriod is the duration between snapshots. This can be set
	// relatively low to ensure accuracy, because if the new snapshot matches
	// the last snapshot taken, no file will be written. Therefore, setting
	// this low causes only slight CPU/memory usage but doesn't result in
	// disk IO. If this isn't set, ManagerSnapshotPeriod will be the default.
	//
	// This only has an effect if snapshots are enabled (DataDir is set).
	SnapshotPeriod time.Duration

	// CoalescePeriod and QuiescencePeriod control the timers for coalescing
	// updates from the local state. See the defaults at the top of this
	// file for more documentation. These will be set to those defaults
	// by NewManager.
	CoalescePeriod  time.Duration
	QuiescentPeriod time.Duration

	// AllowRoot configures whether proxies can be executed as root (EUID == 0).
	// If this is false then the manager will run and proxies can be added
	// and removed but none will be started an errors will be logged
	// to the logger.
	AllowRoot bool
	// contains filtered or unexported fields
}

Manager starts, stops, snapshots, and restores managed proxies.

The manager will not start or stop any processes until Start is called. Prior to this, any configuration, snapshot loading, etc. can be done. Even if a process is no longer running after loading the snapshot, it will not be restarted until Start is called.

The Manager works by subscribing to change notifications on a local.State structure. Whenever a change is detected, the Manager syncs its internal state with the local.State and starts/stops any necessary proxies. The manager never holds a lock on local.State (except to read the proxies) and state updates may occur while the Manger is syncing. This is okay, since a change notification will be queued to trigger another sync.

The change notifications from the local state are coalesced (see ManagerCoalescePeriod) so that frequent changes within the local state do not trigger dozens of proxy resyncs.

func NewManager

func NewManager() *Manager

NewManager initializes a Manager. After initialization, the exported fields should be configured as desired. To start the Manager, execute Run in a goroutine.

func (*Manager) Close

func (m *Manager) Close() error

Close stops the manager. Managed processes are NOT stopped.

func (*Manager) Kill

func (m *Manager) Kill() error

Kill will Close the manager and Kill all proxies that were being managed. Only ONE of Kill or Close must be called. If Close has been called already then this will have no effect.

func (*Manager) Restore

func (m *Manager) Restore(path string) error

Restore restores the manager state from a snapshot at path. If path doesn't exist, this does nothing and no error is returned.

This restores proxy state but does not restore any Manager configuration such as DataDir, Logger, etc. All of those should be set _before_ Restore is called.

Restore must be called before Run. Restore will immediately start supervising the restored processes but will not sync with the local state store until Run is called.

If an error is returned the manager state is left untouched.

func (*Manager) Run

func (m *Manager) Run()

Run syncs with the local state and supervises existing proxies.

This blocks and should be run in a goroutine. If another Run is already executing, this will do nothing and return.

func (*Manager) Snapshot

func (m *Manager) Snapshot(path string) error

Snapshot will persist a snapshot of the proxy manager state that can be restored with Restore.

If DataDir is non-empty, then the Manager will automatically snapshot whenever the set of managed proxies changes. This method generally doesn't need to be called manually.

func (*Manager) SnapshotPath

func (m *Manager) SnapshotPath() string

SnapshotPath returns the default snapshot path for this manager. This will return empty if DataDir is not set. This file may not exist yet.

type Noop

type Noop struct{}

Noop implements Proxy and does nothing.

func (*Noop) Close

func (p *Noop) Close() error

func (*Noop) Equal

func (p *Noop) Equal(Proxy) bool

func (*Noop) MarshalSnapshot

func (p *Noop) MarshalSnapshot() map[string]interface{}

func (*Noop) Start

func (p *Noop) Start() error

func (*Noop) Stop

func (p *Noop) Stop() error

func (*Noop) UnmarshalSnapshot

func (p *Noop) UnmarshalSnapshot(map[string]interface{}) error

type Proxy

type Proxy interface {
	// Start starts the proxy. If an error is returned then the managed
	// proxy registration is rejected. Therefore, this should only fail if
	// the configuration of the proxy itself is irrecoverable, and should
	// retry starting for other failures.
	//
	// Starting an already-started proxy should not return an error.
	Start() error

	// Stop stops the proxy and disallows it from ever being started again.
	// This should also clean up any resources used by this Proxy.
	//
	// If the proxy is not started yet, this should not return an error, but
	// it should disallow Start from working again. If the proxy is already
	// stopped, this should not return an error.
	Stop() error

	// Close should clean up any resources associated with this proxy but
	// keep it running in the background. Only one of Close or Stop can be
	// called.
	Close() error

	// Equal returns true if the argument is equal to the proxy being called.
	// This is called by the manager to determine if a change in configuration
	// results in a proxy that needs to be restarted or not. If Equal returns
	// false, then the manager will stop the old proxy and start the new one.
	// If Equal returns true, the old proxy will remain running and the new
	// one will be ignored.
	Equal(Proxy) bool

	// MarshalSnapshot returns the state that will be stored in a snapshot
	// so that Consul can recover the proxy process after a restart. The
	// result should only contain primitive values and containers (lists/maps).
	//
	// MarshalSnapshot does NOT need to store the following fields, since they
	// are part of the manager snapshot and will be automatically restored
	// for any proxies: proxy ID.
	//
	// UnmarshalSnapshot is called to restore the receiving Proxy from its
	// marshalled state. If UnmarshalSnapshot returns an error, the snapshot
	// is ignored and the marshalled snapshot will be lost. The manager will
	// log.
	//
	// This should save/restore enough state to be able to regain management
	// of a proxy process as well as to perform the Equal method above. The
	// Equal method will be called when a local state sync happens to determine
	// if the recovered process should be restarted or not.
	MarshalSnapshot() map[string]interface{}
	UnmarshalSnapshot(map[string]interface{}) error
}

Proxy is the interface implemented by all types of managed proxies.

Calls to all the functions on this interface must be concurrency safe. Please read the documentation carefully on top of each function for expected behavior.

Whenever a new proxy type is implemented, please also update proxyExecMode and newProxyFromMode and newProxy to support the new proxy.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL