How do I expose the Kubernetes services running on my Amazon EKS cluster?

Last updated: 2020-12-28

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

Short description

The following resolution shows you how to create a sample application, and then apply the following Kubernetes ServiceTypes to your sample application: ClusterIP, NodePort, and LoadBalancer.

Keep in mind the following:

  • ClusterIP exposes the service on a cluster's internal IP address.
  • NodePort exposes the service on each node’s IP address at a static port.
  • LoadBalancer exposes the service externally using a load balancer.

Note: Amazon EKS supports the Network Load Balancer and the Classic Load Balancer for pods running on Amazon Elastic Compute Cloud (Amazon EC2) instance worker nodes through LoadBalancer. You can load balance network traffic to a Network Load Balancer (instance or IP targets) or to a Classic Load Balancer (instance target only).

Resolution

Create a sample application

1.    Define and apply a deployment file. The following example creates a ReplicaSet that spins up two nginx pods, and then creates filed called nginx-deployment.yaml.

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

The output is similar to the following:

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

Create a ClusterIP service

1.    Create a file called clusterip.yaml, and then set type to ClusterIP. For example:

cat <<EOF > clusterip.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
EOF

2.    Create the ClusterIP object in Kubernetes using either a declarative or imperative command.

To create the object and apply the clusterip.yaml file, run the following declarative command:

kubectl create -f clusterip.yaml

You receive the following output:

service/nginx-service created

-or-

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

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

You receive the following output:

service "nginx-service" exposed

Note: The exposed command creates a service without creating a YAML file. However, kubectl translates your imperative command into a declarative Kubernetes Deployment object.

3.    To access the application and get the ClusterIP number, run the following command:

kubectl get service nginx-service

You receive the following output:

NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
nginx-service   ClusterIP   172.20.65.130   <none>        80/TCP    15s

Create a NodePort service

1.    To create a NodePort service, create a file called nodeport.yaml, and then set type to NodePort. For example:

cat <<EOF > nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
EOF

2.    To delete the ClusterIP service and create a NodePort service with the same service name (nginx-service), run the following command:

kubectl delete service nginx-service

You receive the following output:

service "nginx-service" deleted

3.    Create the NodePort object in Kubernetes using either a declarative or imperative command.

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 NodePort type, run the following imperative command:

kubectl expose deployment nginx  --type=NodePort  --name=nginx-serviceservice "nginx-service" exposed

You receive the following output:

service/nginx-service created

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

kubectl get service/nginx-service

You receive the following output:

NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
nginx-service   NodePort   172.20.36.247   <none>        80:30648/TCP   11s

Note: The ServiceType is NodePort. ClusterIP is created automatically and takes the route from the NodePort. The NodePort service is exposed externally on the available worker nodes on port 30648.

5.    To check the node’s public IP address, run the following command:

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

You receive the following 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

Important: Before you access NodeIP:NodePort from an outside cluster, you must enable the security group of the nodes to allow incoming traffic through port 30648.

Create a LoadBalancer service

1.    To create a LoadBalancer service, create a file called loadbalancer.yaml, and then set type to LoadBalancer. For example:

cat <<EOF > loadbalancer.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
EOF

2.    To delete the ClusterIP service and create a LoadBalancer service with the same service name (nginx-service), run the following command:

kubectl delete service nginx-service

You receive the following output:

service "nginx-service" deleted

3.    To apply the loadbalancer.yaml file, run the following command:

kubectl create -f loadbalancer.yaml

You receive the following output:

service/nginx-service created

-or-

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

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

You receive the following output:

service "nginx-service" exposed

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

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

You receive the following output:

NAME           TYPE          EXTERNAL-IP                        PORT(S)
nginx-service  LoadBalancer  *****.eu-west-1.elb.amazonaws.com  80:30039/TCP

5.    To verify that you can access the load balancer externally, run the following command:

curl -silent *****.eu-west-1.elb.amazonaws.com:80 | grep title

You should receive the following output between HTML title tags: "Welcome to nginx!"

Note: By default, the preceding LoadBalancer service creates a Classic Load Balancer.

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

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

To create a Network Load Balancer with IP targets, see Load balancer – IP targets.


Did this article help?


Do you need billing or technical support?