Access AWS cluster endpoint running Kubernetes

3/13/2019

I am new to Kubernetes and I am currently deploying a cluster in AWS using Kubeadm. The containers are deployed just fine, but I can't seem to access them with by browser. When I used to do this via Docker Swarm I could simply use the IP address of the AWS node to access and login in my application with by browser, but this does not seem to work with my current Kubernetes setting.

Therefore my question is how can I access my running application under these new settings?

-- João Matos
amazon-web-services
kubernetes

3 Answers

3/13/2019

Basically the way kubernetes is constructed is different. First of all your containers are kept hidden from the world, unless you create a service to expose them, a load balancer or nodePort. If you create a service of the type of clusterIP, it will be available only from inside the cluster. For simplicity use port forwading to test your containers, if everything is working then create a service to expose them (Node Port or load balancer). The best and more difficult approach is to create an ingress to handle inbound traffic and routing to the services.

Port Forwading example:

kubectl port-forward redis-master-765d459796-258hz 6379:6379

Change redis for your pod name and the appropriate port of your container.

-- Leandro Donizetti Soares
Source: StackOverflow

3/14/2019

Both answers were helpful in my pursuit for a solution to my problem, but I ended up getting lost in the details. Here is an example that may help others with a similar situation:

1) Consider the following application yaml:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: my-web-app
  labels:
    app: my-web-app
spec:
  serviceName: my-web-app
  replicas: 1
  selector:
    matchLabels:
      app: my-web-app
  template:
    metadata:
      labels:
        app: my-web-app
    spec:
      containers:
      - name: my-web-app
        image: myregistry:443/mydomain/my-web-app
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          name: cp

2) I decided to adopt Node Port (thank you @Leandro for pointing it out) to expose my service, hence I added the following to my application yaml:

---
apiVersion: v1
kind: Service
metadata:
  name: my-web-app
  labels:
    name: my-web-app
spec:
  type: NodePort
  ports:
    - name: http1
      port: 80
      nodePort: 30036
      targetPort: 8080
      protocol: TCP
  selector:
     name: my-web-app

One thing that I was missing is that the label names in both sets must match in order to link my-web-app:StatefulSet (1) to my-web-app:Service (2). Then, my-web-app:StatefulSet:containerPort must be the same as my-web-app:Service:targetPort (8080). Finally, my-web-app:Service:nodePort is the port that we expose publicly and it must be a value between 30000-32767.

3) The last step is to ensure that the security group in AWS allows inbound traffic for the chosen my-web-app:Service:nodePort, in this case 30036, if not add the rule.

After following these steps I was able to access my application via aws-node-ip:30036/my-web-app.

-- João Matos
Source: StackOverflow

3/14/2019

You should read about how to use Services in Kubernetes:

A Kubernetes Service is an abstraction which defines a logical set of Pods and a policy by which to access them - sometimes called a micro-service.

Basically Services allows a Deployment (or Pod) to be reached from inside or outside the cluster.

In your case, if you want to expose a single service in AWS, it is as simple as:

apiVersion: v1
kind: Service
metadata:
  name: myApp
  labels:
    app: myApp
spec:
  ports:
  - port: 80 #port that the service exposes
    targetPort: 8080 #port of a container in "myApp"
  selector:
    app: myApp #your deployment must have the label "app: myApp"
  type: LoadBalancer

You can check if the Service was created successfully in the AWS EC2 console under "Elastic Load Balancers" or using kubectl describe service myApp

-- victortv
Source: StackOverflow