A workload can be accessed from public networks through a load balancer, which is more secure and reliable than EIP.
The LoadBalancer access address is in the format of <IP address of public network load balancer>:<access port>, for example, 10.117.117.117:80.
In this access mode, requests are transmitted through an ELB load balancer to a node and then forwarded to the destination pod through the Service.
When CCE Turbo clusters and dedicated load balancers are used, passthrough networking is supported to reduce service latency and ensure zero performance loss.
External access requests are directly forwarded from a load balancer to pods. Internal access requests can be forwarded to a pod through a Service.
Select the load balancer to interconnect. Only load balancers in the same VPC as the cluster are supported. If no load balancer is available, click Create Load Balancer to create one on the ELB console.
You can click the edit icon in the row of Set ELB to configure load balancer parameters.
You can set the access type when creating a workload using kubectl. This section uses an Nginx workload as an example to describe how to add a LoadBalancer Service using kubectl.
The file names are user-defined. nginx-deployment.yaml and nginx-elb-svc.yaml are merely example file names.
vi nginx-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: nginx name: nginx imagePullSecrets: - name: default-secret
vi nginx-elb-svc.yaml
Before enabling sticky session, ensure that the following conditions are met:
apiVersion: v1 kind: Service metadata: annotations: kubernetes.io/elb.id: 5083f225-9bf8-48fa-9c8b-67bd9693c4c0 # ELB ID. Replace it with the actual value. kubernetes.io/elb.class: union # Load balancer type name: nginx spec: ports: - name: service0 port: 80 # Port for accessing the Service, which is also the listener port on the load balancer. protocol: TCP targetPort: 80 # Port used by a Service to access the target container. This port is closely related to the applications running in a container. selector: app: nginx type: LoadBalancer
Parameter |
Mandatory |
Type |
Description |
---|---|---|---|
kubernetes.io/elb.class |
Yes |
String |
Select a proper load balancer type as required. The value can be:
|
kubernetes.io/elb.session-affinity-mode |
No |
String |
Listeners ensure session stickiness based on IP addresses. Requests from the same IP address will be forwarded to the same backend server.
|
kubernetes.io/elb.session-affinity-option |
No |
Table 2 Object |
This parameter specifies the sticky session timeout. |
kubernetes.io/elb.id |
Yes |
String |
This parameter indicates the ID of a load balancer. The value can contain 1 to 100 characters. Mandatory when an existing load balancer is to be associated. Obtaining the load balancer ID: On the management console, click Service List, and choose Networking > Elastic Load Balance. Click the name of the target load balancer. On the Summary tab page, find and copy the ID. NOTE:
The system preferentially interconnects with the load balancer based on the kubernetes.io/elb.id field. If this field is not specified, the spec.loadBalancerIP field is used (optional and available only in 1.23 and earlier versions). Do not use the spec.loadBalancerIP field to connect to the load balancer. This field will be discarded by Kubernetes. For details, see Deprecation. |
kubernetes.io/elb.subnet-id |
- |
String |
This parameter indicates the ID of the subnet where the cluster is located. The value can contain 1 to 100 characters.
|
kubernetes.io/elb.lb-algorithm |
No |
String |
This parameter indicates the load balancing algorithm of the backend server group. The default value is ROUND_ROBIN. Options:
When the value is SOURCE_IP, the weights of backend servers in the server group are invalid. |
kubernetes.io/elb.health-check-flag |
No |
String |
Whether to enable the ELB health check.
If this parameter is enabled, the kubernetes.io/elb.health-check-option field must also be specified at the same time. |
kubernetes.io/elb.health-check-option |
No |
Table 3 Object |
ELB health check configuration items. |
Parameter |
Mandatory |
Type |
Description |
---|---|---|---|
persistence_timeout |
Yes |
String |
Sticky session timeout, in minutes. This parameter is valid only when elb.session-affinity-mode is set to SOURCE_IP. Value range: 1 to 60. Default value: 60 |
Parameter |
Mandatory |
Type |
Description |
---|---|---|---|
delay |
No |
String |
Initial waiting time (in seconds) for starting the health check. Value range: 1 to 50. Default value: 5 |
timeout |
No |
String |
Health check timeout, in seconds. Value range: 1 to 50. Default value: 10 |
max_retries |
No |
String |
Maximum number of health check retries. Value range: 1 to 10. Default value: 3 |
protocol |
No |
String |
Health check protocol. Default value: protocol of the associated Service Value options: TCP, UDP, or HTTP |
path |
No |
String |
Health check URL. This parameter needs to be configured when the protocol is HTTP. Default value: / The value can contain 1 to 10,000 characters. |
kubectl create -f nginx-deployment.yaml
If information similar to the following is displayed, the workload has been created.
deployment/nginx created
kubectl get pod
If information similar to the following is displayed, the workload is running.
NAME READY STATUS RESTARTS AGE nginx-2601814895-c1xhw 1/1 Running 0 6s
kubectl create -f nginx-elb-svc.yaml
If information similar to the following is displayed, the Service has been created.
service/nginx created
kubectl get svc
If information similar to the following is displayed, the access type has been set successfully, and the workload is accessible.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.247.0.1 <none> 443/TCP 3d nginx LoadBalancer 10.247.130.196 10.78.42.242 80:31540/TCP 51s
The Nginx is accessible.
You can add a Service when creating a workload using kubectl. This section uses an Nginx workload as an example to describe how to add a LoadBalancer Service using kubectl.
The file names are user-defined. nginx-deployment.yaml and nginx-elb-svc.yaml are merely example file names.
vi nginx-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: nginx name: nginx imagePullSecrets: - name: default-secret
vi nginx-elb-svc.yaml
Before enabling sticky session, ensure that the following conditions are met:
apiVersion: v1 kind: Service metadata: annotations: kubernetes.io/elb.class: union kubernetes.io/elb.autocreate: '{ "type": "public", "bandwidth_name": "cce-bandwidth-1551163379627", "bandwidth_chargemode": "bandwidth", "bandwidth_size": 5, "bandwidth_sharetype": "PER", "eip_type": "5_bgp" }' labels: app: nginx name: nginx spec: ports: - name: service0 port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: LoadBalancer
apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx namespace: default annotations: kubernetes.io/elb.class: performance kubernetes.io/elb.autocreate: '{ "type": "public", "bandwidth_name": "cce-bandwidth-1626694478577", "bandwidth_chargemode": "bandwidth", "bandwidth_size": 5, "bandwidth_sharetype": "PER", "eip_type": "5_bgp", "available_zone": [ "" ], "l4_flavor_name": "L4_flavor.elb.s1.small" }' spec: selector: app: nginx ports: - name: cce-service-0 targetPort: 80 nodePort: 0 port: 80 protocol: TCP type: LoadBalancer
Parameter |
Mandatory |
Type |
Description |
---|---|---|---|
kubernetes.io/elb.class |
Yes |
String |
Select a proper load balancer type as required. The value can be:
|
kubernetes.io/elb.subnet-id |
- |
String |
This parameter indicates the ID of the subnet where the cluster is located. The value can contain 1 to 100 characters.
|
kubernetes.io/elb.session-affinity-option |
No |
Table 2 Object |
Sticky session timeout. |
kubernetes.io/elb.autocreate |
Yes |
elb.autocreate object |
Whether to automatically create a load balancer associated with the Service. Example: |
kubernetes.io/elb.lb-algorithm |
No |
String |
This parameter indicates the load balancing algorithm of the backend server group. The default value is ROUND_ROBIN. Options:
When the value is SOURCE_IP, the weights of backend servers in the server group are invalid. |
kubernetes.io/elb.health-check-flag |
No |
String |
Whether to enable the ELB health check.
If this parameter is enabled, the kubernetes.io/elb.health-check-option field must also be specified at the same time. |
kubernetes.io/elb.health-check-option |
No |
Table 3 Object |
ELB health check configuration items. |
kubernetes.io/elb.session-affinity-mode |
No |
String |
Listeners ensure session stickiness based on IP addresses. Requests from the same IP address will be forwarded to the same backend server.
|
kubernetes.io/elb.session-affinity-option |
No |
Table 2 Object |
Sticky session timeout. |
kubernetes.io/hws-hostNetwork |
No |
String |
This parameter indicates whether the workload Services use the host network. Setting this parameter to true will enable the ELB load balancer to forward requests to the host network. The host network is not used by default. The value can be true or false. |
externalTrafficPolicy |
No |
String |
If sticky session is enabled, add this parameter so that requests are transferred to a fixed node. If a LoadBalancer Service with this parameter set to Local is created, a client can access the target backend only if the client is installed on the same node as the backend. |
Parameter |
Mandatory |
Type |
Description |
---|---|---|---|
name |
No |
String |
Name of the load balancer that is automatically created. Value range: 1 to 64 characters, including lowercase letters, digits, and underscores (_). The value must start with a lowercase letter and end with a lowercase letter or digit. Default: cce-lb+service.UID |
type |
No |
String |
Network type of the load balancer.
Default: inner |
bandwidth_name |
Yes for public network load balancers |
String |
Bandwidth name. The default value is cce-bandwidth-******. Value range: 1 to 64 characters, including lowercase letters, digits, and underscores (_). The value must start with a lowercase letter and end with a lowercase letter or digit. |
bandwidth_chargemode |
No |
String |
Bandwidth mode. |
bandwidth_size |
Yes for public network load balancers |
Integer |
Bandwidth size. The default value is 1 to 2000 Mbit/s. Set this parameter based on the bandwidth range allowed in your region. |
bandwidth_sharetype |
Yes for public network load balancers |
String |
Bandwidth sharing mode.
|
eip_type |
Yes for public network load balancers |
String |
EIP type.
|
available_zone |
Yes |
Array of strings |
AZ where the load balancer is located. This parameter is available only for dedicated load balancers. |
l4_flavor_name |
Yes |
String |
Flavor name of the layer-4 load balancer. This parameter is available only for dedicated load balancers. |
l7_flavor_name |
No |
String |
Flavor name of the layer-7 load balancer. This parameter is available only for dedicated load balancers. |
elb_virsubnet_ids |
No |
Array of strings |
Subnet where the backend server of the load balancer is located. If this parameter is left blank, the default cluster subnet is used. Load balancers occupy different number of subnet IP addresses based on their specifications. Therefore, you are not advised to use the subnet CIDR blocks of other resources (such as clusters and nodes) as the load balancer CIDR block. This parameter is available only for dedicated load balancers. Example: "elb_virsubnet_ids": [ "14567f27-8ae4-42b8-ae47-9f847a4690dd" ] |
kubectl create -f nginx-deployment.yaml
If information similar to the following is displayed, the workload is being created.
deployment/nginx created
kubectl get po
If information similar to the following is displayed, the workload is running.
NAME READY STATUS RESTARTS AGE nginx-2601814895-c1xhw 1/1 Running 0 6s
kubectl create -f nginx-elb-svc.yaml
If information similar to the following is displayed, the Service has been created.
service/nginx created
kubectl get svc
If information similar to the following is displayed, the access type has been set successfully, and the workload is accessible.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.247.0.1 <none> 443/TCP 3d nginx LoadBalancer 10.247.130.196 10.78.42.242 80:31540/TCP 51s
The Nginx is accessible.
After a Service of the LoadBalancer type is created, you can view the listener forwarding rules of the load balancer on the ELB console.
You can find that a listener is created for the load balancer. Its backend server is the node where the pod is located, and the backend server port is the NodePort (node port) of the Service. When traffic passes through ELB, it is forwarded to IP address of the node where the pod is located:Node port. That is, the Service is accessed and then the pod is accessed, which is the same as that described in Scenario.
In the passthrough networking scenario (CCE Turbo + dedicated load balancer), after a LoadBalancer Service is created, you can view the listener forwarding rules of the load balancer on the ELB console.
You can see that a listener is created for the load balancer. The backend server address is the IP address of the pod, and the service port is the container port. This is because the pod uses an ENI or sub-ENI. When traffic passes through the load balancer, it directly forwards the traffic to the pod. This is the same as that described in Scenario.
upstream connect error or disconnect/reset before headers. reset reason: connection failure
This is because when the LoadBalancer Service is created, kube-proxy adds the ELB access address as the external IP to iptables or IPVS. If a client initiates a request to access the ELB address from inside the cluster, the address is considered as the external IP address of the service and is directly forwarded by kube-proxy without passing through the ELB outside the cluster.
When the value of externalTrafficPolicy is Local, the situation varies according to the container network model and service forwarding mode. The details are as follows:
Server |
Client |
Container Tunnel Network Cluster (IPVS) |
VPC Network Cluster (IPVS) |
Container Tunnel Network Cluster (iptables) |
VPC Network Cluster (iptables) |
NodePort Service |
Same node |
OK. The node where the pod runs is accessible, not any other nodes. |
OK. The node where the pod runs is accessible. |
OK. The node where the pod runs is accessible. |
OK. The node where the pod runs is accessible. |
Cross-node |
OK. The node where the pod runs is accessible, not any other nodes. |
OK. The node where the pod runs is accessible. |
OK. The node where the pod runs is accessible by visiting the node IP + port, not by any other ways. |
OK. The node where the pod runs is accessible by visiting the node IP + port, not by any other ways. |
|
Containers on the same node |
OK. The node where the pod runs is accessible, not any other nodes. |
OK. The node where the pod runs is not accessible. |
OK. The node where the pod runs is accessible. |
OK. The node where the pod runs is not accessible. |
|
Containers across nodes |
OK. The node where the pod runs is accessible, not any other nodes. |
OK. The node where the pod runs is accessible. |
OK. The node where the pod runs is accessible. |
OK. The node where the pod runs is accessible. |
|
LoadBalancer Service using a dedicated load balancer |
Same node |
Accessible for public networks, not private networks. |
Accessible for public networks, not private networks. |
Accessible for public networks, not private networks. |
Accessible for public networks, not private networks. |
Containers on the same node |
Accessible for public networks, not private networks. |
Accessible for public networks, not private networks. |
Accessible for public networks, not private networks. |
Accessible for public networks, not private networks. |
|
Local Service of the nginx-ingress add-on using a dedicated load balancer |
Same node |
Accessible for public networks, not private networks. |
Accessible for public networks, not private networks. |
Accessible for public networks, not private networks. |
Accessible for public networks, not private networks. |
Containers on the same node |
Accessible for public networks, not private networks. |
Accessible for public networks, not private networks. |
Accessible for public networks, not private networks. |
Accessible for public networks, not private networks. |
The following methods can be used to solve this problem:
apiVersion: v1 kind: Service metadata: annotations: kubernetes.io/elb.class: union kubernetes.io/elb.autocreate: '{"type":"public","bandwidth_name":"cce-bandwidth","bandwidth_chargemode":"bandwidth","bandwidth_size":5,"bandwidth_sharetype":"PER","eip_type":"5_bgp","name":"james"}' labels: app: nginx name: nginx spec: externalTrafficPolicy: Cluster ports: - name: service0 port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: LoadBalancer