I've set up the following Ingress and deployment for Traefik on Kubernetes. I keep getting a bad gateway error on the actual domain name.
For some reason the service isn't working or I have got the connections wrong or something is amiss with the selectors etc.
apiVersion: v1
kind: Service
metadata:
name: web
labels:
app: wordpress
spec:
selector:
k8s-app: traefik-ingress-lb
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
selector:
app: wordpress
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-ingress
annotations:
kubernetes.io/ingress.class: traefik
# traefik.ingress.kubernetes.io/frontend-entry-points: http,https
spec:
rules:
- host: test.example.services
http:
paths:
- path: /
backend:
serviceName: web
servicePort: http
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:4.8-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: wordpress-mysql
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wp-pv-claim
My code is below so if there are any corrections to be made, advice is appreciated.
There are few things to consider:
I see that you are missing the namsespace: in your metadata:. Check if that is the case.
Try to create two services. One for wordpress and one for treafik-ingress-lb.
You might have used too many spaces after ports:. Try something like this:
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
Check if your labels are correctly configured. If you need more detials regarding them, try this documentation.
Please let me know if that helped.
Related
I have a kubernetes cluster with a deployment of rabbitmq. I want to expose the rabbitmanagment UI in that way I can access to it in my browser. To do that I have a deployment, service and ingress file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: rabbitmq
spec:
replicas: 1
selector:
matchLabels:
app: rabbitmq
template:
metadata:
labels:
app: rabbitmq
spec:
containers:
- image: rabbitmq:3.8.9-management
name: rabbitmq
ports:
- containerPort: 5672
- containerPort: 15672
resources: {}
restartPolicy: Always
The service:
apiVersion: v1
kind: Service
metadata:
name: rabbitmq
spec:
ports:
- name: "5672"
port: 5672
targetPort: 5672
- name: "15672"
port: 15672
targetPort: 15672
selector:
app: rabbitmq
Ingress file
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
spec:
rules:
- http:
paths:
- path: /rabbitmq
pathType: Prefix
backend:
service:
name: rabbitmq
port:
number: 15672
When I type http://localhost/rabbitmq in my browser I get this nginx error: {"error":"Object Not Found","reason":"Not Found"}
But when I enter in some other pod and I type: curl http://rabbitmq:15672 It get the a response of the website.
Im new to kubernetes, I havent found any relevant solution to my problem, If someone could help me I would very grateful!!
Thanks for reading.
Try:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx # <-- assumed you only have 1 ingress-nginx
rules:
- http:
paths:
- path: /rabbitmq(/|$)(.*)
...
Request to http://localhost/rabbitmq will be seen by your rabbitmq service as /
inside my ingress config i changed default backend.
spec:
defaultBackend:
service:
name: navigation-service
port:
number: 80
When I describe ingress i have got
Name: ingress-nginx
Namespace: default
Address: 127.0.0.1
Default backend: navigation-service:80 (10.1.173.59:80)
I trying to access it via localhost and i have got 404. However when i curl 10.1.173.59, i have got my static page. So my navigation-service its ok and something is wrong with defaultbacked? Even if i trying
- pathType: Prefix
path: /
backend:
service:
name: navigation-service
port:
number: 80
I have got 500 error.
What im doing wrong?
Edit: Works via NodePort but I need to access it via ingress.
apiVersion: apps/v1
kind: Deployment
metadata:
name: navigation-deployment
spec:
selector:
matchLabels:
app: navigation-deployment
template:
metadata:
labels:
app: navigation-deployment
spec:
containers:
- name: nginx
image: nginx:1.13.3-alpine
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html/index.html
name: nginx-html
- mountPath: /etc/nginx/conf.d/default.conf
name: nginx-default
volumes:
- name: nginx-html
hostPath:
path: /home/x/navigation/index.html
- name: nginx-default
hostPath:
path: /home/x/navigation/default.conf
apiVersion: v1
kind: Service
metadata:
name: navigation-service
spec:
type: ClusterIP
selector:
app: navigation-deployment
ports:
- name: "http"
port: 80
targetPort: 80
If someone have this problem then you need to run ingress controller with args - --default-backend-service=namespace/service_name
I am trying to expose some custom metrics of a kubernetes application at prometheus.
I successfully deploy deploy my app at kubernetes. The ServiceMonitor is also added but no targets are discovered (0/0 up) .
The application is an nginx server with the relevant nginx-prometheus-exporter sidecar.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-example-v3
labels:
app: nginx-example-v3
spec:
selector:
matchLabels:
app: nginx-example-v3
template:
metadata:
labels:
app: nginx-example-v3
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "128Mi"
cpu: "100m"
ports:
- name: http
containerPort: 8080
volumeMounts:
- name: "config"
mountPath: "/etc/nginx/nginx.conf"
subPath: "nginx.conf"
- name: exporter
image: nginx/nginx-prometheus-exporter:0.8.0
ports:
- containerPort: 9113
volumes:
- name: "config"
configMap:
name: "nginx-example-v2-config"
---
apiVersion: v1
kind: Service
metadata:
labels:
name: nginx-example-v3
name: nginx-example-v3
spec:
type: LoadBalancer
selector:
app: nginx-example-v3
ports:
- name: http
port: 8080
targetPort: 8080
- name: http-exporter
port: 9113
targetPort: 9113
After that i can see the nginx custom metrics exposed at the /metrics API:
Then i apply the monitoring service:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: nginx-example-v3
spec:
endpoints:
- bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
interval: 15s
port: web
selector:
matchLabels:
app: nginx-example-v3
i can see that the service is successfully added at prometheus "Service Discovery" section:
BUT no targets are discovered (0/0 up) on behalf of prometheus
What i am missing???
Any help is really apreciated since i have been stuck on this many days!
Thank you very much in advance. :-)
Replies
#efotopoulou
I slightly changed the service manifest and i am able to get the metrics now.
sorry for the new discussion. i hope my manifests help other persons to configure their services.
This is the updated manifest.
:-)
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-example-v3
name: nginx-example-v3
spec:
type: LoadBalancer
selector:
app: nginx-example-v3
ports:
- name: http
port: 8080
targetPort: 8080
- name: web
port: 9113
targetPort: 9113
I'm a newbie in kubernetes and Traefik.
I follow up that tutorial:
https://docs.traefik.io/user-guides/crd-acme/
And I changed it to use my Service in Scala, that it is under https and 9463 port.
I'm trying to deploy my Scala service with kubernetes and traefik.
When I forward directly to the service :
kubectl port-forward service/core-service 8001:9463
And I perform a curl -k 'https://localhost:8001/health' :
I get the "{Message:Ok}"
But when I perform a port forward to traefik
kubectl port-forward service/traefik 9463:9463 -n default
And perform a curl -k 'https://ejemplo.com:9463/tls/health'
I get an "Internal server error"
I guess the problem is that my "core-service" is listening over HTTPS protocol, that's what I add scheme:https.
I tried to find the solution over the documentation but it is confusing.
Those are my yml files:
Services.yaml
apiVersion: v1
kind: Service
metadata:
name: traefik
spec:
ports:
- protocol: TCP
name: admin
port: 8080
- protocol: TCP
name: websecure
port: 9463
selector:
app: traefik
---
apiVersion: v1
kind: Service
metadata:
name: core-service
spec:
ports:
- protocol: TCP
name: websecure
port: 9463
selector:
app: core-service
Deployment.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: default
name: traefik-ingress-controller
---
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: default
name: traefik
labels:
app: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
containers:
- name: traefik
image: traefik:v2.0
args:
- --api.insecure
- --accesslog
- --entrypoints.websecure.Address=:9463
- --providers.kubernetescrd
- --certificatesresolvers.default.acme.tlschallenge
- --certificatesresolvers.default.acme.email=foo#you.com
- --certificatesresolvers.default.acme.storage=acme.json
# Please note that this is the staging Let's Encrypt server.
# Once you get things working, you should remove that whole line altogether.
- --certificatesresolvers.default.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
ports:
- name: websecure
containerPort: 9463
- name: admin
containerPort: 8080
---
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: default
name: core-service
labels:
app: core-service
spec:
replicas: 1
selector:
matchLabels:
app: core-service
template:
metadata:
labels:
app: core-service
spec:
containers:
- name: core-service
image: core-service:0.1.4-SNAPSHOT
ports:
- name: websecure
containerPort: 9463
livenessProbe:
httpGet:
port: 9463
scheme: HTTPS
path: /health
initialDelaySeconds: 10
IngressRoute2.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutetls
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`ejemplo.com`) && PathPrefix(`/tls`)
kind: Rule
services:
- name: core-service
port: 9463
scheme: https
tls:
certResolver: default
From the docs
A TLS router will terminate the TLS connection by default. However,
the passthrough option can be specified to set whether the requests
should be forwarded "as is", keeping all data encrypted.
In your case SSL Passthrough need to be enabled because the pod is expecting HTTPS traffic.
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutetls
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`ejemplo.com`) && PathPrefix(`/tls`)
kind: Rule
services:
- name: core-service
port: 9463
scheme: https
tls:
certResolver: default
passthrough: true
When I test my Spring boot app without docker, I test it with:
https://localhost:8081/points/12345/search
And it works great. I get an error if I use http
Now, I want to deploy it with Kubernetes in local, with url: https://sge-api.local
When I use http, I get the same error as when I don't use docker.
But when I use https, I get:
<html><body><h1>404 Not Found</h1></body></html>
Here is my deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: sge-api-local
name: sge-api-local
namespace: sge
spec:
selector:
matchLabels:
app: sge-api-local
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: sge-api-local
spec:
containers:
- image: sge_api:local
name: sge-api-local
Here is my ingress:
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: sge-ingress
namespace: sge
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: sge-api.local
http:
paths:
- backend:
serviceName: sge-api-local
servicePort: 8081
tls:
- secretName: sge-api-tls-cert
with :
kubectl -n kube-system create secret tls sge-api-tls-cert --key=../certs/privkey.pem --cert=../certs/cert1.pem
Finally, here is my service:
apiVersion: v1
kind: Service
metadata:
labels:
app: sge-api-local
name: sge-api-local
namespace: sge
spec:
ports:
- name: "8081"
port: 8081
selector:
app: sge-api-local
What should I do ?
EDIT:
traefik-config.yml:
kind: ConfigMap
apiVersion: v1
metadata:
name: traefik-config
data:
traefik.toml: |
# traefik.toml
defaultEntryPoints = ["http","https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
traefik-deployment:
kind: DaemonSet
apiVersion: apps/v1
metadata:
name: traefik-ingress-controller
labels:
k8s-app: traefik-ingress-lb
spec:
selector:
matchLabels:
k8s-app: traefik-ingress-lb
template:
metadata:
labels:
k8s-app: traefik-ingress-lb
name: traefik-ingress-lb
spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 60
containers:
- image: traefik:1.7
name: traefik-ingress-lb
ports:
- name: http
containerPort: 80
hostPort: 80
- name: https
containerPort: 443
hostPort: 443
- name: admin
containerPort: 8080
hostPort: 8080
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
args:
- --api
- --kubernetes
- --logLevel=INFO
traefik-service.yml
kind: Service
apiVersion: v1
metadata:
name: traefik-ingress-service
spec:
selector:
k8s-app: traefik-ingress-lb
ports:
- protocol: TCP
port: 80
name: web
- protocol: TCP
port: 8080
name: admin
Please make sure that you have enable TLS. Let’s Encrypt is a free TLS Certificate Authority (CA) and you can use it to automatically request and renew Let’s Encrypt certificates for public domain names. Make sure that you have created configmap. Check if you follow every steps during traefik setup: traefik-ingress-controller.
Then you have to assign to which hosts creted secret have to be assigned, egg.
tls:
- secretName: sge-api-tls-cert
hosts:
- sge-api.local
Remember to add specific port assigned to host while executing link.
In your case should be: https://sge-api.local:8081
When using SSL offloading outside of cluster it may be useful to enforce a redirect to HTTPS even when there is no TLS certificate available.
You could also add annotations to ingress configuration file:
traefik.ingress.kubernetes.io/frontend-entry-points: http, https
traefik.ingress.kubernetes.io/redirect-entry-point: https
to enable Redirect to another entryPoint for that frontend (e.g. HTTPS).
Let me know if it helps.