Exposing containers
kubectl expose
creates a service for existing pods- A service is a stable address for pod(s)
- If we want to connect to pod(s) we need a service
- CoreDNS (part of control plane) allows us to resolve services by name
- There are different types of services
- ClusterIP (default)
- Single, internal virtual IP allocated
- Only reachable from within cluster (nodes and pods)
- Pods can reach service on apps port number
- Always available in Kubernetes
- NodePort
- High port allocated on each node
- Port is open on every node's IP
- Anyone can connect (if they can reach node)
- Other pods need to be updated to this port
- Always available in Kubernetes
- LoadBalancer
- Controls LB endpoint external to the cluster
- Only available when infrastructure provider gives you a load balancer (AWS ELB, etc)
- Creates NodePort + ClusterIP services, tells external load balancer to send traffic to NodePort
- ExternalName
- Adds CNAME DNS records to CoreDNS only
- Not used for pods, but for giving pods a DNS name to use for something outside Kubernetes
kubectl get pods -w
kubectl create deployment httpenv --image=bretfisher/httpenv
kubectl scale deployment/httpenv --replicas=5
kubectl expose deployment/httpenv --port 8888
kubectl get service
kubectl run --generator run-pod/v1 tmp-shell --rm -it --image=bretfisher/netshoot -- bash
curl httpenv:8888
{
"HOME": "/root",
"HOSTNAME": "httpenv-7cc9888d59-s9sj6",
"KUBERNETES_PORT": "tcp://10.96.0.1:443",
"KUBERNETES_PORT_443_TCP": "tcp://10.96.0.1:443",
"KUBERNETES_PORT_443_TCP_ADDR": "10.96.0.1",
"KUBERNETES_PORT_443_TCP_PORT": "443",
"KUBERNETES_PORT_443_TCP_PROTO": "tcp",
"KUBERNETES_SERVICE_HOST": "10.96.0.1",
"KUBERNETES_SERVICE_PORT": "443",
"KUBERNETES_SERVICE_PORT_HTTPS": "443",
"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
}
kubectl expose deployment/httpenv --port 8888 --name httpenv-np --type NodePort
kubectl get services
NAME | TYPE | CLUSTER-IP | EXTERNAL-IP | PORT(S) | AGE |
httpenv | ClusterIP | 10.107.92.157 | none | 8888/TCP | 24h |
httpenv-np | NodePort | 10.109.25.172 | none | 8888:31642/TCP | 8s |
kubernetes | ClusterIP | 10.96.0.1 | none | 443/TCP | 2d13h |
- 8888:31642/TCP - from port 8888 inside the cluster to port 31642 externally accessible
- Default port ranges in the cluster 30000-32767
- These 3 service types are additive, each one creates one above it:
- ClusterIP
- NodePort
- LoadBalancer
curl localhost:31642
(on Linux - goes directly to NodePort, on Mac/Windows goes through Docker VPNKit)
- Docker Desktop provides a built-in LoadBalancer that publishes the port on localhost
kubectl expose deployment/httpenv --port 8888 --name httpenv-lb --type LoadBalancer
curl localhost:8888
NAME | TYPE | CLUSTER-IP | EXTERNAL-IP | PORT(S) | AGE |
httpenv | ClusterIP | 10.107.92.157 | none | 8888/TCP | 24h |
httpenv-np | NodePort | 10.109.25.172 | none | 8888:31642/TCP | 8s |
httpenv-lb | LoadBalancer | 10.98.39.13 | localhost | 8888:30695/TCP | 19s |
kubernetes | ClusterIP | 10.96.0.1 | none | 443/TCP | 2d13h |
kubectl delete service/httpenv service/httpenv-np service/httpenv-lb deployment/httpenv
- Starting with 1.11, internal DNS is provided by CoreDNS
- Like Swarm, this is DNS-based service discovery
- Accessing services by hostname works only if they're in the same namespace
kubectl get namespaces
- Services also have a FQDN
curl <hostname>.<namespace>.svc.cluster.local
Last modified 3yr ago