Specify NodePort

If you are using a NodePort or LoadBalancer type Ingress, a NodePort or LoadBalancer type Service is used to expose HAProxy pods respectively. If no node port is specified for each HAProxy Service port, Kubernetes will randomly assign one for you.

Since 3.2.0, you have the option to specify a NodePort for each HAProxy Service port. This allows you to guarantee that the port will not get changed, as you make changes to an Ingress object. If you specify nothing, Kubernetes will auto assign as before.

Below is an example Ingress that demonstrates this feature:

apiVersion: voyager.appscode.com/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  namespace: default
  annotations:
    ingress.appscode.com/type: NodePort
spec:
  rules:
  - host: one.example.com
    http:
      port: '8989'
      nodePort: '32666'
      paths:
      - path: /t1
        backend:
          serviceName: test-service
          servicePort: '80'
      - path: /t2
        backend:
          serviceName: test-service
          servicePort: '80'
  - host: other.example.com
    http:
      port: '8989'
      nodePort: '32666'
      paths:
      - backend:
          serviceName: test-service
          servicePort: '80'
  - host: appscode.example.com
    tcp:
      port: '4343'
      nodePort: '32667'
      backend:
        serviceName: test-service
        servicePort: '80'

Since ingress.appscode.com/type: NodePort annotation is used, this Ingress is going to expose HAProxy pods via a NodePort Service. This service will listen to 8989 and 4343 port for incoming HTTP connections and these port will map to specified node ports, and will pass any request coming to it to the desired backend.

$ kubectl get svc voyager-test-ingress -o yaml

apiVersion: v1
kind: Service
metadata:
  annotations:
    ingress.appscode.com/origin-api-schema: voyager.appscode.com/v1beta1
    ingress.appscode.com/origin-name: test-ingress
  creationTimestamp: 2017-09-07T12:01:35Z
  name: voyager-test-ingress
  namespace: default
  resourceVersion: "1161"
  selfLink: /api/v1/namespaces/default/services/voyager-test-ingress
  uid: 4baf3dbf-93c4-11e7-bf12-080027a9d54f
spec:
  clusterIP: 10.0.0.41
  externalTrafficPolicy: Cluster
  ports:
  - name: tcp-8989
    nodePort: 32666
    port: 8989
    protocol: TCP
    targetPort: 8989
  - name: tcp-4343
    nodePort: 32667
    port: 4343
    protocol: TCP
    targetPort: 4343
  selector:
    origin: voyager
    origin-api-group: voyager.appscode.com
    origin-api-version: v1beta1
    origin-name: test-ingress
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

Now, if you check the HAProxy configuration generated by Voyager, you should see something like below:

# check the haproxy.cfg key in `data`
$ kubectl get configmap voyager-test-ingress -o yaml

# Generated HAProxy config snippet
frontend http-8989
	bind *:8989
	mode http
	option httplog
	option forwardfor

	acl host_acl_test-server.default:80-t3bu6y hdr(host) -i one.example.com:32666
	acl url_acl_test-server.default:80-t3bu6y path_beg /t1
	use_backend test-server.default:80-t3bu6y if host_acl_test-server.default:80-t3bu6y url_acl_test-server.default:80-t3bu6y

	acl host_acl_test-server.default:80-s46phe hdr(host) -i one.example.com:32666
	acl url_acl_test-server.default:80-s46phe path_beg /t2
	use_backend test-server.default:80-s46phe if host_acl_test-server.default:80-s46phe url_acl_test-server.default:80-s46phe

	acl host_acl_test-server.default:80-iv3d2y hdr(host) -i other.example.com:32666

	use_backend test-server.default:80-iv3d2y if host_acl_test-server.default:80-iv3d2y


backend test-server.default:80-t3bu6y
	server pod-172.17.0.5 172.17.0.5:8080

backend test-server.default:80-s46phe
	server pod-172.17.0.5 172.17.0.5:8080

backend test-server.default:80-iv3d2y
	server pod-172.17.0.5 172.17.0.5:8080

frontend tcp-4343
	bind *:4343
	mode tcp
	default_backend test-server.default:80-kfk4b2

backend test-server.default:80-kfk4b2
	mode tcp
	server pod-172.17.0.5 172.17.0.5:8080

Port 8989 has 2 separate hosts one.example.com and other.example.com . one.example.com has 2 paths /t1 and /t2. Since they all are exposed via the same HTTP port, they must use the same NodePort.

Take your team where it needs to go.

Create your cluster in minutes. Our team is here to help and would be happy to chat with you.