mirror of
https://github.com/tailscale/tailscale.git
synced 2025-05-09 17:16:50 +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 Signed-off-by: Lee Briggs <lee@leebriggs.co.uk>
This commit is contained in:
parent
b03a2a323b
commit
d050cfc5c7
@ -1557,6 +1557,13 @@ spec:
|
||||
May also be set in PodSecurityContext. If set in both SecurityContext and
|
||||
PodSecurityContext, the value specified in SecurityContext takes precedence.
|
||||
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:
|
||||
description: |-
|
||||
Tolerations for Recorder Pods. By default, the operator does not apply
|
||||
|
@ -4552,6 +4552,13 @@ spec:
|
||||
type: string
|
||||
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:
|
||||
description: |-
|
||||
Tolerations for Recorder Pods. By default, the operator does not apply
|
||||
|
@ -169,14 +169,17 @@ func (r *RecorderReconciler) maybeProvision(ctx context.Context, tsr *tsapi.Reco
|
||||
}); err != nil {
|
||||
return fmt.Errorf("error creating state Secret: %w", err)
|
||||
}
|
||||
sa := tsrServiceAccount(tsr, r.tsNamespace)
|
||||
if _, err := createOrUpdate(ctx, r.Client, r.tsNamespace, sa, func(s *corev1.ServiceAccount) {
|
||||
s.ObjectMeta.Labels = sa.ObjectMeta.Labels
|
||||
s.ObjectMeta.Annotations = sa.ObjectMeta.Annotations
|
||||
s.ObjectMeta.OwnerReferences = sa.ObjectMeta.OwnerReferences
|
||||
}); err != nil {
|
||||
return fmt.Errorf("error creating ServiceAccount: %w", err)
|
||||
}
|
||||
// Create the ServiceAccount only if the user hasn't specified a custom name
|
||||
if tsr.Spec.StatefulSet.Pod.ServiceAccountName == "" {
|
||||
sa := tsrServiceAccount(tsr, r.tsNamespace)
|
||||
if _, err := createOrUpdate(ctx, r.Client, r.tsNamespace, sa, func(s *corev1.ServiceAccount) {
|
||||
s.ObjectMeta.Labels = sa.ObjectMeta.Labels
|
||||
s.ObjectMeta.Annotations = sa.ObjectMeta.Annotations
|
||||
s.ObjectMeta.OwnerReferences = sa.ObjectMeta.OwnerReferences
|
||||
}); err != nil {
|
||||
return fmt.Errorf("error creating ServiceAccount: %w", err)
|
||||
}
|
||||
}
|
||||
role := tsrRole(tsr, r.tsNamespace)
|
||||
if _, err := createOrUpdate(ctx, r.Client, r.tsNamespace, role, func(r *rbacv1.Role) {
|
||||
r.ObjectMeta.Labels = role.ObjectMeta.Labels
|
||||
|
@ -39,7 +39,13 @@ func tsrStatefulSet(tsr *tsapi.Recorder, namespace string) *appsv1.StatefulSet {
|
||||
Annotations: tsr.Spec.StatefulSet.Pod.Annotations,
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
ServiceAccountName: tsr.Name,
|
||||
ServiceAccountName: func() string {
|
||||
if tsr.Spec.StatefulSet.Pod.ServiceAccountName != "" {
|
||||
return tsr.Spec.StatefulSet.Pod.ServiceAccountName
|
||||
}
|
||||
|
||||
return tsr.Name
|
||||
}(),
|
||||
Affinity: tsr.Spec.StatefulSet.Pod.Affinity,
|
||||
SecurityContext: tsr.Spec.StatefulSet.Pod.SecurityContext,
|
||||
ImagePullSecrets: tsr.Spec.StatefulSet.Pod.ImagePullSecrets,
|
||||
@ -144,25 +150,30 @@ func tsrRole(tsr *tsapi.Recorder, namespace string) *rbacv1.Role {
|
||||
}
|
||||
|
||||
func tsrRoleBinding(tsr *tsapi.Recorder, namespace string) *rbacv1.RoleBinding {
|
||||
return &rbacv1.RoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: tsr.Name,
|
||||
Namespace: namespace,
|
||||
Labels: labels("recorder", tsr.Name, nil),
|
||||
OwnerReferences: tsrOwnerReference(tsr),
|
||||
},
|
||||
Subjects: []rbacv1.Subject{
|
||||
{
|
||||
Kind: "ServiceAccount",
|
||||
Name: tsr.Name,
|
||||
Namespace: namespace,
|
||||
},
|
||||
},
|
||||
RoleRef: rbacv1.RoleRef{
|
||||
Kind: "Role",
|
||||
Name: tsr.Name,
|
||||
},
|
||||
}
|
||||
saName := tsr.Spec.StatefulSet.Pod.ServiceAccountName
|
||||
if saName == "" {
|
||||
saName = tsr.Name
|
||||
}
|
||||
|
||||
return &rbacv1.RoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: tsr.Name,
|
||||
Namespace: namespace,
|
||||
Labels: labels("recorder", tsr.Name, nil),
|
||||
OwnerReferences: tsrOwnerReference(tsr),
|
||||
},
|
||||
Subjects: []rbacv1.Subject{
|
||||
{
|
||||
Kind: "ServiceAccount",
|
||||
Name: saName,
|
||||
Namespace: namespace,
|
||||
},
|
||||
},
|
||||
RoleRef: rbacv1.RoleRef{
|
||||
Kind: "Role",
|
||||
Name: tsr.Name,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func tsrAuthSecret(tsr *tsapi.Recorder, namespace string, authKey string) *corev1.Secret {
|
||||
|
@ -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 | | |
|
||||
| `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 | | |
|
||||
| `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
|
||||
|
@ -94,6 +94,7 @@ type RecorderStatefulSet struct {
|
||||
// Configuration for pods created by the Recorder's StatefulSet.
|
||||
// +optional
|
||||
Pod RecorderPod `json:"pod,omitempty"`
|
||||
|
||||
}
|
||||
|
||||
type RecorderPod struct {
|
||||
@ -142,6 +143,13 @@ type RecorderPod struct {
|
||||
// https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling
|
||||
// +optional
|
||||
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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user