Kubernetes services with spec type ClusterIP and spec type Nodeport

3/9/2021

I m trying to create a service where there is a connection between the pods via a service with the spec type: ClusterIPand now I want to expose this application to my browser with the spec type: NodePort However I m not able to add the type NodePort to the existing service.yaml. How do I specify the second specs in the same service for the same application?

app1-->connects to app2(db via ClusterIP: port 1521) app1-->expose to ingress to access it from my browser

apiVersion: v1
kind: Service
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"partner-service","namespace":"default"},"spec":{"ports":[{"port":1521,"protocol":"TCP","targetPort":1521}]}}
  creationTimestamp: "2021-03-08T14:32:02Z"
  labels:
    app: partner-db
  name: partner-service
  namespace: default
  resourceVersion: "12574"
  uid: b5106bef-a292-4a16-aafc-9676a81cd763
spec:
  clusterIP: 10.96.122.33
  clusterIPs:
  - 10.96.122.33
  ports:
  - port: 1521
    protocol: TCP
    targetPort: 1521
  selector:
    app: partner-db
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

This throws error that ClusterIp is required. Is it possible to have 2 types of connections in the same service?

I also tried k expose deployment partner-as --type=NodePort --ports=8080 but with the error service already exists

This runs on a vagrant VM where minikube is installed

As per the comment added a second service.

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2021-03-09T09:28:00Z"
  labels:
    app: partner-as
  name: service-as
  namespace: default
  resourceVersion: "16889"
  uid: bed7ab44-c350-45e6-87c4-8aac037740c3
spec:
  clusterIP: 10.104.102.177
  clusterIPs:
  - 10.104.102.177
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 30029
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: partner-as
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

and my ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-as
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - host: partner.info
      http:
        paths:
          - path: /partner
            pathType: Prefix
            backend:
              service:
                name: service-as
                port:
                  number: 8080

Added partner.info in my etc hosts in the vagrant vm.

Still the IP is not accessible from ym local machine.(so no access from brwoser)

Describe my service-as

Name:                     service-as
Namespace:                default
Labels:                   app=partner-as
Annotations:              <none>
Selector:                 app=partner-as
Type:                     NodePort
IP Families:              <none>
IP:                       10.104.102.177
IPs:                      10.104.102.177
Port:                     <unset>  8080/TCP
TargetPort:               8080/TCP
NodePort:                 <unset>  30029/TCP
Endpoints:                172.17.0.5:8080
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>
-- Vini
kubernetes
minikube

2 Answers

3/9/2021

You can create two services with a different name but just keep the same selector

To a single service, you can not apply multiple types. ClusterIP or NodePort you can only use one

in a single file what you can do is like

service.yaml

apiVersion: v1
kind: Service
metadata:
  labels:
    app: partner-db
  name: partner-service
  namespace: default
spec:
  ports:
  - port: 1521
    protocol: TCP
    targetPort: 1521
  selector:
    app: partner-db
  sessionAffinity: None
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: partner-db
  name: partner-service-node-port
  namespace: default
spec:
  ports:
  - port: 1521
    protocol: TCP
    targetPort: 1521
  selector:
    app: partner-db
  type: NodePort

For internal use you can use cluster IP but if you are looking forward to use or expose the service using Domain i would suggest you to use ingress.

For this

app1-->connects to app2(db via ClusterIP: port 1521) app1-->expose to ingress to access it from my browser

If you are using the ingress you can use both service type as ClusterIP as you want to access your app1 over browser.

-- Harsh Manvar
Source: StackOverflow

3/9/2021

You can't define a service with type both ClusterIP and NodePort.

You need to delete the old service of type ClusterIP and create a new one of type NodePort.

Remember to keep the selector labels in the Service spec so that the new service correctly routes the traffic to the right set of pods.

-- Krishna Chaurasia
Source: StackOverflow