mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-20 01:47:33 +00:00
cmd/k8s-operator,k8s-operator: recorder custom service account
Allows configuring a custom service account for the recorder pods, allowing the use of IRSA and other mechanisms for authing to write to recorder buckets Fixes #15875 Signed-off-by: Lee Briggs <lee@leebriggs.co.uk>
This commit is contained in:
@@ -1557,6 +1557,13 @@ spec:
|
|||||||
May also be set in PodSecurityContext. If set in both SecurityContext and
|
May also be set in PodSecurityContext. If set in both SecurityContext and
|
||||||
PodSecurityContext, the value specified in SecurityContext takes precedence.
|
PodSecurityContext, the value specified in SecurityContext takes precedence.
|
||||||
type: string
|
type: string
|
||||||
|
serviceAccountName:
|
||||||
|
description: |-
|
||||||
|
The service account to use for the Recorder's StatefulSet. If not set,
|
||||||
|
the operator will create a service account with the same name as the
|
||||||
|
Recorder resource.
|
||||||
|
https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#service-account
|
||||||
|
type: string
|
||||||
tolerations:
|
tolerations:
|
||||||
description: |-
|
description: |-
|
||||||
Tolerations for Recorder Pods. By default, the operator does not apply
|
Tolerations for Recorder Pods. By default, the operator does not apply
|
||||||
|
@@ -4552,6 +4552,13 @@ spec:
|
|||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
|
serviceAccountName:
|
||||||
|
description: |-
|
||||||
|
The service account to use for the Recorder's StatefulSet. If not set,
|
||||||
|
the operator will create a service account with the same name as the
|
||||||
|
Recorder resource.
|
||||||
|
https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#service-account
|
||||||
|
type: string
|
||||||
tolerations:
|
tolerations:
|
||||||
description: |-
|
description: |-
|
||||||
Tolerations for Recorder Pods. By default, the operator does not apply
|
Tolerations for Recorder Pods. By default, the operator does not apply
|
||||||
|
@@ -169,13 +169,16 @@ func (r *RecorderReconciler) maybeProvision(ctx context.Context, tsr *tsapi.Reco
|
|||||||
}); err != nil {
|
}); err != nil {
|
||||||
return fmt.Errorf("error creating state Secret: %w", err)
|
return fmt.Errorf("error creating state Secret: %w", err)
|
||||||
}
|
}
|
||||||
sa := tsrServiceAccount(tsr, r.tsNamespace)
|
// Create the ServiceAccount only if the user hasn't specified a custom name
|
||||||
if _, err := createOrUpdate(ctx, r.Client, r.tsNamespace, sa, func(s *corev1.ServiceAccount) {
|
if tsr.Spec.StatefulSet.Pod.ServiceAccountName == "" {
|
||||||
s.ObjectMeta.Labels = sa.ObjectMeta.Labels
|
sa := tsrServiceAccount(tsr, r.tsNamespace)
|
||||||
s.ObjectMeta.Annotations = sa.ObjectMeta.Annotations
|
if _, err := createOrUpdate(ctx, r.Client, r.tsNamespace, sa, func(s *corev1.ServiceAccount) {
|
||||||
s.ObjectMeta.OwnerReferences = sa.ObjectMeta.OwnerReferences
|
s.ObjectMeta.Labels = sa.ObjectMeta.Labels
|
||||||
}); err != nil {
|
s.ObjectMeta.Annotations = sa.ObjectMeta.Annotations
|
||||||
return fmt.Errorf("error creating ServiceAccount: %w", err)
|
s.ObjectMeta.OwnerReferences = sa.ObjectMeta.OwnerReferences
|
||||||
|
}); err != nil {
|
||||||
|
return fmt.Errorf("error creating ServiceAccount: %w", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
role := tsrRole(tsr, r.tsNamespace)
|
role := tsrRole(tsr, r.tsNamespace)
|
||||||
if _, err := createOrUpdate(ctx, r.Client, r.tsNamespace, role, func(r *rbacv1.Role) {
|
if _, err := createOrUpdate(ctx, r.Client, r.tsNamespace, role, func(r *rbacv1.Role) {
|
||||||
|
@@ -39,12 +39,18 @@ func tsrStatefulSet(tsr *tsapi.Recorder, namespace string) *appsv1.StatefulSet {
|
|||||||
Annotations: tsr.Spec.StatefulSet.Pod.Annotations,
|
Annotations: tsr.Spec.StatefulSet.Pod.Annotations,
|
||||||
},
|
},
|
||||||
Spec: corev1.PodSpec{
|
Spec: corev1.PodSpec{
|
||||||
ServiceAccountName: tsr.Name,
|
ServiceAccountName: func() string {
|
||||||
Affinity: tsr.Spec.StatefulSet.Pod.Affinity,
|
if tsr.Spec.StatefulSet.Pod.ServiceAccountName != "" {
|
||||||
SecurityContext: tsr.Spec.StatefulSet.Pod.SecurityContext,
|
return tsr.Spec.StatefulSet.Pod.ServiceAccountName
|
||||||
ImagePullSecrets: tsr.Spec.StatefulSet.Pod.ImagePullSecrets,
|
}
|
||||||
NodeSelector: tsr.Spec.StatefulSet.Pod.NodeSelector,
|
|
||||||
Tolerations: tsr.Spec.StatefulSet.Pod.Tolerations,
|
return tsr.Name
|
||||||
|
}(),
|
||||||
|
Affinity: tsr.Spec.StatefulSet.Pod.Affinity,
|
||||||
|
SecurityContext: tsr.Spec.StatefulSet.Pod.SecurityContext,
|
||||||
|
ImagePullSecrets: tsr.Spec.StatefulSet.Pod.ImagePullSecrets,
|
||||||
|
NodeSelector: tsr.Spec.StatefulSet.Pod.NodeSelector,
|
||||||
|
Tolerations: tsr.Spec.StatefulSet.Pod.Tolerations,
|
||||||
Containers: []corev1.Container{
|
Containers: []corev1.Container{
|
||||||
{
|
{
|
||||||
Name: "recorder",
|
Name: "recorder",
|
||||||
@@ -144,6 +150,11 @@ func tsrRole(tsr *tsapi.Recorder, namespace string) *rbacv1.Role {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func tsrRoleBinding(tsr *tsapi.Recorder, namespace string) *rbacv1.RoleBinding {
|
func tsrRoleBinding(tsr *tsapi.Recorder, namespace string) *rbacv1.RoleBinding {
|
||||||
|
saName := tsr.Spec.StatefulSet.Pod.ServiceAccountName
|
||||||
|
if saName == "" {
|
||||||
|
saName = tsr.Name
|
||||||
|
}
|
||||||
|
|
||||||
return &rbacv1.RoleBinding{
|
return &rbacv1.RoleBinding{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: tsr.Name,
|
Name: tsr.Name,
|
||||||
@@ -154,7 +165,7 @@ func tsrRoleBinding(tsr *tsapi.Recorder, namespace string) *rbacv1.RoleBinding {
|
|||||||
Subjects: []rbacv1.Subject{
|
Subjects: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
Kind: "ServiceAccount",
|
Kind: "ServiceAccount",
|
||||||
Name: tsr.Name,
|
Name: saName,
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@@ -726,6 +726,7 @@ _Appears in:_
|
|||||||
| `imagePullSecrets` _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.3/#localobjectreference-v1-core) array_ | Image pull Secrets for Recorder Pods.<br />https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec | | |
|
| `imagePullSecrets` _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.3/#localobjectreference-v1-core) array_ | Image pull Secrets for Recorder Pods.<br />https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec | | |
|
||||||
| `nodeSelector` _object (keys:string, values:string)_ | Node selector rules for Recorder Pods. By default, the operator does<br />not apply any node selector rules.<br />https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling | | |
|
| `nodeSelector` _object (keys:string, values:string)_ | Node selector rules for Recorder Pods. By default, the operator does<br />not apply any node selector rules.<br />https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling | | |
|
||||||
| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.3/#toleration-v1-core) array_ | Tolerations for Recorder Pods. By default, the operator does not apply<br />any tolerations.<br />https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling | | |
|
| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.3/#toleration-v1-core) array_ | Tolerations for Recorder Pods. By default, the operator does not apply<br />any tolerations.<br />https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling | | |
|
||||||
|
| `serviceAccountName` _string_ | The service account to use for the Recorder's StatefulSet. If not set,<br />the operator will create a service account with the same name as the<br />Recorder resource.<br />https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#service-account | | |
|
||||||
|
|
||||||
|
|
||||||
#### RecorderSpec
|
#### RecorderSpec
|
||||||
|
@@ -142,6 +142,13 @@ type RecorderPod struct {
|
|||||||
// https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling
|
// https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling
|
||||||
// +optional
|
// +optional
|
||||||
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
|
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
|
||||||
|
|
||||||
|
// The service account to use for the Recorder's StatefulSet. If not set,
|
||||||
|
// the operator will create a service account with the same name as the
|
||||||
|
// Recorder resource.
|
||||||
|
// https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#service-account
|
||||||
|
// +optional
|
||||||
|
ServiceAccountName string `json:"serviceAccountName,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecorderContainer struct {
|
type RecorderContainer struct {
|
||||||
|
Reference in New Issue
Block a user