mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #27997 from aaronlehmann/raft-options
cli: Add options for Raft snapshotting
This commit is contained in:
commit
29a38a4fe8
9 changed files with 57 additions and 45 deletions
|
@ -60,7 +60,7 @@ type RaftConfig struct {
|
||||||
|
|
||||||
// KeepOldSnapshots is the number of snapshots to keep beyond the
|
// KeepOldSnapshots is the number of snapshots to keep beyond the
|
||||||
// current snapshot.
|
// current snapshot.
|
||||||
KeepOldSnapshots uint64 `json:",omitempty"`
|
KeepOldSnapshots *uint64 `json:",omitempty"`
|
||||||
|
|
||||||
// LogEntriesForSlowFollowers is the number of log entries to keep
|
// LogEntriesForSlowFollowers is the number of log entries to keep
|
||||||
// around to sync up slow followers after a snapshot is created.
|
// around to sync up slow followers after a snapshot is created.
|
||||||
|
|
|
@ -24,6 +24,8 @@ const (
|
||||||
flagToken = "token"
|
flagToken = "token"
|
||||||
flagTaskHistoryLimit = "task-history-limit"
|
flagTaskHistoryLimit = "task-history-limit"
|
||||||
flagExternalCA = "external-ca"
|
flagExternalCA = "external-ca"
|
||||||
|
flagMaxSnapshots = "max-snapshots"
|
||||||
|
flagSnapshotInterval = "snapshot-interval"
|
||||||
)
|
)
|
||||||
|
|
||||||
type swarmOptions struct {
|
type swarmOptions struct {
|
||||||
|
@ -31,6 +33,8 @@ type swarmOptions struct {
|
||||||
dispatcherHeartbeat time.Duration
|
dispatcherHeartbeat time.Duration
|
||||||
nodeCertExpiry time.Duration
|
nodeCertExpiry time.Duration
|
||||||
externalCA ExternalCAOption
|
externalCA ExternalCAOption
|
||||||
|
maxSnapshots uint64
|
||||||
|
snapshotInterval uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeAddrOption is a pflag.Value for listening addresses
|
// NodeAddrOption is a pflag.Value for listening addresses
|
||||||
|
@ -167,11 +171,11 @@ func addSwarmFlags(flags *pflag.FlagSet, opts *swarmOptions) {
|
||||||
flags.DurationVar(&opts.dispatcherHeartbeat, flagDispatcherHeartbeat, time.Duration(5*time.Second), "Dispatcher heartbeat period")
|
flags.DurationVar(&opts.dispatcherHeartbeat, flagDispatcherHeartbeat, time.Duration(5*time.Second), "Dispatcher heartbeat period")
|
||||||
flags.DurationVar(&opts.nodeCertExpiry, flagCertExpiry, time.Duration(90*24*time.Hour), "Validity period for node certificates")
|
flags.DurationVar(&opts.nodeCertExpiry, flagCertExpiry, time.Duration(90*24*time.Hour), "Validity period for node certificates")
|
||||||
flags.Var(&opts.externalCA, flagExternalCA, "Specifications of one or more certificate signing endpoints")
|
flags.Var(&opts.externalCA, flagExternalCA, "Specifications of one or more certificate signing endpoints")
|
||||||
|
flags.Uint64Var(&opts.maxSnapshots, flagMaxSnapshots, 0, "Number of additional Raft snapshots to retain")
|
||||||
|
flags.Uint64Var(&opts.snapshotInterval, flagSnapshotInterval, 10000, "Number of log entries between Raft snapshots")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (opts *swarmOptions) ToSpec(flags *pflag.FlagSet) swarm.Spec {
|
func (opts *swarmOptions) mergeSwarmSpec(spec *swarm.Spec, flags *pflag.FlagSet) {
|
||||||
spec := swarm.Spec{}
|
|
||||||
|
|
||||||
if flags.Changed(flagTaskHistoryLimit) {
|
if flags.Changed(flagTaskHistoryLimit) {
|
||||||
spec.Orchestration.TaskHistoryRetentionLimit = &opts.taskHistoryLimit
|
spec.Orchestration.TaskHistoryRetentionLimit = &opts.taskHistoryLimit
|
||||||
}
|
}
|
||||||
|
@ -184,5 +188,16 @@ func (opts *swarmOptions) ToSpec(flags *pflag.FlagSet) swarm.Spec {
|
||||||
if flags.Changed(flagExternalCA) {
|
if flags.Changed(flagExternalCA) {
|
||||||
spec.CAConfig.ExternalCAs = opts.externalCA.Value()
|
spec.CAConfig.ExternalCAs = opts.externalCA.Value()
|
||||||
}
|
}
|
||||||
|
if flags.Changed(flagMaxSnapshots) {
|
||||||
|
spec.Raft.KeepOldSnapshots = &opts.maxSnapshots
|
||||||
|
}
|
||||||
|
if flags.Changed(flagSnapshotInterval) {
|
||||||
|
spec.Raft.SnapshotInterval = opts.snapshotInterval
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts *swarmOptions) ToSpec(flags *pflag.FlagSet) swarm.Spec {
|
||||||
|
var spec swarm.Spec
|
||||||
|
opts.mergeSwarmSpec(&spec, flags)
|
||||||
return spec
|
return spec
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,10 +39,7 @@ func runUpdate(dockerCli *command.DockerCli, flags *pflag.FlagSet, opts swarmOpt
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mergeSwarm(&swarm, flags)
|
opts.mergeSwarmSpec(&swarm.Spec, flags)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = client.SwarmUpdate(ctx, swarm.Version, swarm.Spec, updateFlags)
|
err = client.SwarmUpdate(ctx, swarm.Version, swarm.Spec, updateFlags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -53,31 +50,3 @@ func runUpdate(dockerCli *command.DockerCli, flags *pflag.FlagSet, opts swarmOpt
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mergeSwarm(swarm *swarm.Swarm, flags *pflag.FlagSet) error {
|
|
||||||
spec := &swarm.Spec
|
|
||||||
|
|
||||||
if flags.Changed(flagTaskHistoryLimit) {
|
|
||||||
taskHistoryRetentionLimit, _ := flags.GetInt64(flagTaskHistoryLimit)
|
|
||||||
spec.Orchestration.TaskHistoryRetentionLimit = &taskHistoryRetentionLimit
|
|
||||||
}
|
|
||||||
|
|
||||||
if flags.Changed(flagDispatcherHeartbeat) {
|
|
||||||
if v, err := flags.GetDuration(flagDispatcherHeartbeat); err == nil {
|
|
||||||
spec.Dispatcher.HeartbeatPeriod = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if flags.Changed(flagCertExpiry) {
|
|
||||||
if v, err := flags.GetDuration(flagCertExpiry); err == nil {
|
|
||||||
spec.CAConfig.NodeCertExpiry = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if flags.Changed(flagExternalCA) {
|
|
||||||
value := flags.Lookup(flagExternalCA).Value.(*ExternalCAOption)
|
|
||||||
spec.CAConfig.ExternalCAs = value.Value()
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -114,6 +114,9 @@ func prettyPrintInfo(dockerCli *command.DockerCli, info types.Info) error {
|
||||||
fmt.Fprintf(dockerCli.Out(), " Task History Retention Limit: %d\n", taskHistoryRetentionLimit)
|
fmt.Fprintf(dockerCli.Out(), " Task History Retention Limit: %d\n", taskHistoryRetentionLimit)
|
||||||
fmt.Fprintf(dockerCli.Out(), " Raft:\n")
|
fmt.Fprintf(dockerCli.Out(), " Raft:\n")
|
||||||
fmt.Fprintf(dockerCli.Out(), " Snapshot Interval: %d\n", info.Swarm.Cluster.Spec.Raft.SnapshotInterval)
|
fmt.Fprintf(dockerCli.Out(), " Snapshot Interval: %d\n", info.Swarm.Cluster.Spec.Raft.SnapshotInterval)
|
||||||
|
if info.Swarm.Cluster.Spec.Raft.KeepOldSnapshots != nil {
|
||||||
|
fmt.Fprintf(dockerCli.Out(), " Number of Old Snapshots to Retain: %d\n", *info.Swarm.Cluster.Spec.Raft.KeepOldSnapshots)
|
||||||
|
}
|
||||||
fmt.Fprintf(dockerCli.Out(), " Heartbeat Tick: %d\n", info.Swarm.Cluster.Spec.Raft.HeartbeatTick)
|
fmt.Fprintf(dockerCli.Out(), " Heartbeat Tick: %d\n", info.Swarm.Cluster.Spec.Raft.HeartbeatTick)
|
||||||
fmt.Fprintf(dockerCli.Out(), " Election Tick: %d\n", info.Swarm.Cluster.Spec.Raft.ElectionTick)
|
fmt.Fprintf(dockerCli.Out(), " Election Tick: %d\n", info.Swarm.Cluster.Spec.Raft.ElectionTick)
|
||||||
fmt.Fprintf(dockerCli.Out(), " Dispatcher:\n")
|
fmt.Fprintf(dockerCli.Out(), " Dispatcher:\n")
|
||||||
|
|
|
@ -2841,14 +2841,14 @@ _docker_swarm_leave() {
|
||||||
|
|
||||||
_docker_swarm_update() {
|
_docker_swarm_update() {
|
||||||
case "$prev" in
|
case "$prev" in
|
||||||
--cert-expiry|--dispatcher-heartbeat|--task-history-limit)
|
--cert-expiry|--dispatcher-heartbeat|--max-snapshots|--snapshot-interval|--task-history-limit)
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
case "$cur" in
|
case "$cur" in
|
||||||
-*)
|
-*)
|
||||||
COMPREPLY=( $( compgen -W "--cert-expiry --dispatcher-heartbeat --help --task-history-limit" -- "$cur" ) )
|
COMPREPLY=( $( compgen -W "--cert-expiry --dispatcher-heartbeat --help --max-snapshots --snapshot-interval --task-history-limit" -- "$cur" ) )
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
|
@ -1630,7 +1630,10 @@ __docker_swarm_subcommand() {
|
||||||
"($help)--advertise-addr[Advertised address]:ip\:port: " \
|
"($help)--advertise-addr[Advertised address]:ip\:port: " \
|
||||||
"($help)*--external-ca=[Specifications of one or more certificate signing endpoints]:endpoint: " \
|
"($help)*--external-ca=[Specifications of one or more certificate signing endpoints]:endpoint: " \
|
||||||
"($help)--force-new-cluster[Force create a new cluster from current state]" \
|
"($help)--force-new-cluster[Force create a new cluster from current state]" \
|
||||||
"($help)--listen-addr=[Listen address]:ip\:port: " && ret=0
|
"($help)--listen-addr=[Listen address]:ip\:port: " \
|
||||||
|
"($help)--max-snapshots[Number of additional Raft snapshots to retain]" \
|
||||||
|
"($help)--snapshot-interval[Number of log entries between Raft snapshots]" \
|
||||||
|
"($help)--task-history-limit=[Task history retention limit]:limit: " && ret=0
|
||||||
;;
|
;;
|
||||||
(join)
|
(join)
|
||||||
_arguments $(__docker_arguments) \
|
_arguments $(__docker_arguments) \
|
||||||
|
@ -1655,7 +1658,10 @@ __docker_swarm_subcommand() {
|
||||||
_arguments $(__docker_arguments) \
|
_arguments $(__docker_arguments) \
|
||||||
$opts_help \
|
$opts_help \
|
||||||
"($help)--cert-expiry=[Validity period for node certificates]:duration: " \
|
"($help)--cert-expiry=[Validity period for node certificates]:duration: " \
|
||||||
|
"($help)*--external-ca=[Specifications of one or more certificate signing endpoints]:endpoint: " \
|
||||||
"($help)--dispatcher-heartbeat=[Dispatcher heartbeat period]:duration: " \
|
"($help)--dispatcher-heartbeat=[Dispatcher heartbeat period]:duration: " \
|
||||||
|
"($help)--max-snapshots[Number of additional Raft snapshots to retain]" \
|
||||||
|
"($help)--snapshot-interval[Number of log entries between Raft snapshots]" \
|
||||||
"($help)--task-history-limit=[Task history retention limit]:limit: " && ret=0
|
"($help)--task-history-limit=[Task history retention limit]:limit: " && ret=0
|
||||||
;;
|
;;
|
||||||
(help)
|
(help)
|
||||||
|
|
|
@ -21,7 +21,7 @@ func SwarmFromGRPC(c swarmapi.Cluster) types.Swarm {
|
||||||
},
|
},
|
||||||
Raft: types.RaftConfig{
|
Raft: types.RaftConfig{
|
||||||
SnapshotInterval: c.Spec.Raft.SnapshotInterval,
|
SnapshotInterval: c.Spec.Raft.SnapshotInterval,
|
||||||
KeepOldSnapshots: c.Spec.Raft.KeepOldSnapshots,
|
KeepOldSnapshots: &c.Spec.Raft.KeepOldSnapshots,
|
||||||
LogEntriesForSlowFollowers: c.Spec.Raft.LogEntriesForSlowFollowers,
|
LogEntriesForSlowFollowers: c.Spec.Raft.LogEntriesForSlowFollowers,
|
||||||
HeartbeatTick: int(c.Spec.Raft.HeartbeatTick),
|
HeartbeatTick: int(c.Spec.Raft.HeartbeatTick),
|
||||||
ElectionTick: int(c.Spec.Raft.ElectionTick),
|
ElectionTick: int(c.Spec.Raft.ElectionTick),
|
||||||
|
@ -82,8 +82,8 @@ func MergeSwarmSpecToGRPC(s types.Spec, spec swarmapi.ClusterSpec) (swarmapi.Clu
|
||||||
if s.Raft.SnapshotInterval != 0 {
|
if s.Raft.SnapshotInterval != 0 {
|
||||||
spec.Raft.SnapshotInterval = s.Raft.SnapshotInterval
|
spec.Raft.SnapshotInterval = s.Raft.SnapshotInterval
|
||||||
}
|
}
|
||||||
if s.Raft.KeepOldSnapshots != 0 {
|
if s.Raft.KeepOldSnapshots != nil {
|
||||||
spec.Raft.KeepOldSnapshots = s.Raft.KeepOldSnapshots
|
spec.Raft.KeepOldSnapshots = *s.Raft.KeepOldSnapshots
|
||||||
}
|
}
|
||||||
if s.Raft.LogEntriesForSlowFollowers != 0 {
|
if s.Raft.LogEntriesForSlowFollowers != 0 {
|
||||||
spec.Raft.LogEntriesForSlowFollowers = s.Raft.LogEntriesForSlowFollowers
|
spec.Raft.LogEntriesForSlowFollowers = s.Raft.LogEntriesForSlowFollowers
|
||||||
|
|
|
@ -28,6 +28,8 @@ Options:
|
||||||
--force-new-cluster Force create a new cluster from current state
|
--force-new-cluster Force create a new cluster from current state
|
||||||
--help Print usage
|
--help Print usage
|
||||||
--listen-addr value Listen address (format: <ip|interface>[:port])
|
--listen-addr value Listen address (format: <ip|interface>[:port])
|
||||||
|
--max-snapshots int Number of additional Raft snapshots to retain
|
||||||
|
--snapshot-interval int Number of log entries between Raft snapshots
|
||||||
--task-history-limit int Task history retention limit (default 5)
|
--task-history-limit int Task history retention limit (default 5)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -64,7 +66,7 @@ This flag sets the validity period for node certificates.
|
||||||
This flags sets the frequency with which nodes are told to use as a
|
This flags sets the frequency with which nodes are told to use as a
|
||||||
period to report their health.
|
period to report their health.
|
||||||
|
|
||||||
### `--external-ca value`
|
### `--external-ca`
|
||||||
|
|
||||||
This flag sets up the swarm to use an external CA to issue node certificates. The value takes
|
This flag sets up the swarm to use an external CA to issue node certificates. The value takes
|
||||||
the form `protocol=X,url=Y`. The value for `protocol` specifies what protocol should be used
|
the form `protocol=X,url=Y`. The value for `protocol` specifies what protocol should be used
|
||||||
|
@ -75,7 +77,7 @@ The URL specifies the endpoint where signing requests should be submitted.
|
||||||
|
|
||||||
This flag forces an existing node that was part of a quorum that was lost to restart as a single node Manager without losing its data.
|
This flag forces an existing node that was part of a quorum that was lost to restart as a single node Manager without losing its data.
|
||||||
|
|
||||||
### `--listen-addr value`
|
### `--listen-addr`
|
||||||
|
|
||||||
The node listens for inbound swarm manager traffic on this address. The default is to listen on
|
The node listens for inbound swarm manager traffic on this address. The default is to listen on
|
||||||
0.0.0.0:2377. It is also possible to specify a network interface to listen on that interface's
|
0.0.0.0:2377. It is also possible to specify a network interface to listen on that interface's
|
||||||
|
@ -84,7 +86,7 @@ address; for example `--listen-addr eth0:2377`.
|
||||||
Specifying a port is optional. If the value is a bare IP address or interface
|
Specifying a port is optional. If the value is a bare IP address or interface
|
||||||
name, the default port 2377 will be used.
|
name, the default port 2377 will be used.
|
||||||
|
|
||||||
### `--advertise-addr value`
|
### `--advertise-addr`
|
||||||
|
|
||||||
This flag specifies the address that will be advertised to other members of the
|
This flag specifies the address that will be advertised to other members of the
|
||||||
swarm for API access and overlay networking. If unspecified, Docker will check
|
swarm for API access and overlay networking. If unspecified, Docker will check
|
||||||
|
@ -103,6 +105,21 @@ name, the default port 2377 will be used.
|
||||||
|
|
||||||
This flag sets up task history retention limit.
|
This flag sets up task history retention limit.
|
||||||
|
|
||||||
|
### `--max-snapshots`
|
||||||
|
|
||||||
|
This flag sets the number of old Raft snapshots to retain in addition to the
|
||||||
|
current Raft snapshots. By default, no old snapshots are retained. This option
|
||||||
|
may be used for debugging, or to store old snapshots of the swarm state for
|
||||||
|
disaster recovery purposes.
|
||||||
|
|
||||||
|
### `--snapshot-interval`
|
||||||
|
|
||||||
|
This flag specifies how many log entries to allow in between Raft snapshots.
|
||||||
|
Setting this to a higher number will trigger snapshots less frequently.
|
||||||
|
Snapshots compact the Raft log and allow for more efficient transfer of the
|
||||||
|
state to new managers. However, there is a performance cost to taking snapshots
|
||||||
|
frequently.
|
||||||
|
|
||||||
## Related information
|
## Related information
|
||||||
|
|
||||||
* [swarm join](swarm_join.md)
|
* [swarm join](swarm_join.md)
|
||||||
|
|
|
@ -25,6 +25,8 @@ Options:
|
||||||
--dispatcher-heartbeat duration Dispatcher heartbeat period (default 5s)
|
--dispatcher-heartbeat duration Dispatcher heartbeat period (default 5s)
|
||||||
--external-ca value Specifications of one or more certificate signing endpoints
|
--external-ca value Specifications of one or more certificate signing endpoints
|
||||||
--help Print usage
|
--help Print usage
|
||||||
|
--max-snapshots int Number of additional Raft snapshots to retain
|
||||||
|
--snapshot-interval int Number of log entries between Raft snapshots
|
||||||
--task-history-limit int Task history retention limit (default 5)
|
--task-history-limit int Task history retention limit (default 5)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue