Skip to content

Commit c5ea9cf

Browse files
kgcarrtekton-robot
authored andcommitted
tektoncd#7617 support k8s native sidecar
1 parent fb10d39 commit c5ea9cf

29 files changed

+454
-9
lines changed

config/config-feature-flags.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,5 @@ data:
138138
disable-inline-spec: ""
139139
# Setting this flag to "true" will enable the use of concise resolver syntax
140140
enable-concise-resolver-syntax: "false"
141+
# Setthing this flag to "true" will enable native Kubernetes Sidecar support
142+
enable-kubernetes-sidecar: "false"

docs/additional-configs.md

+2
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,8 @@ enables [beta features](#beta-features). When using v1 APIs, setting this field
333333
allows only stable features, and setting it to "beta" allows only beta features.
334334
Set this field to "alpha" to allow [alpha features](#alpha-features) to be used.
335335

336+
- `enable-kubernetes-sidecar`: Set this flag to `"true"` to enable native kubernetes sidecar support. This will allow Tekton sidecars to run as Kubernetes sidecars. Must be using Kubernetes v1.29 or greater.
337+
336338
For example:
337339

338340
```yaml

docs/pipeline-api.md

+34
Original file line numberDiff line numberDiff line change
@@ -4135,6 +4135,23 @@ other Step or Sidecar that does not also request this Workspace will
41354135
not have access to it.</p>
41364136
</td>
41374137
</tr>
4138+
<tr>
4139+
<td>
4140+
<code>restartPolicy</code><br/>
4141+
<em>
4142+
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#containerrestartpolicy-v1-core">
4143+
Kubernetes core/v1.ContainerRestartPolicy
4144+
</a>
4145+
</em>
4146+
</td>
4147+
<td>
4148+
<em>(Optional)</em>
4149+
<p>RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an
4150+
initContainer and must have it&rsquo;s policy set to &ldquo;Always&rdquo;. It is currently
4151+
left optional to help support Kubernetes versions prior to 1.29 when this feature
4152+
was introduced.</p>
4153+
</td>
4154+
</tr>
41384155
</tbody>
41394156
</table>
41404157
<h3 id="tekton.dev/v1.SidecarState">SidecarState
@@ -13459,6 +13476,23 @@ other Step or Sidecar that does not also request this Workspace will
1345913476
not have access to it.</p>
1346013477
</td>
1346113478
</tr>
13479+
<tr>
13480+
<td>
13481+
<code>restartPolicy</code><br/>
13482+
<em>
13483+
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#containerrestartpolicy-v1-core">
13484+
Kubernetes core/v1.ContainerRestartPolicy
13485+
</a>
13486+
</em>
13487+
</td>
13488+
<td>
13489+
<em>(Optional)</em>
13490+
<p>RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an
13491+
initContainer and must have it&rsquo;s policy set to &ldquo;Always&rdquo;. It is currently
13492+
left optional to help support Kubernetes versions prior to 1.29 when this feature
13493+
was introduced.</p>
13494+
</td>
13495+
</tr>
1346213496
</tbody>
1346313497
</table>
1346413498
<h3 id="tekton.dev/v1beta1.SidecarState">SidecarState

docs/tasks.md

+5
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,11 @@ to run alongside the `Steps` in your `Task`. You can use `Sidecars` to provide a
11131113
`Sidecars` spin up before your `Task` executes and are deleted after the `Task` execution completes.
11141114
For further information, see [`Sidecars` in `TaskRuns`](taskruns.md#specifying-sidecars).
11151115

1116+
**Note**: Starting in v0.62 you can enable native Kubernetes sidecar support using the `enable-kubernetes-sidecar` feature flag ([see instructions](./additional-configs.md#customizing-the-pipelines-controller-behavior)). If kubernetes does not wait for your sidecar application to be ready, use a `startupProbe` to help kubernetes identify when it is ready.
1117+
1118+
Refer to the detailed instructions listed in [additional config](additional-configs.md#enabling-larger-results-using-sidecar-logs)
1119+
to learn how to enable this feature.
1120+
11161121
In the example below, a `Step` uses a Docker-in-Docker `Sidecar` to build a Docker image:
11171122

11181123
```yaml

examples/v1/taskruns/sidecar-ready-script.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ spec:
99
image: docker.io/library/ubuntu
1010
script: |
1111
echo "hello from sidecar" > /shared/message
12+
sleep 2
1213
volumeMounts:
1314
- name: shared
1415
mountPath: /shared

examples/v1/taskruns/sidecar-ready.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ spec:
1818
- -c
1919
- sleep 5 && touch /shared/ready
2020
timeoutSeconds: 10
21+
# Adding startup probe for k8s native sidecar support
22+
# Readiness Probe is not honored for k8s native sidecar support
23+
startupProbe:
24+
exec:
25+
command:
26+
- sh
27+
- -c
28+
- sleep 5 && touch /shared/ready
29+
timeoutSeconds: 10
2130
volumeMounts:
2231
- name: shared
2332
mountPath: /shared

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module github.com/tektoncd/pipeline
22

33
go 1.22
4+
45
toolchain go1.22.4
56

67
require (

pkg/apis/config/feature_flags.go

+8
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ const (
108108
EnableParamEnum = "enable-param-enum"
109109
// EnableConciseResolverSyntax is the flag to enable concise resolver syntax
110110
EnableConciseResolverSyntax = "enable-concise-resolver-syntax"
111+
// EnableKubernetesSidecar is the flag to enable kubernetes sidecar support
112+
EnableKubernetesSidecar = "enable-kubernetes-sidecar"
113+
// DefaultEnableKubernetesSidecar is the default value for EnableKubernetesSidecar
114+
DefaultEnableKubernetesSidecar = false
111115

112116
// DisableInlineSpec is the flag to disable embedded spec
113117
// in Taskrun or Pipelinerun
@@ -208,6 +212,7 @@ type FeatureFlags struct {
208212
EnableArtifacts bool
209213
DisableInlineSpec string
210214
EnableConciseResolverSyntax bool
215+
EnableKubernetesSidecar bool
211216
}
212217

213218
// GetFeatureFlagsConfigName returns the name of the configmap containing all
@@ -312,6 +317,9 @@ func NewFeatureFlagsFromMap(cfgMap map[string]string) (*FeatureFlags, error) {
312317
if err := setPerFeatureFlag(EnableConciseResolverSyntax, DefaultEnableConciseResolverSyntax, &tc.EnableConciseResolverSyntax); err != nil {
313318
return nil, err
314319
}
320+
if err := setFeature(EnableKubernetesSidecar, DefaultEnableKubernetesSidecar, &tc.EnableKubernetesSidecar); err != nil {
321+
return nil, err
322+
}
315323

316324
return &tc, nil
317325
}

pkg/apis/config/feature_flags_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ func TestNewFeatureFlagsFromConfigMap(t *testing.T) {
8383
EnableParamEnum: true,
8484
DisableInlineSpec: "pipeline,pipelinerun,taskrun",
8585
EnableConciseResolverSyntax: true,
86+
EnableKubernetesSidecar: true,
8687
},
8788
fileName: "feature-flags-all-flags-set",
8889
},
@@ -314,6 +315,9 @@ func TestNewFeatureFlagsConfigMapErrors(t *testing.T) {
314315
}, {
315316
fileName: "feature-flags-invalid-enable-concise-resolver-syntax",
316317
want: `failed parsing feature flags config "invalid": strconv.ParseBool: parsing "invalid": invalid syntax for feature enable-concise-resolver-syntax`,
318+
}, {
319+
fileName: "feature-flags-invalid-enable-kubernetes-sidecar",
320+
want: `failed parsing feature flags config "invalid": strconv.ParseBool: parsing "invalid": invalid syntax`,
317321
}} {
318322
t.Run(tc.fileName, func(t *testing.T) {
319323
cm := test.ConfigMapFromTestFile(t, tc.fileName)

pkg/apis/config/testdata/feature-flags-all-flags-set.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,4 @@ data:
3838
enable-artifacts: "true"
3939
disable-inline-spec: "pipeline,pipelinerun,taskrun"
4040
enable-concise-resolver-syntax: "true"
41+
enable-kubernetes-sidecar: "true"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright 2024 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+
enable-kubernetes-sidecar: "invalid"

pkg/apis/pipeline/v1/container_types.go

+35
Original file line numberDiff line numberDiff line change
@@ -543,10 +543,43 @@ type Sidecar struct {
543543
// +optional
544544
// +listType=atomic
545545
Workspaces []WorkspaceUsage `json:"workspaces,omitempty"`
546+
547+
// RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an
548+
// initContainer and must have it's policy set to "Always". It is currently
549+
// left optional to help support Kubernetes versions prior to 1.29 when this feature
550+
// was introduced.
551+
// +optional
552+
RestartPolicy *corev1.ContainerRestartPolicy `json:"restartPolicy,omitempty"`
546553
}
547554

548555
// ToK8sContainer converts the Sidecar to a Kubernetes Container struct
549556
func (s *Sidecar) ToK8sContainer() *corev1.Container {
557+
if s.RestartPolicy == nil {
558+
return &corev1.Container{
559+
Name: s.Name,
560+
Image: s.Image,
561+
Command: s.Command,
562+
Args: s.Args,
563+
WorkingDir: s.WorkingDir,
564+
Ports: s.Ports,
565+
EnvFrom: s.EnvFrom,
566+
Env: s.Env,
567+
Resources: s.ComputeResources,
568+
VolumeMounts: s.VolumeMounts,
569+
VolumeDevices: s.VolumeDevices,
570+
LivenessProbe: s.LivenessProbe,
571+
ReadinessProbe: s.ReadinessProbe,
572+
StartupProbe: s.StartupProbe,
573+
Lifecycle: s.Lifecycle,
574+
TerminationMessagePath: s.TerminationMessagePath,
575+
TerminationMessagePolicy: s.TerminationMessagePolicy,
576+
ImagePullPolicy: s.ImagePullPolicy,
577+
SecurityContext: s.SecurityContext,
578+
Stdin: s.Stdin,
579+
StdinOnce: s.StdinOnce,
580+
TTY: s.TTY,
581+
}
582+
}
550583
return &corev1.Container{
551584
Name: s.Name,
552585
Image: s.Image,
@@ -561,6 +594,7 @@ func (s *Sidecar) ToK8sContainer() *corev1.Container {
561594
VolumeDevices: s.VolumeDevices,
562595
LivenessProbe: s.LivenessProbe,
563596
ReadinessProbe: s.ReadinessProbe,
597+
RestartPolicy: s.RestartPolicy,
564598
StartupProbe: s.StartupProbe,
565599
Lifecycle: s.Lifecycle,
566600
TerminationMessagePath: s.TerminationMessagePath,
@@ -597,6 +631,7 @@ func (s *Sidecar) SetContainerFields(c corev1.Container) {
597631
s.Stdin = c.Stdin
598632
s.StdinOnce = c.StdinOnce
599633
s.TTY = c.TTY
634+
s.RestartPolicy = c.RestartPolicy
600635
}
601636

602637
// GetVarSubstitutionExpressions walks all the places a substitution reference can be used

pkg/apis/pipeline/v1/container_types_test.go

+32
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,35 @@ func TestSidecarGetVarSubstitutionExpressions(t *testing.T) {
120120
t.Fatalf("Unexpected result (-want, +got): %s", d)
121121
}
122122
}
123+
124+
func TestSidecarRestartPolicyToK8sContainer(t *testing.T) {
125+
always := corev1.ContainerRestartPolicyAlways
126+
s := Sidecar{
127+
Name: "sidecarName",
128+
RestartPolicy: &always,
129+
}
130+
131+
expectedContainer := corev1.Container{
132+
Name: "sidecarName",
133+
RestartPolicy: &always,
134+
}
135+
136+
c := s.ToK8sContainer()
137+
138+
if !(c.RestartPolicy == expectedContainer.RestartPolicy) {
139+
t.Fatalf("Unexpected result with RestartPolicy")
140+
}
141+
142+
s = Sidecar{
143+
Name: "sidecarName",
144+
}
145+
146+
expectedContainer = corev1.Container{
147+
Name: "sidecarName",
148+
}
149+
150+
c = s.ToK8sContainer()
151+
if !(c.RestartPolicy == expectedContainer.RestartPolicy) {
152+
t.Fatalf("Unexpected result without RestartPolicy")
153+
}
154+
}

pkg/apis/pipeline/v1/openapi_generated.go

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/apis/pipeline/v1/swagger.json

+4
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,10 @@
13251325
"description": "Periodic probe of Sidecar service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes",
13261326
"$ref": "#/definitions/v1.Probe"
13271327
},
1328+
"restartPolicy": {
1329+
"description": "RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an initContainer and must have it's policy set to \"Always\". It is currently left optional to help support Kubernetes versions prior to 1.29 when this feature was introduced.",
1330+
"type": "string"
1331+
},
13281332
"script": {
13291333
"description": "Script is the contents of an executable file to execute.\n\nIf Script is not empty, the Step cannot have an Command or Args.",
13301334
"type": "string"

pkg/apis/pipeline/v1/zz_generated.deepcopy.go

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/apis/pipeline/v1beta1/container_types.go

+35
Original file line numberDiff line numberDiff line change
@@ -747,10 +747,43 @@ type Sidecar struct {
747747
// +optional
748748
// +listType=atomic
749749
Workspaces []WorkspaceUsage `json:"workspaces,omitempty"`
750+
751+
// RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an
752+
// initContainer and must have it's policy set to "Always". It is currently
753+
// left optional to help support Kubernetes versions prior to 1.29 when this feature
754+
// was introduced.
755+
// +optional
756+
RestartPolicy *corev1.ContainerRestartPolicy `json:"restartPolicy,omitempty"`
750757
}
751758

752759
// ToK8sContainer converts the Sidecar to a Kubernetes Container struct
753760
func (s *Sidecar) ToK8sContainer() *corev1.Container {
761+
if s.RestartPolicy == nil {
762+
return &corev1.Container{
763+
Name: s.Name,
764+
Image: s.Image,
765+
Command: s.Command,
766+
Args: s.Args,
767+
WorkingDir: s.WorkingDir,
768+
Ports: s.Ports,
769+
EnvFrom: s.EnvFrom,
770+
Env: s.Env,
771+
Resources: s.Resources,
772+
VolumeMounts: s.VolumeMounts,
773+
VolumeDevices: s.VolumeDevices,
774+
LivenessProbe: s.LivenessProbe,
775+
ReadinessProbe: s.ReadinessProbe,
776+
StartupProbe: s.StartupProbe,
777+
Lifecycle: s.Lifecycle,
778+
TerminationMessagePath: s.TerminationMessagePath,
779+
TerminationMessagePolicy: s.TerminationMessagePolicy,
780+
ImagePullPolicy: s.ImagePullPolicy,
781+
SecurityContext: s.SecurityContext,
782+
Stdin: s.Stdin,
783+
StdinOnce: s.StdinOnce,
784+
TTY: s.TTY,
785+
}
786+
}
754787
return &corev1.Container{
755788
Name: s.Name,
756789
Image: s.Image,
@@ -765,6 +798,7 @@ func (s *Sidecar) ToK8sContainer() *corev1.Container {
765798
VolumeDevices: s.VolumeDevices,
766799
LivenessProbe: s.LivenessProbe,
767800
ReadinessProbe: s.ReadinessProbe,
801+
RestartPolicy: s.RestartPolicy,
768802
StartupProbe: s.StartupProbe,
769803
Lifecycle: s.Lifecycle,
770804
TerminationMessagePath: s.TerminationMessagePath,
@@ -801,4 +835,5 @@ func (s *Sidecar) SetContainerFields(c corev1.Container) {
801835
s.Stdin = c.Stdin
802836
s.StdinOnce = c.StdinOnce
803837
s.TTY = c.TTY
838+
s.RestartPolicy = c.RestartPolicy
804839
}

pkg/apis/pipeline/v1beta1/openapi_generated.go

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/apis/pipeline/v1beta1/swagger.json

+4
Original file line numberDiff line numberDiff line change
@@ -1932,6 +1932,10 @@
19321932
"default": {},
19331933
"$ref": "#/definitions/v1.ResourceRequirements"
19341934
},
1935+
"restartPolicy": {
1936+
"description": "RestartPolicy refers to kubernetes RestartPolicy. It can only be set for an initContainer and must have it's policy set to \"Always\". It is currently left optional to help support Kubernetes versions prior to 1.29 when this feature was introduced.",
1937+
"type": "string"
1938+
},
19351939
"script": {
19361940
"description": "Script is the contents of an executable file to execute.\n\nIf Script is not empty, the Step cannot have an Command or Args.",
19371941
"type": "string"

0 commit comments

Comments
 (0)