Using pssh is acceptable, but it's an extra command we need to remember. Ideally, this configuration should be recorded inside stateful-set.yaml, so that the commands only run on nodes that have our Elasticsearch StatefulSet deployed there. Kuberentes provides a special type of Container called Init Containers, which allows us to do just that.
Init Containers are special Containers that run and exit before your "normal" app Containers are initiated. When multiple Init Containers are specified, they run in a sequential order. Also, if the previous Init Container exits with a non-zero exit status, then the next Init Container is not ran and the whole Pod fails.
This allows you to use Init Containers to:
- Poll for the readiness of other services. For instance, if your service X depends on another service Y, you can use an Init Container to poll service Y, and this exits only when service Y responds correctly. After the Init Container exits, the app container can begin its initialization steps.
- Update configurations on the node running the Pod.
Therefore, we can define Init Containers inside stateful-set.yaml, which will update the configurations on nodes running our Elasticsearch StatefulSet.
Inside stateful-set.yaml, under spec.template.spec, add a new field called initContainers with the following settings:
initContainers:
- name: increase-max-map-count
image: busybox
command:
- sysctl
- -w
- vm.max_map_count=262144
securityContext:
privileged: true
- name: increase-file-descriptor-limit
image: busybox
command:
- sh
- -c
- ulimit -n 65536
securityContext:
privileged: true
The final stateful-set.yaml file should look like this:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: elasticsearch
labels:
app: elasticsearch
spec:
replicas: 3
serviceName: elasticsearch
selector:
matchLabels:
app: elasticsearch
template:
metadata:
labels:
app: elasticsearch
spec:
initContainers:
- name: increase-max-map-count
image: busybox
command:
- sysctl
- -w
- vm.max_map_count=262144
securityContext:
privileged: true
- name: increase-file-descriptor-limit
image: busybox
command:
- sh
- -c
- ulimit -n 65536
securityContext:
privileged: true
containers:
- name: elasticsearch
image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.3.2
ports:
- containerPort: 9200
name: http
- containerPort: 9300
name: tcp
env:
- name: discovery.zen.ping.unicast.hosts
value: "elasticsearch-0.elasticsearch.default.svc.cluster.local,elasticsearch-1.elasticsearch.default.svc.cluster.local,elasticsearch-2.elasticsearch.default.svc.cluster.local"
This configures our nodes in the same way as pssh, but with the added benefit of configuration-as-code, since it's now part of our stateful-set.yaml.