Skip to content

Commit

Permalink
Merge pull request vmware-tanzu#58 from abiogenesis-now/chuck/jsonnet
Browse files Browse the repository at this point in the history
[docs][chuck] Example YAML generation using ksonnet and kubecfg
Signed-off-by: Jesse Hamilton jesse.hamilton@heptio.com
  • Loading branch information
Ken Simon authored Aug 24, 2017
2 parents b50249f + abbd530 commit e5b9fab
Show file tree
Hide file tree
Showing 19 changed files with 731 additions and 265 deletions.
31 changes: 24 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#
# Note the only reason we are creating this is because upstream
# does not yet publish a released e2e container
# https://github.com/kubernetes/kubernetes/issues/47920

EXAMPLE_FILES = $(wildcard examples/quickstart/*.jsonnet)
EXAMPLE_OUTPUT = $(patsubst examples/quickstart/%.jsonnet,examples/quickstart/%.json,$(EXAMPLE_FILES))
EXAMPLE_FILES = $(wildcard examples/ksonnet/components/*.jsonnet)
EXAMPLE_OUTPUT = examples/quickstart/aggregate.yaml $(patsubst examples/ksonnet/components/%.jsonnet,examples/quickstart/components/%.yaml,$(EXAMPLE_FILES))
KSONNET_BUILD_IMAGE = ksonnet/ksonnet-lib:beta.2

TARGET = sonobuoy
Expand All @@ -41,6 +41,15 @@ TESTARGS ?= -v -timeout 60s
TEST = go test $(TEST_PKGS) $(TESTARGS)
TEST_PKGS ?= $(GOTARGET)/cmd/... $(GOTARGET)/pkg/...

WORKDIR ?= /sonobuoy
RBAC_ENABLED ?= 1
KUBECFG_CMD = $(DOCKER) run \
-v $(DIR):$(WORKDIR) \
--workdir $(WORKDIR) \
--rm \
$(KSONNET_BUILD_IMAGE) \
kubecfg show -o yaml -V RBAC_ENABLED=$(RBAC_ENABLED) -J $(WORKDIR) -o yaml $< > $@

.PHONY: all container push clean cbuild test local generate-examples

all: container
Expand Down Expand Up @@ -71,12 +80,20 @@ push:
$(DOCKER) push $(REGISTRY)/$(TARGET):latest; \
fi

gcloud docker -- push $(REGISTRY)/$(TARGET):$(VERSION)

clean:
rm -f $(TARGET)
$(DOCKER) rmi $(REGISTRY)/$(TARGET) || true
rm -f ./examples/quickstart/*.json
find ./examples/ -type f -name '*.yaml' -delete

generate-examples: latest-ksonnet $(EXAMPLE_OUTPUT)

examples/quickstart/components/%.yaml: examples/ksonnet/components/%.jsonnet
$(KUBECFG_CMD)

generate-examples: $(EXAMPLE_OUTPUT)
examples/quickstart/%.yaml: examples/ksonnet/%.jsonnet
$(KUBECFG_CMD)

examples/quickstart/%.json: examples/quickstart/%.jsonnet
$(DOCKER) run -v $(DIR):/sonobuoy --workdir /sonobuoy --rm $(KSONNET_BUILD_IMAGE) jsonnet -o $@ $<
latest-ksonnet:
$(DOCKER) pull $(KSONNET_BUILD_IMAGE)
33 changes: 20 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,22 @@ git clone git@github.com:heptio/sonobuoy.git

### 2. Run

Run the following command in the Sonobuoy root directory to deploy a Sonobuoy pod to your cluster:
Determine if your `kube-apiserver` supports RBAC with the following command:
```
kubectl apply -f examples/quickstart/
export RBAC_ENABLED=$(kubectl api-versions | grep "rbac.authorization.k8s.io/v1beta1" -c)
```
The environment variable you set here indicates whether RBAC-related resources should be included in the autogenerated, standalone YAML file. In an cluster running with `--authorization-mode=RBAC`, these resources are required to allow Sonobuoy to run properly.

Generate the YAML examples:
```
make generate-examples
```

This should create a collection of YAML files in your `examples/quickstart` directory. Note that the `components` sub-directory exists to help you understand Sonobuoy's different working parts, but is not necessary to run Sonobuoy itself.

To actually deploy a Sonobuoy pod to your cluster, run the following command in the Sonobuoy root directory:
```
kubectl apply -f examples/quickstart/aggregate.yaml
```

You can view actively running pods with the following command:
Expand All @@ -65,13 +78,7 @@ If you see the log line `no-exit was specified, sonobuoy is now blocking`, the S
> * **In practice, you should make sure that the Sonobuoy pod writes its results to a Persistent Volume.** The quickstart example writes its output to an `emptyDir` volume for simplicity.
>
> *Troubleshooting errors from `kubectl logs`*:
> * `plugin <name> does not exist`
>
> * Delete the `sonobuoy` pod via `kubectl delete pod sonobuoy --namespace heptio-sonobuoy` and rerun the `kubectl apply` command above. This error occurs when Sonobuoy's ConfigMap creations are not completed before its pod creation. While the YAML files in `examples/quickstart` use numeric prefixes ("00-", "10-", etc.) to specify the order of resource creation, `kubectl apply` is asynchronous and can result in dependency issues.
>
> * Other errors
>
> * If you are able to debug and resolve the issue on your own, *make sure to delete and reapply Sonobuoy's YAML manifests*. Otherwise, [file an issue][10].
> * If you are able to debug and resolve the issue on your own, *make sure to delete and reapply Sonobuoy's YAML manifests*. Otherwise, [file an issue][10].
>
To view the output, copy the output directory from the main Sonobuoy pod to somewhere local:
Expand All @@ -90,9 +97,9 @@ For information on the contents of the snapshot, see the [snapshot documentation

### 3. Tear down

To clean up Kubernetes objects created by Sonobuoy, run the following commands:
To clean up Kubernetes objects created by Sonobuoy, run the following command:
```
kubectl delete -f examples/quickstart/
kubectl delete -f examples/quickstart/aggregate.yaml
```

## Further documentation
Expand Down Expand Up @@ -124,8 +131,8 @@ developer certificate of origin that we require.
See [the list of releases](/CHANGELOG.md) to find out about feature changes.

[0]: https://github.com/heptio
[1]: https://jenkins.i.heptio.com/buildStatus/icon?job=sonobuoy-tag-deployer
[2]: https://jenkins.i.heptio.com/job/sonobuoy-tag-deployer/
[1]: https://jenkins.i.heptio.com/buildStatus/icon?job=sonobuoy-deployer
[2]: https://jenkins.i.heptio.com/job/sonobuoy-deployer/
[3]: https://github.com/kubernetes/kubernetes
[4]: /docs/build-from-scratch.md
[5]: http://docs.heptio.com/content/tutorials/aws-cloudformation-k8s.html
Expand Down
8 changes: 4 additions & 4 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Documentation Index

## Setting Up
## Setting up
* [Build From Scratch](build-from-scratch.md)
* [Configuration](configuration.md)
* [JSON templates](/examples)
* [Pre-generated YAML](/examples/quickstart)
* [Snapshot Layout](snapshot.md)

## Use Cases
* [Conformance Testing](conformance-testing.md)
* [Plugins](plugins.md)

## Developing Examples
* [Generating Example JSON](building-examples.md)
## Next Steps
* [Generating your own YAML manifests](/examples/README.md)
3 changes: 2 additions & 1 deletion docs/build-from-scratch.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ The results will be placed in the `ResultsDir` specified by `config.json`, where
> * Which container image is being used
> * Where your Sonobuoy output will be written
You should create a directory for your YAML manifest files. Feel free to use the [provided manifests][8] as a template to get started.
You should create a directory for your YAML manifest files. Feel free to use the [provided manifests][8] as a template to get started, or the [ksonnet files][9] to autogenerate the YAML more quickly.

*Standup*
```
Expand All @@ -88,3 +88,4 @@ kubectl delete -f <YAML_CONFIG_DIR>
[6]: /docs/plugins.md#overview
[7]: configuration.md#sonobuoy-config
[8]: /examples/quickstart
[9]: /examples/ksonnet
9 changes: 0 additions & 9 deletions docs/building-examples.md

This file was deleted.

24 changes: 13 additions & 11 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ Once the configs are loaded (in either case), Sonobuoy parses them and gathers d

| | Overview|Path on Cluster Node|[STANDALONE]<br>JSON example(s)|[CONTAINERIZED]<br>YAML manifest example(s)
|---|---|---|---|---|
|*Data configuration*| What Sonobuoy records, how, and where. |*ANY of the following*:<br>(1) `config.json` in the directory where `sonobuoy` is executed<br>(2) `/etc/sonobuoy/config.json`<br>(3) `$SONOBUOY_CONFIG`<br><br>|[`config.json`][10]|<br> [`examples/quickstart/10-configmaps.yaml`][11]<br><br>*The YAML file is basically a wrapper for the `config.json` file, which allows it to be properly mounted onto the cluster's Sonobuoy pod.* <br><br>
|*Plugin configuration*|Settings for each plugin integration.|*ANY of the following*:<br>(1) `/etc/sonobuoy/plugins.d`<br>(2) `$HOME/.sonobuoy/plugins.d`<br>(3) `./plugins.d`<br>(4) `PluginSearchPath` (override from the data configuration) <br><br>| There is a YAML config for each plugin:<br>(1) [`plugins.d/e2e.yaml`][16]<br>(2)[`plugins.d/systemdlogs.yaml`][17]|<br>[`examples/quickstart/10-configmaps.yaml`][11]
|*Kubernetes component definitions*|The various K8s objects that need to be defined for Sonobuoy to run as a containerized app.|N/A (manifest only)|N/A|The example splits this into two manifests:<br>(1) [`rbac.yaml`][12]<br>(2) [`pod.yaml`][13]|
|*Data configuration*| What Sonobuoy records, how, and where. |*ANY of the following*:<br>(1) `config.json` in the directory where `sonobuoy` is executed<br>(2) `/etc/sonobuoy/config.json`<br>(3) `$SONOBUOY_CONFIG`<br><br>|[`config.json`][10]|<br> [`examples/quickstart/components/10-configmaps.yaml`][11]<br><br>*The YAML file is basically a wrapper for the `config.json` file, which allows it to be properly mounted onto the cluster's Sonobuoy pod.* <br><br>
|*Plugin configuration*|Settings for each plugin integration.|*ANY of the following*:<br>(1) `/etc/sonobuoy/plugins.d`<br>(2) `$HOME/.sonobuoy/plugins.d`<br>(3) `./plugins.d`<br>(4) `PluginSearchPath` (override from the data configuration) <br><br>| There is a YAML config for each plugin:<br>(1) [`plugins.d/e2e.yaml`][16]<br>(2)[`plugins.d/systemdlogs.yaml`][17]|<br>[`examples/quickstart/components/10-configmaps.yaml`][11]<br><br>*Same comment about the YAML file as above.*
|*Kubernetes component definitions*|The various K8s objects that need to be defined for Sonobuoy to run as a containerized app.|N/A (manifest only)|N/A|The example splits this into two manifests:<br>(1) [`examples/quickstart/components/00-rbac.yaml`][12]<br>(2) [`examples/quickstart/components/20-pod.yaml`][13]|



*NOTE: The configuration for the containerized example is split into three manifests for the reader's sake---one covering the data and plugin configs, and two covering the Kubernetes component definitions. However, all of these specifications would still work if consolidated into one YAML file, as long as RBAC settings are defined first.*
*NOTE: The configuration for the containerized example is split into three manifests for the reader's sake---one covering the data and plugin configs, and two covering the Kubernetes component definitions. However, all of these specifications would still work if consolidated into one YAML file (as in [`examples/quickstart/aggregate.yaml`][18]), as long as any RBAC settings are defined first. *


## Data configuration
Expand Down Expand Up @@ -130,11 +130,11 @@ For more details on creating custom plugins, see the [plugin reference][9].

### Overview

*This section of the configuration is only applicable when Sonobuoy is run as a containerized pod.*
*This section of the configuration is only applicable when running Sonobuoy as a containerized pod.*

While the other configuration sections control Sonobuoy's data collection, this part defines the required Kubernetes resources to actually run Sonobuoy on the cluster. In the quickstart example, it is split into two manifests:
1. `rbac.yaml`: This sets up gives Sonobuoy the necessary permissions to query the API server.
2. `pod.yaml`: This sets up the Sonobuoy Pod and associated Service.
While the other configuration sections control Sonobuoy's data collection, this part defines the Kubernetes resources required to actually run Sonobuoy on your cluster. In the [`examples/quickstart/components`][19] example, it is split into two manifests:
1. `00-rbac.yaml`: This sets up gives Sonobuoy the necessary permissions to query the API server.
2. `20-pod.yaml`: This sets up the Sonobuoy Pod and associated Service.

### RBAC

Expand Down Expand Up @@ -175,10 +175,12 @@ However, ensure that your pod declaration has addressed the following aspects, w
[8]: #pod
[9]: plugins.md
[10]: /config.json
[11]: /examples/quickstart/10-configmaps.yaml
[12]: /examples/quickstart/rbac.yaml
[13]: /examples/quickstart/pod.yaml
[11]: /examples/quickstart/components/10-configmaps.yaml
[12]: /examples/quickstart/components/00-rbac.yaml
[13]: /examples/quickstart/components/20-pod.yaml
[14]: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
[15]: https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/
[16]: /plugins.d/e2e.yaml
[17]: plugins.d/systemdlogs.yaml
[18]: /examples/quickstart/aggregate.yaml
[19]: /examples/quickstart/components
4 changes: 2 additions & 2 deletions docs/conformance-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@ To customize the set of tests that will be run as part of the report, the follow
[5]: plugins.md
[6]: https://github.com/heptio/sonobuoy/blob/master/build/Dockerfile
[7]: https://github.com/heptio/sonobuoy/blob/master/plugins.d/e2e.yaml
[8]: https://github.com/heptio/sonobuoy/blob/master/examples/quickstart/10-configmaps.yaml#L185
[9]: https://github.com/heptio/sonobuoy/blob/master/examples/quickstart/10-configmaps.yaml#L71
[8]: https://github.com/heptio/sonobuoy/blob/master/examples/quickstart/components/10-configmaps.yaml#L185
[9]: https://github.com/heptio/sonobuoy/blob/master/examples/quickstart/components/10-configmaps.yaml#L71
[10]: https://github.com/kubernetes/kubernetes/issues/49313
31 changes: 30 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
# Examples

The YAML config files in this directory can be used to quickly deploy a containerized Sonobuoy pod.
This directory contains two sub-directories:
* [`/ksonnet`][4] - You can autogenerate Sonobuoy's YAML manifests with the [ksonnet][0] files in this directory. To do so, execute the `make generate-examples` command in the root of the Sonobuoy repo.

* [`/quickstart`][5] - You can use the YAML config files in this directory to quickly deploy a containerized Sonobuoy pod.

## /ksonnet

Sonobuoy's `make generate-examples` command compiles `*.jsonnet` files into YAML. This compilation process uses the [`kubecfg`][2] executable in the [official ksonnet Docker image][1].

This sub-directory is itself broken down into:
* `/components` - Each of the files in this directory covers a fairly distinct part of Sonobuoy's setup. The YAML that they generate is a more human-friendly way of viewing how Sonobuoy's component resources are set up.

* `00-rbac.jsonnet` - This sets up basic scaffolding (e.g. a dedicated namespace). If RBAC is enabled on the cluster, it also configures the necessary permissions for Sonobuoy to read data and dispatch pods into the cluster.

* `10-configmaps.jsonnet` - This sets up configurations for Sonobuoy as well as its plugins. The [configuration guide][3] explains in depth how to change these values.

* `20-pod.jsonnet` - This sets up the pod that actually runs the `sonobuoy` executable.

* `aggregate.jsonnet` - This combines all the `components` together to generate a standalone YAML file. As demonstrated in the README, the YAML file can be used to immediately take a Sonobuoy snapshot with `kubectl apply -f`.

## /quickstart

This directory structure maps 1:1 to that of the `/ksonnet` subdirectory (`*.yaml` instead of `*.jsonnet`), so the descriptions above should suffice.

[0]: http://ksonnet.heptio.com
[1]: https://hub.docker.com/r/ksonnet/ksonnet-lib/
[2]: https://github.com/ksonnet/kubecfg
[3]: /docs/configuration.md
[4]: #ksonnet
[5]: #quickstart
19 changes: 19 additions & 0 deletions examples/ksonnet/aggregate.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright 2017 Heptio Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

local rbac = import "examples/ksonnet/components/00-rbac.jsonnet";
local configmaps = import "examples/ksonnet/components/10-configmaps.jsonnet";
local pod = import "examples/ksonnet/components/20-pod.jsonnet";

rbac + configmaps + pod
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,12 @@ local clusterRole =
cr.rulesType.verbs("*"),
]);

local optRbacObj =
if std.extVar("RBAC_ENABLED") != "0"
then [clusterRoleBinding, clusterRole]
else [];

k.core.v1.list.new([
namespace,
serviceaccount,
clusterRoleBinding,
clusterRole,])
namespace,
serviceaccount
] + optRbacObj)
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

local k = import "ksonnet.beta.2/k.libsonnet";
local kubecfg = import "kubecfg.libsonnet";
local configMap = k.core.v1.configMap;

local conf = {
Expand Down Expand Up @@ -304,15 +305,15 @@ local e2eConfig = {
};

local plugins = {
"systemdlogs.json": std.toString(systemdlogsConfig),
"e2e.json": std.toString(e2eConfig),
"systemdlogs.yaml": kubecfg.manifestYaml(systemdlogsConfig),
"e2e.yaml": kubecfg.manifestYaml(e2eConfig),
};

local sonobuoyConfig = configMap.new() +
configMap.mixin.metadata.name(conf.sonobuoyCfg.name) +
configMap.mixin.metadata.namespace(conf.namespace) +
configMap.mixin.metadata.labels(conf.labels) +
configMap.data({"config.json": std.toString(sonobuoyConfigData)});
configMap.data({"config.json": kubecfg.manifestJson(sonobuoyConfigData)});

local pluginConfigs = configMap.new() +
configMap.mixin.metadata.name(conf.pluginsCfg.name) +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ local conf = {
},
{
name: "output-volume",
hostPath: {path: "/tmp/sonobuoy"},
emptyDir: {},
},
],
name: "sonobuoy",
Expand Down
Loading

0 comments on commit e5b9fab

Please sign in to comment.