-
Overview
- Kubernetes' advanced software-defined networking (SDN) enables packet routing and forwarding for Pods, Services, and nodes in a cluster.
- Kubernetes and Google Cloud dynamically configure IP filtering rules, routing tables, and firewall rules on each node
- Do not manually make changes to nodes because they are overridden by GKE, and clusters may not function correctly
- The only reason to access a node directly is to debug problems with configuration
- The Kubernetes networking model relies heavily on IP addresses
- Services, Pods, containers, and nodes communicate using IP addresses and ports
- Kubernetes provides different types of load balancing to direct traffic to the correct Pods
- ClusterIP: The IP address assigned to a Service. This address is stable for the lifetime of the Service
- Pod IP: The IP address assigned to a given Pod. This is ephemeral
- Node IP: The IP address assigned to a given node
- Each node has an IP address assigned from the cluster's Virtual Private Cloud (VPC) network
- This node IP provides connectivity from control components like kube-proxy and the kubelet to the Kubernetes API server
- This IP is the node's connection to the rest of the cluster
- Each node has a pool of IP addresses that GKE assigns Pods running on that node (a /24 CIDR block by default)
- Users can optionally specify the range of IPs when creating the cluster
- The Flexible Pod CIDR range feature allows users to reduce the size of the range for Pod IPs for nodes in a given node pool
- Users can run a maximum of 110 Pods on a node with a /24 range, not 256 as you might expect
- This provides a buffer so that Pods don't become unschedulable due to a transient lack of IP addresses in the Pod IP range for a given node
- For ranges smaller than /24, roughly half as many Pods can be scheduled as IP addresses in the range
- Each Pod has a single IP address assigned from the Pod CIDR range of its node
- This IP address is shared by all containers running within the Pod, and connects them to other Pods running in the cluster
- Each Service has an IP address, called the ClusterIP, assigned from the cluster's VPC network
- Users can optionally customize the VPC network when creating the cluster
- In Kubernetes, a Pod is the most basic deployable unit within a Kubernetes cluster
- A Pod runs one or more containers
- Zero or more Pods run on a node
- Each node in the cluster is part of a node pool
- In GKE, these nodes are virtual machines, each running as an instance in Compute Engine
- Pods can also attach to external storage volumes and other custom resources
- When Kubernetes schedules a Pod to run on a node, it creates a network namespace for the Pod in the node's Linux kernel
- This network namespace connects the node's physical network interface, such as eth0, with the Pod using a virtual network interface, so that packets can flow to and from the Pod
- The associated virtual network interface in the node's root network namespace connects to a Linux bridge that allows communication among Pods on the same node
- A Pod can also send packets outside of the node using the same virtual interface
- Kubernetes assigns an IP address (the Pod IP) to the virtual network interface in the Pod's network namespace from a range of addresses reserved for Pods on the node
- This address range is a subset of the IP address range assigned to the cluster for Pods, which can be configured when a cluster is created
- A container running in a Pod uses the Pod's network namespace
- From the container's point of view, the Pod appears to be a physical machine with one network interface
- All containers in the Pod see this same network interface
- Each container's localhost is connected, through the Pod, to the node's physical network interface, such as eth0
- By default, each Pod has unfiltered access to all the other Pods running on all nodes of the cluster, but users can limit access among Pods
- A Pod's IP address is an implementation detail, and should not be relied upon
- Kubernetes provides stable IP addresses using Services
- Users can assign arbitrary key-value pairs called labels to any Kubernetes resource
- Kubernetes uses labels to group multiple related Pods into a logical unit called a Service
- A Service has a stable IP address and ports, and provides load balancing among the set of Pods whose labels match all the labels defined in the label selector when the Service is created
- Kubernetes assigns a stable, reliable IP address to each newly-created Service (the ClusterIP) from the cluster's pool of available Service IP addresses
- Kubernetes also assigns a hostname to the ClusterIP, by adding a DNS entry
- The ClusterIP and hostname are unique within the cluster and do not change throughout the lifecycle of the Service
- Kubernetes only releases the ClusterIP and hostname if the Service is deleted from the cluster's configuration
- Users can reach a healthy Pod running an application using either the ClusterIP or the hostname of the Service
- Kubernetes spreads traffic as evenly as possible across the full set of Pods, running on many nodes, so a
- A cluster can withstand an outage affecting one or more (but not all) nodes
- Kubernetes manages connectivity among Pods and Services using the kube-proxy component, which runs on each node
- kube-proxy is not an in-line proxy, but an egress-based load-balancing controller
- It watches the Kubernetes API server and continually maps the ClusterIP to healthy Pods by adding and removing destination NAT (DNAT) rules to the node's iptables subsystem
- When a container running in a Pod sends traffic to a Service's ClusterIP, the node selects a Pod at random and routes the traffic to that Pod
- When a Service is configured, users can optionally remap its listening port by defining values for port and targetPort
- The port is where clients reach the application
- The targetPort is the port where the application is actually listening for traffic within the Pod
- kube-proxy manages this port remapping by adding and removing iptables rules on the node
- By default, Pods do not expose an external IP address, because kube-proxy manages all traffic on each node
- Pods and their containers can communicate freely, but connections outside the cluster cannot access the Service
- Clients outside the cluster cannot access the frontend Service via its ClusterIP
- GKE provides three different types of Load Balancers to control access and to spread incoming traffic across clusters as evenly as possible
- Users can configure one Service to use multiple types of Load Balancers simultaneously
- External Load Balancers manage traffic coming from outside the cluster and outside your Google Cloud Virtual Private Cloud (VPC) network
- They use forwarding rules associated with the Google Cloud network to route traffic to a Kubernetes node
- Internal Load Balancers manage traffic coming from within the same VPC network
- Like external load balancers, they use forwarding rules associated with the Google Cloud network to route traffic to a Kubernetes node
- HTTP(S) Load Balancers are specialized external load balancers used for HTTP(S) traffic
- They use an Ingress resource rather than a forwarding rule to route traffic to a Kubernetes node
- When traffic reaches a Kubernetes node, it is handled the same way, regardless of the type of load balancer
- The load balancer is not aware of which nodes in the cluster are running Pods for its Service
- The Service balances traffic across all nodes in the cluster, even those not running a relevant Pod
- On a regional cluster, the load is spread across all nodes in all zones for the cluster's region
- When traffic is routed to a node, the node routes the traffic to a Pod, which may be running on the same node or a different node
- The node forwards the traffic to a randomly chosen Pod by using the iptables rules that kube-proxy manages on the node
- When a load balancer sends traffic to a node, the traffic might get forwarded to a Pod on a different node
- This requires extra network hops
- To avoid the extra hops, specify that traffic must go to a Pod that is on the same node that initially receives the traffic
- To specify that traffic must go to a Pod on the same node, set externalTrafficPolicy to Local in the Service manifest
- When externalTrafficPolicy is set to Local, the load balancer sends traffic only to nodes that have a healthy Pod that belongs to the Service
- The load balancer uses a health check to determine which nodes have the appropriate Pods
- If a Service needs to be reachable from outside the cluster and outside the VPC network, the Service can be configured as a LoadBalancer
- GKE then provisions a Network Load Balancer in front of the Service
- The Network Load Balancer is aware of all nodes in the cluster and configures VPC network's firewall rules to allow connections to the Service from outside the VPC network, using the Service's external IP address
- A static external IP address can be assigned to the Service
- When using the external load balancer, arriving traffic is initially routed to a node using a forwarding rule associated with the Google Cloud network
- After the traffic reaches the node, the node uses its iptables NAT table to choose a Pod
- kube-proxy manages the iptables rules on the node
- For traffic that needs to reach a cluster from within the same VPC network, configure the Service to provision an Internal Load Balancer
- The Internal Load Balancer chooses an IP address from the cluster's VPC subnet instead of an external IP address
- Applications or services within the VPC network can use this IP address to communicate with Services inside the cluster
- When the traffic reaches a given node, that node uses its iptables NAT table to choose a Pod, even if the Pod is on a different node
- kube-proxy manages the iptables rules on the node
- When traffic reaches a given node, that node uses its iptables NAT table to choose a Pod, even if the Pod is on a different node
- kube-proxy manages the iptables rules on the node
- Many applications, such as RESTful web service APIs, communicate using HTTP(S)
- Users can allow clients external to the VPC network to access applications using a Kubernetes Ingress resource
- An Ingress resource map hostnames and URL paths to Services within the cluster
- When using a HTTP(S) load balancer, configure the Service to use a NodePort, as well as a ClusterIP
- When traffic accesses the Service on a node's IP at the NodePort, GKE routes traffic to a healthy Pod for the Service
- A NodePort can be specified to allow GKE to assign a random unused port
- When an Ingress resource is created, GKE provisions an HTTP(S) Load Balancer in the Google Cloud project
- The load balancer sends a request to a node's IP address at the NodePort
- After the request reaches the node, the node uses its iptables NAT table to choose a Pod
- kube-proxy manages the iptables rules on the node
- When an Ingress object is created, the GKE Ingress controller configures a Google Cloud HTTP(S) load balancer according to the rules in the Ingress manifest and the associated Service manifests
- The client sends a request to the HTTP(S) load balancer
- The load balancer is an actual proxy
- The load balancer chooses a node and forwards the request to that node's NodeIP:NodePort combination
- The node uses its iptables NAT table to choose a Pod
- kube-proxy manages the iptables rules on the node
- By default, all Pods running within the same cluster can communicate freely
- Access among Pods can be limited using a network policy
- Network policy definitions allow users to restrict the ingress and egress of Pods based on an arbitrary combination of labels, IP ranges, and port numbers
- By default, there is no network policy, so all traffic among Pods in the cluster is allowed
- As soon as the first network policy is created in a namespace, all other traffic is denied
- After creating a network policy, users must explicitly enable it for the cluster
- If a Service uses an External Load Balancer, traffic from any external IP address can access the Service by default
- If a service uses the HTTP(S) Load Balancer, Google Cloud Armor security policy can be used to limit which external IP addresses can access the Service and which responses to return when access is denied because of the security policy
- Users can configure Logging to log information about these interactions
- If a Google Cloud Armor security policy is not fine-grained enough, users can enable the Identity-Aware Proxy on endpoints to implement user-based authentication and authorization for applications
-
DNS
- Service discovery is implemented with autogenerated service names that map to the service's IP address
- Service names follow a standard specification my-svc.my-namespace.svc.my-zone
- Pods can access external services, like example.com, through their names
- GKE provides managed DNS for resolving service names and for resolving external names
- Managed DNS is implemented by kube-dns, a cluster add-on that is deployed by default in all GKE clusters
- kube-dns runs as a Deployment that schedules redundant kube-dns Pods to nodes in the cluster
- The kube-dns Pods are in the kube-system namespace
- The kube-dns deployment is accessed through a corresponding Service that groups the kube-dns Pods and gives them a single IP address
- By default, all Pods in a cluster use this service to resolve DNS queries
- kube-dns scales to serve the DNS demands of the cluster
- This scaling is controlled by the kube-dns-autoscaler which is deployed by default in all GKE clusters
- kube-dns-autoscaler adjusts the number of replicas in the kube-dns deployment based on the number of nodes and cores in the cluster
- The kubelet agent running on each Pod configures the Pod's etc/resolv.conf to use the kube-dns service's ClusterIP
- kube-dns is the authoritative name server for the cluster domain (cluster.local) and it recursively resolves external names
- Short names that are not fully qualified, like myservice, are completed first with local search paths, e.g. myservice.default.svc.cluster.local, myservice.svc.cluster.local, myservice.cluster.local, myservice.c.my-project-id.internal, and myservice.google.internal.
-
Load Balancing
- Ingress object defines rules for routing external HTTP(S) traffic to applications
- Ingress object is associated with one or more Service objects, each associated with Pods
- GKE ingress controller creates and configures a Google Cloud HTTP(S) load balancer based on Ingress object configuration
- Configuration of the HTTP(S) load balancer and its components, including target proxies, URL maps, and backend services must not be manually updated
- Ingress defines how traffic reaches Services and is routed to an application
- Ingress can provide a single IP address for multiple Services in a cluster
- Ingress can configure Google Cloud features such as Google-managed SSL certificates, Google Cloud Armor, Cloud CDN, and Identity-Aware Proxy
- Ingress can specify the use of multiple TLS certificates for request termination
- Google-managed SSL certificates are provisioned, deployed, renewed, and managed for domains
- Managed certificates do not support wildcard domains or multiple subject alternative names (SANs)
- Users can provision SSL certificate and create a certificate resource in Google Cloud project
- Users can list custom certificate resource in an annotation on an Ingress to create an HTTP(S) load balancer that uses the certificate
- Users can provision their own SSL certificate and create a Secret to hold it
- Secret can be referenced in an Ingress specification to create an HTTP(S) load balancer that uses the certificate
- GKE ingress controller to use readinessProbes as health checks, the Pods for an Ingress must exist at the time of Ingress creation
- If replicas are scaled to 0, the default health check applies
- Changes to a Pod's readinessProbe do not affect the Ingress after it is created
- HTTPS load balancer terminates TLS in locations that are distributed globally, to minimize latency between clients and the load balancer
- If geographic control over where TLS is terminated is required, use a custom ingress controller and GCP Network Load Balancing instead, and terminate TLS on backends that are located in appropriate regions
- HTTP(S) load balancer provides one stable IP address to route requests to a variety of backend services
- Load balancer can route requests to different backend services depending on the URL path
- Load balancer can route requests according to the hostname
- Users create and configure an HTTP(S) load balancer by creating a Kubernetes Ingress object
- Ingress object must be associated with one or more Service objects, each of which is associated with a set of Pods
- When an Ingress is created, GKE ingress controller creates and configures an HTTP(S) load balancer according to the information in the Ingress and the associated Services
- The ingress load balancer is given a stable IP address that can be associated with a domain name
- The only supported wildcard character for the path field of an Ingress is the * character.
- The * character must follow a forward slash (/) and must be the last character in the pattern
- A more specific pattern takes precedence over a less specific pattern, so where there is /foo/* and /foo/bar/*, then /foo/bar/bat is taken to match /foo/bar/*
- Service type of NodePort is the required type for an Ingress that is used to configure an HTTP(S) load balancer
- Service manifest, the selector field indicates that any Pod that has the specified label is a member of the Service
- A default backend can be configured by providing a backend field in the Ingress manifest
- Any requests that don't match the paths in the rules field are sent to the Service and port specified in the backend field
- If a default backend is not specified, GKE provides a default backend that returns 404
- A Service exposed through an Ingress must respond to health checks from the load balancer
- Any container that is the final destination of load-balanced traffic must serve a response with an HTTP 200 status to GET requests on the / path to indicate that it is healthy
- Configure an HTTP readiness probe
- Serve a response with an HTTP 200 status to GET requests on the path specified by the readiness probe
- The Service exposed through an Ingress must point to the same container port on which the readiness probe is enabled
- If the Deployment is configured or scaled to 0 Pods, the HTTP readiness probe's path is set to /, regardless of the value of readinessProbe.path
- A Kubernetes Service and a Google Cloud backend service are distinct
- GKE ingress controller creates a Google Cloud backend service for each (serviceName, servicePort) pair in an Ingress manifest
- Kubernetes Service object can be related to several Google Cloud backend services
- BackendConfig can be used to configure HTTP(S) load balancer to use features like Google Cloud Armor, Cloud CDN, and IAP
- BackendConfig is a custom resource that holds configuration information for Google Cloud features
- An Ingress manifest refers to a Service, and the Service manifest refers to a BackendConfig by using a beta.cloud.google.com/backend-config annotation
- With HTTP(S) Load Balancing, the WebSocket protocol just works and requires no configuration
- You might want to use a timeout value larger than the default 30 seconds
- To set the timeout value for a backend service configured through Ingress, create a BackendConfig object, and use the beta.cloud.google.com/backend-config annotation in your Service manifest
- An Ingress object is associated with a stable external IP address that clients can use to access Services and in turn, running containers
- The stable IP address lasts for the lifetime of the Ingress object
- If Ingress is deleted and recreated from the same manifest file, there is no guarantee to get the same external IP address
- To get a permanent IP address, reserve a global static external IP address
- Include the annotation kubernetes.io/ingress.global-static-ip-name in Ingress manifest for the name of reserved static IP address
- HTTP(S) load balancer acts as a proxy between clients and application
- To accept HTTPS requests from clients, the load balancer must have a certificate to prove its identity to clients
- The load balancer must also have a private key to complete the HTTPS handshake
- HTTPS traffic between the client and the load balancer is encrypted using TLS
- Load balancer terminates TLS encryption, and forwards the request without encryption to the application
- Use self managed or Google-managed SSL certificates
- Create a Kubernetes Secret to provide an HTTP(S) load balancer with a certificate and key
- To use the Secret, add its name in the tls field of Ingress manifest
- Changes to Secrets are picked up periodically, so it can take up to 10 minutes for changes to be applied to the load balancer
- To force all traffic between the client and the HTTP(S) load balancer to use HTTPS, disable HTTP by including the kubernetes.io/ingress.allow-http annotation in Ingress manifest, and set the value of the annotation to "false"
- As an alternative to using Kubernetes Secrets to provide certificates to the load balancer for HTTP(S) termination, certificates previously uploaded to GCP project can be used
- Clients can use HTTP or HTTPS to communicate with the load balancer proxy
- The connection from the load balancer proxy to application uses HTTP by default
- Where the application running in a GKE Pod is capable of receiving HTTPS requests, configure the load balancer to use HTTPS to forward requests to the application
- To configure the protocol used between the load balancer and application, use the cloud.google.com/app-protocols annotation in Service manifest to specify ports
- To enable a HTTP(S) load balancer to serve content from two hostnames using separate certificate, specify multiple certificates in an Ingress manifest
- The load balancer chooses a certificate if the Common Name (CN) in the certificate matches the hostname used in the request.
-
BackendConfig
- BackendConfig is a custom resource definition that is used by the Kubernetes Engine Ingress controller
- Users can provide configuration for a Cloud load balancer by associating Service ports with BackendConfig objects
- A BackendConfig can be used to configure Cloud CDN (Cloud CDN), Google Cloud Armor, Identity-Aware Proxy (IAP), Timeout, Connection draining timeout, Session affinity and User-defined request headers features of HTTP(S) Load Balancing
- When a Kubernetes Ingress object is created, the GKE Ingress controller creates and configures an HTTP(S) load balancer
- Ingress has rules, each of which references a port in a Kubernetes Service object
- If a port of a Service is referenced by an Ingress, the port is associated with an HTTP(S) Load Balancing backend service
- If a Service port is referenced by an Ingress, and if the Service port is associated with a BackendConfig, then the HTTP(S) load balancing backend service takes part of its configuration from the BackendConfig