How can I communicate with gRPC on ingress nginx controller?
My Ingress service code is below.
It was made by referring to a famous example
LoadBalancer changed 443 port and changed certificate.
However, the LB address of Ingress and Service Loadbalancer is different.
Service
apiVersion: v1
kind: Service
metadata:
name: test-grpc-service
labels:
test: grpc
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-internal: "false"
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "aarn:aws:acm:xxxxxx"
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "tcp"
spec:
type: LoadBalancer
selector:
test: grpc
ports:
- port: 8888
targetPort: 8888
name: grpc
Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-grpc-ingress
labels:
test: grpc
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: GRPC
nginx.ingress.kubernetes.io/ssl-redirect: 'false'
spec:
tls:
- hosts:
- test.test.com
secretName: test-secret
rules:
- host: test.test.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-grpc-service
port:
number: 8888
Related
I've tried everything on stack overflow and beyond and can't find a solution that works to redirect http to https. My current config is below.
My ingress is:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
annotations:
kubernetes.io/ingress.class: "nginx"
kubernetes.io/ingress.global-static-ip-name: my-address
networking.gke.io/managed-certificates: my-certificate
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
spec:
rules:
- host: mydomain.com
http:
paths:
- path: /*
pathType: ImplementationSpecific
backend:
service:
name: my-service
port:
number: 2400
And my service is:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app: nodeweb
ports:
- name: my-service-port
protocol: TCP
port: 2400
targetPort: 2400
For GKE (1.17.13-gke.2600+), find this document explaining how to configure FrontendConfig with http-to-https redirect. Then you associate the FrontendConfig with your Ingress using networking.gke.io/v1beta1.FrontendConfig annotation.
I have a local website.
The website was created by a docker-compose and it is listening on a localhost port 3000.
When I try:
curl 127.0.0.1:3000
I can see the response.
What I did:
From my domain provider I edited the DNS to point to my server, then I changed nginx-ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: virtual-host-ingress
namespace: ingress-basic
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/use-regex: "true"
cert-manager.io/cluster-issuer: "letsencrypt-pp"
spec:
tls:
- hosts:
- nextformulainvesting.com
secretName: ***
rules:
- host: "nextformulainvesting.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: e-frontend-saleor
port:
number: 80
and I created the service:
apiVersion: v1
kind: Service
metadata:
name: e-frontend-saleor
spec:
ports:
- protocol: TCP
port: 80
targetPort: 3000
But with the service or without the service I receive the error 503 Service Temporarily Unavailable.
How can I use nginx-ingress to point to my local TCP service?
To clarify the issue I am posting a community wiki answer.
The answer that helped to resolve this issue is available at this link. Based on that - the clue of the case is to create manually a Service and an Endpoint objects for external server.
After that one can create an Ingress object that will point to Service external-ip with adequate port .
Here are the examples of objects provided in similar question.
Service and an Endpoint objects:
apiVersion: v1
kind: Service
metadata:
name: external-ip
spec:
ports:
- name: app
port: 80
protocol: TCP
targetPort: 5678
clusterIP: None
type: ClusterIP
---
apiVersion: v1
kind: Endpoints
metadata:
name: external-ip
subsets:
- addresses:
- ip: 10.0.40.1
ports:
- name: app
port: 5678
protocol: TCP
Ingress object:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: external-service
spec:
rules:
- host: service.example.com
http:
paths:
- backend:
serviceName: external-ip
servicePort: 80
path: /
See also this reference.
Your service that you have created is for forwarding the traffic to deployments
As your service is running out side of Kubernetes cluster you should be using the Endpoint in this case
apiVersion: v1
kind: Endpoints
metadata:
name: my-service
subsets:
- addresses:
- IP: <External IP>
ports:
- port: 3000
and you can use this Endpoint to ingress so that it will route the traffic.
Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: virtual-host-ingress
namespace: ingress-basic
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/use-regex: "true"
cert-manager.io/cluster-issuer: "letsencrypt-pp"
spec:
tls:
- hosts:
- nextformulainvesting.com
secretName: ***
rules:
- host: "nextformulainvesting.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: my-service
port:
number: 3000
I have 2 services, one serves up a rest API and the other serves up static content via nginx web server.
I can retrieve the static content from the pod running an nginx web server via the ingress controller using https provided that I don't use the following annotation within the ingress yaml
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
However, the backend API service no longer works. If I add that annotation back, the backend service URL https://fqdn/restservices/engine-rest/v1/api works but the front end https://fqdn/ web server throws a 502.
Ingress
Ingress
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: ingress
namespace: namespace-abc
annotations:
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
spec:
rules:
- http:
paths:
- path: /restservices/engine-rest/v1
backend:
serviceName: a
servicePort: 8080
- path: /
backend:
serviceName: b
servicePort: 8011
Service API
kind: Service
apiVersion: v1
metadata:
name: a
namespace: namespace-abc
labels:
app: a
version: 1
spec:
ports:
- name: https
protocol: TCP
port: 80
targetPort: 8080
nodePort: 31019
selector:
app: a
version: 1
clusterIP: <cluster ip>
type: LoadBalancer
sessionAffinity: ClientIP
externalTrafficPolicy: Cluster
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
Service UI
kind: Service
apiVersion: v1
metadata:
name: b
namespace: namespace-abc
labels:
app: b
version: 1
annotations:
spec:
ports:
- name: http
protocol: TCP
port: 8011
targetPort: 8011
nodePort: 32620
selector:
app: b
version: 1
clusterIP: <cluster ip>
type: LoadBalancer
sessionAffinity: None
externalTrafficPolicy: Cluster
If your problem is that adding nginx.ingress.kubernetes.io/backend-protocol: HTTPS makes service-A work but fails service-B, and removing it makes service-A fail but works for service-B, then the solution is to create two different Ingress objects so they can be annotated independently
---
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: ingress-a
namespace: namespace-abc
annotations:
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
spec:
rules:
- http:
paths:
- path: /restservices/engine-rest/v1
backend:
serviceName: a
servicePort: 8080
---
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: ingress-b
namespace: namespace-abc
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: b
servicePort: 8011
I am still struggling with kubernetes.
I have issue with preserving request IP address on service for logging purposes. Logging is done with GRPC server. This code is working outside kubernetes as intended.
Service is defined similar to this.
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
name: grpc-api
name: grpc-api
namespace: myns
spec:
ports:
- name: ext-5000
port: 5000
targetPort: 5000
- name: grpc-5050
port: 5050
targetPort: 5050
selector:
name: grpc-api
type: ClusterIP
Ingress is:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
certmanager.k8s.io/cluster-issuer: letsencrypt-myns
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/backend-protocol: GRPC
nginx.ingress.kubernetes.io/service-upstream: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
labels:
name: api-grpc
name: api-grpc
namespace: myns
spec:
rules:
- host: api.example.org
http:
paths:
- backend:
serviceName: grpc-api
servicePort: 5000
path: /
tls:
- hosts:
- api.example.org
secretName: grpc-api-ingress-cert
Documentation mentions externalTrafficPolicy: Local in service, where type is LoadBalancer. Would it be enough to add parameter above to ClusterIP type service or do I have to change it to something else?
Thank you in advance.
How does an ingress forward https traffic to port 443 of the service(eventually to 8443 on my container)? Do I have to make any changes to my ingress or is this done automatically.
On GCP, I have a layer 4 balancer -> nginx-ingress controller -> ingress
My ingress is:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-keycloak
annotations:
kubernetes.io/ingress.class: "nginx"
certmanager.k8s.io/issuer: "letsencrypt-prod"
certmanager.k8s.io/acme-challenge-type: http01
spec:
tls:
- hosts:
- mysite.com
secretName: staging-iam-tls
rules:
- host: mysite.com
http:
paths:
- path: /auth
backend:
serviceName: keycloak-http
servicePort: 80
I searched online but I don't see explicit examples of hitting 443. It's always 80(or 8080)
My service keycloak-http is(elided and my container is actually listening at 8443)
apiVersion: v1
kind: Service
metadata:
creationTimestamp: 2019-05-15T12:45:58Z
labels:
app: keycloak
chart: keycloak-4.12.0
heritage: Tiller
release: keycloak
name: keycloak-http
namespace: default
..
spec:
clusterIP: ..
externalTrafficPolicy: Cluster
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: 8443
selector:
app: keycloak
release: keycloak
sessionAffinity: None
type: NodePort
status:
loadBalancer: {}
Try this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-keycloak
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
certmanager.k8s.io/issuer: "letsencrypt-prod"
certmanager.k8s.io/acme-challenge-type: http01
spec:
tls:
- hosts:
- mysite.com
secretName: staging-iam-tls
rules:
- host: mysite.com
http:
paths:
- path: /auth
backend:
serviceName: keycloak-http
servicePort: 443