-
Notifications
You must be signed in to change notification settings - Fork 40k
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
Strategy for pods sharing same host port ? #1799
Comments
Host port is more or less a hack. For real services at scale, you're going to want to run through load balancers, etc. Even for small scales, you'll most likely want some frontend nginx type thing to distribute requests. It's unlikely that you want to send raw requests right to your minions. We definitely need to make it easier to get data/requests into the system, like telling a DNS system where to find our services (in the works, I think?). |
Short answer: no. HTTP is but one protocol that is supported. Longer answer: we need a more formalized model about externalizing ports I know that is unsatisfying, but please know that we have some ideas, and I On Tue, Oct 14, 2014 at 8:24 PM, Daniel Smith notifications@github.com
|
#1161 discussion is pretty good. In my opinion I think providing support for both option 1 and 2 would be needed. For now we need to build something custom. |
No plugin system yet-- see #991. One thing you can do is query for service endpoints, either directly, or by visiting /api/v1beta1/redirect/services/, which will send back an HTTP redirection header. (You could just extract the destination if you don't have an HTTP service, of course.) |
Not sure if I am following, how is querying services going to work to allow for many pods to share same port on same public ip? |
The idea is that the service is the public IP; incoming requests are load-balanced across all pods in the service. Pods will never literally "share same port on same public IP". Are you talking about doing some analog of running a bunch of different websites on a box, and having nginx (or apache) dispatch stuff based on the requested URL? If that's what you want to do, you would accomplish that by running nginx in one pod and routing all requests to it, with it dispatching appropriately; if it sees a request for foo.com, it forwards on to kubernetes' foo-service, which is served by N foo-pods. If we make our services visible via DNS you should even be able to write a short rule. It's questionable that you should do it that way, though-- instead of configuring your traffic source to send to your nginx pod it might make sense to teach it about kubernetes services and just route stuff to the right place to begin with. Basically, the gateway to your system needs to be able to distribute requests. We need to make that easy information to get, because we're not supplying the gateway. |
Yes that's exactly what I was talking about, running bunch of different websites on same box. I totally understand that might not be standard use case for kubernetes. I understand that for large traffic cases this might not be optimal and you would want to have the forwarding and load balancing done outside of nodes on dedicated hardware, but there could be a lot of use cases for a lot of smaller traffic pod instances where it could be enough without more complex LB setups. Like in my case, each of the pod instances will receive very little traffic since it is only used for development and testing by developers. |
For small scales, you should be able to have an nginx thingy like this on a single machine (not necessarily a node). For large scales, you shouldn't do this. :) At any rate, I don't think you should do this setup on every node. |
I agree about the large scales. Either way I think a lot of kubernetes users are probably going to run into a problem where they want to host multiple pods occupying the same port, I think it would be useful it there was some kind of default solution provided by kubernetes. It would be no different then how current node/minion proxy works its just instead of routing and load balancing based on the port you would route based on the domain/hostname. |
I think what you're really asking for is HTTP routing. I think that's probably more complicated than we want to build into our proxy, but we would be happy to see proposals about standard ways to set it up. |
Well yeah it's both an http router and proxy since you need to get the requests inside private network. |
I was thinking about what it would take to introduce the new http router capability. Since I would not be sure that my changes would end up in the main kubernetes code base, I would want to architect it in certain way so that it minimizes the amount of work it would take me to keep it in-sync with the main kubernetes upstream repo. This is all very preliminary and I haven't spent much time really digging into the code to see if it's all possible. First thing that I started looking into is the Service definition part. So far I have thought of 3 options. OPTION 1: Expand existing "Service" definitionModify existing service definition {
"id": "wordpress1",
"kind": "Service",
"apiVersion": "v1beta1",
"port": 80,
"containerPort": 80,
"router": {
"host": "subdomain.domain.com",
"path": "/path/.*"
}
"selector": {
"name": "wordpress1"
}
} This option is probably easier to implement but would probably be harder to keep in sync with upstream repo. OPTION 2: Create new "Router" definitionThis would be a new type which would define the route (host, path) and point to the existing Service definition. Example : # route definition
{
"id" : "wordpress-route1"
"kind": "Route",
"host": "subdomain.domain.com",
"path": "/path/.*",
"selector": {
"name": "wordpress-service1"
}
}
# service definiton
{
"id": "wordpress-service1",
"kind": "Service",
"apiVersion": "v1beta1",
"port": 80,
"containerPort": 80,
"selector": {
"name": "wordpress-pod1"
}
} This option would probably require more work but I think it would keep it cleaner and more flexible OPTION 3: Plugin systemThis would introduce a plugin property for most of the existing types. Whenever kubernetes is reading or processing one of the definitions and encounters a plugin property it would instantiate the plugin and then just hand over the data to the plugin to handle it. There could also be different events issued based on when in the flow plugin is called. Example : # plugin definition for routes
{
"id" : "route-plugin-1"
"kind" : "Plugin",
"host": "subdomain.domain.com",
"path": "/path/.*",
"selector": {
"name": "wordpress-service1"
}
"someOtherFiled": "someValue"
}
# plugin definition for pods
{
"id" : "pod-plugin-1"
"kind" : "Plugin",
"customData": "someValue"
}
# service definiton
{
"id": "wordpress-service1",
"kind": "Service",
"apiVersion": "v1beta1",
"port": 80,
"containerPort": 80,
"plugin": "route-plugin-1"
"selector": {
"name": "wordpress-pod1"
}
}
# pod definiton
{
"id": "redis-master-2",
"kind": "Pod",
"apiVersion": "v1beta1",
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "wordpress-pod1",
"containers": [{
"name": "master",
"image": "dockerfile/wordpress",
"ports": [{
"containerPort": 80,
"hostPort": 80
}]
}]
}
},
"plugin": "pod-plugin-1"
"labels": {
"name": "wordpress-pod1"
}
} With either option I could expand the existing proxy capability or build a new reverse proxy that would handle the routing. Building a new separate one would probably make it easy to sync with main repo but it could take longer. I was also looking at http://www.vulcanproxy.com/library.html and it looks like a good library for it. |
IMO, this should be done by making a pod with nginx/apache in it and a forwarding configuration that can direct traffic to k8s services. |
Ok so option (4 would be nginx or vulcand way:
Only thing is you have two types of proxying going , one from nginx to k8s proxy and another from k8s proxy to the actual container. I don't know if this would impact responsiveness. |
That's not quite right.
|
For IP-per-service how do I enable that? do I not set host "port" in service definition or is there a special property? |
We're enabling IP-per-service as we speak. Head is borken right now, though, so I'd wait a bit before trying :) |
K thanks. Also on another note It would also be great if there was property in each one of the definitions which would allow to pass in arbitrary data that would be passed around along with pod or services thru k8s. it could be called "meta" or "data" like : {
"id": "wordpress-service1",
"kind": "Service",
"apiVersion": "v1beta1",
"port": 80,
"containerPort": 80,
"meta": "whatever text or serialized data we want in here"
"selector": {
"name": "wordpress-pod1"
}
} |
We are adding Annotations in v1beta3, which will do what you want. |
That's great :) |
For those who might have similar needs as I do, I've created a docker container that acts as a reverse proxy for kubernetes pods, allowing multiple pods to share same public ip. It's using nginx and confd to to read the k8s etcd specs and configure the nginx routing to the k8s service ip. All you have to do is install the Container and add annotations to your k8s service. It's not a perfect solution and it's still in its early stages but it gives basic capability to host multiple pod ports on same node. To find out more on how to use this reverse proxy you can check out the main github repo page : And get the docker image at: To quickly run the proxy do: docker run -d -e CONFD_ETCD_NODE=<ETCD-IP>:<ETCD-PORT> -t -p 80:80 darkgaro/kubernetes-reverseproxy ##ETCD-IP## and ##ETCD-PORT## is one where kubernetes is installed and using. You will also need to add following annotations to your k8s service definitions "annotations":{
"kubernetesReverseproxyHost":"some.host.name",
"kubernetesReverseproxyPort":"port number"
} |
This has lost the meaning of the original bug - if there is work to do here, please reopen and retitle this or open a new issue. |
The solution nowadays seems to be the Ingress resource |
CNF-8809: admission: add new admission for handling shared cpus request
I don't know if kubernetes is currently supporting or has plans to provide a capability for two or more pods to be sharing the same port on the node with same public ip address. Same way like nginx and apache can host multiple websites on the same ip by named based virtual hosting.
Lets say I have 2 pods and each pod hosts a wordpress app on port 80. It could be expensive to provide a public ip for each pod, plus I don't know if kubernetes even supports multiple public ips.
I was wondering what are options for accomplishing something like that with kubernetes.
One way I was thinking is by running an Nginx or other proxy service one each node, which would proxy requests based on the domain name to internal pod IPs.
Maybe kubernetes could expand it's current proxy system to offer this capability as well ?
Are there any other ways as well ?
The text was updated successfully, but these errors were encountered: