mirror of
https://github.com/holos-run/holos.git
synced 2026-03-03 11:38:56 +00:00
Compare commits
5 Commits
release
...
301-docs-s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
488f7ae985 | ||
|
|
4817491aab | ||
|
|
30ce72a9b7 | ||
|
|
958f65ddcf | ||
|
|
a1c9111a05 |
272
doc/md/topics/4-local-cluster.mdx
Normal file
272
doc/md/topics/4-local-cluster.mdx
Normal file
@@ -0,0 +1,272 @@
|
||||
---
|
||||
description: Build a local Cluster to use with these guides.
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Local Cluster
|
||||
|
||||
In this guide we'll set up a local k3d cluster to apply and explore the
|
||||
configuration described in our other guides. After completing this guide you'll
|
||||
have a standard Kubernetes API server with proper DNS and TLS certificates.
|
||||
You'll be able to easily reset the cluster to a known good state to iterate on
|
||||
your own Platform.
|
||||
|
||||
## Reset the Cluster
|
||||
|
||||
If you've already followed this guide, reset the cluster by running the
|
||||
following commands. Skip this section if you're creating a cluster for the
|
||||
first time.
|
||||
|
||||
First, delete the cluster.
|
||||
|
||||
<Tabs groupId="k3d-cluster-delete">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
k3d cluster delete workload
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
INFO[0000] Deleting cluster 'workload'
|
||||
INFO[0000] Deleting cluster network 'k3d-workload'
|
||||
INFO[0000] Deleting 1 attached volumes...
|
||||
INFO[0000] Removing cluster details from default kubeconfig...
|
||||
INFO[0000] Removing standalone kubeconfig file (if there is one)...
|
||||
INFO[0000] Successfully deleted cluster workload!
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Then create the cluster again.
|
||||
|
||||
<Tabs groupId="k3d-cluster-create">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
k3d cluster create workload \
|
||||
--registry-use k3d-registry.holos.localhost:5100 \
|
||||
--port "443:443@loadbalancer" \
|
||||
--k3s-arg "--disable=traefik@server:0"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
INFO[0000] portmapping '443:443' targets the loadbalancer: defaulting to [servers:*:proxy agents:*:proxy]
|
||||
INFO[0000] Prep: Network
|
||||
INFO[0000] Created network 'k3d-workload'
|
||||
INFO[0000] Created image volume k3d-workload-images
|
||||
INFO[0000] Starting new tools node...
|
||||
INFO[0000] Starting node 'k3d-workload-tools'
|
||||
INFO[0001] Creating node 'k3d-workload-server-0'
|
||||
INFO[0001] Creating LoadBalancer 'k3d-workload-serverlb'
|
||||
INFO[0001] Using the k3d-tools node to gather environment information
|
||||
INFO[0001] HostIP: using network gateway 172.17.0.1 address
|
||||
INFO[0001] Starting cluster 'workload'
|
||||
INFO[0001] Starting servers...
|
||||
INFO[0001] Starting node 'k3d-workload-server-0'
|
||||
INFO[0003] All agents already running.
|
||||
INFO[0003] Starting helpers...
|
||||
INFO[0003] Starting node 'k3d-workload-serverlb'
|
||||
INFO[0009] Injecting records for hostAliases (incl. host.k3d.internal) and for 3 network members into CoreDNS configmap...
|
||||
INFO[0012] Cluster 'workload' created successfully!
|
||||
INFO[0012] You can now use it like this:
|
||||
kubectl cluster-info
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Finally, add your trusted certificate authority.
|
||||
|
||||
<Tabs groupId="apply-local-ca">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f "$(mkcert -CAROOT)/namespace.yaml"
|
||||
kubectl apply --server-side=true -n cert-manager -f "$(mkcert -CAROOT)/local-ca.yaml"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
namespace/cert-manager serverside-applied
|
||||
secret/local-ca serverside-applied
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
You're back to the same state as the first time you completed this guide.
|
||||
|
||||
## What you'll need {#requirements}
|
||||
|
||||
You'll need the following tools installed to complete this guide.
|
||||
|
||||
1. [holos](/docs/install) - to build the platform.
|
||||
2. [helm](https://helm.sh/docs/intro/install/) - to render Holos components that wrap upstream Helm charts.
|
||||
3. [k3d](https://k3d.io/#installation) - to provide a k8s api server.
|
||||
4. [OrbStack](https://docs.orbstack.dev/install) or [Docker](https://docs.docker.com/get-docker/) - to use k3d.
|
||||
5. [kubectl](https://kubernetes.io/docs/tasks/tools/) - to interact with the k8s api server.
|
||||
6. [mkcert](https://github.com/FiloSottile/mkcert?tab=readme-ov-file#installation) - to make trusted TLS certificates.
|
||||
7. [jq](https://jqlang.github.io/jq/download/) - to fiddle with JSON output.
|
||||
|
||||
## Configure DNS {#configure-dns}
|
||||
|
||||
Configure your machine to resolve `*.holos.localhost` to your loopback
|
||||
interface. This is necessary for requests to reach the workload cluster. Save
|
||||
this script to a file and execute it.
|
||||
|
||||
```bash showLineNumbers
|
||||
#! /bin/bash
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
[[ -d "$tmpdir" ]] && rm -rf "$tmpdir"
|
||||
}
|
||||
trap finish EXIT
|
||||
cd "$tmpdir"
|
||||
|
||||
brew install dnsmasq
|
||||
|
||||
cat <<EOF >"$(brew --prefix)/etc/dnsmasq.d/holos.localhost.conf"
|
||||
# Refer to https://holos.run/docs/tutorial/local/k3d/
|
||||
address=/holos.localhost/127.0.0.1
|
||||
EOF
|
||||
|
||||
if [[ -r /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist ]]; then
|
||||
echo "dnsmasq already configured"
|
||||
else
|
||||
sudo cp "$(brew list dnsmasq | grep 'dnsmasq.plist$')" \
|
||||
/Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
|
||||
sudo launchctl unload /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
|
||||
sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
|
||||
dscacheutil -flushcache
|
||||
echo "dnsmasq configured"
|
||||
fi
|
||||
|
||||
sudo mkdir -p /etc/resolver
|
||||
sudo tee /etc/resolver/holos.localhost <<EOF
|
||||
domain holos.localhost
|
||||
nameserver 127.0.0.1
|
||||
EOF
|
||||
sudo killall -HUP mDNSResponder
|
||||
|
||||
echo "all done."
|
||||
```
|
||||
|
||||
## Create the Cluster {#create-the-cluster}
|
||||
|
||||
The Workload Cluster is where your applications and services will be deployed.
|
||||
In production this is usually an EKS, GKE, or AKS cluster.
|
||||
|
||||
:::tip
|
||||
|
||||
Holos supports all compliant Kubernetes clusters. Holos was developed and tested
|
||||
on GKE, EKS, Talos, k3s, and Kubeadm clusters.
|
||||
|
||||
:::
|
||||
|
||||
Create a local registry to speed up image builds and pulls.
|
||||
|
||||
```bash
|
||||
k3d registry create registry.holos.localhost --port 5100
|
||||
```
|
||||
|
||||
Create the workload cluster configured to use the local registry.
|
||||
|
||||
```bash
|
||||
k3d cluster create workload \
|
||||
--registry-use k3d-registry.holos.localhost:5100 \
|
||||
--port "443:443@loadbalancer" \
|
||||
--k3s-arg "--disable=traefik@server:0"
|
||||
```
|
||||
|
||||
Traefik is disabled because Istio provides the same functionality.
|
||||
|
||||
## Setup Root CA {#setup-root-ca}
|
||||
|
||||
Platforms most often use cert-manager to issue tls certificates. The browser
|
||||
and tools we're using need to trust these certificates to work together.
|
||||
Generate a local, trusted root certificate authority with the following script.
|
||||
|
||||
Admin access is necessary for `mkcert` to manage the certificate into your trust
|
||||
stores.
|
||||
|
||||
```bash
|
||||
sudo -v
|
||||
```
|
||||
|
||||
Manage the local CA and copy the CA key to the workload cluster so that cert
|
||||
manager can manage trusted certificates.
|
||||
|
||||
Save this script to a file and execute it to configure a trusted certificate
|
||||
authority.
|
||||
|
||||
```bash showLineNumbers
|
||||
#! /bin/bash
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
mkcert --install
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
[[ -d "$tmpdir" ]] && rm -rf "$tmpdir"
|
||||
}
|
||||
trap finish EXIT
|
||||
cd "$tmpdir"
|
||||
|
||||
# Create the local CA Secret with ca.crt, tls.crt, tls.key
|
||||
|
||||
mkdir local-ca
|
||||
cd local-ca
|
||||
CAROOT="$(mkcert -CAROOT)"
|
||||
cp -p "${CAROOT}/rootCA.pem" ca.crt
|
||||
cp -p "${CAROOT}/rootCA.pem" tls.crt
|
||||
cp -p "${CAROOT}/rootCA-key.pem" tls.key
|
||||
kubectl create secret generic --from-file=. --dry-run=client -o yaml local-ca > ../local-ca.yaml
|
||||
echo 'type: kubernetes.io/tls' >> ../local-ca.yaml
|
||||
|
||||
cd ..
|
||||
|
||||
cat <<EOF > namespace.yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
kubernetes.io/metadata.name: cert-manager
|
||||
name: cert-manager
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
EOF
|
||||
kubectl apply --server-side=true -f namespace.yaml
|
||||
kubectl apply -n cert-manager --server-side=true -f local-ca.yaml
|
||||
|
||||
# Save the Secret to easily reset the cluster later.
|
||||
install -m 0644 namespace.yaml "${CAROOT}/namespace.yaml"
|
||||
install -m 0600 local-ca.yaml "${CAROOT}/local-ca.yaml"
|
||||
```
|
||||
|
||||
:::warning
|
||||
|
||||
Take care to run the local-ca script each time you create the workload cluster
|
||||
so that Certificates are issued correctly.
|
||||
|
||||
:::
|
||||
|
||||
## Clean Up {#clean-up}
|
||||
|
||||
If you'd like to clean up the resources you created in this guide, remove them
|
||||
with:
|
||||
|
||||
```bash
|
||||
k3d cluster delete workload
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
Now that you have a real cluster, continue your Holos journey by following the
|
||||
[Tutorial](../tutorial/1-overview.mdx) and setting up your own Platform.
|
||||
@@ -1 +1,94 @@
|
||||
# Overview
|
||||
|
||||
Holos is an open-source tool that simplifies software integration for platform
|
||||
teams. While most Kubernetes tools focus on application management, Holos takes
|
||||
a holistic infrastructure-as-code (IaC) approach, targeting the integration
|
||||
layer where applications and organizational data converge. By providing
|
||||
well-defined, typed structures for consistent validation, Holos reduces errors,
|
||||
streamlines integration, and creates clear pathways for teams to easily
|
||||
integrate their services.
|
||||
|
||||
# How Holos works
|
||||
|
||||
Holos implements the [rendered manifests pattern][rmp], generating fully
|
||||
rendered Kubernetes manifests from [CUE language][CUE] abstractions called
|
||||
Components. These Components can model [Helm charts][Helm], [Kustomize
|
||||
bases][Kustomize], or native Kubernetes resources. A Holos Platform consists of
|
||||
one or more Components and is applied to one or more Kubernetes clusters.
|
||||
|
||||
```mermaid
|
||||
graph BT
|
||||
Platform[Platform]
|
||||
Cluster[Cluster]
|
||||
Component[Component]
|
||||
Helm[Helm]
|
||||
Kustomize[Kustomize]
|
||||
CUE[CUE]
|
||||
|
||||
Platform --> Cluster
|
||||
Component --> Platform
|
||||
Helm --> Component
|
||||
Kustomize --> Component
|
||||
CUE --> Component
|
||||
```
|
||||
|
||||
# Holos' role in your workflow
|
||||
|
||||
Holos generates, but does not apply, rendered manifests, allowing teams to use
|
||||
`git diff` to clearly see changes and assess the impact on clusters and services
|
||||
before deploying. Instead, Holos manages the GitOps configuration for tools like
|
||||
ArgoCD and Flux CD, enabling continuous deployment of resource changes with the
|
||||
full visibility and control that these tools provide. As a result, expect Holos
|
||||
to sit at the very end of a CI pipeline.
|
||||
|
||||
# Advantages of using Holos
|
||||
|
||||
### Safety
|
||||
|
||||
* CUE constraints on Holos Components surface validation errors early in the
|
||||
development process, reducing the number of failed deployments and the time
|
||||
spent troubleshooting them.
|
||||
* Holos natively provides a "blast radius" to code
|
||||
changes by identifying the rendered manifests across your fleet of Kubernetes
|
||||
clusters that will be affected by the change.
|
||||
* CUE's unification strategy allows multiples teams to contribute to the desired
|
||||
state of a service:
|
||||
* The Platform team provides definitions for shared resources.
|
||||
* Engineering teams populate definitions with service-specific data.
|
||||
* The Security team provides concrete values that cannot be changed to harden the company's security posture.
|
||||
|
||||
### Flexibility
|
||||
|
||||
* CUE is adept at modeling variation and organizational complexity at scale,
|
||||
while Holos enables seamless integration of CUE data with native Kubernetes
|
||||
tools such as [Helm][Helm] and [Kustomize][Kustomize].
|
||||
* Holos is extensible, allowing Holos Components to be modeled from any tool that
|
||||
generates (e.g. `helm`) or transforms (e.g. `kustomize`) manifest data.
|
||||
|
||||
### Consistency
|
||||
|
||||
* Holos manages the execution context for Helm and Kustomize, ensuring that
|
||||
rendered manifests are consistently and reliably reproducible, no matter where
|
||||
Holos is run.
|
||||
* CUE constraints ensure that data abstractions include the required information
|
||||
in the expected format, triggering early failures if any required data is
|
||||
missing.
|
||||
|
||||
|
||||
# When not to use Holos
|
||||
|
||||
Holos excels at configuration management and is most effective when integrated
|
||||
into a broader Kubernetes deployment strategy. If you need a single tool to
|
||||
manage the entire lifecycle of a Kubernetes cluster, Holos may not fully meet
|
||||
your needs on its own.
|
||||
|
||||
# Next Steps
|
||||
|
||||
Now that you have a base understanding of how Holos works, continue
|
||||
to the [Setup page](./2-setup.mdx) that guides you through installing Holos and
|
||||
initializing your first Platform.
|
||||
|
||||
[rmp]: https://akuity.io/blog/the-rendered-manifests-pattern
|
||||
[Helm]: https://helm.sh/
|
||||
[Kustomize]: https://kustomize.io/
|
||||
[CUE]: https://cuelang.org/
|
||||
|
||||
@@ -1 +1,85 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Setup
|
||||
|
||||
This tutorial will guide you through the installation of Holos and its
|
||||
dependencies, as well as the initialization of a minimal Platform that you can
|
||||
extend to meet your specific needs.
|
||||
|
||||
# Prerequisites
|
||||
|
||||
Holos integrates with the following tools that should be installed to enable
|
||||
their functionality.
|
||||
|
||||
* [Helm][helm] to fetch and render Helm chart Components
|
||||
* [Kubectl][kubectl] to [kustomize][kustomize] components.
|
||||
|
||||
# Install Holos
|
||||
|
||||
Holos is distributed as a single file executable that can be installed in a couple of ways.
|
||||
|
||||
### Releases
|
||||
|
||||
Download `holos` from the [releases](https://github.com/holos-run/holos/releases) page and place the executable into your shell path.
|
||||
|
||||
### Go install
|
||||
|
||||
Alternatively, install directly into your go bin path using:
|
||||
|
||||
```shell
|
||||
go install github.com/holos-run/holos/cmd/holos@latest
|
||||
```
|
||||
|
||||
# Do I need a Kubernetes cluster?
|
||||
|
||||
Holos only generates rendered Kubernetes manifests, so you don't need a
|
||||
Kubernetes cluster to start using the tool or understand its workflow. However,
|
||||
you will need a cluster eventually to apply the rendered manifests and verify
|
||||
that they achieve the desired end state.
|
||||
|
||||
We recommend using [k3d](https://k3d.io/) to set up a minimal Kubernetes cluster with
|
||||
[Orbstack](https://docs.orbstack.dev/install) or
|
||||
[Docker](https://docs.docker.com/get-started/get-docker/). To simplify this,
|
||||
we've created [the Local Cluster guide](../topics/4-local-cluster.mdx) which
|
||||
automates the process, ensuring proper DNS and TLS certificates, and includes a
|
||||
script to reset the cluster to a known good state.
|
||||
|
||||
When you're ready to experiment with a live Kubernetes cluster, refer to [the
|
||||
Local Cluster guide](../topics/4-local-cluster.mdx).
|
||||
|
||||
# Initialize a new Platform
|
||||
|
||||
Use Holos to generate a minimal platform using the recommended directory structure
|
||||
by creating an empty directory and then using the `holos generate platform` subcommand:
|
||||
|
||||
<Tabs groupId="tutorial-setup-generate-platform">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
mkdir holos_platform
|
||||
cd holos_platform
|
||||
holos generate platform v1alpha4
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
no output
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Holos creates a `platform` directory with a `platform.gen.cue` file that serves
|
||||
as the foundation for your newly initialized Holos Platform. For each Holos
|
||||
Component you model, you'll add a new CUE file to the platform directory,
|
||||
mapping it to the location of the Component's CUE code, and extending the
|
||||
capabilities of your platform.
|
||||
|
||||
# Next Steps
|
||||
|
||||
Now that you've got Holos and its prerequisites installed, continue on to the
|
||||
[Hello Holos page](./3-hello-holos.mdx) where we will guide you through the
|
||||
process of creating your first Component and modeling a Helm chart.
|
||||
|
||||
[helm]: https://github.com/helm/helm/releases
|
||||
[kubectl]: https://kubernetes.io/docs/tasks/tools/
|
||||
[kustomize]: https://kustomize.io/
|
||||
@@ -1 +1,74 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Hello Holos
|
||||
|
||||
One of the first exercises you perform when learning a new programming language
|
||||
is to print out the "Hello World!" greeting. For Holos, our "Hello Holos"
|
||||
exercise involves modeling the [podinfo Helm chart][podinfo] that produces a
|
||||
similar greeting message from a Kubernetes Pod.
|
||||
|
||||
By the end of this tutorial you will gain the understanding of how to model
|
||||
an individual Holos Component using a Helm chart as its source.
|
||||
|
||||
# The code
|
||||
|
||||
### Podinfo Helm Chart
|
||||
|
||||
Let's start by creating a directory for `podinfo`, touching an empty CUE file,
|
||||
and then populating it with the CUE code below:
|
||||
|
||||
<Tabs groupId="tutorial-hello-podinfo-helm-cue-code">
|
||||
<TabItem value="projects/tutorial/components/podinfo/podinfo.cue" label="Podinfo Helm Chart">
|
||||
```bash
|
||||
mkdir -p projects/tutorial/components/podinfo
|
||||
touch projects/tutorial/components/podinfo/podinfo.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
_HelmChart.BuildPlan
|
||||
|
||||
_HelmChart: #Helm & {
|
||||
Name: "podinfo"
|
||||
Chart: {
|
||||
version: "6.6.2"
|
||||
repository: {
|
||||
name: "podinfo"
|
||||
url: "https://stefanprodan.github.io/podinfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Register the podinfo component
|
||||
|
||||
Now let's register the code modeling the `podinfo` Helm chart as a Holos
|
||||
Component and assign it to a cluser. For this we will need a create new file in
|
||||
the `platform` directory with the following contents:
|
||||
|
||||
<Tabs groupId="tutorial-hello-register-podinfo-component">
|
||||
<TabItem value="platform/podinfo.cue" label="Register Podinfo">
|
||||
```bash
|
||||
touch plaform/podinfo.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
_Platform: Components: podinfo: {
|
||||
name: "podinfo"
|
||||
component: "projects/tutorial/components/podinfo"
|
||||
cluster: "local"
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[podinfo]: https://github.com/stefanprodan/podinfo
|
||||
Reference in New Issue
Block a user