Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding sidecars to nodepools for any additional functionality #928

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,309 changes: 1,309 additions & 0 deletions charts/opensearch-operator/files/opensearch.opster.io_opensearchclusters.yaml

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions docs/designs/crd.md
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,12 @@ Every NodePool is defining different Opensearch Nodes StatefulSet
<td>Updates the probes timeouts and thresholds config</td>
<td>false</td>
<td>-</td>
</tr><tr>
<td><b>sidecars</b></td>
<td>[]object</td>
<td>List of sidecar containers to be attached to the OpenSearch node pods. Each sidecar follows the Kubernetes container spec.</td>
<td>false</td>
<td>-</td>
</tr>
</table>

Expand Down
42 changes: 42 additions & 0 deletions docs/userguide/main.md
Original file line number Diff line number Diff line change
Expand Up @@ -1432,3 +1432,45 @@ spec:
```

Note: the `.spec.name` is immutable, meaning that it cannot be changed after the resources have been deployed to a Kubernetes cluster

## Adding sidecar containers

You can add sidecar containers to your OpenSearch node pods. This is useful for running additional services alongside OpenSearch, such as log collectors, metrics exporters, or custom monitoring agents. Here's an example:

```yaml
apiVersion: opensearch.opster.io/v1
kind: OpenSearchCluster
metadata:
name: my-cluster
spec:
nodePools:
- component: masters
replicas: 3
diskSize: "5Gi"
sidecars:
- name: log-collector
image: fluent/fluent-bit:latest
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
- name: metrics-exporter
image: prom/node-exporter:latest
ports:
- containerPort: 9100
name: metrics
```

Each sidecar container follows the standard Kubernetes container specification, allowing you to configure:
- Container image and version
- Resource requests and limits
- Environment variables
- Volume mounts
- Ports
- Command and arguments
- Security context

Sidecar containers are deployed alongside the OpenSearch containers in the same pod, sharing the same network namespace and allowing for localhost communication.
2 changes: 2 additions & 0 deletions opensearch-operator/api/v1/opensearch_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ type NodePool struct {
PriorityClassName string `json:"priorityClassName,omitempty"`
Pdb *PdbConfig `json:"pdb,omitempty"`
Probes *ProbesConfig `json:"probes,omitempty"`
// Sidecars defines the sidecar containers to be added to the nodepool pods
Sidecars []corev1.Container `json:"sidecars,omitempty"`
}

// PersistencConfig defines options for data persistence
Expand Down
7 changes: 7 additions & 0 deletions opensearch-operator/api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions opensearch-operator/pkg/builders/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ func NewSTSForNodePool(
Annotations: annotations,
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
Containers: append([]corev1.Container{
{
Env: []corev1.EnvVar{
{
Expand Down Expand Up @@ -523,7 +523,7 @@ func NewSTSForNodePool(
VolumeMounts: volumeMounts,
SecurityContext: securityContext,
},
},
}, node.Sidecars...),
InitContainers: initContainers,
Volumes: volumes,
ServiceAccountName: cr.Spec.General.ServiceAccount,
Expand Down
43 changes: 43 additions & 0 deletions opensearch-operator/pkg/builders/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,49 @@ var _ = Describe("Builders", func() {
Value: "-Xmx1024M -Xms1024M -Dopensearch.transport.cname_in_publish_address=true",
}))
})
It("should only use valid roles", func() {
clusterObject := ClusterDescWithVersion("2.2.1")
result := NewSTSForNodePool("foobar", &clusterObject, opsterv1.NodePool{
Roles: []string{"cluster_manager", "data", "invalid"},
}, "foobar", nil, nil, nil)
Expect(len(result.Spec.Template.Spec.Containers[0].Env)).To(Equal(8))
for _, env := range result.Spec.Template.Spec.Containers[0].Env {
if env.Name == "node.roles" {
Expect(env.Value).To(Equal("cluster_manager,data"))
}
}
})
It("should include sidecar containers when specified", func() {
clusterObject := ClusterDescWithVersion("2.2.1")
sidecar := corev1.Container{
Name: "sidecar",
Image: "sidecar:latest",
}
result := NewSTSForNodePool("foobar", &clusterObject, opsterv1.NodePool{
Roles: []string{"cluster_manager"},
Sidecars: []corev1.Container{sidecar},
}, "foobar", nil, nil, nil)
Expect(len(result.Spec.Template.Spec.Containers)).To(Equal(2))
Expect(result.Spec.Template.Spec.Containers[1].Name).To(Equal("sidecar"))
})
It("should include multiple sidecar containers when specified", func() {
clusterObject := ClusterDescWithVersion("2.2.1")
sidecar1 := corev1.Container{
Name: "sidecar1",
Image: "sidecar1:latest",
}
sidecar2 := corev1.Container{
Name: "sidecar2",
Image: "sidecar2:latest",
}
result := NewSTSForNodePool("foobar", &clusterObject, opsterv1.NodePool{
Roles: []string{"cluster_manager"},
Sidecars: []corev1.Container{sidecar1, sidecar2},
}, "foobar", nil, nil, nil)
Expect(len(result.Spec.Template.Spec.Containers)).To(Equal(3))
Expect(result.Spec.Template.Spec.Containers[1].Name).To(Equal("sidecar1"))
Expect(result.Spec.Template.Spec.Containers[2].Name).To(Equal("sidecar2"))
})
})

When("Constructing a bootstrap pod", func() {
Expand Down