-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Fotis Soldatos
committed
Aug 3, 2022
0 parents
commit ea386af
Showing
6 changed files
with
293 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# ECK stack Setup on Kubernetes | ||
|
||
This directory includes all scripts needed for setting up a working ECK inside a Kubernetes cluster. | ||
|
||
## Prerequisites | ||
|
||
[Kubernetes](https://kubernetes.io/docs/setup/) | ||
|
||
[kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) | ||
|
||
[yq](https://github.com/mikefarah/yq) | ||
|
||
## Run | ||
```bash | ||
./eck-deployer.sh <k8s-namespace> elastic-cluster.yaml kibana-agent.yaml beat-agent.yaml | ||
``` | ||
|
||
## Legend | ||
|
||
[elastic-cluster](./elastic-cluster.yaml), k8s manifest for a single `elasticsearch` CRD. | ||
|
||
[kibana-agent](./kibana-agent.yaml),k8s manifest for a single `kibana` CRD. | ||
|
||
[beat-agent](./beat-agent.yaml), k8s manifest for a single `beat` CRD. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
apiVersion: beat.k8s.elastic.co/v1beta1 | ||
kind: Beat | ||
metadata: | ||
name: filebeat | ||
spec: | ||
type: filebeat | ||
version: 8.2.2 # version will be generated when running `./eck-deployer.sh` | ||
elasticsearchRef: | ||
name: elasticsearch | ||
kibanaRef: | ||
name: kibana | ||
config: | ||
filebeat.inputs: | ||
- type: container | ||
multiline.type: pattern | ||
multiline.pattern: '^[[:space:]]' | ||
multiline.negate: false | ||
multiline.match: after | ||
paths: | ||
- /var/log/containers/*.log | ||
processors: | ||
- drop_fields: | ||
fields: ["host.name", "ecs.version", "agent.version", "agent.type", "agent.id", "agent.ephemeral_id", "agent.hostname", "agent.name", "input.type", "stream", "log.offset", "log.flags"] | ||
# https://discuss.elastic.co/t/docker-logs-includes-unreadable-in-kibana/303196/4 | ||
- decode_json_fields: | ||
fields: ["message"] | ||
process_array: false | ||
max_depth: 2 | ||
target: "" | ||
overwrite_keys: true | ||
- script: | ||
lang: javascript | ||
source: > | ||
function process(event){ | ||
var regex = new RegExp('\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])','g'); | ||
var clean = event.Get('message'); | ||
clean = clean.replace(regex, ''); | ||
event.Put('message',clean); | ||
return event; | ||
} | ||
daemonSet: | ||
podTemplate: | ||
metadata: | ||
labels: | ||
app: filebeat | ||
spec: | ||
dnsPolicy: ClusterFirstWithHostNet | ||
hostNetwork: true | ||
securityContext: | ||
runAsUser: 0 | ||
containers: | ||
- name: filebeat | ||
volumeMounts: | ||
- name: varlogcontainers | ||
mountPath: /var/log/containers | ||
- name: varlogpods | ||
mountPath: /var/log/pods | ||
- name: varlibdockercontainers | ||
mountPath: /var/lib/docker/containers | ||
volumes: | ||
- name: varlogcontainers | ||
hostPath: | ||
path: /var/log/containers | ||
- name: varlogpods | ||
hostPath: | ||
path: /var/log/pods | ||
- name: varlibdockercontainers | ||
hostPath: | ||
path: /var/lib/docker/containers |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
ECK_VERSION=2.2.0 | ||
ELASTIC_CLUSTER_VERSION=8.2.2 | ||
KIBANA_AGENT_VERSION=8.2.2 | ||
BEAT_AGENT_VERSION=8.2.2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
#!/usr/bin/env bash | ||
set -o errexit | ||
set -o nounset | ||
#set -o xtrace | ||
|
||
source config | ||
|
||
if [ ! -x "$(command -v kubectl)" ]; then | ||
echo >&2 "You must have kubectl installed to use this script." | ||
exit 1 | ||
fi | ||
|
||
if [ ! -x "$(command -v yq)" ]; then | ||
echo >&2 "You must have yq (https://github.com/mikefarah/yq) installed to use this script." | ||
exit 1 | ||
fi | ||
|
||
function usage() { | ||
echo >&2 "Usage: $0 <K8s-namespace> <elastic-cluster-manifest> <kibana-agent-manifest> <beat-agent-manifest>" | ||
} | ||
|
||
if [ $# -ne 4 ]; then | ||
usage | ||
exit 1 | ||
fi | ||
|
||
K8S_NAMESPACE="${1}" | ||
ELASTIC_CLUSTER_MANIFEST="${2}" | ||
KIBANA_AGENT_MANIFEST="${3}" | ||
BEAT_AGENT_MANIFEST="${4}" | ||
|
||
function install-eck() { | ||
install-eck-crds-and-operator | ||
install-elastic-cluster | ||
install-kibana-agent | ||
install-beat-agent | ||
print-kibana-connection-info | ||
printf "\nDone!\n" | ||
} | ||
|
||
function install-eck-crds-and-operator() { | ||
# Default namespace from the ECK operator deployment descriptors is `elastic-system` | ||
DEFAULT_ECK_OPERATOR_NAMESPACE="elastic-system" | ||
ECK_CRDS_DESCRIPTOR="https://download.elastic.co/downloads/eck/${ECK_VERSION}/crds.yaml" | ||
ECK_OPERATOR_DESCRIPTOR="https://download.elastic.co/downloads/eck/${ECK_VERSION}/operator.yaml" | ||
|
||
printf "\nInstalling ECK custom resource definitions...\n\n" | ||
kubectl delete --wait=true --ignore-not-found=true -f "${ECK_CRDS_DESCRIPTOR}" | ||
kubectl create -f "${ECK_CRDS_DESCRIPTOR}" | ||
printf "\n" | ||
kubectl --namespace "${DEFAULT_ECK_OPERATOR_NAMESPACE}" delete --wait=true --ignore-not-found=true -f "${ECK_OPERATOR_DESCRIPTOR}" | ||
kubectl --namespace "${DEFAULT_ECK_OPERATOR_NAMESPACE}" wait pod -l control-plane=elastic-operator --for=delete --timeout=300s | ||
kubectl --namespace "${DEFAULT_ECK_OPERATOR_NAMESPACE}" create -f "${ECK_OPERATOR_DESCRIPTOR}" | ||
kubectl -n "${DEFAULT_ECK_OPERATOR_NAMESPACE}" wait --for=condition=Ready --timeout=300s pod -l control-plane=elastic-operator | ||
printf "\nECK operator deployed successfully!\n" | ||
} | ||
|
||
function install-elastic-cluster() { | ||
printf "\nInstalling Elastic cluster...\n\n" | ||
# Bump elastic cluster version | ||
yq e '.spec.version = "'"${ELASTIC_CLUSTER_VERSION}"'"' -i "${ELASTIC_CLUSTER_MANIFEST}" | ||
ELASTIC_CLUSTER_NAME=$(yq e '.metadata.name' "${ELASTIC_CLUSTER_MANIFEST}") | ||
ELASTIC_CLUSTER_LABEL=$(yq e '.spec.nodeSets[0].podTemplate.metadata.labels.app' "${ELASTIC_CLUSTER_MANIFEST}") | ||
|
||
create-namespace "${K8S_NAMESPACE}" "${ELASTIC_CLUSTER_MANIFEST}" | ||
|
||
# Waiting pod associated with CRD defined in $ELASTIC_CLUSTER_MANIFEST to be deleted | ||
kubectl --namespace "${K8S_NAMESPACE}" wait pod -l app="${ELASTIC_CLUSTER_LABEL}" --for=delete --timeout=300s | ||
|
||
kubectl --namespace "${K8S_NAMESPACE}" create -f "${ELASTIC_CLUSTER_MANIFEST}" | ||
printf "\n" | ||
kubectl --namespace "${K8S_NAMESPACE}" wait elasticsearch "${ELASTIC_CLUSTER_NAME}" --for=jsonpath='{.metadata.name}'="${ELASTIC_CLUSTER_NAME}" --timeout=400s | ||
|
||
while ! kubectl -n "${K8S_NAMESPACE}" get secret "${ELASTIC_CLUSTER_NAME}"-es-elastic-user ; do echo "Waiting "${ELASTIC_CLUSTER_NAME}"-es-elastic-user secret to be created..."; sleep 3; done | ||
while [[ $(kubectl --namespace "${K8S_NAMESPACE}" get pods -l app="${ELASTIC_CLUSTER_LABEL}" -o 'jsonpath={..status.conditions[?(@.type=="Ready")].status}') != "True" ]]; do echo "Waiting for elasticsearch pod to be Ready..." && sleep 3; done | ||
kubectl --namespace "${K8S_NAMESPACE}" wait pod -l app="${ELASTIC_CLUSTER_LABEL}" --for=jsonpath='{.status.phase}'=Running --timeout=400s | ||
printf "\nElastic cluster deployed successfully!\n" | ||
} | ||
|
||
function install-kibana-agent() { | ||
printf "\nInstalling Kibana agent...\n\n" | ||
# Bump kibana agent version | ||
yq e '.spec.version = "'"${KIBANA_AGENT_VERSION}"'"' -i "${KIBANA_AGENT_MANIFEST}" | ||
KIBANA_AGENT_NAME=$(yq e '.metadata.name' "${KIBANA_AGENT_MANIFEST}") | ||
KIBANA_AGENT_LABEL=$(yq e '.spec.podTemplate.metadata.labels.app' "${KIBANA_AGENT_MANIFEST}") | ||
create-namespace "${K8S_NAMESPACE}" "${KIBANA_AGENT_MANIFEST}" | ||
|
||
# Waiting pod associated with CRD defined in $KIBANA_AGENT_MANIFEST to be deleted | ||
kubectl --namespace "${K8S_NAMESPACE}" wait pod -l app="${KIBANA_AGENT_LABEL}" --for=delete --timeout=300s | ||
|
||
kubectl --namespace "${K8S_NAMESPACE}" create -f "${KIBANA_AGENT_MANIFEST}" | ||
printf "\n" | ||
kubectl --namespace "${K8S_NAMESPACE}" wait kibana "${KIBANA_AGENT_NAME}" --for=jsonpath='{.metadata.name}'="${KIBANA_AGENT_NAME}" --timeout=400s | ||
|
||
while [[ $(kubectl --namespace "${K8S_NAMESPACE}" get pods -l app="${KIBANA_AGENT_LABEL}" -o 'jsonpath={..status.conditions[?(@.type=="Ready")].status}') != "True" ]]; do echo "Waiting for kibana pod to be Ready..." && sleep 5; done | ||
kubectl --namespace "${K8S_NAMESPACE}" wait pod -l app="${KIBANA_AGENT_LABEL}" --for=jsonpath='{.status.phase}'=Running --timeout=400s | ||
printf "\nKibana agent deployed successfully!\n" | ||
} | ||
|
||
function install-beat-agent() { | ||
printf "\nInstalling Beat agent...\n\n" | ||
# Bump Beat agent version | ||
yq e '.spec.version = "'"${BEAT_AGENT_VERSION}"'"' -i "${BEAT_AGENT_MANIFEST}" | ||
yq e '.spec.version = "'"${BEAT_AGENT_VERSION}"'"' -i "${BEAT_AGENT_MANIFEST}" | ||
|
||
BEAT_AGENT_NAME=$(yq e '.metadata.name' "${BEAT_AGENT_MANIFEST}") | ||
BEAT_AGENT_LABEL=$(yq e '.spec.daemonSet.podTemplate.metadata.labels.app' "${BEAT_AGENT_MANIFEST}") | ||
|
||
create-namespace "${K8S_NAMESPACE}" "${BEAT_AGENT_MANIFEST}" | ||
|
||
# Waiting pod associated with CRD defined in $BEAT_AGENT_MANIFEST to be deleted | ||
kubectl --namespace "${K8S_NAMESPACE}" wait pod -l app="${BEAT_AGENT_LABEL}" --for=delete --timeout=300s | ||
|
||
kubectl --namespace "${K8S_NAMESPACE}" create -f "${BEAT_AGENT_MANIFEST}" | ||
printf "\n" | ||
kubectl --namespace "${K8S_NAMESPACE}" wait beat "${BEAT_AGENT_NAME}" --for=jsonpath='{.metadata.name}'="${BEAT_AGENT_NAME}" --timeout=400s | ||
|
||
while ! kubectl --namespace "${K8S_NAMESPACE}" get pod -l app="${BEAT_AGENT_LABEL}" ; do echo "Waiting beat pods to be created..."; sleep 3; done | ||
kubectl --namespace "${K8S_NAMESPACE}" wait pod -l app="${BEAT_AGENT_LABEL}" --for=jsonpath='{.status.phase}'=Running --timeout=400s | ||
printf "\nBeat agent deployed successfully!\n" | ||
} | ||
|
||
function create-namespace() { | ||
# Create namespace iff does not exist or delete the resources specified inside the manifest file | ||
if [ "$(kubectl get ns | grep "${1}" | cut -d ' ' -f1)" == "${1}" ]; then | ||
printf "K8s namespace [%s] already exists! \n\n" "$1" | ||
printf "Deleting K8s resources specified in [%s] manifest... \n" "${2}" | ||
|
||
kubectl --namespace "${1}" delete --wait=true --ignore-not-found=true -f "${2}" | ||
printf "\n" | ||
else | ||
echo "Creating K8s namespace [${1}]..." | ||
kubectl create namespace "${1}" | ||
fi | ||
} | ||
|
||
function print-kibana-connection-info() { | ||
NODE_IP=$(kubectl get nodes --selector=kubernetes.io/role!=master -o jsonpath={.items[0].status.addresses[?\(@.type==\"InternalIP\"\)].address}) | ||
ELASTICSEARCH_NAME=$(yq e '.metadata.name' "${ELASTIC_CLUSTER_MANIFEST}") | ||
KIBANA_PASSWORD=$(kubectl -n "${K8S_NAMESPACE}" get secret "${ELASTICSEARCH_NAME}"-es-elastic-user -o=jsonpath='{.data.elastic}' | base64 --decode; echo) | ||
|
||
printf "Access Kibana UI through [https://%s:5601]\n\n" "${NODE_IP}" | ||
printf "Username: elastic\n" | ||
printf "Password: %s\n" "${KIBANA_PASSWORD}" | ||
} | ||
|
||
install-eck |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
apiVersion: elasticsearch.k8s.elastic.co/v1 | ||
kind: Elasticsearch | ||
metadata: | ||
name: elasticsearch | ||
spec: | ||
version: 8.2.2 # version will be generated when running `./eck-deployer.sh` | ||
nodeSets: | ||
- name: default | ||
count: 1 # number of Elastic clusters to deploy | ||
podTemplate: | ||
metadata: | ||
labels: | ||
app: elasticsearch | ||
config: | ||
node.store.allow_mmap: false # https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-virtual-memory.html#k8s-virtual-memory |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
apiVersion: kibana.k8s.elastic.co/v1 | ||
kind: Kibana | ||
metadata: | ||
name: kibana | ||
spec: | ||
version: 8.2.2 # version will be generated when running `./eck-deployer.sh` | ||
count: 1 # number of Kibana agents to deploy | ||
podTemplate: | ||
metadata: | ||
labels: | ||
app: kibana | ||
elasticsearchRef: | ||
name: elasticsearch | ||
http: | ||
service: | ||
spec: | ||
type: LoadBalancer |