Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3dfb2a8

Browse files
committedDec 2, 2022
feature flags.
1 parent 09c7285 commit 3dfb2a8

9 files changed

+200
-1
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
kind: ClusterRole
2+
apiVersion: rbac.authorization.k8s.io/v1
3+
metadata:
4+
name: tekton-pipelines-controller-pod-log-access
5+
labels:
6+
app.kubernetes.io/component: controller
7+
app.kubernetes.io/instance: default
8+
app.kubernetes.io/part-of: tekton-pipelines
9+
rules:
10+
- apiGroups: [""]
11+
# Controller needs to get the logs of the results sidecar created by TaskRuns to extract results.
12+
resources: ["pods/log"]
13+
verbs: ["get"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
kind: ClusterRoleBinding
2+
apiVersion: rbac.authorization.k8s.io/v1
3+
metadata:
4+
name: tekton-pipelines-controller-pod-log-access
5+
labels:
6+
app.kubernetes.io/component: controller
7+
app.kubernetes.io/instance: default
8+
app.kubernetes.io/part-of: tekton-pipelines
9+
subjects:
10+
- kind: ServiceAccount
11+
name: tekton-pipelines-controller
12+
namespace: tekton-pipelines
13+
roleRef:
14+
kind: ClusterRole
15+
name: tekton-pipelines-controller-pod-log-access
16+
apiGroup: rbac.authorization.k8s.io

‎docs/install.md

+20
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ This guide explains how to install Tekton Pipelines. It covers the following top
2424
- [Customizing the Pipelines Controller behavior](#customizing-the-pipelines-controller-behavior)
2525
- [Alpha Features](#alpha-features)
2626
- [Beta Features](#beta-features)
27+
- [Enabling larger results using sidecar logs](#enabling-larger-results-using-sidecar-logs)
2728
- [Configuring High Availability](#configuring-high-availability)
2829
- [Configuring tekton pipeline controller performance](#configuring-tekton-pipeline-controller-performance)
2930
- [Creating a custom release of Tekton Pipelines](#creating-a-custom-release-of-tekton-pipelines)
@@ -421,6 +422,7 @@ features](#alpha-features) to be used.
421422
do both. For more information, see [Configuring usage of `TaskRun` and `Run` embedded statuses](pipelineruns.md#configuring-usage-of-taskrun-and-run-embedded-statuses).
422423

423424
- `resource-verification-mode`: Setting this flag to "enforce" will enforce verification of tasks/pipeline. Failing to verify will fail the taskrun/pipelinerun. "warn" will only log the err message and "skip" will skip the whole verification.
425+
- `results-from`: set this flag to "termination-message" to use the container's termination message to fetch results from. This is the default method of extracting results. Set it to "sidecar-logs" to enable use of a results sidecar logs to extract results instead of termination message.
424426

425427
- `enable-provenance-in-status`: set this flag to "true" to enable recording
426428
the `provenance` field in `TaskRun` and `PipelineRun` status. The `provenance`
@@ -477,6 +479,24 @@ the `feature-flags` ConfigMap alongside your Tekton Pipelines deployment via
477479

478480
For beta versions of Tekton CRDs, setting `enable-api-fields` to "beta" is the same as setting it to "stable".
479481

482+
## Enabling larger results using sidecar logs
483+
484+
**Note**: The maximum size of a Task's results is limited by the container termination message feature of Kubernetes, as results are passed back to the controller via this mechanism. At present, the limit is per task is “4096 bytes”. All results produced by the task share this upper limit.
485+
486+
To exceed this limit of 4096 bytes, you can enable larger results using sidecar logs. By enabling this feature, you will have a configurable limit (with a default of 4096 bytes) per result with no restriction on the number of results.
487+
488+
**Note**: to enable this feature, you need to grant `get` access to all `pods/log` to the `Tekton pipeline controller`. This means that the tekton pipeline controller has the ability to access the pod logs.
489+
490+
1. Create a cluster role and rolebinding by applying the following spec to provide log access to `tekton-pipelines-controller`.
491+
492+
```
493+
kubectl apply -f config/enable-log-access-to-controller/
494+
```
495+
496+
2. Set the `results-from` feature flag to use sidecar logs by setting `results-from: sidecar-logs` in the [configMap](#customizing-the-pipelines-controller-behavior).
497+
498+
3. If you want the size per result to be something other than 4096 bytes, you can set the `max-result-size` feature flag in bytes by setting `max-result-size: 8192(whatever you need here)`. **Note:** The value you can set here cannot exceed the size of the CRD limit of 1.5 MB.
499+
480500
## Configuring High Availability
481501
482502
If you want to run Tekton Pipelines in a way so that webhooks are resiliant against failures and support

‎docs/tasks.md

+13-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ weight: 200
2323
- [Specifying `Resources`](#specifying-resources)
2424
- [Specifying `Workspaces`](#specifying-workspaces)
2525
- [Emitting `Results`](#emitting-results)
26+
- [Larger `Results` using sidecar logs](#larger-results-using-sidecar-logs)
2627
- [Specifying `Volumes`](#specifying-volumes)
2728
- [Specifying a `Step` template](#specifying-a-step-template)
2829
- [Specifying `Sidecars`](#specifying-sidecars)
@@ -835,7 +836,7 @@ This also means that the number of Steps in a Task affects the maximum size of a
835836
as each Step is implemented as a container in the TaskRun's pod.
836837
The more containers we have in our pod, *the smaller the allowed size of each container's
837838
message*, meaning that the **more steps you have in a Task, the smaller the result for each step can be**.
838-
For example, if you have 10 steps, the size of each step's Result will have a maximum of less than 1KB*.
839+
For example, if you have 10 steps, the size of each step's Result will have a maximum of less than 1KB.
839840

840841
If your `Task` writes a large number of small results, you can work around this limitation
841842
by writing each result from a separate `Step` so that each `Step` has its own termination message.
@@ -847,6 +848,17 @@ available size will less than 4096 bytes.
847848
As a general rule-of-thumb, if a result needs to be larger than a kilobyte, you should likely use a
848849
[`Workspace`](#specifying-workspaces) to store and pass it between `Tasks` within a `Pipeline`.
849850

851+
#### Larger `Results` using sidecar logs
852+
853+
This is an experimental feature. The `results-from` feature flag must be set to `"sidecar-logs"`](./install.md#enabling-larger-results-using-sidecar-logs).
854+
855+
Instead of using termination messages to store results, the taskrun controller injects a sidecar container which monitors the results of all the steps. The sidecar mounts the volume where results of all the steps are stored. As soon as it finds a new result, it logs it to std out. The controller has access to the logs of the sidecar container (Caution: we need you to enable access to [kubernetes pod/logs](./install.md#enabling-larger-results-using-sidecar-logs).
856+
857+
This feature allows users to store up to 4 KB per result by default. Because we are not limited by the size of the termination messages, users can have as many results as they require (or until the CRD reaches its limit). If the size of a result exceeds this limit, then the TaskRun will be placed into a failed state with the following message: `Result exceeded the maximum allowed limit.`
858+
859+
**Note**: If you require even larger results, you can specify a different upper limit per result by setting `max-result-size` feature flag to your desired size in bytes ([see instructions](./install.md#enabling-larger-results-using-sidecar-logs)). **CAUTION**: the larger you make the size, more likely will the CRD reach its max limit enforced by the `etcd` server leading to bad user experience.
860+
861+
850862
### Specifying `Volumes`
851863

852864
Specifies one or more [`Volumes`](https://kubernetes.io/docs/concepts/storage/volumes/) that the `Steps` in your

‎pkg/apis/config/feature_flags.go

+53
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ const (
5050
WarnResourceVerificationMode = "warn"
5151
// SkipResourceVerificationMode is the value used for "resource-verification-mode" when verification is skipped
5252
SkipResourceVerificationMode = "skip"
53+
// ResultExtractionMethodTerminationMessage is the value used for "results-from" as a way to extract results from tasks using kubernetes termination message.
54+
ResultExtractionMethodTerminationMessage = "termination-message"
55+
// ResultExtractionMethodSidecarLogs is the value used for "results-from" as a way to extract results from tasks using sidecar logs.
56+
ResultExtractionMethodSidecarLogs = "sidecar-logs"
5357
// DefaultDisableAffinityAssistant is the default value for "disable-affinity-assistant".
5458
DefaultDisableAffinityAssistant = false
5559
// DefaultDisableCredsInit is the default value for "disable-creds-init".
@@ -76,6 +80,10 @@ const (
7680
DefaultResourceVerificationMode = SkipResourceVerificationMode
7781
// DefaultEnableProvenanceInStatus is the default value for "enable-provenance-status".
7882
DefaultEnableProvenanceInStatus = false
83+
// DefaultResultExtractionMethod is the default value for ResultExtractionMethod
84+
DefaultResultExtractionMethod = ResultExtractionMethodTerminationMessage
85+
// DefaultMaxResultSize is the default value in bytes for the size of a result
86+
DefaultMaxResultSize = 4096
7987

8088
disableAffinityAssistantKey = "disable-affinity-assistant"
8189
disableCredsInitKey = "disable-creds-init"
@@ -90,6 +98,8 @@ const (
9098
enableSpire = "enable-spire"
9199
verificationMode = "resource-verification-mode"
92100
enableProvenanceInStatus = "enable-provenance-in-status"
101+
resultExtractionMethod = "results-from"
102+
maxResultSize = "max-result-size"
93103
)
94104

95105
// FeatureFlags holds the features configurations
@@ -109,6 +119,8 @@ type FeatureFlags struct {
109119
EnableSpire bool
110120
ResourceVerificationMode string
111121
EnableProvenanceInStatus bool
122+
ResultExtractionMethod string
123+
MaxResultSize int
112124
}
113125

114126
// GetFeatureFlagsConfigName returns the name of the configmap containing all
@@ -166,6 +178,12 @@ func NewFeatureFlagsFromMap(cfgMap map[string]string) (*FeatureFlags, error) {
166178
if err := setFeature(enableProvenanceInStatus, DefaultEnableProvenanceInStatus, &tc.EnableProvenanceInStatus); err != nil {
167179
return nil, err
168180
}
181+
if err := setResultExtractionMethod(cfgMap, DefaultResultExtractionMethod, &tc.ResultExtractionMethod); err != nil {
182+
return nil, err
183+
}
184+
if err := setMaxResultSize(cfgMap, DefaultMaxResultSize, &tc.MaxResultSize); err != nil {
185+
return nil, err
186+
}
169187

170188
// Given that they are alpha features, Tekton Bundles and Custom Tasks should be switched on if
171189
// enable-api-fields is "alpha". If enable-api-fields is not "alpha" then fall back to the value of
@@ -223,6 +241,41 @@ func setEmbeddedStatus(cfgMap map[string]string, defaultValue string, feature *s
223241
return nil
224242
}
225243

244+
// setResultExtractionMethod sets the "results-from" flag based on the content of a given map.
245+
// If the feature gate is invalid or missing then an error is returned.
246+
func setResultExtractionMethod(cfgMap map[string]string, defaultValue string, feature *string) error {
247+
value := defaultValue
248+
if cfg, ok := cfgMap[resultExtractionMethod]; ok {
249+
value = strings.ToLower(cfg)
250+
}
251+
switch value {
252+
case ResultExtractionMethodTerminationMessage, ResultExtractionMethodSidecarLogs:
253+
*feature = value
254+
default:
255+
return fmt.Errorf("invalid value for feature flag %q: %q", resultExtractionMethod, value)
256+
}
257+
return nil
258+
}
259+
260+
// setMaxResultSize sets the "max-result-size" flag based on the content of a given map.
261+
// If the feature gate is invalid or missing then an error is returned.
262+
func setMaxResultSize(cfgMap map[string]string, defaultValue int, feature *int) error {
263+
value := defaultValue
264+
if cfg, ok := cfgMap[maxResultSize]; ok {
265+
v, err := strconv.Atoi(cfg)
266+
if err != nil {
267+
return err
268+
}
269+
value = v
270+
}
271+
// if max limit is > 1.5 MB (CRD limit).
272+
if value >= 1572864 {
273+
return fmt.Errorf("invalid value for feature flag %q: %q. This is exceeding the CRD limit", resultExtractionMethod, value)
274+
}
275+
*feature = value
276+
return nil
277+
}
278+
226279
// setResourceVerificationMode sets the "resource-verification-mode" flag based on the content of a given map.
227280
// If the value is invalid or missing then an error is returned.
228281
func setResourceVerificationMode(cfgMap map[string]string, defaultValue string, feature *string) error {

‎pkg/apis/config/feature_flags_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package config_test
1818

1919
import (
20+
"log"
2021
"testing"
2122

2223
"github.com/google/go-cmp/cmp"
@@ -47,6 +48,8 @@ func TestNewFeatureFlagsFromConfigMap(t *testing.T) {
4748
EmbeddedStatus: config.DefaultEmbeddedStatus,
4849
ResourceVerificationMode: config.DefaultResourceVerificationMode,
4950
EnableProvenanceInStatus: config.DefaultEnableProvenanceInStatus,
51+
ResultExtractionMethod: config.DefaultResultExtractionMethod,
52+
MaxResultSize: config.DefaultMaxResultSize,
5053
},
5154
fileName: config.GetFeatureFlagsConfigName(),
5255
},
@@ -64,6 +67,8 @@ func TestNewFeatureFlagsFromConfigMap(t *testing.T) {
6467
EnableSpire: true,
6568
ResourceVerificationMode: "enforce",
6669
EnableProvenanceInStatus: true,
70+
ResultExtractionMethod: "termination-message",
71+
MaxResultSize: 4096,
6772
},
6873
fileName: "feature-flags-all-flags-set",
6974
},
@@ -84,6 +89,8 @@ func TestNewFeatureFlagsFromConfigMap(t *testing.T) {
8489
SendCloudEventsForRuns: config.DefaultSendCloudEventsForRuns,
8590
EmbeddedStatus: config.DefaultEmbeddedStatus,
8691
ResourceVerificationMode: config.DefaultResourceVerificationMode,
92+
ResultExtractionMethod: config.DefaultResultExtractionMethod,
93+
MaxResultSize: config.DefaultMaxResultSize,
8794
},
8895
fileName: "feature-flags-enable-api-fields-overrides-bundles-and-custom-tasks",
8996
},
@@ -101,6 +108,8 @@ func TestNewFeatureFlagsFromConfigMap(t *testing.T) {
101108
SendCloudEventsForRuns: config.DefaultSendCloudEventsForRuns,
102109
EmbeddedStatus: config.DefaultEmbeddedStatus,
103110
ResourceVerificationMode: config.DefaultResourceVerificationMode,
111+
ResultExtractionMethod: config.DefaultResultExtractionMethod,
112+
MaxResultSize: config.DefaultMaxResultSize,
104113
},
105114
fileName: "feature-flags-bundles-and-custom-tasks",
106115
},
@@ -118,6 +127,8 @@ func TestNewFeatureFlagsFromConfigMap(t *testing.T) {
118127
SendCloudEventsForRuns: config.DefaultSendCloudEventsForRuns,
119128
EmbeddedStatus: config.DefaultEmbeddedStatus,
120129
ResourceVerificationMode: config.DefaultResourceVerificationMode,
130+
ResultExtractionMethod: config.DefaultResultExtractionMethod,
131+
MaxResultSize: config.DefaultMaxResultSize,
121132
},
122133
fileName: "feature-flags-beta-api-fields",
123134
},
@@ -129,6 +140,8 @@ func TestNewFeatureFlagsFromConfigMap(t *testing.T) {
129140
ResourceVerificationMode: config.DefaultResourceVerificationMode,
130141
RunningInEnvWithInjectedSidecars: config.DefaultRunningInEnvWithInjectedSidecars,
131142
AwaitSidecarReadiness: config.DefaultAwaitSidecarReadiness,
143+
ResultExtractionMethod: config.DefaultResultExtractionMethod,
144+
MaxResultSize: config.DefaultMaxResultSize,
132145
},
133146
fileName: "feature-flags-enable-spire",
134147
},
@@ -159,6 +172,8 @@ func TestNewFeatureFlagsFromEmptyConfigMap(t *testing.T) {
159172
EnableSpire: config.DefaultEnableSpire,
160173
ResourceVerificationMode: config.DefaultResourceVerificationMode,
161174
EnableProvenanceInStatus: config.DefaultEnableProvenanceInStatus,
175+
ResultExtractionMethod: config.DefaultResultExtractionMethod,
176+
MaxResultSize: config.DefaultMaxResultSize,
162177
}
163178
verifyConfigFileWithExpectedFeatureFlagsConfig(t, FeatureFlagsConfigEmptyName, expectedConfig)
164179
}
@@ -201,9 +216,16 @@ func TestNewFeatureFlagsConfigMapErrors(t *testing.T) {
201216
fileName: "feature-flags-invalid-embedded-status",
202217
}, {
203218
fileName: "feature-flags-invalid-resource-verification-mode",
219+
}, {
220+
fileName: "feature-flags-invalid-results-from",
221+
}, {
222+
fileName: "feature-flags-invalid-max-result-size-too-large",
223+
}, {
224+
fileName: "feature-flags-invalid-max-result-size-bad-value",
204225
}} {
205226
t.Run(tc.fileName, func(t *testing.T) {
206227
cm := test.ConfigMapFromTestFile(t, tc.fileName)
228+
log.Println(cm)
207229
if _, err := config.NewFeatureFlagsFromConfigMap(cm); err == nil {
208230
t.Error("expected error but received nil")
209231
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright 2021 The Tekton Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
apiVersion: v1
16+
kind: ConfigMap
17+
metadata:
18+
name: feature-flags
19+
namespace: tekton-pipelines
20+
data:
21+
max-result-size: "foo"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright 2021 The Tekton Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
apiVersion: v1
16+
kind: ConfigMap
17+
metadata:
18+
name: feature-flags
19+
namespace: tekton-pipelines
20+
data:
21+
max-result-size: 10000000000000
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright 2021 The Tekton Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
apiVersion: v1
16+
kind: ConfigMap
17+
metadata:
18+
name: feature-flags
19+
namespace: tekton-pipelines
20+
data:
21+
results-from: "im-not-a-valid-results-from"

0 commit comments

Comments
 (0)
Please sign in to comment.