Expose a Service
In this guide, you'll learn how to expose a service with Holos using the Gateway API.
The Concepts page defines capitalized terms such as Platform and Component.
What you'll need
You'll need the following tools installed to complete this guide.
- holos - to build the Platform.
- helm - to render Helm Components.
- kubectl - to render Kustomize Components.
As an optional, but recommended step, complete the Local Cluster guide if you'd like to apply the rendered manifests to a cluster. This will smooth out the friction of managing certificates.
Create a Git Repository
Start by initializing an empty Git repository. Holos operates on local files stored in a Git repository.
- Command
- Output
mkdir expose-a-service
cd expose-a-service
git init
Initialized empty Git repository in /expose-a-service/.git/
This guide assumes you will run commands from the root directory of the Git repository unless stated otherwise.
Generate the Platform
Generate a platform with one workload cluster. The guide
Platform is intended
as a starting point for all of our guides.
- Command
- Output
holos generate platform guide
holos generate component workload-cluster
generated component
Commit the generated platform config to the repository.
- Command
- Output
git add .
git commit -m "holos generate platform guide - $(holos --version)"
[main (root-commit) 0b17b7f] holos generate platform guide - 0.93.3
213 files changed, 72349 insertions(+)
...
Namespaces
We often need to manage namespaces prior to workloads being deployed. This is necessary because a namespace is a security boundary. Holos makes it easier, safer, and more consistent to manage service accounts, role bindings, and secrets prior to deploying workloads into a namespace.
We'll see how this works with the namespaces component, which offers a mechanism for other components to register their namespaces. The namespaces component initializes each registered namespace, optionally mixing in resources consistently.
Run the following command to generate the namespaces component.
- Command
- Output
holos generate component namespaces
generated component
The command generates two main configuration files like we've seen with other components. One file at the leaf, and another at the root. The leaf uses a Kubernetes build plan to produce resources directly from CUE.
- Leaf
- Root
components/namespaces/namespaces.cue
package holos
let Objects = {
Name: "namespaces"
Resources: Namespace: #Namespaces
}
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).Output
namespaces.gen.cue
package holos
import corev1 "k8s.io/api/core/v1"
// #Namespaces defines all managed namespaces in the Platform.
// Holos adopts the sig-multicluster position of namespace sameness.
#Namespaces: {
// Validate against v1 of the kubernetes core api
[Name=string]: corev1.#Namespace & {
metadata: name: Name
}
}
// Manage the Component on every Cluster in the Platform
for Fleet in #Fleets {
for Cluster in Fleet.clusters {
#Platform: Components: "\(Cluster.name)/namespaces": {
path: "components/namespaces"
cluster: Cluster.name
}
}
}
Notice the highlighted line in the leaf file. Resources are managed directly in
CUE at the leaf using the Kubernetes component. This is the same mechanism used
to mix-in resources to Helm and Kustomize components. The leaf refers to
#Namespaces
defined at the root. At the root #Namespaces
enforces a
constraint: each Namespace must conform to the k8s.io/api/core/v1
specification.
- At the leaf Holos tailors the component to your platform, mixing in resources and customizing the rendered output.
- At the root Holos integrates a component with the rest of your platform.
You'll see this pattern again and again as you build your platform.
Render the platform to render the component for the workload clusters.
- Command
- Output
holos render platform ./platform
rendered components/namespaces for cluster workload in 72.675292ms
Add and commit the configuration and rendered manifests.
- Command
- Output
git add .
git commit -m "add namespaces component"
[main 1bf0d61] add namespaces component
3 files changed, 30 insertions(+)
create mode 100644 components/namespaces/namespaces.cue
create mode 100644 deploy/clusters/workload/components/namespaces/namespaces.gen.yaml
create mode 100644 namespaces.gen.cue
#Namespaces
is currently empty, so the rendered output of
namespaces.gen.yaml
is also empty.
Namespaces will be automatically managed as we add more components to the platform over time.
Cert Manager
We'll need a valid certificate to browse to httpbin. We'll manage cert-manager in our cluster to issue valid tls certificates.
Run the following command to generate the cert-manager component.
- Command
- Output
holos generate component cert-manager
generated component
This command generates a configuration file at the leaf and the root. At the leaf two helm values configure the behavior of the upstream cert-manager chart. At the root cert-manager is managed on all clusters in the platform.
- The leaf references the version and namespace fields defined in
#CertManager
at the root. - The leaf defines two Helm values to manage. Holos makes it easier and safer to focus on how software is integrated into our platform.
- The root registers cert-manager for the namespaces component to manage consistently across all clusters in the platform.
- The root manages the component on all clusters in the platform.
- Leaf
- Root
components/cert-manager/cert-manager.cue
package holos
// Produce a helm chart build plan.
(#Helm & Chart).Output
let Chart = {
Name: "cert-manager"
Version: #CertManager.Version
Namespace: #CertManager.Namespace
Repo: name: "jetstack"
Repo: url: "https://charts.jetstack.io"
Values: installCRDs: true
Values: startupapicheck: enabled: false
}
cert-manager.gen.cue
package holos
// Platform wide configuration
#CertManager: {
Version: "1.15.3"
Namespace: "cert-manager"
}
// Register the namespace
#Namespaces: (#CertManager.Namespace): _
// Manage the component on every cluster in the platform
for Fleet in #Fleets {
for Cluster in Fleet.clusters {
#Platform: Components: "\(Cluster.name)/cert-manager": {
path: "components/cert-manager"
cluster: Cluster.name
}
}
}
Render the platform to render manifests into the deploy directory.
- Command
- Output
holos render platform ./platform
rendered components/namespaces for cluster workload in 65.184791ms
rendered components/cert-manager for cluster workload in 467.379292ms
Add and commit the configuration and rendered manifests.
- Command
- Output
git add .
git commit -m "integrate cert-manager into the platform"
[main c6ab5f4] integrate cert-manager into the platform
3 files changed, 9434 insertions(+)
create mode 100644 cert-manager.gen.cue
create mode 100644 components/cert-manager/cert-manager.cue
create mode 100644 deploy/clusters/workload/components/cert-manager/cert-manager.gen.yaml
We often need to understand how a change affects the platform as a whole. Holos offers the ability to use your preferred tooling to understand platform wide changes.
For example, git
summarizes all of the components and clusters affected by
adding cert-manager. The output shows both the namespaces and cert-manager
components have changed on the workload cluster.
- Command
- Output
git show --stat deploy
deploy/clusters/workload/components/cert-manager/cert-manager.gen.yaml | 9407
deploy/clusters/workload/components/namespaces/namespaces.gen.yaml | 8
2 files changed, 9415 insertions(+)
As an optional step, apply the changes.
- Command
- Output
kubectl apply --server-side=true -f deploy/clusters/workload/components/namespaces
namespace/cert-manager serverside-applied
- Command
- Output
kubectl apply --server-side=true -f deploy/clusters/workload/components/cert-manager
serviceaccount/cert-manager-cainjector serverside-applied
serviceaccount/cert-manager serverside-applied
serviceaccount/cert-manager-webhook serverside-applied
customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io serverside-applied
clusterrole.rbac.authorization.k8s.io/cert-manager-cainjector serverside-applied
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-issuers serverside-applied
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-clusterissuers serverside-applied
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-certificates serverside-applied
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-orders serverside-applied
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-challenges serverside-applied
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-ingress-shim serverside-applied
clusterrole.rbac.authorization.k8s.io/cert-manager-cluster-view serverside-applied
clusterrole.rbac.authorization.k8s.io/cert-manager-view serverside-applied
clusterrole.rbac.authorization.k8s.io/cert-manager-edit serverside-applied
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-approve:cert-manager-io serverside-applied
clusterrole.rbac.authorization.k8s.io/cert-manager-controller-certificatesigningrequests serverside-applied
clusterrole.rbac.authorization.k8s.io/cert-manager-webhook:subjectaccessreviews serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-cainjector serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-issuers serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-clusterissuers serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-certificates serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-orders serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-challenges serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-ingress-shim serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-approve:cert-manager-io serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-controller-certificatesigningrequests serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/cert-manager-webhook:subjectaccessreviews serverside-applied
role.rbac.authorization.k8s.io/cert-manager-cainjector:leaderelection serverside-applied
role.rbac.authorization.k8s.io/cert-manager:leaderelection serverside-applied
role.rbac.authorization.k8s.io/cert-manager-webhook:dynamic-serving serverside-applied
rolebinding.rbac.authorization.k8s.io/cert-manager-cainjector:leaderelection serverside-applied
rolebinding.rbac.authorization.k8s.io/cert-manager:leaderelection serverside-applied
rolebinding.rbac.authorization.k8s.io/cert-manager-webhook:dynamic-serving serverside-applied
service/cert-manager serverside-applied
service/cert-manager-webhook serverside-applied
deployment.apps/cert-manager-cainjector serverside-applied
deployment.apps/cert-manager serverside-applied
deployment.apps/cert-manager-webhook serverside-applied
mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook serverside-applied
validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook serverside-applied
Check the pods become ready
- Command
- Output
kubectl get pods -n cert-manager
NAME READY STATUS RESTARTS AGE
cert-manager-9647b459d-d5q8f 1/1 Running 0 9s
cert-manager-cainjector-5d8798687c-kv8bs 1/1 Running 0 9s
cert-manager-webhook-c77744d75-j6hv8 1/1 Running 0 9s
Gateway API
The Gateway API is an official Kubernetes project focused on L4 and L7 routing . You'll use the custom resources defined by the Gateway API to expose the httpbin service outside of the cluster. The Kubernetes Gateway API does not come installed by default on most Kubernetes clusters, so we need to manage the custom resource definitions (CRDs).
Run the following command to generate a Component to manage the Gateway API.
- Command
- Output
holos generate component gateway-api
generated component
The command generates two main configuration files, one at the leaf, and another at the root of the tree. At the leaf, the config produces a Kustomize build plan for Holos to render. At the root, the config adds the Component to all Clusters in the Platform.
Notice the kustomization.yaml
file at the leaf. This is an unmodified
upstream copy of the standard way to install the Gateway API.
- Leaf
- kustomization.yaml
- Root
components/gateway-api/gateway-api.cue
package holos
// Produce a kubectl kustomize build plan.
(#Kustomize & {Name: "gateway-api"}).Output
components/gateway-api/kustomization.yaml
resources:
- standard/gateway.networking.k8s.io_gatewayclasses.yaml
- standard/gateway.networking.k8s.io_gateways.yaml
- standard/gateway.networking.k8s.io_grpcroutes.yaml
- standard/gateway.networking.k8s.io_httproutes.yaml
- standard/gateway.networking.k8s.io_referencegrants.yaml
gateway-api.gen.cue
package holos
// Manage on every Cluster in the Platform
for Fleet in #Fleets {
for Cluster in Fleet.clusters {
#Platform: Components: "\(Cluster.name)/gateway-api": {
path: "components/gateway-api"
cluster: Cluster.name
}
}
}
We've covered three kinds of components so far: Kubernetes, Helm, and Kustomize.
Holos offers a consistent way to manage these different kinds of packaging safely and easily.
Render the Platform to render the Component for the workload clusters.
- Command
- Output
holos render platform ./platform
rendered components/namespaces for cluster workload in 73.789333ms
rendered components/cert-manager for cluster workload in 137.878584ms
rendered components/gateway-api for cluster workload in 176.406666ms
This example is equivalent to running kubectl kustomize ./components/gateway-api
and saving the output to a file. Holos simplifies
this task and makes it consistent with Helm and other tools.
Add and commit the configuration and rendered manifests.
- Command
- Output
git add .
git commit -m "add gateway-api component"
[main 88575a5] add gateway-api component
9 files changed, 26907 insertions(+)
create mode 100644 components/gateway-api/gateway-api.cue
create mode 100644 components/gateway-api/kustomization.yaml
create mode 100644 components/gateway-api/standard/gateway.networking.k8s.io_gatewayclasses.yaml
create mode 100644 components/gateway-api/standard/gateway.networking.k8s.io_gateways.yaml
create mode 100644 components/gateway-api/standard/gateway.networking.k8s.io_grpcroutes.yaml
create mode 100644 components/gateway-api/standard/gateway.networking.k8s.io_httproutes.yaml
create mode 100644 components/gateway-api/standard/gateway.networking.k8s.io_referencegrants.yaml
create mode 100644 deploy/clusters/workload/components/gateway-api/gateway-api.gen.yaml
create mode 100644 gateway-api.gen.cue
As an optional step, apply the rendered component to your cluster.
- Command
- Output
kubectl apply --server-side=true -f deploy/clusters/workload/components/gateway-api
customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io serverside-applied
Istio Service Mesh
We'll manage Istio to implement the Gateway API so we can expose the httpbin service outside of the cluster.
Run the following command to generate the istio components.
- Command
- Output
holos generate component istio
generated component
Mix in the istio-k3d
component if you're applying the rendered manifests to
k3d as described in our Local Cluster guide.
Skip this step if you aren't using k3d. Istio needs to be configured to refer to the nonstandard cni configuration paths k3d uses.
- Command
- Output
- istio-k3d.gen.cue
holos generate component istio-k3d
generated component
Holos makes it easier and safer to mix-in this additional configuration at the root.
package holos
// If you are using k3d with the default Flannel CNI, you must append some
// values to your installation command, as k3d uses nonstandard locations for
// CNI configuration and binaries.
//
// See https://istio.io/latest/docs/ambient/install/platform-prerequisites/#k3d
#Istio: Values: cni: {
cniConfDir: "/var/lib/rancher/k3s/agent/etc/cni/net.d"
cniBinDir: "/bin"
}
Consistent with the other components we've seen, the istio components define configuration at the root and leafs of the tree. Unlike previous components we've generated, this command generated multiple components to manage Istio.
- Command
- Output
tree components/istio
components/istio
├── base
│ ├── istio-base.cue
│ └── values.gen.cue
├── cni
│ ├── cni.cue
│ └── values.gen.cue
├── gateway
│ ├── gateway.cue
│ └── values.gen.cue
├── istiod
│ ├── istiod.cue
│ └── values.gen.cue
└── ztunnel
├── values.gen.cue
└── ztunnel.cue
6 directories, 10 files
These components share the configuration defined at the root in istio.gen.cue
.
Let's review how Holos makes it safer and easier to share Helm values defined at the root with the istiod and cni components defined at the leaf.
- istiod and cni use version
"1.23.1"
and namespace"istio-system"
defined at the root. - The Helm value to configure ambient (sidecar-less) mode is defined once at the root.
- The root adds a constraint to fail validation if the istio system namespace
is not
"istio-system"
. Future upgrades are safer with this constraint, if the upstream vendor changes the default in the future the component will fail validation. - The root registers two Namespaces,
"istio-system"
and"istio-ingress"
. - The root manages the components on all workload clusters in the platform.
- istiod
- cni
- Root
Leaf components/istio/istiod/istiod.cue
package holos
// Produce a helm chart build plan.
(#Helm & Chart).Output
let Chart = {
Name: "istiod"
Version: #Istio.Version
Namespace: #Istio.System.Namespace
Chart: chart: name: "istiod"
Repo: name: "istio"
Repo: url: "https://istio-release.storage.googleapis.com/charts"
Values: #Istio.Values
}
Leaf components/istio/cni/cni.cue
package holos
// Produce a helm chart build plan.
(#Helm & Chart).Output
let Chart = {
Name: "istio-cni"
Version: #Istio.Version
Namespace: #Istio.System.Namespace
Chart: chart: name: "cni"
Repo: name: "istio"
Repo: url: "https://istio-release.storage.googleapis.com/charts"
Values: #Istio.Values
}
Root istio.gen.cue
package holos
// #Istio represents platform wide configuration
#Istio: {
Version: "1.23.1"
System: Namespace: "istio-system"
Gateway: Namespace: "istio-ingress"
// Constrain Helm values for safer, easier upgrades and consistency across
// platform components.
Values: global: istioNamespace: System.Namespace
// Configure ambient mode
Values: profile: "ambient"
}
// Register the Namespaces
#Namespaces: (#Istio.System.Namespace): _
#Namespaces: (#Istio.Gateway.Namespace): _
// Manage istio on workload clusters
for Cluster in #Fleets.workload.clusters {
#Platform: Components: {
"\(Cluster.name)/istio-base": {
path: "components/istio/base"
cluster: Cluster.name
}
"\(Cluster.name)/istiod": {
path: "components/istio/istiod"
cluster: Cluster.name
}
"\(Cluster.name)/istio-cni": {
path: "components/istio/cni"
cluster: Cluster.name
}
"\(Cluster.name)/istio-ztunnel": {
path: "components/istio/ztunnel"
cluster: Cluster.name
}
"\(Cluster.name)/istio-gateway": {
path: "components/istio/gateway"
cluster: Cluster.name
}
}
}
Many software projects managed by Holos are organized into a collection of components working together, for example to safely manage custom resource definitions, secrets, and policy separately from the workloads that rely on them.
Render the platform to render the istio components for the workload clusters.
- Command
- Output
holos render platform ./platform
rendered components/namespaces for cluster workload in 85.490833ms
rendered components/istio/ztunnel for cluster workload in 111.784667ms
rendered components/istio/cni for cluster workload in 112.362417ms
rendered components/istio/base for cluster workload in 113.058ms
rendered components/istio/gateway for cluster workload in 119.018208ms
rendered components/istio/istiod for cluster workload in 127.736334ms
rendered components/gateway-api for cluster workload in 181.922333ms
Add and commit the configuration and rendered manifests.
- Command
- Output
git add .
git commit -m "add istio"
[main aca8ff6] add istio
18 files changed, 18955 insertions(+)
create mode 100644 components/istio/base/istio-base.cue
create mode 100644 components/istio/base/values.gen.cue
create mode 100644 components/istio/cni/cni.cue
create mode 100644 components/istio/cni/values.gen.cue
create mode 100644 components/istio/gateway/gateway.cue
create mode 100644 components/istio/gateway/values.gen.cue
create mode 100644 components/istio/istiod/istiod.cue
create mode 100644 components/istio/istiod/values.gen.cue
create mode 100644 components/istio/ztunnel/values.gen.cue
create mode 100644 components/istio/ztunnel/ztunnel.cue
create mode 100644 deploy/clusters/workload/components/istio-base/istio-base.gen.yaml
create mode 100644 deploy/clusters/workload/components/istio-cni/istio-cni.gen.yaml
create mode 100644 deploy/clusters/workload/components/istio-gateway/istio-gateway.gen.yaml
create mode 100644 deploy/clusters/workload/components/istio-ztunnel/istio-ztunnel.gen.yaml
create mode 100644 deploy/clusters/workload/components/istiod/istiod.gen.yaml
create mode 100644 istio-k3d.gen.cue
create mode 100644 istio.gen.cue
Optionally apply the rendered component to your cluster.
- Command
- Output
kubectl apply --server-side=true -f deploy/clusters/workload/components/namespaces
namespace/istio-ingress serverside-applied
namespace/istio-system serverside-applied
- Command
- Output
kubectl apply --server-side=true -f deploy/clusters/workload/components/istio-base
customresourcedefinition.apiextensions.k8s.io/wasmplugins.extensions.istio.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/destinationrules.networking.istio.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/envoyfilters.networking.istio.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/gateways.networking.istio.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/proxyconfigs.networking.istio.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/serviceentries.networking.istio.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/sidecars.networking.istio.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/virtualservices.networking.istio.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/workloadentries.networking.istio.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/workloadgroups.networking.istio.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/authorizationpolicies.security.istio.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/peerauthentications.security.istio.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/requestauthentications.security.istio.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/telemetries.telemetry.istio.io serverside-applied
serviceaccount/istio-reader-service-account serverside-applied
validatingwebhookconfiguration.admissionregistration.k8s.io/istiod-default-validator serverside-applied
- Command
- Output
kubectl apply --server-side=true -f deploy/clusters/workload/components/istiod
poddisruptionbudget.policy/istiod serverside-applied
serviceaccount/istiod serverside-applied
configmap/istio serverside-applied
configmap/istio-sidecar-injector serverside-applied
clusterrole.rbac.authorization.k8s.io/istiod-clusterrole-istio-system serverside-applied
clusterrole.rbac.authorization.k8s.io/istiod-gateway-controller-istio-system serverside-applied
clusterrole.rbac.authorization.k8s.io/istio-reader-clusterrole-istio-system serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/istiod-clusterrole-istio-system serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/istiod-gateway-controller-istio-system serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/istio-reader-clusterrole-istio-system serverside-applied
role.rbac.authorization.k8s.io/istiod serverside-applied
rolebinding.rbac.authorization.k8s.io/istiod serverside-applied
service/istiod serverside-applied
deployment.apps/istiod serverside-applied
horizontalpodautoscaler.autoscaling/istiod serverside-applied
mutatingwebhookconfiguration.admissionregistration.k8s.io/istio-sidecar-injector serverside-applied
validatingwebhookconfiguration.admissionregistration.k8s.io/istio-validator-istio-system serverside-applied
- Command
- Output
kubectl apply --server-side=true -f deploy/clusters/workload/components/istio-cni
serviceaccount/istio-cni serverside-applied
configmap/istio-cni-config serverside-applied
clusterrole.rbac.authorization.k8s.io/istio-cni serverside-applied
clusterrole.rbac.authorization.k8s.io/istio-cni-repair-role serverside-applied
clusterrole.rbac.authorization.k8s.io/istio-cni-ambient serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/istio-cni serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/istio-cni-repair-rolebinding serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/istio-cni-ambient serverside-applied
daemonset.apps/istio-cni-node serverside-applied
- Command
- Output
kubectl apply --server-side=true -f deploy/clusters/workload/components/istio-ztunnel
serviceaccount/ztunnel serverside-applied
daemonset.apps/ztunnel serverside-applied
- Command
- Output
kubectl apply --server-side=true -f deploy/clusters/workload/components/istio-gateway
serviceaccount/gateway serverside-applied
role.rbac.authorization.k8s.io/gateway serverside-applied
rolebinding.rbac.authorization.k8s.io/gateway serverside-applied
service/gateway serverside-applied
deployment.apps/gateway serverside-applied
horizontalpodautoscaler.autoscaling/gateway serverside-applied
Make sure all pod containers become ready.
- Command
- Output
kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
istio-ingress gateway-6748c5f547-s46pj 1/1 Running 0 26s
istio-system istio-cni-node-852nr 1/1 Running 0 2m9s
istio-system istiod-5b4d8d4c77-t694z 1/1 Running 0 3m15s
istio-system ztunnel-msqbn 1/1 Running 0 63s
kube-system coredns-576bfc4dc7-2g4k9 1/1 Running 0 113m
kube-system local-path-provisioner-6795b5f9d8-wsz8p 1/1 Running 0 113m
kube-system metrics-server-557ff575fb-fctr7 1/1 Running 0 113m
kube-system svclb-gateway-5d311af0-fp5mk 3/3 Running 0 26s
Once all pods are ready, we're ready for the next step toward exposing httpbin.
Certificate Issuer
We need to issue certificates our browser trusts so we can browse httpbin. We'll do this by configuring a ClusterIssuer using the ca private key we created in the Local Cluster guide.
Run the following command to generate the local-ca component.
- Command
- Output
holos generate component local-ca
generated component
At the leaf, the configuration refers to the #CertManager.Namespace
value
defined previously at the root by the cert-manager component.
- Leaf
package holos
import ci "cert-manager.io/clusterissuer/v1"
// Produce a kubernetes objects build plan.
(#Kubernetes & Objects).Output
let Objects = {
Name: "local-ca"
Namespace: #CertManager.Namespace
Resources: ClusterIssuer: LocalCA: ci.#ClusterIssuer & {
metadata: name: "local-ca"
metadata: namespace: #CertManager.Namespace
// The secret name must align with the local cluster guide at
// https://holos.run/docs/guides/local-cluster/
spec: ca: secretName: "local-ca"
}
}
Render the platform to render manifests into the deploy directory.
- Command
- Output
holos render platform ./platform
TODO
Add and commit the configuration and rendered manifests.
- Command
- Output
git add .
git commit -m "integrate local-ca into the platform"
TODO
As an optional step, apply the configuration to the cluster.
- Command
- Output
kubectl apply --server-side=true -f deploy/clusters/workload/components/local-ca
clusterissuer.cert-manager.io/local-ca serverside-applied
Verify the local-ca ClusterIssuer is ready:
- Command
- Output
kubectl get clusterissuers.cert-manager.io
NAME READY AGE
local-ca True 12s
httpbin Workload
Generate the component.
- Command
- Output
holos generate component httpbin-workload
holos generate component referencegrant
generated component
generated component
REVIEW THE FILES
Render the platform.
- Command
- Output
- Manifest
holos render platform ./platform
rendered components/httpbin/workload for cluster workload in 100.821083ms
rendered components/istio/ztunnel for cluster workload in 123.260917ms
rendered components/istio/base for cluster workload in 124.368417ms
rendered components/istio/gateway for cluster workload in 124.71975ms
rendered components/istio/cni for cluster workload in 125.941709ms
rendered components/istio/istiod for cluster workload in 139.979666ms
rendered components/cert-manager for cluster workload in 165.070041ms
rendered components/local-ca for cluster workload in 78.725625ms
rendered components/gateway-api for cluster workload in 193.146417ms
rendered components/namespaces for cluster workload in 79.939875ms
deploy/clusters/workload/components/httpbin-workload/httpbin-workload.gen.yaml
---
# Source: CUE apiObjects.Deployment.httpbin
metadata:
name: httpbin
namespace: httpbin
labels:
app: httpbin
spec:
selector:
matchLabels:
app: httpbin
app.kubernetes.io/instance: httpbin
template:
metadata:
labels:
app: httpbin
app.kubernetes.io/instance: httpbin
spec:
containers:
- name: httpbin
image: quay.io/holos/mccutchen/go-httpbin
ports:
- containerPort: 8080
securityContext:
seccompProfile:
type: RuntimeDefault
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 8192
runAsGroup: 8192
capabilities:
drop:
- ALL
securityContext:
seccompProfile:
type: RuntimeDefault
kind: Deployment
apiVersion: apps/v1
---
# Source: CUE apiObjects.ReferenceGrant.httpbin
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: istio-ingress
namespace: httpbin
labels:
app: httpbin
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: istio-ingress
to:
- group: ""
kind: Service
---
# Source: CUE apiObjects.Service.httpbin
metadata:
name: httpbin
namespace: httpbin
labels:
app: httpbin
spec:
selector:
app: httpbin
app.kubernetes.io/instance: httpbin
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
kind: Service
apiVersion: v1
Add and commit the configuration and rendered manifests.
- Command
- Output
git add .
git commit -m "integrate httpbin workload into the platform"
[main 838ee91] integrate httpbin workload into the platform
5 files changed, 177 insertions(+)
create mode 100644 components/httpbin/workload/httpbin-workload.cue
create mode 100644 deploy/clusters/workload/components/httpbin-workload/httpbin-workload.gen.yaml
create mode 100644 httpbin-workload.gen.cue
create mode 100644 referencegrant.gen.cue
As an optional step, apply the rendered manifests.
- Command
- Output
kubectl apply --server-side=true -f deploy/clusters/workload/components/namespaces
namespace/cert-manager serverside-applied
namespace/httpbin serverside-applied
namespace/istio-ingress serverside-applied
namespace/istio-system serverside-applied
- Command
- Output
kubectl apply --server-side=true -f deploy/clusters/workload/components/httpbin-workload
deployment.apps/httpbin serverside-applied
referencegrant.gateway.networking.k8s.io/istio-ingress serverside-applied
service/httpbin serverside-applied
Verify the pod is ready.
- Command
- Output
kubectl get pods -n httpbin
NAME READY STATUS RESTARTS AGE
httpbin-699b8dd85b-qc8v2 1/1 Running 0 22s
HTTP Routes
httpbin is running but still isn't exposed outside of the cluster, so we can't browse to it. We'll add HTTPRoute and Certificate resources to expose the service.
TODO