Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Manage namespaces in multitenant clusters with Argo CD, Kustomize, and Helm

April 13, 2022
Saumeya Katyal
Related topics:
DevOpsGitOpsKubernetes
Related products:
Red Hat OpenShift Container Platform

Share:

    Cluster administrators on Kubernetes need to create namespaces for multiple developer teams and limit their use of resources by provisioning those namespaces with resource quotas and limit ranges. In this article, you'll learn how to automate these tasks with Argo CD, and how to use either Kustomize or Helm charts to simplify the process. The result implements the fundamentals of DevOps and GitOps, whereby any changes to the repository update the deployed resources.

    There are two types of configuration that administrators have to deal with are:

    • Resource quota: A Kubernetes object that controls the amount of CPU or memory consumed by a namespace. This quota can also limit the number of resources that can be created in a namespace.
    • Limit range: This is used in Kubernetes along with resource quotas. Although resource quotas control the overall resource consumption of an entire namespace, they do not place any limit on a pod or container within that namespace, so a single pod or container could use up all of the namespace's resources. Limit ranges specify resources available per pod or container.

    While the general principles outlined here apply to any Kubernetes environment, some of the examples in this article assume that you are deploying on Red Hat OpenShift and can use its graphical user interface as well as the oc command-line interface (CLI).

    A simple Argo CD application

    To automate the administrator's configuration tasks, you'll use Argo CD, a powerful continuous delivery tool for Kubernetes resources. Because namespaces and quotas are Kubernetes resources, Argo CD can manage them.

    In this section, you'll create a simple Argo CD application from an example in my GitHub repository. In the sections that follow this one, I'll demonstrate two better ways to create the application using Kustomize and Helm along with Argo CD. But we'll start with a simple example to help you get your bearings with Argo CD.

    1. Create a Git repository on your system based on the namespaces-config example in my GitHub repository. The repository comprises the manifest for all namespaces, quotas, and limit ranges for all the teams in the example.

    2. Add Syncwaves under the annotations property in these configuration files. Syncwaves is valuable for imposing an order on separate activities. In this case, you need to create a namespace before you can associate a resource quota and limit range to it. The following files show how you can assure that the namespace is created first by assigning a Syncwave of -1, whereas the resource quota and limit range have a Syncwave of 0.

      The configuration for a namespace looks like this:

      apiVersion: v1
      kind: Namespace
      metadata:
        name: dev
        annotations:
          argocd.argoproj.io/sync-wave: "-1"
        labels:
          argocd.argoproj.io/managed-by: openshift-gitops

      The configuration for a resource quota looks like this:

      apiVersion: v1
      kind: ResourceQuota
      metadata:
        name: resource-quota
        namespace: dev
        annotations:
          argocd.argoproj.io/sync-wave: "0"
      spec:
        hard:
          pods: "10"

      The configuration for a limit range looks like this:

      apiVersion: v1
      kind: LimitRange
      metadata:
        name: limits
        namespace: dev
        annotations:
          argocd.argoproj.io/sync-wave: "0"
      spec:
        limits:
        - default:
            cpu: 200m
            memory: 512Mi
          defaultRequest:
            cpu: 100m
            memory: 256Mi
          type: Container
    3. Log in to your OpenShift cluster as a cluster administrator.

    4. The Argo CD application controller needs additional permissions to create resource quotas and limit ranges in cluster namespaces. Use OpenShift cluster roles and cluster role bindings to grant these permissions to the application controller of the default argocd instance in the openshift-gitops namespace. To carry out this step, create a ClusterRole and ClusterRoleBinding and apply them to your cluster.

      The configuration for a cluster role looks like this:

      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        # "namespace" omitted since ClusterRoles are not namespaced
        name: quota-limit-cluster-role
      rules:
      - apiGroups: [""] #specifies core api groups
        resources: ["resourcequotas", "limitranges"]
        verbs: ["create"]

      Enter the following command to create the ClusterRole on the cluster:

      $ oc create -f <cluster-role-file-name>.yaml

      The configuration for a cluster role binding looks like this:

      apiVersion: rbac.authorization.k8s.io/v1
      # This cluster role binding allows Service Account to create resource quotas and limit ranges in any namespace.
      kind: ClusterRoleBinding
      metadata:
        name: create-quota-limit-global
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: quota-limit-cluster-role # Name of cluster role to be referenced
      subjects:
      - kind: ServiceAccount
        name: openshift-gitops-argocd-application-controller
        namespace: openshift-gitops

      Enter the following command to create the ClusterRoleBinding on the cluster:

      $ oc create -f cluster-role-binding.yaml
    5. Create an Argo CD Application via the user interface (Figure 1), with the following sample Git repository:

      In the OpenShift console, you can create an Argo CD Application from this article's example repository.
      Figure 1. In the OpenShift console, you can create an Argo CD Application from this article's example repository.
      Figure 1: In the OpenShift console, you can create an Argo CD Application from this article's example repository.

      You could also use an Application custom resource to create an application using the CLI. If you want to take this route, your configuration should look like this:

      apiVersion: argoproj.io/v1alpha1
      kind: Application
      metadata:
      name: namespace-management
      spec:
      destination:
        name: ''
        namespace: default
        server: 'https://kubernetes.default.svc'
      source:
        path: namespaces-config
        repoURL: 'https://github.com/saumeya/blog-example-repo.git'
        targetRevision: HEAD
      project: default
      Enter the following command to create the application:
      $ oc create -f <application-cr-file-name>.yaml
    6. Refresh and synchronize the application to create the namespaces with their related quotas and limit ranges (Figure 2).

    The Topology view of the OpenShift console shows the Argo CD Application and its limit assignments to other namespaces.
    Figure 2. The Topology view of the OpenShift console shows the Argo CD Application and its limit assignments to other namespaces.
    Figure 2: The Topology view of the OpenShift console shows the Argo CD application and its limit assignments to other namespaces.

    Argo CD automates the assignment of resource limits, but the procedure shown in this example so far requires you to maintain an individual manifest for each team. This repetition of files makes it tedious to manage the configurations, especially if you're dealing with a large number of teams and projects. In the following sections, you'll see some better approaches that make use of Kustomize and Helm.

    Use Kustomize to create and manage resources

    The procedure in this section optimizes some of the tasks in the previous section and leaves others unchanged. By using custom patches in Kustomize, a Kubernetes-native configuration management tool, you can avoid creating multiple manifests and reuse common elements from resource quotas and limit ranges.

    I have placed the relevant files for this example in my GitHub repository. The teams directory defines all the patches for different teams in the base manifests. The associated resources are created when you create the Argo CD Application.

    Here is the kustomization.yaml for a patch:

    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization
    
    namespace: team-a
    
    bases:
    - ../../base
    
    patches:
    - target:
        kind: Namespace
        name: default-dev
      patch: |-
        - op: replace
          path: /metadata/name
          value: team-a
    - target:
        kind: ResourceQuota
        name: resource-quota
      patch: |-
        - op: replace
          path: /metadata/name
          value: quota-team-a
        - op: replace
          path: /spec/hard/limits.cpu
          value: 1
        - op: replace
          path: /spec/hard/services
          value: 10
    - target:
        kind: LimitRange
        name: limit-range
      patch: |-
        - op: replace
          path: /metadata/name
          value: quota-team-a

    Here is the kustomization.yaml file for all the teams:

    bases:
    - ./team-a
    - ./team-b
    - ./team-c

    Now follow steps 3, 4, and 5 from the previous example to grant additional permissions and create Argo CD Applications to manage your namespaces (Figure 3). Make sure to correctly specify the Path in step 5 to kustomize-namespace-config/teams. Refresh and synchronize the application.

    The Topology view of the OpenShift console shows the Argo CD Application created by Kustomize and its limit assignments to other namespaces.
    Figure 3. The Topology view of the OpenShift console shows the Argo CD Application created by Kustomize and its limit assignments to other namespaces.
    Figure 3: The Topology view of the OpenShift console shows the Argo CD Application created by Kustomize and its limit assignments to other namespaces.

    Use Helm and an ApplicationSet to create and manage resources

    Helm templates can also be used to parameterize configurations for namespaces, resource quotas, and limit ranges. A simple use of Helm charts, however, would require you to create more Argo CD applications to manage these namespaces. To avoid creating multiple applications one by one, use an ApplicationSet resource to specify the value files and create all the applications in one go.

    1. Create a Helm chart and add the resource files from my example repository.

      Here is the templates/namespace.yaml file:

      apiVersion: v1
      kind: Namespace
      metadata:
        name: {{ .Values.namespace }}
        annotations:
          argocd.argoproj.io/sync-wave: "-1"
        labels:
          argocd.argoproj.io/managed-by: openshift-gitops

      Here is the templates/limit-range.yaml file:

      apiVersion: v1
      kind: LimitRange
      metadata:
        name: limit-range
        namespace: {{ .Values.namespace }}
        annotations:
          argocd.argoproj.io/sync-wave: "0"
      spec:
        limits:
        - default:
            cpu: {{ .Values.limits.default.cpu | default "200m" }}
            memory: {{ .Values.limits.default.memory | default "512Mi" }}
          defaultRequest:
            cpu: {{ .Values.limits.defaultRequest.cpu | default "100m"}}
            memory: {{ .Values.limits.defaultRequest.memory | default "256Mi"}}
          type: {{ .Values.limits.type | default "Container" }}

      Here is the templates/resource-quota.yaml file:

      apiVersion: v1
      kind: ResourceQuota
      metadata:
        name: resource-quota
        namespace: {{ .Values.namespace }}
        annotations:
          argocd.argoproj.io/sync-wave: "0"
      spec:
        hard:
          requests.cpu: {{ .Values.quota.requests.cpu | default "1"}}
          requests.memory: {{ .Values.quota.requests.memory | default "1Gi"}}
          limits.cpu: {{ .Values.quota.limits.cpu | default "2"}}
          limits.memory: {{ .Values.quota.limits.memory | default "2Gi"}}
          pods: {{ .Values.quota.pods | default "10"}}
          persistentvolumeclaims: {{ .Values.quota.persistentvolumeclaims | default "20"}}
          resourcequotas: {{ .Values.quota.resourcequotas | default "1"}}
          services: {{ .Values.quota.services | default "5"}}

      The values.yaml file contains default values. You can create value files with different names and specify those in Argo CD while creating an application:

      # Default values for namespace-app.
      # This is a YAML-formatted file.
      # Declare variables to be passed into your templates.
      
      namespace: default-dev
      
      #specifies the quota to be used for resources
      quota:
        requests:
          cpu: '1'
          memory: 1Gi
        limits:
          cpu: '2'
          memory: 2Gi
        pods: "10"
        persistentvolumeclaims: "20"
        resourcequotas: "1"
        services: "5"
      
        #specifies the limit ranges for the chart
      limits:
        default:    
          memory: 512Mi
        defaultRequest:
          cpu: 100m
          memory: 256Mi
        type: Container
      

      Here is the Chart.yaml file:

      apiVersion: v2
      name: helm-namespace-config
      description: A Helm chart for Namespace Management
      type: application
      version: 0.1.0
      appVersion: "1.16.0"
    2. Follow steps 3 and 4 from the first example in this article to grant additional permissions and create Argo CD applications to manage your namespaces.

    3. Now use an ApplicationSet resource to create multiple applications. Check the teams directory in my example repository, which contains custom value files for various teams. Add the relative paths of these custom value files in the list generator. This procedure generates the applications for specific teams with the required configurations, as illustrated in Figure 4.

      Here is the configuration file for the ApplicationSet resource:

      apiVersion: argoproj.io/v1alpha1
      kind: ApplicationSet
      metadata:
      name: namespace-config
      namespace: openshift-gitops
      spec:
      generators:
      - list:
          elements:
          - filepath: teams/team-a.yaml
            name: team-a
          - filepath: teams/team-b.yaml
            name: team-b
          - filepath: teams/team-c.yaml
            name: team-c
      template:
        metadata:
          name: '{{name}}-namespace-config'
        spec:
          project: default
          syncPolicy:
            automated:
              prune: true
              selfHeal: true
            syncOptions:
              - CreateNamespace=true
          source:
            repoURL: 'https://github.com/saumeya/blog-example-repo'
            targetRevision: HEAD
            path: helm-namespace-config
            helm:
              valueFiles:
              - '{{filepath}}'
          destination:
            server: 'https://kubernetes.default.svc'
            namespace: openshift-gitops

      Apply the ApplicationSet configuration file to your cluster by running the following command:

      $ oc apply -f <application-set-file-name>.yaml
      The Application Set created three Applications.
      Figure 4. The Application Set created three Applications.
      Figure 4: The ApplicationSet has created three applications.

      You can now synchronize each application and click on an individual application to see the created resources, as illustrated in Figure 5.

    The Topology view of the OpenShift console shows the Team A application created by Helm.
    Figure 5. The Topology view of the OpenShift console shows the Team A application created by Helm.
    Figure 5: The Topology view of the OpenShift console shows the Team A application created by Helm.

    More information about how to create applications using Helm can be found in Argo CD's documentation.

    Conclusion

    This article has shown how to use Argo CD in conjunction with other convenient open source tools to simplify the creation, management, and configuration of Kubernetes namespaces. Whenever you need to change the quotas or limits, all you need to do is modify the configuration files in the source repository and Argo CD does the rest of the work.

    If you want to learn more about using Argo CD with Red Hat OpenShift, check out Part 1 and Part 2 of the "Building modern CI/CD workflows for serverless applications with Red Hat OpenShift Pipelines and Argo CD" series on Red Hat Developer.

    OSZAR »
    Last updated: September 20, 2023

    Recent Posts

    • How to use pipelines for AI/ML automation at the edge

    • What's new in network observability 1.8

    • LLM Compressor: Optimize LLMs for low-latency deployments

    • How to set up NVIDIA NIM on Red Hat OpenShift AI

    • Leveraging Ansible Event-Driven Automation for Automatic CPU Scaling in OpenShift Virtualization

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue

    OSZAR »