--- tags: work, problems, spike --- # Join Namespace Network Policy ## Problem Statement * At the moment, we are using api to ansible tower to perform the join namespace whenever the plan requested to do so. * Join namespace is performed in bi-directional way. That would means when we requested `namespace-a` to join `namespace-b` we called ansible tower two times, to create the following network policy (ingress) : * `allow-from-namespace-b` network policy in `namespace-a` * `allow-from-namespace-a` network policy in `namespace-b` * This causes us massive creation of network policy that never get cleaned up on the long lived namespace. * For example, we have `namspace-a` that many other namespace has needs to join here, let's say `namespace-1` to `namespace-n`. This would means there will be `allow-from-namespace-1` to `allow-from-namespace-n` in `namespace-a`. * When we deleted `namespace-1` to `namespace-n` the network policies that gets deleted only those under the deleted namespace, the long lived namespace would never get cleaned up its obsoleted network policy ### Additional information * There are few default network policy created when we create namespace in the cluster * default-deny * allow-from-same-namespace * allow-from-global-namespace * We are using kubernetes network policy, its not external CRD. So everything in kubernetes example should be applicable. ```yaml kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: default-deny namespace: da-saas-alfonz-test ``` * Below is the example of the current network policy definitions. ```yaml spec: podSelector: {} ingress: - from: - namespaceSelector: matchLabels: name: da-saas-non-prod-c7f9b7fac9154c44a88003dba6902194 policyTypes: - Ingress ``` * We have the following network policy by the time we created the service group via provisioning service * `allow-from-global-namespace` ```yaml spec: podSelector: {} ingress: - from: - namespaceSelector: matchLabels: system-network-namespace: 'true' policyTypes: - Ingress ``` * `allow-from-same-namespace` ```yaml spec: podSelector: {} ingress: - from: - podSelector: {} policyTypes: - Ingress ``` * `default-deny` ```yaml spec: podSelector: {} policyTypes: - Ingress ``` ## Solution & Options * Provisioning service to have a strategy to join the namespace * managed by **ANSIBLE_TOWER** * Use existing implementation, in which the join namespace can be bidirectional/uni-directional depending on current configuration * managed by **OPENSHIFT** * Creating new object into the namespace to apply network policy during join namespace * We will still create 2 network policy, one is from the short lived namespace and another one in the long lived namespace * On the creation of network policy, the main policy should be from the shorter lived namespace. * Provisioning service will track the joined namespace * Refer to the following policy example to be autogenerated by provisioning service on the source namespace of join namespace ```yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: default spec: podSelector: matchLabels: role: db policyTypes: - Ingress - Egress ingress: - from: - namespaceSelector: matchLabels: name: da-saas-dev egress: - to: - namespaceSelector: matchLabels: name: da-saas-dev ``` * When the namespace get deleted, the network policy will also be deleted naturally. ## Appendix ### Example of NetworkPolicy ```yaml= apiVersion: v1 kind: Namespace metadata: name: dono-test-1 labels: networking/name: dono-test-1 --- apiVersion: v1 kind: Pod metadata: name: app-1 namespace: dono-test-1 labels: name: app-1 spec: containers: - name: app-1 image: joshrosso/nginx-curl:v2 imagePullPolicy: IfNotPresent resources: limits: memory: "128Mi" cpu: "500m" --- apiVersion: v1 kind: Service metadata: name: app-1 namespace: dono-test-1 spec: ports: - port: 80 targetPort: 80 name: http protocol: TCP selector: name: app-1 ``` ```yaml= apiVersion: v1 kind: Namespace metadata: name: dono-test-2 labels: networking/name: dono-test-2 --- apiVersion: v1 kind: Pod metadata: name: app-2 namespace: dono-test-2 labels: name: app-2 spec: containers: - name: app-2 image: joshrosso/nginx-curl:v2 imagePullPolicy: IfNotPresent resources: limits: memory: "128Mi" cpu: "500m" --- apiVersion: v1 kind: Service metadata: name: app-2 namespace: dono-test-2 spec: ports: - port: 80 targetPort: 80 name: http protocol: TCP selector: name: app-2 --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-interaction-to-dono-test-1 namespace: dono-test-2 spec: podSelector: {} policyTypes: - Ingress - Egress ingress: - from: - namespaceSelector: matchLabels: name: dono-test-1 egress: - to: - namespaceSelector: matchLabels: name: dono-test-1 ```