From b2ebc8153356f9a5f9da246237d5f726ea074235 Mon Sep 17 00:00:00 2001 From: Nelson Wang Date: Sat, 23 May 2020 17:28:17 -0700 Subject: [PATCH] Adding test and docs to use image as root --- docs/EXAMPLES.md | 100 ++++++++++++++++++++---------------- tests/test_docker_splunk.py | 74 ++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 44 deletions(-) diff --git a/docs/EXAMPLES.md b/docs/EXAMPLES.md index 0179fcc2..77ee386a 100644 --- a/docs/EXAMPLES.md +++ b/docs/EXAMPLES.md @@ -15,6 +15,7 @@ Note that for more complex scenarios, we will opt to use a [Docker compose file] * [...with a SplunkBase app](#create-standalone-with-splunkbase-app) * [...with SSL enabled](#create-standalone-with-ssl-enabled) * [...with a Splunk Free license](#create-standalone-with-splunk-free-license) +* [Create sidecar forwarder running as root](#create-sidecar-root-forwarder) * [Create standalone and universal forwarder](#create-standalone-and-universal-forwarder) * [Create heavy forwarder](#create-heavy-forwarder) * [Create heavy forwarder and deployment server](#create-heavy-forwarder-and-deployment-server) @@ -22,7 +23,6 @@ Note that for more complex scenarios, we will opt to use a [Docker compose file] * [Create search head cluster](#create-search-head-cluster) * [Create indexer cluster and search head cluster](#create-indexer-cluster-and-search-head-cluster) * [Enable root endpoint on SplunkWeb](#enable-root-endpoint-on-splunkweb) -* [Create sidecar forwarder](#create-sidecar-forwarder) * [More](#more) ## Create standalone from CLI @@ -221,6 +221,61 @@ $ docker run --name so1 --hostname so1 -p 8000:8000 \ -it splunk/splunk:latest ``` +## Create sidecar root forwarder + +
k8s-sidecar.yml

+ +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: example +spec: + securityContext: + runAsUser: 0 + runAsGroup: 0 + containers: + - name: splunk-uf + image: splunk/universalforwarder:latest + env: + - name: SPLUNK_START_ARGS + value: --accept-license + - name: SPLUNK_USER + value: root + - name: SPLUNK_GROUP + value: root + - name: SPLUNK_PASSWORD + value: helloworld + - name: SPLUNK_CMD + value: add monitor /var/log/ + - name: SPLUNK_STANDALONE_URL + value: splunk.company.internal + volumeMounts: + - name: shared-data + mountPath: /var/log + - name: my-app + image: my-app + volumeMounts: + - name: shared-data + mountPath: /app/logs/ + volumes: + - name: shared-data + emptyDir: {} +``` +

+ +Execute the following to bring up your deployment: +``` +$ kubectl apply -f k8s-sidecar.yml +``` + +Alternatively, if you're not using Kubernetes you can use the Docker CLI to bring up the Universal Forwarder under the `root` user with the following: +``` +$ docker run -d -P --user root -e SPLUNK_START_ARGS=--accept-license -e SPLUNK_PASSWORD=helloworld -e SPLUNK_USER=root -e SPLUNK_GROUP=root splunk/universalforwarder:latest +``` + +After your pod is ready, the universal forwarder will be reading the logs generated by your app via the shared volume mount. In the ideal case, your app is generating the logs while the forwarder is reading them and streaming the output to a separate Splunk instance located at splunk.company.internal. + ## Create standalone and universal forwarder You can also enable distributed deployments. In this case, we can create a Splunk universal forwarder running in a container to stream logs to a Splunk standalone, also running in a container. @@ -855,48 +910,5 @@ $ SPLUNK_PASSWORD= docker-compose up -d Then, visit SplunkWeb on your browser with the root endpoint in the URL, such as `http://localhost:8000/splunkweb`. -## Create sidecar forwarder - -
k8s-sidecar.yml

- -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: example -spec: - containers: - - name: splunk-uf - image: splunk/universalforwarder:latest - env: - - name: SPLUNK_START_ARGS - value: --accept-license - - name: SPLUNK_PASSWORD - value: helloworld - - name: SPLUNK_CMD - value: add monitor /var/log/ - - name: SPLUNK_STANDALONE_URL - value: splunk.company.internal - volumeMounts: - - name: shared-data - mountPath: /var/log - - name: my-app - image: my-app - volumeMounts: - - name: shared-data - mountPath: /app/logs/ - volumes: - - name: shared-data - emptyDir: {} -``` -

- -Execute the following to bring up your deployment: -``` -$ kubectl apply -f k8s-sidecar.yml -``` - -After your pod is ready, the universal forwarder will be reading the logs generated by your app via the shared volume mount. In the ideal case, your app is generating the logs while the forwarder is reading them and streaming the output to a separate Splunk instance located at splunk.company.internal. - ## More There are a variety of Docker compose scenarios in the `docker-splunk` repo [here](https://github.com/splunk/docker-splunk/tree/develop/test_scenarios). Feel free to use any of those for reference in deploying different topologies! diff --git a/tests/test_docker_splunk.py b/tests/test_docker_splunk.py index 51537306..8ddaf96d 100644 --- a/tests/test_docker_splunk.py +++ b/tests/test_docker_splunk.py @@ -1445,6 +1445,80 @@ def test_adhoc_1uf_bind_mount_apps(self): except OSError: pass + def test_adhoc_1so_run_as_root(self): + # Create a splunk container + cid = None + try: + splunk_container_name = generate_random_string() + cid = self.client.create_container(self.SPLUNK_IMAGE_NAME, tty=True, ports=[8089], name=splunk_container_name, user="root", + environment={ + "DEBUG": "true", + "SPLUNK_START_ARGS": "--accept-license", + "SPLUNK_PASSWORD": self.password, + "SPLUNK_USER": "root", + "SPLUNK_GROUP": "root" + }, + host_config=self.client.create_host_config(port_bindings={8089: ("0.0.0.0",)}) + ) + cid = cid.get("Id") + self.client.start(cid) + # Poll for the container to be ready + assert self.wait_for_containers(1, name=splunk_container_name) + # Check splunkd + splunkd_port = self.client.port(cid, 8089)[0]["HostPort"] + url = "https://localhost:{}/services/server/info".format(splunkd_port) + kwargs = {"auth": ("admin", self.password), "verify": False} + status, content = self.handle_request_retry("GET", url, kwargs) + assert status == 200 + # Check that root owns the splunkd process + exec_command = self.client.exec_create(cid, "ps -u root", user="root") + std_out = self.client.exec_start(exec_command) + assert "entrypoint.sh" in std_out + assert "splunkd" in std_out + except Exception as e: + self.logger.error(e) + raise e + finally: + if cid: + self.client.remove_container(cid, v=True, force=True) + + def test_adhoc_1uf_run_as_root(self): + # Create a uf container + cid = None + try: + splunk_container_name = generate_random_string() + cid = self.client.create_container(self.UF_IMAGE_NAME, tty=True, ports=[8089], name=splunk_container_name, user="root", + environment={ + "DEBUG": "true", + "SPLUNK_START_ARGS": "--accept-license", + "SPLUNK_PASSWORD": self.password, + "SPLUNK_USER": "root", + "SPLUNK_GROUP": "root" + }, + host_config=self.client.create_host_config(port_bindings={8089: ("0.0.0.0",)}) + ) + cid = cid.get("Id") + self.client.start(cid) + # Poll for the container to be ready + assert self.wait_for_containers(1, name=splunk_container_name) + # Check splunkd + splunkd_port = self.client.port(cid, 8089)[0]["HostPort"] + url = "https://localhost:{}/services/server/info".format(splunkd_port) + kwargs = {"auth": ("admin", self.password), "verify": False} + status, content = self.handle_request_retry("GET", url, kwargs) + assert status == 200 + # Check that root owns the splunkd process + exec_command = self.client.exec_create(cid, "ps -u root", user="root") + std_out = self.client.exec_start(exec_command) + assert "entrypoint.sh" in std_out + assert "splunkd" in std_out + except Exception as e: + self.logger.error(e) + raise e + finally: + if cid: + self.client.remove_container(cid, v=True, force=True) + def test_adhoc_1so_hec_idempotence(self): """ This test is intended to check how the container gets provisioned with changing splunk.hec.* parameters