snippetkubernetesMinor
How to add rules to Kubernetes NGINX Ingress controller from different yml definitions?
Viewed 0 times
ingresskubernetesnginxcontrollerdifferentymlhowrulesfromadd
Problem
I'm trying to implement a Kubernetes cluster with a fanout pattern using an NGINX Ingress which routes traffic on multiple different hosts and paths to different microservices. The code for each microservice is hosted in their own Git repo, including the kubernetes definition yml files which deploys the pods (Deployment) and services for each service respectively.
Considering that there will be a single Ingress which routes traffic to all the different Services, where (by convention or industry standard) should the definition file be stored? I would like to keep the Ingress rules related to a single microservice in the git repo where the rest of the code is. I don't particularly want a separate git repo just for the Ingress.
Is it possible to define only a subset of an Ingress' rules in a file which would then get "appended" to the list of rules instead of overwriting them.
For example, could I have these two different definitions which creates a single Ingress with two rules (based on having the same name):
foo-ingress-rules.yml
baz-ingress-rules.yml
Considering that there will be a single Ingress which routes traffic to all the different Services, where (by convention or industry standard) should the definition file be stored? I would like to keep the Ingress rules related to a single microservice in the git repo where the rest of the code is. I don't particularly want a separate git repo just for the Ingress.
Is it possible to define only a subset of an Ingress' rules in a file which would then get "appended" to the list of rules instead of overwriting them.
For example, could I have these two different definitions which creates a single Ingress with two rules (based on having the same name):
foo-ingress-rules.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
spec:
tls:
- hosts:
- foo.bar.com
secretName: tls-secret
rules:
- host: foo.bar.com
http:
paths:
- path: /
backend:
serviceName: foo-web-svc
servicePort: 80
- path: /api
backend:
serviceName: foo-rest-svc
servicePort: 80baz-ingress-rules.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
spec:
tls:
- hosts:
- baz.bar.com
secretName: tls-secret
rules:
- host: baz.bar.com
http:
paths:
- path: /
backend:
serviceName: baz-web-svc
servicePort: 80
- path: /api
backend:
serviceName: baz-rest-svc
servicePort: 80Solution
I was able to combine your two example files by first converting them to JSON.
foo.json
baz.json
You can then combine the rules for each by using jq.
While yaml is more common JSON is perfectly valid for the Kubernetes API. All credit for the jq logic goes to @Jeff Mercado and his answer.
foo.json
{
"apiVersion": "extensions/v1beta1",
"kind": "Ingress",
"metadata": {
"name": "nginx-ingress"
},
"spec": {
"tls": [
{
"hosts": [
"foo.bar.com"
],
"secretName": "tls-secret"
}
],
"rules": [
{
"host": "foo.bar.com",
"http": {
"paths": [
{
"path": "/",
"backend": {
"serviceName": "foo-web-svc",
"servicePort": 80
}
},
{
"path": "/api",
"backend": {
"serviceName": "foo-rest-svc",
"servicePort": 80
}
}
]
}
}
]
}
}baz.json
{
"apiVersion": "extensions/v1beta1",
"kind": "Ingress",
"metadata": {
"name": "nginx-ingress"
},
"spec": {
"tls": [
{
"hosts": [
"baz.bar.com"
],
"secretName": "tls-secret"
}
],
"rules": [
{
"host": "baz.bar.com",
"http": {
"paths": [
{
"path": "/",
"backend": {
"serviceName": "baz-web-svc",
"servicePort": 80
}
},
{
"path": "/api",
"backend": {
"serviceName": "baz-rest-svc",
"servicePort": 80
}
}
]
}
}
]
}
}You can then combine the rules for each by using jq.
levi@La-Tower:~$ jq 'reduce inputs as $i (.; .spec.rules += $i.spec.rules)' foo.json baz.json
{
"apiVersion": "extensions/v1beta1",
"kind": "Ingress",
"metadata": {
"name": "nginx-ingress"
},
"spec": {
"tls": [
{
"hosts": [
"foo.bar.com"
],
"secretName": "tls-secret"
}
],
"rules": [
{
"host": "foo.bar.com",
"http": {
"paths": [
{
"path": "/",
"backend": {
"serviceName": "foo-web-svc",
"servicePort": 80
}
},
{
"path": "/api",
"backend": {
"serviceName": "foo-rest-svc",
"servicePort": 80
}
}
]
}
},
{
"host": "baz.bar.com",
"http": {
"paths": [
{
"path": "/",
"backend": {
"serviceName": "baz-web-svc",
"servicePort": 80
}
},
{
"path": "/api",
"backend": {
"serviceName": "baz-rest-svc",
"servicePort": 80
}
}
]
}
}
]
}
}While yaml is more common JSON is perfectly valid for the Kubernetes API. All credit for the jq logic goes to @Jeff Mercado and his answer.
Code Snippets
{
"apiVersion": "extensions/v1beta1",
"kind": "Ingress",
"metadata": {
"name": "nginx-ingress"
},
"spec": {
"tls": [
{
"hosts": [
"foo.bar.com"
],
"secretName": "tls-secret"
}
],
"rules": [
{
"host": "foo.bar.com",
"http": {
"paths": [
{
"path": "/",
"backend": {
"serviceName": "foo-web-svc",
"servicePort": 80
}
},
{
"path": "/api",
"backend": {
"serviceName": "foo-rest-svc",
"servicePort": 80
}
}
]
}
}
]
}
}{
"apiVersion": "extensions/v1beta1",
"kind": "Ingress",
"metadata": {
"name": "nginx-ingress"
},
"spec": {
"tls": [
{
"hosts": [
"baz.bar.com"
],
"secretName": "tls-secret"
}
],
"rules": [
{
"host": "baz.bar.com",
"http": {
"paths": [
{
"path": "/",
"backend": {
"serviceName": "baz-web-svc",
"servicePort": 80
}
},
{
"path": "/api",
"backend": {
"serviceName": "baz-rest-svc",
"servicePort": 80
}
}
]
}
}
]
}
}levi@La-Tower:~$ jq 'reduce inputs as $i (.; .spec.rules += $i.spec.rules)' foo.json baz.json
{
"apiVersion": "extensions/v1beta1",
"kind": "Ingress",
"metadata": {
"name": "nginx-ingress"
},
"spec": {
"tls": [
{
"hosts": [
"foo.bar.com"
],
"secretName": "tls-secret"
}
],
"rules": [
{
"host": "foo.bar.com",
"http": {
"paths": [
{
"path": "/",
"backend": {
"serviceName": "foo-web-svc",
"servicePort": 80
}
},
{
"path": "/api",
"backend": {
"serviceName": "foo-rest-svc",
"servicePort": 80
}
}
]
}
},
{
"host": "baz.bar.com",
"http": {
"paths": [
{
"path": "/",
"backend": {
"serviceName": "baz-web-svc",
"servicePort": 80
}
},
{
"path": "/api",
"backend": {
"serviceName": "baz-rest-svc",
"servicePort": 80
}
}
]
}
}
]
}
}Context
StackExchange DevOps Q#3953, answer score: 2
Revisions (0)
No revisions yet.