With your Service manifest written, you're ready to deploy it to your cluster and test that it works. The process is similar to deploying your Deployment manifest, using kubectl apply to create the resource. However, testing a Service requires a few additional steps because you need to wait for AWS to provision the load balancer and then extract the public hostname before you can access your application.
Start by applying the Service manifest to your cluster:
kubectl apply -f service.yaml
Kubernetes receives the manifest, validates it, and creates the Service resource. The output confirms that the Service was created:
service/my-web-svc created
At this point, the Service exists in Kubernetes, but the AWS load balancer hasn't been provisioned yet. If you immediately check the Service status with kubectl get svc, you'll see that the external IP field shows <pending>:
kubectl get svc my-web-svc -n apps
The output shows the Service but without an external endpoint yet:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-web-svc LoadBalancer 10.100.200.50 <pending> 80:31234/TCP 10s
The CLUSTER-IP field shows the internal IP address that was assigned to the Service. Other pods in the cluster can use this IP to access your application, but you can't use it from outside the cluster. The EXTERNAL-IP field shows <pending>, indicating that AWS is still provisioning the load balancer. The PORT(S) field shows 80:31234/TCP, which means the Service listens on port 80 and has been assigned NodePort 31234 on each cluster node. The NodePort is assigned automatically from the available range.
Rather than repeatedly running kubectl get svc to check whether the load balancer is ready, you can use the -w flag to watch for changes in real time:
kubectl get svc my-web-svc -n apps -w
This command displays the current Service status and then continues running, showing updates as they happen. You'll see the same <pending> status initially, and then after a few minutes, the output will update to show the external hostname:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-web-svc LoadBalancer 10.100.200.50 <pending> 80:31234/TCP 10s
my-web-svc LoadBalancer 10.100.200.50 a1b2c3d4e5f6g7h8-1234567890.us-east-1.elb.amazonaws.com 80:31234/TCP 2m15s
When you see the hostname appear in the EXTERNAL-IP field, you can press Ctrl+C to stop watching and proceed to test your application. The hostname is the public DNS name of the AWS load balancer that was created for your Service. This hostname is what you'll use to access your application from anywhere on the internet.
To make testing easier, you can extract the hostname programmatically and store it in an environment variable. This is useful because the hostname is long and difficult to type manually:
EXTERNAL=$(kubectl get svc my-web-svc -n apps -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
echo "Service endpoint: http://$EXTERNAL/"
This command uses JSONPath to extract just the hostname from the Service status and stores it in the EXTERNAL variable. The echo command then displays the full URL you can use to access your application:
Service endpoint: http://a1b2c3d4e5f6g7h8-1234567890.us-east-1.elb.amazonaws.com/
Now you can test that your application is accessible by making an HTTP request to this URL. The curl command with the -I flag makes a HEAD request that retrieves just the HTTP headers without downloading the full response body:
curl -I "http://$EXTERNAL/"
If everything is working correctly, you'll see HTTP headers indicating a successful response:
HTTP/1.1 200 OK
Date: Thu, 15 Jan 2026 16:45:30 GMT
Server: Werkzeug/2.3.0 Python/3.11.0
Content-Type: text/html; charset=utf-8
Content-Length: 615
Connection: keep-alive
The HTTP/1.1 200 OK status line indicates that your application responded successfully. The other headers show information about the server and response. You can also open this URL in a web browser to see your application's actual output, or you can use curl without the -I flag to see the full response body. The important thing is that you're now accessing your application from outside the cluster using a public endpoint, which means anyone with this URL can access your application.
If you want to clean up the resources you created in this lesson, you can delete the Service and Deployment. Deleting the Service is important because it triggers Kubernetes to delete the AWS load balancer, preventing ongoing charges for the load balancer resource:
kubectl delete svc my-web-svc -n apps
kubectl delete deploy my-web-deploy -n apps
These commands remove the Service and Deployment from your cluster. When you delete the Service, Kubernetes tells AWS to delete the load balancer, which takes a minute or two to complete. The Deployment deletion removes the pods that were running your application. If you want to keep your cluster running for future lessons but don't want to pay for the load balancer, make sure to delete the Service. You can always recreate it later by applying the same manifest file.