Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to TCP Proxy? #3247

Closed
chriscardillo opened this issue Jan 12, 2021 · 8 comments
Closed

How to TCP Proxy? #3247

chriscardillo opened this issue Jan 12, 2021 · 8 comments

Comments

@chriscardillo
Copy link

Hello and thanks for making this awesome product!

I have been learning k8s locally using kind, and I would like to be able to access a service from localhost:5678. I have tried looking over some tutorials and the docs, but I cannot figure out how to do it.

I have a basic HTTPProxy working with the virtual host local.projectcontour.io, but I am unsure how to:

  1. Use localhost instead of local.projectcontour.io
  2. Use tcproxy instead of routes to get the proxy listening on :5678

I am also having trouble understanding what my virtualhost would have to become if I were to move to a service like AWS EKS?

Thanks in advance for your help here, please see my manifest below:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
  labels:
    app: app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      containers:
      - name: app
        image: hashicorp/http-echo:0.2.3
        args:
        - "-text=heyguys"
        livenessProbe:
          httpGet:
            path: /
            port: 5678
          initialDelaySeconds: 5
          timeoutSeconds: 1
          periodSeconds: 10
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /
            port: 5678
          initialDelaySeconds: 30
          timeoutSeconds: 1
          periodSeconds: 10
          failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
  name: app
  labels:
    app: app
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 5678
  selector:
    app: app
  type: ClusterIP
---
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
  name: root
spec:
  virtualhost:
    fqdn: local.projectcontour.io
  routes:
  - services:
    - name: app
      port: 80
    conditions:
      - prefix: /
---

I was trying something along the lines of:

apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
  name: tcpprox
spec:
  virtualhost:
    fqdn: local.projectcontour.io
  tcpproxy:
    services:
      - name: app
        port: 5678

but no luck.

Thanks again!

@youngnick
Copy link
Member

youngnick commented Jan 12, 2021

Thanks for checking Contour out @chriscardillo, and thanks for the issue.

So, local.projectcontour.io is just a convenience DNS record that just resolves to 127.0.0.1 - that is, the same address as localhost. So you can use those two names totally interchangeably.

Your config looks good, for exposing your app that's running on 5678 on the HTTP port 80, that's in your Service definition, the targetPort being diferent to the port is essentially saying "please translate port 80 to port 5678 on the pods that make up this Service". So the TCPProxy can't work like you expect, I think.

What are you looking to do with TCPProxy? Note that we named that wrong when we built it, really it should be called TLSProxy, as its main use is for forwarding sessions to services that need to terminate their own TLS.

@chriscardillo
Copy link
Author

chriscardillo commented Jan 12, 2021

My overall goal is to have control over http/https ingress, as well as the ability to expose additional port services. So in sticking with the example above, I want to be able to:

  • Expose the app service at localhost/ (currently achieved, though I can only get it working with 127.0.0.1/, not localhost/)
  • Expose the app service at localhost:5678 (or 127.0.0.1:5678)

Over time, the goal would be that the app service would be exposed via ingress at 127.0.0.1/app and a db service would be available at a port, e.g. 127.0.0.1:5432.

Also in general trying to understand when to use Kubernetes' networking.k8s.io/v1 Ingress vs Contour's projectcontour.io/v1 HTTPProxy.

I also realized it may be beneficial if I shared my kind config with you, as well!

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  kubeadmConfigPatches:
    - |
      kind: InitConfiguration
      nodeRegistration:
        kubeletExtraArgs:
          node-labels: "ingress-ready=true"
  extraPortMappings:
  - containerPort: 80
    hostPort: 80
    protocol: TCP
  - containerPort: 443
    hostPort: 443
    protocol: TCP
  - containerPort: 5678
    hostPort: 5678
    protocol: TCP
- role: worker

And I stand this up with Contour using the following commands:

kind create cluster --config=kind_config.yml
kubectl apply -f https://projectcontour.io/quickstart/contour.yaml
kubectl patch daemonsets -n projectcontour envoy -p '{"spec":{"template":{"spec":{"nodeSelector":{"ingress-ready":"true"},"tolerations":[{"key":"node-role.kubernetes.io/master","operator":"Equal","effect":"NoSchedule"}]}}}}'

Thanks again! I realize this is maybe a broader help-desk type question, so I appreciate you taking the time out to help.

@youngnick
Copy link
Member

Sorry about the delay in getting back to you @chriscardillo!

Right now, Contour only allows you to specify two listening ports, one for HTTP traffic and one for TLS traffic (either terminated HTTPS traffic, or TLS passthrough). We have #3263 open with a design to change that.

In terms of Ingress vs HTTPProxy, the former is the more generic object, that has annotation-only support for many more advanced features. HTTPProxy is Contour's custom object, that we are actively developing and adding extra features (like external auth and rate limiting) to.

As a small aside, I know you're doing this for Kind, but I really wouldn't recommend exposing a database via an ingress more generally!

@chriscardillo
Copy link
Author

I appreciate the advice! For context, all of my inf would be housed behind a VPN, which may explain my willingness to expose the db :)

I suppose I can just use nodeports and/or port forwarding to accomplish my goal if need be. Thanks again for your help here.

P.S. Having a lot of success with HTTPProxy with the more intended use cases for ingress. Thank you for the project!

@stevesloka
Copy link
Member

@chriscardillo quick question, can you expose your db over :443? If so you just need a 2nd domain name (e.g. db.localhost) for your TCPProxy config which would point to your DB, then have app.localhost point to your apps.

The example DNS names can be anything as long as they point to 127.0.0.1 (like local.projectcontour.io) does. This may not be doable, but thought I'd throw this out in case it works for you.

@chriscardillo
Copy link
Author

Thank you, @stevesloka - I will definitely keep this in mind!

@vamsiikrishna
Copy link

Right now, Contour only allows you to specify two listening ports, one for HTTP traffic and one for TLS traffic (either terminated HTTPS traffic, or TLS passthrough). We have #3263 open with a design to change that.

is it possible to configure these ports ?

@tsaarni
Copy link
Member

tsaarni commented May 9, 2023

is it possible to configure these ports ?

Yes, see contour serve command line parameters --envoy-service-http-port and --envoy-service-https-port https://projectcontour.io/docs/1.24/configuration/#serve-flags. Note that these are the ports that Envoy will bind HTTP and HTTPS listeners, and the ports might be mapped to something else when Envoy is exposed externally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants