From d220ac0d6138ade4db3cfb2a7ad21183df887a45 Mon Sep 17 00:00:00 2001 From: Mario Rodriguez Molins Date: Wed, 10 Apr 2024 13:50:02 +0200 Subject: [PATCH] Allow to run multiple kubernetes agents --- .../_static/elastic-agent-managed.yaml.tmpl | 44 +++++++++---------- internal/agentdeployer/factory.go | 1 + internal/agentdeployer/kubernetes.go | 35 ++++++++++++--- 3 files changed, 52 insertions(+), 28 deletions(-) diff --git a/internal/agentdeployer/_static/elastic-agent-managed.yaml.tmpl b/internal/agentdeployer/_static/elastic-agent-managed.yaml.tmpl index c2ce38713a..e1f4a7dec2 100644 --- a/internal/agentdeployer/_static/elastic-agent-managed.yaml.tmpl +++ b/internal/agentdeployer/_static/elastic-agent-managed.yaml.tmpl @@ -9,14 +9,14 @@ data: apiVersion: apps/v1 kind: DaemonSet metadata: - name: elastic-agent + name: {{ .agentName }} namespace: kube-system labels: - app: elastic-agent + app: {{ .agentName }} spec: selector: matchLabels: - app: elastic-agent + app: {{ .agentName }} updateStrategy: type: RollingUpdate rollingUpdate: @@ -25,12 +25,12 @@ spec: template: metadata: labels: - app: elastic-agent + app: {{ .agentName }} spec: tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule - serviceAccountName: elastic-agent + serviceAccountName: {{ .agentName }} hostNetwork: true dnsPolicy: ClusterFirstWithHostNet containers: @@ -143,50 +143,50 @@ spec: apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - name: elastic-agent + name: {{ .agentName }} subjects: - kind: ServiceAccount - name: elastic-agent + name: {{ .agentName }} namespace: kube-system roleRef: kind: ClusterRole - name: elastic-agent + name: {{ .agentName }} apiGroup: rbac.authorization.k8s.io --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: namespace: kube-system - name: elastic-agent + name: {{ .agentName }} subjects: - kind: ServiceAccount - name: elastic-agent + name: {{ .agentName }} namespace: kube-system roleRef: kind: Role - name: elastic-agent + name: {{ .agentName }} apiGroup: rbac.authorization.k8s.io --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: - name: elastic-agent-kubeadm-config + name: {{ .agentName }}-kubeadm-config namespace: kube-system subjects: - kind: ServiceAccount - name: elastic-agent + name: {{ .agentName }} namespace: kube-system roleRef: kind: Role - name: elastic-agent-kubeadm-config + name: {{ .agentName }}-kubeadm-config apiGroup: rbac.authorization.k8s.io --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: elastic-agent + name: {{ .agentName }} labels: - k8s-app: elastic-agent + k8s-app: {{ .agentName }} rules: - apiGroups: [""] resources: @@ -256,11 +256,11 @@ rules: apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: elastic-agent + name: {{ .agentName }} # should be the namespace where elastic-agent is running namespace: kube-system labels: - k8s-app: elastic-agent + k8s-app: {{ .agentName }} rules: - apiGroups: - coordination.k8s.io @@ -271,10 +271,10 @@ rules: apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: elastic-agent-kubeadm-config + name: {{ .agentName }}-kubeadm-config namespace: kube-system labels: - k8s-app: elastic-agent + k8s-app: {{ .agentName }} rules: - apiGroups: [""] resources: @@ -286,8 +286,8 @@ rules: apiVersion: v1 kind: ServiceAccount metadata: - name: elastic-agent + name: {{ .agentName }} namespace: kube-system labels: - k8s-app: elastic-agent + k8s-app: {{ .agentName }} --- diff --git a/internal/agentdeployer/factory.go b/internal/agentdeployer/factory.go index 1ef47d16fe..02190f138e 100644 --- a/internal/agentdeployer/factory.go +++ b/internal/agentdeployer/factory.go @@ -115,6 +115,7 @@ func Factory(options FactoryOptions) (AgentDeployer, error) { DefinitionsDir: agentDeployerPath, StackVersion: options.StackVersion, PolicyName: options.PolicyName, + DataStream: options.DataStream, RunSetup: options.RunSetup, RunTestsOnly: options.RunTestsOnly, RunTearDown: options.RunTearDown, diff --git a/internal/agentdeployer/kubernetes.go b/internal/agentdeployer/kubernetes.go index 01aa7052be..c34e152895 100644 --- a/internal/agentdeployer/kubernetes.go +++ b/internal/agentdeployer/kubernetes.go @@ -29,6 +29,9 @@ type KubernetesAgentDeployer struct { definitionsDir string stackVersion string policyName string + dataStream string + + agentRunID string runSetup bool runTestsOnly bool @@ -40,6 +43,7 @@ type KubernetesAgentDeployerOptions struct { DefinitionsDir string StackVersion string PolicyName string + DataStream string RunSetup bool RunTestsOnly bool @@ -51,11 +55,13 @@ type kubernetesDeployedAgent struct { profile *profile.Profile stackVersion string + agentName string + definitionsDir string } func (s kubernetesDeployedAgent) TearDown(ctx context.Context) error { - elasticAgentManagedYaml, err := getElasticAgentYAML(s.profile, s.stackVersion, s.agentInfo.Policy.Name) + elasticAgentManagedYaml, err := getElasticAgentYAML(s.profile, s.stackVersion, s.agentInfo.Policy.Name, s.agentName) if err != nil { return fmt.Errorf("can't retrieve Kubernetes file for Elastic Agent: %w", err) } @@ -92,6 +98,7 @@ func NewKubernetesAgentDeployer(opts KubernetesAgentDeployerOptions) (*Kubernete definitionsDir: opts.DefinitionsDir, stackVersion: opts.StackVersion, policyName: opts.PolicyName, + dataStream: opts.DataStream, runSetup: opts.RunSetup, runTestsOnly: opts.RunTestsOnly, runTearDown: opts.RunTearDown, @@ -100,7 +107,9 @@ func NewKubernetesAgentDeployer(opts KubernetesAgentDeployerOptions) (*Kubernete // SetUp function links the kind container with elastic-package-stack network, installs Elastic-Agent and optionally // custom YAML definitions. -func (ksd KubernetesAgentDeployer) SetUp(ctx context.Context, agentInfo AgentInfo) (DeployedAgent, error) { +func (ksd *KubernetesAgentDeployer) SetUp(ctx context.Context, agentInfo AgentInfo) (DeployedAgent, error) { + ksd.agentRunID = agentInfo.Test.RunID + err := kind.VerifyContext(ctx) if err != nil { return nil, fmt.Errorf("kind context verification failed: %w", err) @@ -115,10 +124,11 @@ func (ksd KubernetesAgentDeployer) SetUp(ctx context.Context, agentInfo AgentInf } } + agentName := ksd.agentName() if ksd.runTearDown || ksd.runTestsOnly { logger.Debug("Skip install Elastic Agent in cluster") } else { - err = installElasticAgentInCluster(ctx, ksd.profile, ksd.stackVersion, agentInfo.Policy.Name) + err = installElasticAgentInCluster(ctx, ksd.profile, ksd.stackVersion, agentInfo.Policy.Name, agentName) if err != nil { return nil, fmt.Errorf("can't install Elastic-Agent in the Kubernetes cluster: %w", err) } @@ -134,15 +144,27 @@ func (ksd KubernetesAgentDeployer) SetUp(ctx context.Context, agentInfo AgentInf definitionsDir: ksd.definitionsDir, profile: ksd.profile, stackVersion: ksd.stackVersion, + agentName: agentName, }, nil } +func (ksd *KubernetesAgentDeployer) agentName() string { + name := "elastic-agent" + if ksd.dataStream != "" && ksd.dataStream != "." { + name = fmt.Sprintf("%s-%s", name, strings.ReplaceAll(ksd.dataStream, "_", "-")) + } + if ksd.agentRunID != "" { + name = fmt.Sprintf("%s-%s", name, ksd.agentRunID) + } + return name +} + var _ AgentDeployer = new(KubernetesAgentDeployer) -func installElasticAgentInCluster(ctx context.Context, profile *profile.Profile, stackVersion, policyName string) error { +func installElasticAgentInCluster(ctx context.Context, profile *profile.Profile, stackVersion, policyName, agentName string) error { logger.Debug("install Elastic Agent in the Kubernetes cluster") - elasticAgentManagedYaml, err := getElasticAgentYAML(profile, stackVersion, policyName) + elasticAgentManagedYaml, err := getElasticAgentYAML(profile, stackVersion, policyName, agentName) if err != nil { return fmt.Errorf("can't retrieve Kubernetes file for Elastic Agent: %w", err) } @@ -160,7 +182,7 @@ func installElasticAgentInCluster(ctx context.Context, profile *profile.Profile, //go:embed _static/elastic-agent-managed.yaml.tmpl var elasticAgentManagedYamlTmpl string -func getElasticAgentYAML(profile *profile.Profile, stackVersion, policyName string) ([]byte, error) { +func getElasticAgentYAML(profile *profile.Profile, stackVersion, policyName, agentName string) ([]byte, error) { logger.Debugf("Prepare YAML definition for Elastic Agent running in stack v%s", stackVersion) appConfig, err := install.Configuration() @@ -182,6 +204,7 @@ func getElasticAgentYAML(profile *profile.Profile, stackVersion, policyName stri "caCertPem": caCert, "elasticAgentImage": appConfig.StackImageRefs(stackVersion).ElasticAgent, "elasticAgentTokenPolicyName": getTokenPolicyName(stackVersion, policyName), + "agentName": agentName, }) if err != nil { return nil, fmt.Errorf("can't generate elastic agent manifest: %w", err)