ClusterIP and NodePort Services
Now that we understand the v1.Service
structure, let's use client-go
to create and manage these resources programmatically. We'll focus on the two most common types for internal and testing/external access: ClusterIP
and NodePort
.
Creating a Service involves:
Constructing the
v1.Service
struct: Define the desired Service in Go code, filling in themetadata
(name, namespace) andspec
(selector, ports, type).Getting the Service client: Access
clientset.CoreV1().Services(namespace)
.Calling the
Create
method: Pass the context and the constructed Service struct toservicesClient.Create(...)
.
Let's build a Go program that creates a simple ClusterIP
Service targeting Pods with a specific label.
Creating a ClusterIP
Service
Imagine we have Pods running with the label app=my-web-app
and they expose port 8080
. We want to create a ClusterIP
Service named my-webapp-svc
that listens on port 80
and forwards traffic to the Pods' port 8080
.
Key Points:
v1.Service
Struct: We build the Go struct mirroring the desired YAML definition.Selector
: TheSpec.Selector
map connects the Service to Pods labeledapp=my-web-app
.Ports
: We define the mapping from the Service's port (80
) to the Pods'targetPort
(8080
). We useintstr.FromInt()
to create theIntOrString
type needed forTargetPort
. If targeting a named port on the Pod, you'd useintstr.FromString("port-name")
.Create
Call:servicesClient.Create(...)
sends the request to the API server.IsAlreadyExists
Check: We specifically check if the Service already exists. In a real application, you might want to retrieve and potentially update the existing Service instead of just logging a message.
Managing Services (Get
, Update
, Delete
)
Managing existing Services uses similar patterns:
Get(ctx, name, opts)
: Retrieves a specific Service by name.Update(ctx, service, opts)
: Updates an existing Service. Important: You usually need toGet
the Service first, modify the retrieved object, and then pass that modified object toUpdate
. Kubernetes uses theresourceVersion
field (managed internally) for optimistic concurrency control – trying to update using an object with an outdatedresourceVersion
will result in a conflict error (errors.IsConflict
).Delete(ctx, name, opts)
: Deletes a Service by name.
Modifying to NodePort
Changing the Service type to NodePort
is straightforward programmatically. You would modify the serviceSpec
before creating or updating:
Change
Spec.Type
tov1.ServiceTypeNodePort
.Optionally, specify a
NodePort
value in theServicePort
definition (e.g.,port.NodePort = 30080
). If you don't specify it, Kubernetes will allocate one automatically.
When you create or update the Service with Type: NodePort
, Kubernetes will allocate a port on each node (either the one you specified or an automatic one) and configure kube-proxy
(or equivalent) to forward traffic arriving on that NodeIP:NodePort combination to the Service's ClusterIP
, which then forwards it to the backend Pods.
Being able to create and configure Services programmatically opens up possibilities for automation, custom controllers that manage service exposure based on specific logic, or tools that simplify service management for developers. Next, we'll examine the Endpoints
object, the crucial link that dynamically maps a Service to its ready backend Pod IPs.
Last updated
Was this helpful?