# "Network Tier" in GKE Service with type: LoadBalancer

## About

* [https://cloud.google.com/network-tiers](https://cloud.google.com/network-tiers)
    
* GKE: v1.27
    

## Steps

Starting YAML:

```yaml
---
apiVersion: v1
kind: Service
metadata:
  annotations:
    cloud.google.com/neg: '{"ingress":true}'
  name: lb
  namespace: tests
spec:
  allocateLoadBalancerNodePorts: false
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  ports:
    - name: tcp-hello
      port: 9001
      protocol: TCP
      targetPort: hello
  selector:
    hello: "world"
  sessionAffinity: None
  type: LoadBalancer
```

It creates a GCP Load Balancer with IP with network tier: `Premium` even if default network tier ([https://console.cloud.google.com/net-tier/tiers/details](https://console.cloud.google.com/net-tier/tiers/details)) is set to `Standard`.

### Add annotation

```yaml
metadata:
  annotations:
    cloud.google.com/network-tier: Standard
```

* IP address converts to network tier Standard.
    
* It takes around 1 minute.
    
* It can be changed in both directions (Standard &lt;-&gt; Premium).
    
* IP address changes every time.
    

### Pre-configure IP address and use it

I assume that if `cloud.google.com/network-tier` is the same as the network tier of an IP address it works without any problems.

What if they are conflicted?

```plaintext
# Terraform
resource "google_compute_address" "my_ip" {
  name         = "my-ip"
  network_tier = "Standard"
}
```

Add to YAML:

```yaml
metadata:
  annotations:
    cloud.google.com/network-tier: Premium
spec:
  loadBalancerIP: "a.b.c.d"
```

Result:

It fails with `Error syncing load balancer: failed to ensure load balancer: requested IP "a.b.c.d" belongs to the Standard network tier; expected Premium`

### What if don't define "cloud.google.com/network-tier" and change the network tier of an IP?

1\. Apply YAML without `cloud.google.com/network-tier`, but with specific IP (Premium).

2\. Create another IP address with Standard network tier.

3\. Change `loadBalancerIP` in YAML and apply.  
For me it partially failed:

```yaml
kubectl -n tests describe svc lb
...
Events:
  Type     Reason                  Age                   From                Message
  ----     ------                  ----                  ----                -------
  Normal   EnsuredLoadBalancer     10m                   service-controller  Ensured load balancer
  Normal   LoadbalancerIP          8m26s                 service-controller  old_ip -> new_ip
```

However, the `status` field of the Service still uses old ip.

```yaml
status:
  loadBalancer:
    ingress:
    - ip: old_ip
```

And GCP console shows that the new IP isn't attached to anything. Old IP is still used.

I tried to modify the `status` field manually with `kubectl -n tests edit svc lb --subresource=status` but it didn't work - LoadBalancer went into Pending state and got stuck.

<div data-node-type="callout">
<div data-node-type="callout-emoji">❗</div>
<div data-node-type="callout-text">I didn't find a solution on how to make GKE/K8s to update an IP properly.</div>
</div>
