Cluster Kubernetes - Deploy httpd and access from external

3/24/2021

I created my Kubernetes cluster and I try to deploy this yaml file:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd-deployment
spec:
  selector:
    matchLabels:
      app: httpd
  replicas: 1
  template:
    metadata:
      labels:
        app: httpd
    spec:
      containers:
      - name: httpd
        image: httpd
        ports:
        - containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
  name: httpd-service
spec:
  selector:
    app: httpd-app
  ports:  
    - protocol: TCP
      port: 8080
      targetPort: 80
      nodePort: 30020
      name: httpd-port
  type: NodePort

This is the configuration:

[root@BCA-TST-K8S01 httpd-deploy]# kubectl get all -o wide
NAME                                    READY   STATUS    RESTARTS   AGE     IP          NODE               NOMINATED NODE   READINESS GATES
pod/httpd-deployment-57fc687dcc-rggx9   1/1     Running   0          8m51s   10.44.0.1   bcc-tst-docker02   <none>           <none>

NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE     SELECTOR
service/httpd-service   NodePort    10.102.138.175   <none>        8080:30020/TCP   8m51s   app=httpd-app
service/kubernetes      ClusterIP   10.96.0.1        <none>        443/TCP          134m    <none>

NAME                               READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES   SELECTOR
deployment.apps/httpd-deployment   1/1     1            1           8m51s   httpd        httpd    app=httpd

NAME                                          DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES   SELECTOR
replicaset.apps/httpd-deployment-57fc687dcc   1         1         1       8m51s   httpd        httpd    app=httpd,pod-template-hash=57fc687dcc

But I can't connect to the worker or from the cluster IP:

curl http://bcc-tst-docker02:30020
curl: (7) Failed to connect to bcc-tst-docker02 port 30020: Connection refused

How can I fix the problem? How can expose the cluster using the internal Matser IP (for example I need to access to the httpd-deploy from the master IP 10.100.170.150 open a browser in the same network)

UPDATE:

I modified my yaml file as below:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd-deployment
spec:
  selector:
    matchLabels:
      app: httpd-app
  replicas: 2
  template:
    metadata:
      labels:
        app: httpd-app
    spec:
      containers:
      - name: httpd
        image: httpd
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: http-service
spec:
  externalIPs:
  - 10.100.170.150               **--> IP K8S**
  externalTrafficPolicy: Cluster
  ports:
  - name: httpd-port
    protocol: TCP
    port: 8080
    targetPort: 80
    nodePort: 30020
  selector:
    app: httpd-app
  sessionAffinity: None
  type: LoadBalancer

And these are the result after I run apply command:

[root@K8S01 LoadBalancer]# kubectl get all -o wide
NAME                                    READY   STATUS    RESTARTS   AGE   IP          NODE               NOMINATED NODE   READINESS GATES
pod/httpd-deployment-65d64d47c5-72xp4   1/1     Running   0          60s   10.44.0.2   bcc-tst-docker02   <none>           <none>
pod/httpd-deployment-65d64d47c5-fc645   1/1     Running   0          60s   10.36.0.1   bca-tst-docker01   <none>           <none>

NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE   SELECTOR
service/http-service   LoadBalancer   10.100.236.203   10.100.170.150   8080:30020/TCP   60s   app=httpd-app
service/kubernetes     ClusterIP      10.96.0.1        <none>           443/TCP          13d   <none>

NAME                               READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES   SELECTOR
deployment.apps/httpd-deployment   2/2     2            2           60s   httpd        httpd    app=httpd-app

NAME                                          DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES   SELECTOR
replicaset.apps/httpd-deployment-65d64d47c5   2         2         2       60s   httpd        httpd    app=httpd-app,pod-template-hash=65d64d47c5

but now when I try to connect to the httpd using K8S IP I receive these error:

[root@K8S01 LoadBalancer]# curl http://10.100.170.150:8080
curl: (7) Failed to connect to 10.100.170.150 port 8080: No route to host
[root@K8S01 LoadBalancer]# curl http://10.100.236.203:8080
curl: (7) Failed to connect to 10.100.236.203 port 8080: No route to host

If I try to connect directly to the node I can connect:

[root@K8S01 LoadBalancer]# curl http://bca-tst-docker01:30020
<html><body><h1>It works!</h1></body></html>
[root@K8S01 LoadBalancer]# curl http://bcc-tst-docker02:30020
<html><body><h1>It works!</h1></body></html>
-- Marco Ferrara
kubernetes

1 Answer

4/1/2021

You're are getting the connection refused because the service does not have any endpoints behind it since your label selector is different from the deployment level.

The deployment has httpd label while the service is trying to catch all the deployments with httpd-app. Below you can find corrected selector:

kind: Service
apiVersion: v1
metadata:
  name: httpd-service
spec:
  selector:
    app: httpd  <-------
  ports:  
    - protocol: TCP
      port: 8080
      targetPort: 80
      nodePort: 30020
      name: httpd-port
  type: NodePort

You can always verify if the service has endpoints. Kubernetes has a great section about debugging services and one of it is called: Does the Service have any Endpoints?

-- acid_fuji
Source: StackOverflow