How do I expose the Kubernetes Services that are running on my Amazon EKS cluster?

6 minute read
3

I want to expose the Kubernetes Services that are running on my Amazon Elastic Kubernetes Service (Amazon EKS) cluster.

Resolution

To expose the Kubernetes Services that are running on your cluster, first create a sample application. Then, apply the ClusterIP, NodePort, or LoadBalancer Kubernetes Service type to your sample application. For more information see Service type on the Kubernetes website.

Create a sample application

Complete the following steps:

  1. Define and apply a deployment file in Kubernetes. The following example command creates a file that's called nginx-deployment.yaml, and then creates a ReplicaSet that spins up two nginx pods:

    cat <<EOF > nginx-deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.14.2
            ports:
            - containerPort: 80
    EOF
  2. To create the deployment, run the following command:

    kubectl apply -f nginx-deployment.yaml
  3. To verify that your pods are running and have their own internal IP addresses, run the following command:

    kubectl get pods -l 'app=nginx' -o wide | awk {'print $1" " $3 " " $6'} | column -t

    Example output:

    NAME                               STATUS   IP
    nginx-deployment-574b87c764-hcxdg  Running  192.168.20.8
    nginx-deployment-574b87c764-xsn9s  Running  192.168.53.240

Apply the Service type 

Decide how you want to expose your application, and then apply the appropriate Service type. For information about each Service type, see type: ClusterIP, type: NodePort, and type: LoadBalancer on the Kubernetes website.

ClusterIP Service type

Complete the following steps:

  1. Create a file that's called clusterip.yaml.

  2. Set type to ClusterIP as shown in the following example:

    cat <<EOF > clusterip.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-service-cluster-ip
    spec:
      type: ClusterIP
      selector:
        app: nginx
      ports:
        - protocol: TCP
          port: 80
          targetPort: 80
    EOF
  3. Use either a declarative or imperative command to create the ClusterIP object in Kubernetes.
    To create the object and apply the clusterip.yaml file, run the following declarative command:

    kubectl create -f clusterip.yaml

    Example output:

    service/nginx-service-cluster-ip created>/code>

    -or-

    To expose a deployment of the ClusterIP type, run the following imperative command:

    kubectl expose deployment nginx-deployment  --type=ClusterIP  --name=nginx-service-cluster-ip

    Note: The expose command creates a Service but doesn't create a YAML file. However, kubectl translates your imperative command into a declarative Kubernetes Deployment object.
    Example output:

    service "nginx-service-cluster-ip" exposed
  4. To get the CLUSTER-IP address, run the following command:

    kubectl get service nginx-service-cluster-ip

    Example output:

    NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
    nginx-service-cluster-ip   ClusterIP   10.100.12.153   <none>        80/TCP    23s
  5. To use the CLUSTER-IP address to access the application, run the following command:

    curl -silent 10.100.12.153:80 | grep title

    Note: To access the Service, you must be logged in to a worker node or be within a Pod's container.

  6. To delete the ClusterIP Service, run the following command:

    kubectl delete service nginx-service-cluster-ip

    Example output:

    service "nginx-service-cluster-ip" deleted

NodePort Service type

Complete the following steps:

  1. Create a file that's called nodeport.yaml.

  2. Set type to NodePort as shown in the following example:

    cat <<EOF > nodeport.yaml
    apiVersion: v1
    kind: Service
    metadata:  name: nginx-service-nodeport
    spec:
      type: NodePort
      selector:
        app: nginx
      ports:
        - protocol: TCP
          port: 80
          targetPort: 80
    EOF
  3. Use either a declarative or imperative command to create the NodePort object in Kubernetes.
    To create the object and apply the nodeport.yaml file, run the following declarative command:

    kubectl create -f nodeport.yaml

    -or-

    To expose a deployment of the NodePort type, run the following imperative command:

    kubectl expose deployment nginx-deployment  --type=NodePort  --name=nginx-service-nodeport

    Example output:

    service/nginx-service-nodeport exposed
  4. To get information about nginx-service, run the following command:

    kubectl get service/nginx-service-nodeport

    Example output:

    NAME                     TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
    nginx-service-nodeport   NodePort   10.100.106.151   <none>        80:30994/TCP   27s

    Important: NodePort creates a Service IP address that's accessible within the cluster and uses the specified port to expose the service on every node. The output from the preceding command shows that the NodePort Service type is exposed externally on the port of the available worker node's Amazon Elastic Compute Cloud (Amazon EC2) instance. Before you access NodeIP:NodePort from outside the cluster, set the nodes' security groups to allow incoming traffic through the port that's listed in the output.

  5. For nodes that are in a public subnet and reachable from the internet, check the node's public IP address:

    kubectl get nodes -o wide |  awk {'print $1" " $2 " " $7'} | column -t

    Example output:

    NAME                                      STATUS  EXTERNAL-IP
    ip-10-0-3-226.eu-west-1.compute.internal  Ready   1.1.1.1
    ip-10-1-3-107.eu-west-1.compute.internal  Ready   2.2.2.2

    -or-

    For nodes that are in a private subnet and are only reachable through a virtual private cloud (VPC), check the node's private IP address:

    kubectl get nodes -o wide |  awk {'print $1" " $2 " " $6'} | column -t

    Example output:

    NAME                                      STATUS  INTERNAL-IP
    ip-10-0-3-226.eu-west-1.compute.internal  Ready   10.0.3.226
    ip-10-1-3-107.eu-west-1.compute.internal  Ready   10.1.3.107
  6. To use Node IP and the NodePort to access the application, run the following command:

    curl -silent <Public/PrivateNodeIP>:30994 | grep title
  7. To delete the NodePort Service, run the following command:

    kubectl delete service nginx-service-nodeport

    Example output:

    service "nginx-service-nodeport" deleted

LoadBalancer service type

Complete the following steps:

  1. Create a file that's called loadbalancer.yaml.

  2. Set type to LoadBalancer as shown in the following example:

    cat <<EOF > loadbalancer.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-service-loadbalancer
    spec:
      type: LoadBalancer
      selector:
        app: nginx
      ports:
        - protocol: TCP
          port: 80
          targetPort: 80
    EOF
  3. To apply the loadbalancer.yaml file, run the following command:

    kubectl create -f loadbalancer.yaml

    Example output:

    service/nginx-service-loadbalancer created

    -or-

    To expose a deployment of the LoadBalancer type, run the following command:

    kubectl expose deployment nginx-deployment  --type=LoadBalancer  --name=nginx-service-loadbalancer

    Example output:

    service "nginx-service-loadbalancer" exposed
  4. To get information about nginx-service, run the following command:

    kubectl get service/nginx-service-loadbalancer |  awk {'print $1" " $2 " " $4 " " $5'} | column -t

    Example output:

    NAME                        TYPE          EXTERNAL-IP                        PORT(S)
    nginx-service-loadbalancer  LoadBalancer  *****.eu-west-1.elb.amazonaws.com  80:30039/TCP
  5. To verify that you can externally access the load balancer, run the following command:

    curl -silent *****.eu-west-1.elb.amazonaws.com:80 | grep title
  6. To delete the LoadBalancer Service, run the following command:

    kubectl delete service nginx-service-loadbalancer

    Example output:

    service "nginx-service-loadbalancer" deleted

Note: By default, the LoadBalancer Service type creates a Classic Load Balancer.

To create a Network Load Balancer with an instance type target, add the following annotation to the Service manifest:

service.beta.kubernetes.io/aws-load-balancer-type: nlb

-or-

To create a Network Load Balancer with IP targets, deploy the AWS Load Balancer Controller, and then create a load balancer that uses IP targets.

AWS OFFICIAL
AWS OFFICIALUpdated 2 months ago
4 Comments

Could you add how to access the exposed endpoint - e.g., how to construct the URL so we can make API queries / hit it from the browser? You give a piece of that - how to get the IP - but it'd really save on cross-referencing for newer folks if you could share that full process of constructing a URL for testing from the information here.

replied 2 years ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
MODERATOR
replied 2 years ago

This is great but as being said here we are really missing the client side - How to construct the whole URL and access it with CURL or Postman.

replied a year ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

profile pictureAWS
EXPERT
replied a year ago