{"id":27770522,"url":"https://github.com/jgomezve/aci-k8s-operator","last_synced_at":"2026-04-28T00:31:31.523Z","repository":{"id":37085424,"uuid":"475408360","full_name":"jgomezve/aci-k8s-operator","owner":"jgomezve","description":"Kubernetes Operator to manage Segmentation Policies on a ACI Fabric running the Cisco CNI ","archived":false,"fork":false,"pushed_at":"2023-03-01T15:10:35.000Z","size":1385,"stargazers_count":1,"open_issues_count":10,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-24T08:05:30.657Z","etag":null,"topics":["aci","apic","cisco","kubebuilder","kubernetes","operator"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jgomezve.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-29T11:20:00.000Z","updated_at":"2022-06-08T08:29:50.000Z","dependencies_parsed_at":"2024-06-21T02:26:35.483Z","dependency_job_id":null,"html_url":"https://github.com/jgomezve/aci-k8s-operator","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/jgomezve/aci-k8s-operator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgomezve%2Faci-k8s-operator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgomezve%2Faci-k8s-operator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgomezve%2Faci-k8s-operator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgomezve%2Faci-k8s-operator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jgomezve","download_url":"https://codeload.github.com/jgomezve/aci-k8s-operator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jgomezve%2Faci-k8s-operator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32361477,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-27T20:07:02.737Z","status":"ssl_error","status_checked_at":"2026-04-27T20:07:00.910Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aci","apic","cisco","kubebuilder","kubernetes","operator"],"created_at":"2025-04-29T21:07:28.553Z","updated_at":"2026-04-28T00:31:31.508Z","avatar_url":"https://github.com/jgomezve.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# A Kubernetes Operator to Manage Cisco ACI Policies\n\n[![Tests](https://github.com/jgomezve/aci-k8s-operator/actions/workflows/test.yaml/badge.svg)](https://github.com/jgomezve/aci-k8s-operator/actions/workflows/test.yaml)\n![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/jgomezve/aci-k8s-operator)\n[![Go Report Card](https://goreportcard.com/badge/github.com/jgomezve/aci-k8s-operator)](https://goreportcard.com/report/github.com/jgomezve/aci-k8s-operator)\n![Kubernetes version](https://img.shields.io/badge/kubernetes-1.23%2B-blue)\n[![published](https://static.production.devnetcloud.com/codeexchange/assets/images/devnet-published.svg)](https://developer.cisco.com/codeexchange/github/repo/jgomezve/aci-k8s-operator)\n\nSimplify the Day-2 operation of a [Kubernetes](https://kubernetes.io/) Cluster running the Cisco [ACI Container Network Interface (CNI)](https://www.cisco.com/c/dam/en/us/solutions/collateral/data-center-virtualization/application-centric-infrastructure/solution-overview-c22-739493.pdf), by automating the configuration of the [APIC](https://www.cisco.com/c/en/us/products/cloud-systems-management/application-policy-infrastructure-controller-apic/index.html) using a [Kubernetes Operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/).  This repository contains a Kubernetes Operator used to manage a Custom Resource named `SegmentationPolicy`. The Operator enforces [Namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) segmentation, based on a straightforward and user-friendly Kubernetes manifest, through the configuration of the required objects (Contracts, Filters, EPGs) on the APIC controller.\n\n\n## ACI CNI Unified Networking\n\nThe ACI-CNI is an overlay network plugin that enables a smooth integration between Kubernetes nodes and the ACI Fabric. The plugin makes possible distributed routing and switching with VXLAN overlays on the Fabric and on the Kubernetes nodes. By using the ACI CNI, Pods running inside the Kubernetes cluster become endpoints of the ACI Fabric. As a result, the same level of segmentation and policing applied to Bare-metal servers and virtual machines can also be applied to the Pods.\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"docs/images/aci-k8s-operator.png\"  border=\"0\" width=\"500\"\u003e\n\u003cbr/\u003e\n\nKubernetes administrators can map Deployments and Namespaces to EPGs, which are in turn managed by Network administrators to apply rules with the ACI Policy Model. This Operator eases the collaboration between Network and Kubernetes administrators through the automation of the configuration of ACI Policies based on the specification of a new Custom Resource, the `SegmentationPolicy`.\n\n## Table of Contents\n\n  * [Requirements](#requirements)\n  * [Installation](#installation)\n  * [Usage](#usage)\n\n ## Requirements\n\n* [Cisco APIC](https://www.cisco.com/c/en/us/solutions/data-center-virtualization/application-centric-infrastructure/index.html) \u003e= 5.2.x\n* [Kubernetes](https://kubernetes.io/) \u003e= 1.23\n* [ACI-CNI](https://www.cisco.com/c/en/us/td/docs/switches/datacenter/aci/apic/sw/kb/b_Kubernetes_Integration_with_ACI.html)\n* [Go](https://golang.org/doc/install) \u003e= 1.17 (Optional)\n* [Make](https://www.gnu.org/software/make/)\n* [Kustomize](https://kustomize.io/)  \n\n\n## Installation\n\nThis repository has been scaffolded using [Kubebuilder](https://book.kubebuilder.io/introduction.html). Projects created by Kubebuilder contain a Makefile that eases the installation and testing of the Kubernetes Operator. The Makefile also leverages Kustomize to dynamically generate Kubernetes manifests.\n\n\u003e **Your Kubernetes cluster must have already been configured to use the Cisco ACI CNI**\n\n### 1. Clone this repository\n\n```\n      $ git clone https://github.com/jgomezve/aci-k8s-operator\n      $ cd aci-k8s-operator\n```\n\n\n### 2. Configure the CRD `SegmentationPolicy`\n\n* Configure the Custom Resource Definition (CRD) `SegmentationPolicy` on the Kubernetes clusters\n\n```\n      $ make install\n      customresourcedefinition.apiextensions.k8s.io/segmentationpolicies.apic.aci.cisco configured\n```\n```\n      $ kubectl get crd\n      NAME                                    CREATED AT\n      segmentationpolicies.apic.aci.cisco     2022-04-19T15:58:11Z\n```\n\n* Alternatively you could apply the manifest directly\n\n```\n      $ kubectl apply -f config/crd/bases/apic.aci.cisco_segmentationpolicies.yaml\n      customresourcedefinition.apiextensions.k8s.io/segmentationpolicies.apic.aci.cisco configured\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003econfig/crd/bases/apic.aci.cisco_segmentationpolicies.yaml\u003c/code\u003e\u003c/summary\u003e\n  \n  ```yaml\n    ---\n    apiVersion: apiextensions.k8s.io/v1\n    kind: CustomResourceDefinition\n    metadata:\n      annotations:\n        controller-gen.kubebuilder.io/version: v0.8.0\n      creationTimestamp: null\n      name: segmentationpolicies.apic.aci.cisco\n    spec:\n      group: apic.aci.cisco\n      names:\n        kind: SegmentationPolicy\n        listKind: SegmentationPolicyList\n        plural: segmentationpolicies\n        shortNames:\n        - segpol\n        singular: segmentationpolicy\n      scope: Namespaced\n      versions:\n      - name: v1alpha1\n        schema:\n          openAPIV3Schema:\n            description: SegmentationPolicy is the Schema for the segmentationpolicies\n              API\n            properties:\n              apiVersion:\n                description: 'APIVersion defines the versioned schema of this representation\n                  of an object. Servers should convert recognized schemas to the latest\n                  internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'\n                type: string\n              kind:\n                description: 'Kind is a string value representing the REST resource this\n                  object represents. Servers may infer this from the endpoint the client\n                  submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'\n                type: string\n              metadata:\n                type: object\n              spec:\n                description: SegmentationPolicySpec defines the desired state of SegmentationPolicy\n                properties:\n                  namespaces:\n                    items:\n                      type: string\n                    type: array\n                  rules:\n                    items:\n                      properties:\n                        eth:\n                          type: string\n                        ip:\n                          type: string\n                        port:\n                          type: integer\n                      type: object\n                    type: array\n                required:\n                - namespaces\n                - rules\n                type: object\n              status:\n                description: SegmentationPolicyStatus defines the observed state of SegmentationPolicy\n                type: object\n            type: object\n        served: true\n        storage: true\n        subresources:\n          status: {}\n    status:\n      acceptedNames:\n        kind: \"\"\n        plural: \"\"\n      conditions: []\n      storedVersions: []\n  ```\n\u003c/details\u003e\n\n\n### 3. Start the operator\n \nThe operator requires read/write access privileges to the Kubernetes cluster and the APIC controller. During the start-up phase, the Operator discovers the APIC configuration parameters from the `ConfigMap` ***aci-containers-config***. This `ConfigMap` is automatically deployed during the installation of the ACI CNI. \n\nAPIC's username and private key, which are used by the  Operator, are discovered during the start-up phase.\n\n\n\u003e **Note**:  The `ConfigMap` ***aci-containers-config*** is deployed in the `Namespace` ***aci-containers-system***\n\n#### Option 1: Operator running outside of the K8s Cluster\n\nThis is the preferred method for development environments. Make sure Go \u003e=1.17 is installed on the machine running the Kubernetes Operator\n\n* Set the [kubeconfig file](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) on the hosting machine to grant the Operator access to the Kubernetes cluster\n\n```\n      $ export KUBECONFIG=\u003ckubeconfigfile.yaml\u003e\n```\n\n* Compile the code and execute the binary file \n\n```\n      $ make run\n\n```\n\n* Alternatively you could excute Go commands directly\n\n```\n      $ go run ./main.go\n\n1.6523912324578347e+09\tINFO\tsetup\tACI CNI configuration discovered for tenant k8s-rke-aci-cni-pod-4 in APIC controller 172.20.91.9\n1.6523912325494506e+09\tINFO\tsetup\tstarting manager\n1.6523912325497773e+09\tINFO\tcontroller.segmentationpolicy\tStarting EventSource\t{\"reconciler group\": \"apic.aci.cisco\", \"reconciler kind\": \"SegmentationPolicy\", \"source\": \"kind source: *v1alpha1.SegmentationPolicy\"}\n1.6523912325498345e+09\tINFO\tcontroller.segmentationpolicy\tStarting EventSource\t{\"reconciler group\": \"apic.aci.cisco\", \"reconciler kind\": \"SegmentationPolicy\", \"source\": \"kind source: *v1.Namespace\"}\n1.6523912325498483e+09\tINFO\tcontroller.segmentationpolicy\tStarting Controller\t{\"reconciler group\": \"apic.aci.cisco\", \"reconciler kind\": \"SegmentationPolicy\"}\n1.6523912326504896e+09\tINFO\tcontroller.segmentationpolicy\tStarting workers\t{\"reconciler group\": \"apic.aci.cisco\", \"reconciler kind\": \"SegmentationPolicy\", \"worker count\": 1}\n```\n\n#### Option 2: Operator running inside of the K8s Cluster as a Pod\n      \nThis is the preferred method for production environments. The operator runs as a containerized application inside a `Pod`. `ClusterRole` and corresponding `ClusterRoleBinding` with `ServiceAccount` objects must be configured to ensure that the Pod has the required permissions to read/write the Kubernetes API. Based on best-practices, a `Deployment`, configured in a dedicated `Namespace`, manages the `Pod` which hosts the Operator application\n\n\nConnectivity from the Operator's Pod to the APIC controller can satisfied by any of the following options:\n\n  1. `SnatPolicy`: This new CRD, available in the ACI-CNI, allows Pods to communicate outside of the cluster using SNAT\n  2. `LoadBalancer`: This Service Type exposes Pods in the cluster over a known IP address. It also enables the exposed Pods to reach external networks\n\n\n*  Deploy the Operator on the Kubernetes Cluster\n\n```\n      $ make deploy \n\n      namespace/aci-k8s-operator-system created\n      customresourcedefinition.apiextensions.k8s.io/segmentationpolicies.apic.aci.cisco created\n      serviceaccount/aci-k8s-operator-controller-manager created\n      role.rbac.authorization.k8s.io/aci-k8s-operator-leader-election-role created\n      clusterrole.rbac.authorization.k8s.io/aci-k8s-operator-manager-role created\n      clusterrole.rbac.authorization.k8s.io/aci-k8s-operator-metrics-reader created\n      clusterrole.rbac.authorization.k8s.io/aci-k8s-operator-proxy-role created\n      rolebinding.rbac.authorization.k8s.io/aci-k8s-operator-leader-election-rolebinding created\n      clusterrolebinding.rbac.authorization.k8s.io/aci-k8s-operator-manager-rolebinding created\n      clusterrolebinding.rbac.authorization.k8s.io/aci-k8s-operator-proxy-rolebinding created\n      configmap/aci-k8s-operator-manager-config created\n      service/aci-k8s-operator-controller-manager-metrics-service created\n      deployment.apps/aci-k8s-operator-controller-manager created\n```\n\n* Alternatively you could apply the manifest `config/samples/controller_lightweight.yaml` directly. This manifest creates the minimum resources required to run the operator inside the Kubernetes Cluster:\n  * A `Namespace` which contains the  namespace-scoped resources\n  * A `ServiceAccount` which grants the Operator access tot he Kubernetes API Server\n  * A `ClusterRole` listing the resources and actions the Operator has access to\n  * A `ClusterRoleBinding` which binds the `Role` with the `ServiceAccount`\n  * A `Deployment` of one replica hosting the Operator code.\n\n```\n      $ kubectl apply  -f config/samples/controller_lightweight.yaml\n      namespace/aci-k8s-operator-system created\n      deployment.apps/controller-manager created\n      serviceaccount/controller-manager created\n      clusterrole.rbac.authorization.k8s.io/manager-role created\n      clusterrolebinding.rbac.authorization.k8s.io/manager-rolebinding created\n```\n\n*  Check the Controler status\n\n```\n      $ kubectl get pod -n aci-k8s-operator-system\n      NAME                                              READY   STATUS    RESTARTS   AGE\n      aci-k8s-operator-controller-manager-55d9777c9-89vh4   2/2     Running   0          14m\n```\n\n## Usage \n\nThe following example restricts communication between `Namepaces` ***ns1*** and ***ns2*** to only HTTPS. A Custom Resource of type `SegmentationPolicy` is created. It specifies the name of the Namespaces and the rules under `spec.namespaces[]` and  `spec.rules[]` respectively\n\n* Create the `Namespaces`\n```\n      $ kubectl create namespace ns1\n      $ kubectl create namespace ns2\n      namespace/ns1 created\n      namespace/ns2 created\n```\n```\n      $ kubectl get namespace\n      NAME                    STATUS   AGE\n      ns1                     Active   11s\n      ns2                     Active   8s\n\n```\n\n* Create a `SegmentationPolicy` Custom Resources (CR) \n\n***segmentationpolicy.yaml***\n```yaml\napiVersion: apic.aci.cisco/v1alpha1\nkind: SegmentationPolicy\nmetadata:\n  name: segpol1\nspec:\n  namespaces:\n    - ns1\n    - ns2\n  rules:\n    - eth: ip\n      ip: tcp\n      port: 443\n```\n\n      $ kubectl apply -f segmentationpolicy.yaml\n      segmentationpolicy.apic.aci.cisco/segpol1 created\n\n```\n      $ kubectl get segmentationpolicies\n      NAME      NAMESPACES   RULES        STATE      AGE\n      segpol1   ns1, ns2     ip-tcp-443   Enforced   20s\n```\n\n* The Kubernetes Operator configures the following Objects/Relationship on the APIC Controller\n  1. **Filter** per rule defined in the `SegmentationPolicy` CR. The name of the Filters is built based on the information from the manifest as follows **\u003cmetadata.name\u003e\u003crule.eth\u003e\u003crule.ip\u003e\u003crule.port\u003e**\n  2. **Contract** and **Subject** with the name of the `SegmentationPolicy`. The subject includes all the filters mentioned in point ***(i)***  \n  4. An **Application Profile** named **Seg_Pol_\u003ctenant_name\u003e**\n  5. An **EPG** per Namespace defined in the `SegmentationPolicy` CR. The names of the EPGs are the same names of the `Namespaces` [*]. The following properties are configured under the EPG:\n    * The Bridge Domain is set to the one assigned to the Pod Network\n    * The VMM Domain of type Kubernetes used by the CNI is assigned\n    * The Contracts mentioned in point ***(ii)*** are consumed and assigned\n    * The ACI-CNI \"default\" EPG is set as the Master EPG\n\n\n![add-app](docs/images/aci_topology.png \"ACI Topology\")\n\n\n\u003e **Note**:  [*] If a `Namespace` is defined in the `SegmentationPolicy` but does not exist in the Kubernetes Cluster, the EPG is not created. Likewise, if a `Namespace` listed in a `SegmentationPolicy` is deleted, the Operator reacts and deletes the corresponding EPG.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjgomezve%2Faci-k8s-operator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjgomezve%2Faci-k8s-operator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjgomezve%2Faci-k8s-operator/lists"}