diff --git a/completions/bash/crio b/completions/bash/crio index f88112d2cac..8703f5e54af 100755 --- a/completions/bash/crio +++ b/completions/bash/crio @@ -82,6 +82,7 @@ h --storage-opt --stream-address --stream-enable-tls +--stream-idle-timeout --stream-port --stream-tls-ca --stream-tls-cert diff --git a/completions/fish/crio.fish b/completions/fish/crio.fish index 9aef13f165d..d863b9603df 100644 --- a/completions/fish/crio.fish +++ b/completions/fish/crio.fish @@ -119,6 +119,7 @@ complete -c crio -n '__fish_crio_no_subcommand' -f -l storage-driver -s s -r -d complete -c crio -n '__fish_crio_no_subcommand' -f -l storage-opt -r -d 'OCI storage driver option' complete -c crio -n '__fish_crio_no_subcommand' -f -l stream-address -r -d 'Bind address for streaming socket' complete -c crio -n '__fish_crio_no_subcommand' -f -l stream-enable-tls -d 'Enable encrypted TLS transport of the stream server (default: false)' +complete -c crio -n '__fish_crio_no_subcommand' -f -l stream-idle-timeout -r -d 'Length of time until open streams terminate due to lack of activity' complete -c crio -n '__fish_crio_no_subcommand' -f -l stream-port -r -d 'Bind port for streaming socket. If the port is set to \'0\', then CRI-O will allocate a random free port number.' complete -c crio -n '__fish_crio_no_subcommand' -l stream-tls-ca -r -d 'Path to the x509 CA(s) file used to verify and authenticate client communication with the encrypted stream. This file can change and CRI-O will automatically pick up the changes within 5 minutes (default: "")' complete -c crio -n '__fish_crio_no_subcommand' -l stream-tls-cert -r -d 'Path to the x509 certificate file used to serve the encrypted stream. This file can change and CRI-O will automatically pick up the changes within 5 minutes (default: "")' diff --git a/completions/zsh/_crio b/completions/zsh/_crio index 3701f754bef..0aea3a378d6 100644 --- a/completions/zsh/_crio +++ b/completions/zsh/_crio @@ -7,7 +7,7 @@ it later with **--config**. Global options will modify the output.' 'version:dis _describe 'commands' cmds local -a opts - opts=('--additional-devices' '--apparmor-profile' '--big-files-temporary-dir' '--bind-mount-prefix' '--cgroup-manager' '--cni-config-dir' '--cni-default-network' '--cni-plugin-dir' '--config' '--config-dir' '--conmon' '--conmon-cgroup' '--conmon-env' '--container-attach-socket-dir' '--container-exits-dir' '--ctr-stop-timeout' '--decryption-keys-path' '--default-capabilities' '--default-env' '--default-mounts-file' '--default-runtime' '--default-sysctls' '--default-transport' '--default-ulimits' '--drop-infra-ctr' '--enable-metrics' '--enable-profile-unix-socket' '--gid-mappings' '--global-auth-file' '--grpc-max-recv-msg-size' '--grpc-max-send-msg-size' '--hooks-dir' '--image-volumes' '--infra-ctr-cpuset' '--insecure-registry' '--irqbalance-config-file' '--listen' '--log' '--log-dir' '--log-filter' '--log-format' '--log-journald' '--log-level' '--log-size-max' '--metrics-port' '--metrics-socket' '--namespaces-dir' '--no-pivot' '--pause-command' '--pause-image' '--pause-image-auth-file' '--pids-limit' '--pinns-path' '--profile' '--profile-port' '--read-only' '--registries-conf' '--registry' '--root' '--runroot' '--runtimes' '--seccomp-profile' '--seccomp-use-default-when-empty' '--selinux' '--separate-pull-cgroup' '--signature-policy' '--storage-driver' '--storage-opt' '--stream-address' '--stream-enable-tls' '--stream-port' '--stream-tls-ca' '--stream-tls-cert' '--stream-tls-key' '--uid-mappings' '--version-file' '--version-file-persist' '--help' '--version') + opts=('--additional-devices' '--apparmor-profile' '--big-files-temporary-dir' '--bind-mount-prefix' '--cgroup-manager' '--cni-config-dir' '--cni-default-network' '--cni-plugin-dir' '--config' '--config-dir' '--conmon' '--conmon-cgroup' '--conmon-env' '--container-attach-socket-dir' '--container-exits-dir' '--ctr-stop-timeout' '--decryption-keys-path' '--default-capabilities' '--default-env' '--default-mounts-file' '--default-runtime' '--default-sysctls' '--default-transport' '--default-ulimits' '--drop-infra-ctr' '--enable-metrics' '--enable-profile-unix-socket' '--gid-mappings' '--global-auth-file' '--grpc-max-recv-msg-size' '--grpc-max-send-msg-size' '--hooks-dir' '--image-volumes' '--infra-ctr-cpuset' '--insecure-registry' '--irqbalance-config-file' '--listen' '--log' '--log-dir' '--log-filter' '--log-format' '--log-journald' '--log-level' '--log-size-max' '--metrics-port' '--metrics-socket' '--namespaces-dir' '--no-pivot' '--pause-command' '--pause-image' '--pause-image-auth-file' '--pids-limit' '--pinns-path' '--profile' '--profile-port' '--read-only' '--registries-conf' '--registry' '--root' '--runroot' '--runtimes' '--seccomp-profile' '--seccomp-use-default-when-empty' '--selinux' '--separate-pull-cgroup' '--signature-policy' '--storage-driver' '--storage-opt' '--stream-address' '--stream-enable-tls' '--stream-idle-timeout' '--stream-port' '--stream-tls-ca' '--stream-tls-cert' '--stream-tls-key' '--uid-mappings' '--version-file' '--version-file-persist' '--help' '--version') _describe 'global options' opts return diff --git a/docs/crio.8.md b/docs/crio.8.md index ceb3d7fe0c4..5d6cfe3f4ad 100644 --- a/docs/crio.8.md +++ b/docs/crio.8.md @@ -81,6 +81,7 @@ crio [--storage-opt]=[value] [--stream-address]=[value] [--stream-enable-tls] +[--stream-idle-timeout]=[value] [--stream-port]=[value] [--stream-tls-ca]=[value] [--stream-tls-cert]=[value] @@ -296,6 +297,8 @@ crio [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...] **--stream-enable-tls**: Enable encrypted TLS transport of the stream server (default: false) +**--stream-idle-timeout**="": Length of time until open streams terminate due to lack of activity + **--stream-port**="": Bind port for streaming socket. If the port is set to '0', then CRI-O will allocate a random free port number. (default: 0) **--stream-tls-ca**="": Path to the x509 CA(s) file used to verify and authenticate client communication with the encrypted stream. This file can change and CRI-O will automatically pick up the changes within 5 minutes (default: "") diff --git a/docs/crio.conf.5.md b/docs/crio.conf.5.md index 5fbf2c0ffb2..af2d1284735 100644 --- a/docs/crio.conf.5.md +++ b/docs/crio.conf.5.md @@ -69,6 +69,9 @@ The `crio.api` table contains settings for the kubelet/gRPC interface. **stream_enable_tls**=false Enable encrypted TLS transport of the stream server. +**stream_idle_timeout**="" + Length of time until open streams terminate due to lack of activity. + **stream_tls_cert**="" Path to the x509 certificate file used to serve the encrypted stream. This file can change and CRI-O will automatically pick up the changes within 5 minutes. diff --git a/internal/criocli/criocli.go b/internal/criocli/criocli.go index d38720c8291..14dc18a3830 100644 --- a/internal/criocli/criocli.go +++ b/internal/criocli/criocli.go @@ -272,6 +272,9 @@ func mergeConfig(config *libconfig.Config, ctx *cli.Context) error { if ctx.IsSet("stream-tls-key") { config.StreamTLSKey = ctx.String("stream-tls-key") } + if ctx.IsSet("stream-idle-timeout") { + config.StreamIdleTimeout = ctx.String("stream-idle-timeout") + } if ctx.IsSet("version-file") { config.VersionFile = ctx.String("version-file") } @@ -789,6 +792,11 @@ func getCrioFlags(defConf *libconfig.Config) []cli.Flag { EnvVars: []string{"CONTAINER_TLS_KEY"}, TakesFile: true, }, + &cli.StringFlag{ + Name: "stream-idle-timeout", + Usage: "Length of time until open streams terminate due to lack of activity", + EnvVars: []string{"STREAM_IDLE_TIMEOUT"}, + }, &cli.StringFlag{ Name: "registries-conf", Usage: "path to the registries.conf file", diff --git a/pkg/config/config.go b/pkg/config/config.go index 6e4272df56c..b185ca76916 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -421,6 +421,9 @@ type APIConfig struct { // StreamTLSCA is the x509 CA(s) file used to verify and authenticate client // communication with the tls encrypted stream StreamTLSCA string `toml:"stream_tls_ca"` + + // StreamIdleTimeout is how long to leave idle connections open for + StreamIdleTimeout string `toml:"stream_idle_timeout"` } // MetricsConfig specifies all necessary configuration for Prometheus based diff --git a/pkg/config/template.go b/pkg/config/template.go index 9a9032422f2..2b96ef9af0c 100644 --- a/pkg/config/template.go +++ b/pkg/config/template.go @@ -78,6 +78,9 @@ stream_port = "{{ .StreamPort }}" # Enable encrypted TLS transport of the stream server. stream_enable_tls = {{ .StreamEnableTLS }} +# Length of time until open streams terminate due to lack of activity +stream_idle_timeout = "{{.StreamIdleTimeout}}" + # Path to the x509 certificate file used to serve the encrypted stream. This # file can change, and CRI-O will automatically pick up the changes within 5 # minutes. diff --git a/server/server.go b/server/server.go index 29a3325c0b8..e26a6adaee4 100644 --- a/server/server.go +++ b/server/server.go @@ -399,6 +399,14 @@ func New( // Prepare streaming server streamServerConfig := streaming.DefaultConfig + if config.StreamIdleTimeout != "" { + idleTimeout, err := time.ParseDuration(config.StreamIdleTimeout) + if err != nil { + return nil, errors.New("unable to parse timeout as duration") + } + + streamServerConfig.StreamIdleTimeout = idleTimeout + } streamServerConfig.Addr = net.JoinHostPort(bindAddressStr, config.StreamPort) if config.StreamEnableTLS { certCache := &certConfigCache{ diff --git a/server/server_test.go b/server/server_test.go index c1e136ee7d6..81a867bb25c 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -206,6 +206,22 @@ var _ = t.Describe("Server", func() { Expect(err).NotTo(BeNil()) Expect(server).To(BeNil()) }) + It("should fail with invalid timeout duration", func() { + mockNewServer() + serverConfig.StreamIdleTimeout = "invalid duration" + + server, err := server.New(context.Background(), libMock) + Expect(err).NotTo(BeNil()) + Expect(server).To(BeNil()) + }) + It("should succeed to set a valid timeout duration", func() { + mockNewServer() + serverConfig.StreamIdleTimeout = "200ms" + + server, err := server.New(context.Background(), libMock) + Expect(err).To(BeNil()) + Expect(server).ToNot(BeNil()) + }) }) t.Describe("CreateMetricsEndpoint", func() { diff --git a/server/streaming/streaming.go b/server/streaming/streaming.go index 954411817ad..a6e63264c73 100644 --- a/server/streaming/streaming.go +++ b/server/streaming/streaming.go @@ -98,7 +98,7 @@ type Config struct { // DefaultConfig provides default values for server Config. The DefaultConfig is partial, so // some fields like Addr must still be provided. var DefaultConfig = Config{ - StreamIdleTimeout: 4 * time.Hour, + StreamIdleTimeout: 15 * time.Minute, StreamCreationTimeout: remotecommandconsts.DefaultStreamCreationTimeout, SupportedRemoteCommandProtocols: remotecommandconsts.SupportedStreamingProtocols, SupportedPortForwardProtocols: portforward.SupportedProtocols,