GitOps Driven Configuration of OCM Applications
Did you know?
Get ready for the next evolution of the Open Component Model, designed to empower your cloud-native workflows. Discover a preview of the innovative ocm-k8s-toolkit
here and be part of shaping the future of component management!
Introduction
This guide is the final part of our series exploring OCM, the ocm-controller, and how to drive GitOps processes using OCM as the source of truth.
Check out the previous guides if you haven’t already:
In this guide we will pick up where we left off in the example for deployments to air-gapped environments.
We have successfully transferred a component to our private environment and deployed it using the ocm-controller. However, the Kubernetes Deployment for podinfo is failing because it does not have permission to access our private container images.
Let’s fix that.
Table of Contents
Requirements
Component Content Recap
We saw previously that the podinfo component contains three resources:
podinfocontainer image- kubernetes deployment manifest for
podinfo - configuration file read by the ocm-controller
We can list these resources using the ocm CLI:
ocm get resources ghcr.io/phoban01//phoban.io/podinfo -c v6.3.5
NAME VERSION IDENTITY TYPE RELATION
config 6.3.5 PlainText local
deployment 6.3.5 Directory local
image 6.3.5 ociImage externalLet’s examine the config resource once again and this time focus on a section named configuration:
ocm download resource ghcr.io/phoban01//phoban.io/podinfo -c v6.3.5 config -O -
apiVersion: config.ocm.software/v1alpha1
kind: ConfigData
metadata:
name: ocm-config
configuration:
defaults:
serviceAccountName: default # this is the default value for our variable
rules:
- value: (( serviceAccountName )) # this variable
file: deployment.yaml # will be inserted into this file
path: spec.template.spec.serviceAccountName # at this path
schema: # allows us to define constraints for configuration values
type: object
additionalProperties: false
properties:
serviceAccountName:
type: string
...The configuration section contains a set of rules, some default values, and a schema.
These can be used to provide configuration values, which will be inserted into our resources at runtime by the ocm-controller.
In the above resource we can see that there is a variable named serviceAccountName and a rule which specifies that this variable should be inserted into the path spec.template.spec.serviceAccountName in the deployment.yaml file.
GitOps & Configuration
Similar to how we Localized our deployment resource in the previous guide, we create another Custom Resource with the type Configuration in order to apply our configuration rules:
cat > ./components/localization.yaml >>EOF
apiVersion: delivery.ocm.software/v1alpha1
kind: Configuration
metadata:
name: podinfo-deployment
namespace: ocm-system
spec:
interval: 1m
sourceRef:
kind: Localization
name: podinfo-deployment # this is the podinfo deployment localization
configRef:
kind: ComponentVersion
name: podinfo
resourceRef:
name: config # here we reference the configuration resource
values:
serviceAccountName: app-ops
EOFYou can see that this time we have used the Localization resource as the input for the Configuration and have provided the configuration rules using the spec.configRef field. Finally, we specify our service account name in the spec.values.serviceAccountName field.
Once again we need to update the FluxDeployer so that it consumes the Configuration rather than the Localization:
apiVersion: delivery.ocm.software/v1alpha1
kind: FluxDeployer
metadata:
name: podinfo
namespace: ocm-system
spec:
sourceRef:
kind: Configuration
name: podinfo-deployment
kustomizationTemplate:
interval: 1m0s
path: ./
prune: true
targetNamespace: defaultBefore we push these changes, we need to actually create the ServiceAccount and image-pull Secret in the target namespace.
Let’s create the secret as we did previously (Note that in a real world scenario there are a number of ways to manage secrets when doing Gitops):
kubectl create secret docker-registry -n default ghcr-cred \
--docker-server=ghcr.io \
--docker-username=$GITHUB_USER \
--docker-password=$GITHUB_TOKENNow let’s add the ServiceAccount:
cat > ./clusters/kind/service_account.yaml <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-ops
namespace: default
imagePullSecrets:
- name: ghcr-credFinally we are ready commit, push, and reconcile these changes:
git add ./components ./clusters
git commit -m "move to air-gapped repository"
git push
flux reconcile source git flux-systemVerify Deployment
Flux should now be reconciling the Configured manifest with image references pointing to our private OCM repository and the correct ServiceAccount configured.
We can verify this using kubectl:
kubectl get deployment -n default podinfo -oyaml | grep serviceAccountName | xargs
serviceAccountName: app-opskubectl get deployment -n default podinfo -oyaml | grep image | xargs
image: ghcr.io/phoban01/air-gapped/stefanprodan/podinfo:6.3.5Kubernetes can now retrieve the image and all pods should be happily running.
Conclusion
We have shown how OCM and Flux can be combined to configure applications at runtime.
GitOps driven configuration in tandem with the powerful Localization functionality provided by OCM offers tremendous flexibility, reliability, and scalability when deploying your applications to any kind of compute environment, be it public, private or edge.