Skip to main content
Services provide network access to your deployments. They create stable network endpoints that route traffic to your pods, even as pods are created and destroyed during updates.

What is a Service?

In Kubernetes, pods have ephemeral IP addresses that change when pods restart. A Service provides:
  • A stable DNS name and IP address
  • Load balancing across multiple pod replicas
  • Network access control (internal vs. external)

Service Types

Orchard supports three types of services:

Internal

Accessible only within the cluster

External

Publicly accessible via LoadBalancer

Ingress

HTTP(S) routing with custom domains

Internal (ClusterIP)

Internal services are only accessible from within the Kubernetes cluster. Use these for:
  • Databases that shouldn’t be public
  • Internal APIs between microservices
  • Backend services accessed by frontends
Internal URL format:
{service-name}.{namespace}.svc.cluster.local:{port}
Example:
postgres.acme-prod-api.svc.cluster.local:5432

External (LoadBalancer)

External services are accessible from the internet via a public IP address. Use these for:
  • APIs that need direct external access
  • Services without a custom domain
  • Quick testing and development
External services get a public IP assigned by the cluster. For custom domains with HTTPS, use an Ingress instead.

Ingress

Ingresses provide HTTP(S) routing with custom domains, TLS certificates, and path-based routing. See Ingresses for details.

Creating a Service

1

Open your deployment

Navigate to the deployment you want to expose.
2

Go to Networking tab

Click on the Networking tab.
3

Click 'Add Service'

Click Add Service to create a new service.
4

Configure the service

FieldDescription
NameUnique name for the service
TypeInternal or External
PortThe port to expose
Target PortThe port your container listens on
5

Create

Click Create to set up the service.

Port Configuration

Single Port Service

For most applications with one port:
SettingValue
Container Port3000 (what your app listens on)
Service Port80 (what users connect to)
This maps external port 80 to internal port 3000.

Multiple Ports

Some applications need multiple ports (e.g., HTTP + gRPC):
NameContainer PortService PortProtocol
http808080TCP
grpc90909090TCP
metrics91009100TCP

Accessing Internal Services

To connect to an internal service from another deployment in the same project:
# Full DNS name
http://api-server.acme-prod-myproject.svc.cluster.local:8080

# Or just the service name (if in same namespace)
http://api-server:8080

From Environment Variables

Set the service URL as an environment variable:
DATABASE_URL=postgres://postgres.acme-prod-api.svc.cluster.local:5432/mydb
API_ENDPOINT=http://api-server:8080

Updating Services

To modify an existing service:
1

Open the Networking tab

Navigate to your deployment’s Networking tab.
2

Click on the service

Select the service you want to update.
3

Make changes

Modify the port configuration or other settings.
4

Save

Click Save to apply changes.

Changing Service Exposure

To change a service from internal to external (or vice versa):
1

Open the service

Go to your deployment’s Networking tab and select the service.
2

Change exposure

Click the exposure toggle or button to switch between internal and external.
3

Save

Changes take effect immediately.
Changing from external to internal will remove the public IP. Changing to external will provision a new public IP (which may take a few minutes).

Deleting Services

To remove a service:
1

Open the Networking tab

Go to your deployment’s Networking tab.
2

Find the service

Locate the service you want to delete.
3

Delete

Click the delete button and confirm.
Deleting a service immediately removes network access. Any ingresses pointing to this service will also stop working.

Service Discovery

Within the Same Project

Services in the same project (namespace) can use short names:
http://my-service:8080

Across Projects

To access a service in a different project, use the full DNS name:
http://my-service.other-namespace.svc.cluster.local:8080
Cross-project communication may be restricted by network policies. Check with your administrator.

Load Balancing

When you have multiple replicas, services automatically load balance traffic across all healthy pods:
Service (port 80)

    ├──► Pod 1 (port 3000)
    ├──► Pod 2 (port 3000)
    └──► Pod 3 (port 3000)
Kubernetes uses round-robin load balancing by default.

Health Checks

Services only route traffic to healthy pods. A pod is considered healthy when:
  1. The container has started
  2. Any readiness probes pass
  3. The pod is not terminating
Unhealthy pods are automatically removed from the service’s endpoints.

Best Practices

Start with internal services and only expose externally when needed. This follows the principle of least privilege.
Name services clearly (e.g., postgres, api-server, redis) so they’re easy to identify in configuration.
Keep track of which services use which ports, especially in microservice architectures.
For web traffic with custom domains, use ingresses instead of external services to get HTTPS and better routing.

Troubleshooting

If you can’t reach your service:
  1. Verify the service exists in the Networking tab
  2. Check that pods are running and healthy
  3. Verify the port configuration matches your application
  4. For external services, check the public IP is assigned
If connections are refused:
  1. Verify your application is listening on the correct port
  2. Check that the container port matches what your app uses
  3. Look at pod logs for startup errors
If requests sometimes fail:
  1. Check pod health and restart counts
  2. Verify all replicas are healthy
  3. Look for resource limits being hit

Next Steps