Tutorials ----- # Adding UDS Configuration to a Zarf Package To consider `podinfo` as a fully integrated [UDS Package](https://uds.defenseunicorns.com/structure/packages/), the `Package` Custom Resource for the UDS Operator must be included as part of the Zarf Package for `podinfo`. In this section, we will cover adding the `podinfo-package.yaml` to the sample UDS Bundle that we created in the [first](/tutorials/deploy-with-uds-core) tutorial. ### Prerequisites This guide assumes that you created the UDS `Package` Custom Resource in the [previous](/tutorials/create-uds-package) tutorial. ### Adding Package Manifest to Podinfo Within the `zarf.yaml` file that exists in the `package` directory, modify the `podinfo` component to reference the manifest created in the previous tutorial: ```yaml kind: ZarfPackageConfig metadata: name: podinfo version: 0.0.1 components: - name: podinfo required: true charts: - name: podinfo version: 6.10.1 namespace: podinfo url: https://github.com/stefanprodan/podinfo.git gitPath: charts/podinfo # Add this new manifests section with our Package CR manifests: - name: podinfo-uds-config namespace: podinfo files: - podinfo-package.yaml images: - ghcr.io/stefanprodan/podinfo:6.10.1 actions: onDeploy: after: - wait: cluster: kind: deployment name: podinfo namespace: podinfo condition: available ``` Re-run `zarf package create --confirm` and `uds create --confirm` commands to generate new artifacts that now include the `Package` Custom Resource for `podinfo`. From there, the bundle can be re-deployed (`uds deploy uds-bundle-podinfo-bundle-*-0.0.1.tar.zst --confirm`) and `podinfo` will be automatically integrated with UDS Core. #### Next Steps (Optional) This tutorial deployed podinfo in Istio Sidecar mode - the default deployment method for applications in UDS Core. UDS Core releases v0.40.0 and later added support for Istio Ambient Mesh. To walkthrough migrating the podinfo application to Istio Ambient Mesh using the UDS Operator, continue to the next tutorial. ----- # Integrating an Application with UDS Core ## Background When UDS Core is deployed into a Kubernetes Cluster, an [operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) is deployed. An operator allows users to extend the functionality of their Kubernetes clusters via [Custom Resource Definitions](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) and custom controllers. This operator, henceforth known as the UDS Operator, looks for `Package` Custom Resources to be created. When a user creates a `Package` resource, the UDS Operator processes the request and performs the necessary operations to create the package per the [specification](/reference/configuration/custom-resources/packages-v1alpha1-cr/) given. Read more about the UDS Operator [here](https://uds.defenseunicorns.com/reference/configuration/uds-operator/). ### Prerequisites In this section, we will configure Single Sign On (SSO) for a sample user to access the `podinfo` application. This requires that your Keycloak instance has existing users and groups defined. This configuration has been automated via the `uds` cli. In the root of the `package` directory, create a new file called `tasks.yaml` and include the lines below: ```yaml includes: - common-setup: https://raw.githubusercontent.com/defenseunicorns/uds-common/v1.24.0/tasks/setup.yaml ``` ### Integrate Podinfo with UDS Core You can think of the UDS Operator as the "glue" between your application and the services that are provided by UDS Core. It is a [Kubernetes Operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) that has working knowledge of UDS Core services in the cluster and takes care of integrating your app with those services for you. To register your application with the UDS Operator, you need to create a `Package` Kubernetes Custom Resource. Within the specification of the `Package` resource, you can specify different parameters that dictate how the UDS Operator should integrate your app per its unique requirements. The sections below cover creating a `Package` resource for `podinfo` and integrating `podinfo` with several UDS Core services. :::note The `Package` Custom Kubernetes Resource is different from a [UDS Package](https://uds.defenseunicorns.com/structure/packages/), which is a collection of the Zarf Package for your application and the Kubernetes `Package` Custom Resource. ::: :::note All resources created by the UDS Operator for `podinfo` will have a `uds/package=podinfo` label applied to it. ::: #### Create a Package Resource for Podinfo Below is a baseline definition of a `Package` Custom Resource for the `podinfo` application. As you progress through this demo, you will add values for `network`, `sso`, and `monitor`. These fields instruct the UDS Operator on how to configure networking, SSO, and monitoring for the `podinfo` application. ```yaml apiVersion: uds.dev/v1alpha1 kind: Package metadata: name: podinfo namespace: podinfo spec: network: # Expose rules generate Istio VirtualServices and related network policies expose: {} ``` Copy this YAML into a code editor and save the file as `podinfo-package.yaml`. #### Secure Podinfo with Istio and Network Policies UDS Core deploys [Istio](https://istio.io/), a powerful networking component that allows cluster administrators to end-to-end encrypt all cluster traffic, set explicit rules for traffic routing, add load balancing, and much more. Building on the existing `Package` definition, add the following configuration under `spec.network.expose` field: ```yaml apiVersion: uds.dev/v1alpha1 kind: Package metadata: name: podinfo namespace: podinfo spec: network: # Expose rules generate Istio VirtualServices and related network policies expose: - service: podinfo selector: app.kubernetes.io/name: podinfo gateway: tenant host: podinfo port: 9898 ``` This change will allow us to interact with `podinfo` without having to use `kubectl port-forward`. Save your changes and apply the file: ```bash kubectl apply -f podinfo-package.yaml ``` View the package resource: ```bash ❯ kubectl get package -n podinfo NAME STATUS SSO CLIENTS ENDPOINTS MONITORS NETWORK POLICIES AUTHORIZATION POLICIES AGE podinfo Ready [] ["podinfo.uds.dev"] [] 5 2 4s ``` View the pods. Notice how the podinfo pod has an additional container as a result of the UDS Operator configuring istio: ```bash ❯ kubectl get pods -n podinfo NAME READY STATUS RESTARTS AGE podinfo-5cbbf59f6d-bqhsk 2/2 Running 0 2m ``` Observe the Istio VirtualService that the UDS Operator created: ```bash ❯ kubectl get virtualservice -n podinfo NAME GATEWAYS HOSTS AGE podinfo-tenant-podinfo-9898-podinfo ["istio-tenant-gateway/tenant-gateway"] ["podinfo.uds.dev"] 60s ``` You will also notice that the UDS Operator automatically generated a set of Kubernetes `NetworkPolicies` that restrict access to your application to only required services: ```bash ❯ kubectl get networkpolicy -n podinfo NAME POD-SELECTOR AGE allow-podinfo-egress-dns-lookup-via-coredns 50s allow-podinfo-egress-istiod-communication 50s allow-podinfo-ingress-9898-podinfo-istio-tenant-gateway app.kubernetes.io/name=podinfo 50s allow-podinfo-ingress-sidecar-monitoring 50s deny-podinfo-default 50s ``` Navigate to `podinfo.uds.dev` from your browser to interact with `podinfo`. #### Integrate with Single Sign On At this stage, anyone can access the `podinfo` application. You may wish to protect your application by only allowing authenticated users to access it. As part of UDS Core, [Keycloak](https://www.keycloak.org/) and [Authservice](https://github.com/istio-ecosystem/authservice) are provided for Identity and Authorization management. Add the configuration under the `spec.sso` field below to integrate the `podinfo` application with Keycloak and Authservice ```yaml apiVersion: uds.dev/v1alpha1 kind: Package metadata: name: podinfo namespace: podinfo spec: network: # Expose rules generate Istio VirtualServices and related network policies expose: - service: podinfo selector: app.kubernetes.io/name: podinfo gateway: tenant host: podinfo port: 9898 # SSO allows for the creation of Keycloak clients and with automatic Authservice integration sso: - name: Podinfo SSO clientId: uds-core-podinfo redirectUris: - "https://podinfo.uds.dev/login" enableAuthserviceSelector: app.kubernetes.io/name: podinfo groups: anyOf: - "/UDS Core/Admin" ``` Save the file and apply the changes: ```bash kubectl apply -f podinfo-package.yaml ``` The package will now show the `uds-core-podinfo` client under `SSO CLIENTS`: ```bash ❯ kubectl get package -n podinfo NAME STATUS SSO CLIENTS ENDPOINTS MONITORS NETWORK POLICIES AUTHORIZATION POLICIES AGE podinfo Ready ["uds-core-podinfo"] ["podinfo.uds.dev"] [] 7 4 3m29s ``` :::note Notice how the count under `NETWORK POLICIES` has increased. The UDS Operator recognized that additional `NetworkPolicies` were required for Keycloak to communicate with `podinfo`, so it automatically created additional `NetworkPolicies` to allow that. ::: When navigating to https://podinfo.uds.dev/, you will be redirected to a login screen. Only users that are members of the `/UDS Core/Admin` group in Keycloak are permitted to access the site. Create a test user in that group with the following command (using the uds-common task included above): ```bash uds run common-setup:keycloak-user --set KEYCLOAK_USER_GROUP="/UDS Core/Admin" ``` Use the following credentials to login to https://podinfo.uds.dev/: `username: doug / password: unicorn123!@#UN` #### Add Monitoring and Metrics Scraping UDS Core also deploys Prometheus for collecting application metrics. Prometheus relies on `ServiceMonitor` and `PodMonitor` resources that inform Prometheus on which workloads to collect metrics from. These resources can be configured via the `spec.monitor` field in the `Package` Custom Resource: ```yaml apiVersion: uds.dev/v1alpha1 kind: Package metadata: name: podinfo namespace: podinfo spec: network: # Expose rules generate Istio VirtualServices and related network policies expose: - service: podinfo selector: app.kubernetes.io/name: podinfo gateway: tenant host: podinfo port: 9898 # SSO allows for the creation of Keycloak clients and with automatic secret generation and protocolMappers sso: - name: Podinfo SSO clientId: uds-core-podinfo redirectUris: - "https://podinfo.uds.dev/login" enableAuthserviceSelector: app.kubernetes.io/name: podinfo groups: anyOf: - "/UDS Core/Admin" # Monitor generates Prometheus Service and Pod monitor resources, capturing metrics exposed by your application monitor: - selector: app.kubernetes.io/name: podinfo targetPort: 9898 portName: http description: "podmonitor" kind: PodMonitor - selector: app.kubernetes.io/name: podinfo targetPort: 9898 portName: http description: "svcmonitor" kind: ServiceMonitor ``` Save the file and apply the changes: ```bash kubectl apply -f podinfo-package.yaml ``` The package will now show `ServiceMonitors` and `PodMonitors` configured under `MONITORS`: ```bash ❯ kubectl get package -n podinfo NAME STATUS SSO CLIENTS ENDPOINTS MONITORS NETWORK POLICIES AUTHORIZATION POLICIES AGE podinfo Ready ["uds-core-podinfo"] ["podinfo.uds.dev"] ["podinfo-podmonitor","podinfo-svcmonitor"] 9 6 6m38s ``` View the `PodMonitor` and `ServiceMonitor` resources that were created by the UDS Operator: ```bash ❯ kubectl get podmonitor,servicemonitor -n podinfo NAME AGE podmonitor.monitoring.coreos.com/podinfo-podmonitor 24s NAME AGE servicemonitor.monitoring.coreos.com/podinfo-svcmonitor 24s ``` Logs and Metrics for `podinfo` can now be viewed in Grafana, which is deployed with UDS Core. Navigate to `grafana.admin.uds.dev` and login using the same credentials from the previous step (you may still be signed in since Keycloak is used for all authentication). From the menu, navigate to `Explore`, then select `Prometheus` from the top drop-down. Paste in the query `rate(process_cpu_seconds_total{namespace="podinfo"}[$__rate_interval])` and hit the `Run Query` button (blue refresh button on top right). This will provide us with a graph based on the metrics served by Podinfo. Now you have successfully integrated `podinfo` with UDS Core! #### Next Steps (Optional) With the `Package` Custom resource now created that integrates `podinfo` into UDS Core, the next guide will cover including the `Package` Custom Resource as part of your Zarf Package and UDS Bundle. ----- # Deploying UDS on RKE2 This tutorial demonstrates how to deploy UDS onto a VM-based RKE2 Kubernetes cluster. This scenario is common in on-prem and airgap environments where cloud-based deployments are not feasible. :::caution The deployment in this tutorial is designed specifically for development and testing environments and is *not intended for production use*. ::: ### Prerequisites - Recommended [system requirements](https://uds.defenseunicorns.com/getting-started/basic-requirements/#system-requirements) - Hypervisor for running VMs (recommend [Lima](https://lima-vm.io/)) - [UDS CLI](https://uds.defenseunicorns.com/reference/cli/overview/) ### Quickstart The fastest way to get up and running with UDS Core on RKE2 is using the automation and configuration provided in the [uds-rke2-demo](https://github.com/defenseunicorns-labs/uds-rke2-demo) repo. Follow the instructions in the `README` to either provision a VM running RKE2 with UDS, or install UDS on an RKE2 cluster directly. ### Starting the VM and Installing RKE2 #### Lima (recommended) Lima provides a template for quickly spinning up an Ubuntu VM running RKE2 with appropriate shared network configs, follow the instructions in [uds-rke2-demo](https://github.com/defenseunicorns-labs/uds-rke2-demo) to quickly get up and running. The [automation](https://github.com/defenseunicorns-labs/uds-rke2-demo/blob/303c146fffb9e6660e38902fa6ee4c8a8ca6e98d/tasks.yaml#L39) in the demo repo uses the following Lima command to provision an Ubuntu VM running RKE2: ``` if [[ "$(uname)" == "Darwin" ]]; then limactl start template://experimental/rke2 \ --memory 20 --cpus 10 --vm-type=vz --network=vzNAT -y else limactl start template://experimental/rke2 \ --memory 20 --cpus 10 --vm-type=qemu -y fi ``` After the VM has been created and RKE2 installed, ensure connectivity by setting the `KUBECONFIG`: ``` export KUBECONFIG="$HOME"/.lima/rke2/copied-from-guest/kubeconfig.yaml ``` Then run `kubectl get pods -A` to verify that the pods are running. #### Other Hypervisors ##### VM Requirements Aside from the system requirements mentioned in the prerequisites, you will need to provision a VM running a Linux instance [compatible with RKE2](https://docs.rke2.io/install/requirements#operating-systems). Additionally, this tutorial assumes the following network configuration: - The VM has its own IP and is accessible to the host machine by both SSH and HTTPS - Recommend either a shared network or bridge setup (hypervisor port forwarding can also be useful but is often unnecessary) - Ability to configure DNS resolution (often done by modifying `/etc/hosts`) #### Installing RKE2 SSH into the newly created Linux VM and follow the [official quickstart](https://docs.rke2.io/install/quickstart) to install RKE2 on the VM. Note that this is a single server node setup, no need to add agent nodes. After RKE2 is installed, ensure connectivity by running `kubectl get pods -A` and verifying that the native RKE2 pods are running. You may need to `export KUBECONFIG=/etc/rancher/rke2/rke2.yaml` (read the [official docs](https://docs.rke2.io/install/quickstart#server-node-installation)). Depending on your VM setup, it may be easier to run this command from the VM itself as opposed to the host machine. If running from the host machine, you will need to ensure the Kube API (port 6443) is exposed to the host. ### Bootstrapping the Cluster In order to take advantage of the full range of capabilities UDS provides, the cluster must have the following prerequisites installed: - Default Storage Class - Load Balancer Controller - Object Store Each of these prereqs is covered in greater detail below. :::note The `uds-rke2-demo` repo contains a [zarf.yaml](https://github.com/defenseunicorns-labs/uds-rke2-demo/blob/main/zarf.yaml) that will install the necessary prereqs on your cluster. ::: #### Default Storage Class Since RKE2 does not ship with a `default` [storage class](https://kubernetes.io/docs/tasks/administer-cluster/change-default-storage-class/), you will need to install one. For demo purposes, we recommend using the [local-path-provisioner](https://github.com/rancher/local-path-provisioner) by Rancher. #### Load Balancer Controller Although RKE2 ships with an NGINX ingress controller, UDS uses Istio ingress gateways to logically separate admin traffic from other types of traffic coming into the cluster. Using Istio also ensures that traffic within the cluster is encrypted and all applications are integrated into a secure service mesh. More information can be found in the [UDS service mesh](https://uds.defenseunicorns.com/reference/configuration/service-mesh/ingress/) docs. UDS ingress gateways are K8s `Services` of type `LoadBalancer`. In order to provide an IP to these load balancer services, a load balancer controller, such as [MetalLB](https://metallb.io/), must be installed. An example configuration for MetalLB can be found in the [demo repo](https://github.com/defenseunicorns-labs/uds-rke2-demo/blob/main/chart/templates/metallb.yaml). Note that the base IP used for the MetalLB `IPAddressPool` will come from the internal IP of the cluster nodes, and can be found with: ``` uds zarf tools kubectl get nodes -o=jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}' ``` Note the [Zarf package](https://github.com/defenseunicorns-labs/uds-rke2-demo/blob/303c146fffb9e6660e38902fa6ee4c8a8ca6e98d/zarf.yaml#L30) in the demo repo configures this IP for you. #### Object Store The UDS log store ([Loki](https://github.com/grafana/loki)) uses object storage to store cluster logs. For demo purposes, we recommend installing [Minio](https://github.com/minio/minio) to provide object storage. Example Helm values for Minio can be found [here](https://github.com/defenseunicorns-labs/uds-rke2-demo/blob/main/values/minio-values.yaml). Loki can be configured to use other buckets or storage providers by using UDS bundle overrides to configure the UDS Loki Helm chart [values](https://github.com/defenseunicorns/uds-core/blob/main/src/loki/values/values.yaml#L32). #### Zarf The [zarf init](https://docs.zarf.dev/ref/init-package/#_top) package will bootstrap your cluster and make it airgap-ready. This is typically included as part of the `uds-bundle.yaml` when installing UDS. ### Installing UDS With all prerequisites satisfied, UDS is ready to be installed in the cluster. You can use the [automation](https://github.com/defenseunicorns-labs/uds-rke2-demo?tab=readme-ov-file#quickstart-rke2-already-running) in the demo repo to install UDS with a single command: ``` uds run install ``` Otherwise, a sample [uds-bundle.yaml](https://github.com/defenseunicorns-labs/uds-rke2-demo/blob/main/uds-bundle.yaml) is provided for reference and is partially shown below: ``` kind: UDSBundle metadata: name: uds-rke2-demo description: A UDS bundle for deploying the standard UDS Core package on a development cluster version: "0.1.0" packages: # prereq packages go here ... - name: init repository: ghcr.io/zarf-dev/packages/init ref: - name: core repository: ghcr.io/defenseunicorns/packages/uds/core ref: # additional configuration overrides go here ``` ### Accessing UDS Apps :::note UDS web apps are protected by Keycloak. See the "Configuring Keycloak SSO" section below to create a user for demo purposes. ::: After installing UDS Core, find the IPs of the Istio ingress gateway services. The following command run from the root of the [demo repo](https://github.com/defenseunicorns-labs/uds-rke2-demo) will show the ingress gateway IPs. ``` uds run get-gw-ips ``` You can also use the vendored `kubectl` to get the IPs: ``` # admin gateway ips (repeat for other gateways) uds zarf tools kubectl get svc admin-ingressgateway -n istio-admin-gateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}' ``` :::note It takes a moment for MetalLB to assign IPs to the ingress gateway services, so the IP may not show up right away. ::: After getting the IP, use `/etc/hosts` (or configure a DNS provider) to enable resolution of UDS Core app hostnames, for example: ``` # /etc/hosts ... # admin apps use the admin-ingressgateway IP 192.168.64.200 keycloak.admin.uds.dev grafana.admin.uds.dev neuvector.admin.uds.dev # tenant apps use the tenant-ingressgateway IP 192.168.64.201 sso.uds.dev podinfo.uds.dev ``` UDS Core apps should now be accessible via the host machine's web browser. ### Configuring Keycloak SSO Keycloak is hardened by default and can be configured further as per the documentation in the [UDS IdAM](https://uds.defenseunicorns.com/reference/uds-core/idam/uds-identity-config-overview/) docs. To explore the demo environment, we recommend using the following command, ran from the root of the demo repo, to run a UDS task to create a user we can use to access UDS services: ``` uds run setup:keycloak-user --set KEYCLOAK_USER_GROUP="/UDS Core/Admin" ``` This will create an admin user with the following credentials: ``` username: doug password: unicorn123!@#UN role: /UDS Core/Admin ``` These credentials can be used to log into any of the apps in UDS. ### Integrating a Mission App UDS uses a custom `Package` resource backed by a UDS K8s controller to automatically integrate and secure mission applications with minimal configuration. An example of such a configuration for the app [PodInfo](https://github.com/stefanprodan/podinfo) exists in the [demo repo](https://github.com/defenseunicorns-labs/uds-rke2-demo/tree/main/podinfo). It can be deployed into the UDS RKE2 cluster by running the following command from the root of the repo: ``` uds run deploy-podinfo ``` For a more in-depth explanation of `Package` resources, see the [Package CR](https://uds.defenseunicorns.com/reference/configuration/custom-resources/packages-v1alpha1-cr/) reference docs and the [Integrating an Application with UDS Core](https://uds.defenseunicorns.com/tutorials/create-uds-package/) tutorial. ----- # Switching to Istio Ambient Mesh The UDS Operator supports automatically integrating your application with Istio Ambient Mesh. It also supports automatically migrating your workload from Istio Sidecars to Ambient mode if you are upgrading an existing application. For the sake of this tutorial, we will cover migrating the podinfo application that was deployed in the previous tutorials to Ambient mode. ### Prerequisites For this tutorial please ensure you are running at UDS Core version 0.55.1 or higher. This will ensure full ambient support is present, including Authservice protection. Run `zarf package list` and check the version number for the `core` package: ```bash ❯ zarf package list Package | Namespace Override | Version | Components core | | 0.55.1 | [uds-crds uds-operator-config prometheus-operator-crds pepr-uds-core istio-controlplane gateway-api-crds istio-admin-gateway istio-tenant-gateway keycloak neuvector loki kube-prometheus-stack vector grafana authservice velero] ``` ### Migrate Podinfo To Istio Ambient Mode While not explicitly called out in the previous tutorials, the UDS Operator automatically handled setting up Istio injection for the podinfo application. The default method for Istio mesh integration in UDS is [Sidecar](https://istio.io/latest/docs/reference/config/networking/sidecar/). If you look at the podinfo application and its namespace, you will notice that the UDS Operator added the proper attributes for the workload to be recognized by istio and have sidecar injection enabled. You'll also note that the podinfo pod is running two containers, one of these being the Istio sidecar: ```bash ❯ kubectl get ns podinfo --show-labels NAME STATUS AGE LABELS podinfo Active 33m app.kubernetes.io/managed-by=zarf,istio-injection=enabled,kubernetes.io/metadata.name=podinfo ❯ kubectl get pods -n podinfo NAME READY STATUS RESTARTS AGE podinfo-7d47686cc7-jdxng 2/2 Running 0 25m ``` By default, UDS Core ships with all required components to support both Istio Sidecar mode and Ambient mode starting in release v0.40.0 and onward. v0.48.0 and beyond include support for Authservice with Ambient mode. Migrating podinfo to Istio Ambient mode is as simple as making a single change to the Package Custom Resource. In the Package Custom Resource definition, add a new entry for `spec.network.serviceMesh.mode: ambient`: ```yaml apiVersion: uds.dev/v1alpha1 kind: Package metadata: name: podinfo namespace: podinfo spec: network: # Configure Istio Mode - can be either ambient or sidecar. Default is sidecar. serviceMesh: mode: ambient # Expose rules generate Istio VirtualServices and related network policies expose: - service: podinfo selector: app.kubernetes.io/name: podinfo gateway: tenant host: podinfo port: 9898 # SSO allows for the creation of Keycloak clients and with automatic secret generation and protocolMappers sso: - name: Podinfo SSO clientId: uds-core-podinfo redirectUris: - "https://podinfo.uds.dev/login" enableAuthserviceSelector: app.kubernetes.io/name: podinfo groups: anyOf: - "/UDS Core/Admin" # Monitor generates Prometheus Service and Pod monitor resources, capturing metrics exposed by your application monitor: - selector: app.kubernetes.io/name: podinfo targetPort: 9898 portName: http description: "podmonitor" kind: PodMonitor - selector: app.kubernetes.io/name: podinfo targetPort: 9898 portName: http description: "svcmonitor" kind: ServiceMonitor ``` Save your changes and re-apply the Package Custom Resource with `kubectl apply -f podinfo-package.yaml`. Once applied, the UDS Operator will migrate the podinfo workload to Ambient mode by first updating the Istio label on the namespace: ```bash ❯ kubectl get ns podinfo --show-labels NAME STATUS AGE LABELS podinfo Active 71m app.kubernetes.io/managed-by=zarf,istio.io/dataplane-mode=ambient,kubernetes.io/metadata.name=podinfo ``` The `istio.io/dataplane-mode=ambient` label tells Istio that all workloads in the `podinfo` namespace will use Ambient mode. Next, the operator performed a rolling restart of the podinfo application. This is required to decommission the sidecar that was previously present: ```bash ❯ kubectl get po -n podinfo NAME READY STATUS RESTARTS AGE podinfo-7d47686cc7-mlr59 1/1 Running 0 3m14s uds-core-podinfo-waypoint-55547ff65b-2nqsf 1/1 Running 0 3m13s ``` Notice how the pod only has a single container. The podinfo application has been successfully migrated to Ambient! Also notice the `waypoint` pod which is added here. This waypoint is required to support SSO with Authservice (read more about waypoints [here](https://istio.io/latest/docs/ambient/usage/waypoint/)). :::note Learn more about the changes introduced in Ambient mode [here](https://istio.io/latest/docs/ambient/overview/). ::: You can also validate that all of the other integrations we setup are still present (navigate to https://podinfo.uds.dev/ and login again, etc). #### Clean up Execute the following command to clean up your cluster: ```bash k3d cluster delete uds ``` ----- # Deploy with UDS Core ## Sample Application with UDS Core This tutorial uses UDS CLI to deploy an example application, [podinfo](https://github.com/stefanprodan/podinfo), alongside UDS Core as a UDS Bundle. ### Prerequisites - [Zarf](https://docs.zarf.dev/getting-started/) - [UDS CLI](https://uds.defenseunicorns.com/reference/cli/overview/) - [Docker](https://www.docker.com/) - [k3d](https://k3d.io) ### Quickstart To begin, a Zarf Package needs to be created for `podinfo`. See the [Zarf documentation](https://docs.zarf.dev/) for in-depth information on how to create a Zarf Package, or simply use the information provided below to create a basic package. #### Make a Directory Make a new directory for this package using the following command: ```bash mkdir package && cd package ``` Create the following `zarf.yaml` in the new directory: ```yaml kind: ZarfPackageConfig metadata: name: podinfo version: 0.0.1 components: - name: podinfo required: true charts: - name: podinfo version: 6.10.1 namespace: podinfo url: https://github.com/stefanprodan/podinfo.git gitPath: charts/podinfo images: - ghcr.io/stefanprodan/podinfo:6.10.1 actions: onDeploy: after: - wait: cluster: kind: deployment name: podinfo namespace: podinfo condition: available ``` #### Create the Zarf Package Run the following command in the same directory as the above `zarf.yaml`. This will create a Zarf Package named `zarf-package-podinfo--0.0.1.tar.zst`: ```bash zarf package create --confirm ``` :::note The `` field in the name of your Zarf Package will depend on your system architecture (eg. `zarf-package-podinfo-amd64-0.0.1.tar.zst`). ::: #### Create the UDS Bundle Create the UDS Bundle in the same directory as the `package` directory. The following bundle includes: - k3d cluster: `uds-k3d`. - Zarf init package: `init`. - UDS Core: `core`. - Locally built example application: `podinfo`. Create the following `uds-bundle.yaml`: ```yaml kind: UDSBundle metadata: name: podinfo-bundle description: Bundle with k3d, Zarf init, UDS Core, and podinfo. version: 0.0.1 packages: - name: uds-k3d repository: ghcr.io/defenseunicorns/packages/uds-k3d ref: 0.19.4 overrides: uds-dev-stack: minio: variables: - name: buckets description: "Set Minio Buckets" path: buckets - name: svcaccts description: "Minio Service Accounts" path: svcaccts - name: users description: "Minio Users" path: users - name: policies description: "Minio policies" path: policies - name: init repository: oci://ghcr.io/zarf-dev/packages/init ref: v0.71.1 - name: core repository: oci://ghcr.io/defenseunicorns/packages/uds/core ref: 0.61.0-upstream overrides: # Set overrides for k3d dev stack pepr-uds-core: module: values: - path: additionalIgnoredNamespaces value: - uds-dev-stack keycloak: keycloak: variables: - name: KEYCLOAK_HEAP_OPTIONS description: "Sets the JAVA_OPTS_KC_HEAP environment variable in Keycloak" path: env[0].value values: - path: env[0] value: name: JAVA_OPTS_KC_HEAP value: "-XX:MaxRAMPercentage=70 -XX:MinRAMPercentage=70 -XX:InitialRAMPercentage=50 -XX:MaxRAM=1G" - name: podinfo path: ./ ref: 0.0.1 ``` :::note Use UDS Core version 0.55.1 or newer. Earlier versions may trigger browser certificate errors when accessing example HTTPS endpoints (for example, https://podinfo.uds.dev) due to an outdated development certificate. ::: UDS Bundles can easily be configured to include additional applications and capabilities. For example, if you would like to deploy [dos-games](https://docs.zarf.dev/tutorials/3-deploy-a-retro-arcade/) instead of `podinfo`, in the `uds-bundle.yaml` simply replace: ```yaml - name: podinfo path: ./ ref: 0.0.1 ``` with: ```yaml - name: dos-games repository: oci://defenseunicorns/dos-games ref: 1.0.0 ``` :::note Most UDS Packages are published as Zarf Packages in an OCI registry. This makes it easier to pull packages down into a UDS Bundle. If no OCI artifact is published for a certain application or capability, a new `zarf.yaml` and Zarf Package must be created. Alternatively, you have the option to publish a Zarf Package to an [OCI compliant registry](https://docs.zarf.dev/tutorials/6-publish-and-deploy/). ::: #### Create and Confirm the UDS Bundle This process will take a few minutes while UDS CLI pulls down the images that will be deployed. This command will produce a UDS Bundle named `uds-bundle-podinfo-bundle--0.0.1.tar.zst`: ```bash uds create --confirm ``` :::note As above, the `` field in the name of your UDS Bundle will depend on your system architecture (eg. `uds-bundle-podinfo-bundle-amd64-0.0.1.tar.zst`). ::: #### Deploy You can now deploy the bundle which will create a k3d cluster, deploy UDS Core, and deploy `podinfo`. This process will take approximately 10-15 minutes to complete: ```bash uds deploy uds-bundle-podinfo-bundle-*-0.0.1.tar.zst --confirm ``` #### Interact with Cluster Once successfully deployed, you can interact with the deployed cluster and applications using [kubectl](https://kubernetes.io/docs/tasks/tools/) or [k9s](https://k9scli.io/topics/install/). Both tools are included with `uds` as `uds zarf tools kubectl` and `uds zarf tools monitor` respectively. In the command below, we are listing pods and services in `podinfo` namespace that were just deployed as part of the UDS Bundle. Please note that the output for your `podinfo` pod will likely have a different name: ```bash ❯ kubectl get pods,services -n podinfo NAME READY STATUS RESTARTS AGE pod/podinfo-5cbbf59f6d-bqhsk 1/1 Running 0 2m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/podinfo ClusterIP 10.43.63.124 9898/TCP,9999/TCP 2m ``` Connect to `podinfo` using `kubectl port-forward`: ```bash kubectl port-forward service/podinfo 9898:9898 -n podinfo ``` You can now use a web browser to naviage to `http://localhost:9898` to interact with `podinfo`. #### Next Steps In this section, a Zarf Package was created that consists of the sample application, `podinfo`. The resulting `podinfo` Zarf Package was added to a UDS Bundle where additional Zarf Packages such as a K3d cluster, Zarf Internal components, and UDS Core were included. With the stack now deployed, visit the next page to discover how you can integrate the application with the monitoring, logging, security and other services provided by UDS Core.