<p>I want to change the IP address of my LoadBalancer ingress-nginx-controller in Google Cloud. I have now assigned the IP address via LoadBalancer. See the screenshot. Unfortunately it is not adopted in GKE. Why? Is that a bug?
<a href="https://i.stack.imgur.com/IdOPR.png" rel="nofollow noreferrer">GKE lb IP address change</a></p>

<p>I have verified this on my <code>GKE</code> test cluster.</p>
<p>When you <a href="https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address" rel="nofollow noreferrer">Reserving a static external IP address</a> it isn't assigned to any of your VMs. Depends on how you <code>created cluster</code>/<code>reserved ip</code> (standard or premium) you can get error like below:</p>
<pre><code>Error syncing load balancer: failed to ensure load balancer: failed to create forwarding rule for load balancer (a574130f333b143a2a62281ef47c8dbb(default/nginx-ingress-controller)): googleapi: Error 400: PREMIUM network tier (the project's default network tier) is not supported: The network tier of specified IP address is STANDARD, that of Forwarding Rule must be the same., badRequest
</code></pre>
<p>In this scenario I've used cluster based in <code>us-central-1c</code> and <code>reserved IP</code> as <code>Network Service Tier: Premium</code>, <code>Type: Regional</code> and used region where my cluster is based - <code>us-central-1.</code> My <code>ExternalIP: 34.66.79.1X8</code></p>
<p><strong>NOTE</strong> <code>Reserved IP must be in the same reagion as your cluster</code></p>
<p><strong>Option 1:</strong> - Use <a href="https://helm.sh/" rel="nofollow noreferrer">Helm chart</a></p>
<p>Deploy Nginx</p>
<pre><code>helm install nginx-ingress stable/nginx-ingress  --set controller.service.loadBalancerIP=34.66.79.1X8,rbac.create=true
</code></pre>
<p>Service output:</p>
<pre><code>$ kubectl get svc
NAME                            TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)                      AGE
kubernetes                      ClusterIP      10.8.0.1      &lt;none&gt;        443/TCP                      5h49m
nginx-ingress-controller        LoadBalancer   10.8.5.158    &lt;pending&gt;     80:31898/TCP,443:30554/TCP   27s
nginx-ingress-default-backend   ClusterIP      10.8.13.209   &lt;none&gt;        80/TCP                       27s
</code></pre>
<p>Service describe output:</p>
<pre><code>$ kubectl describe svc nginx-ingress-controller
...
Events:
  Type    Reason                Age   From                Message
  ----    ------                ----  ----                -------
  Normal  EnsuringLoadBalancer  32s   service-controller  Ensuring load balancer
  Normal  EnsuredLoadBalancer   5s    service-controller  Ensured load balancer
</code></pre>
<p>Final output:</p>
<pre><code>$ kubectl get svc
NAME                            TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)                      AGE
kubernetes                      ClusterIP      10.8.0.1      &lt;none&gt;         443/TCP                      5h49m
nginx-ingress-controller        LoadBalancer   10.8.5.158    34.66.79.1X8   80:31898/TCP,443:30554/TCP   35s
nginx-ingress-default-backend   ClusterIP      10.8.13.209   &lt;none&gt;         80/TCP                       35s
</code></pre>
<p><strong>Option 2</strong> - Editing <a href="https://kubernetes.github.io/ingress-nginx/deploy/#gce-gke" rel="nofollow noreferrer">Nginx</a> YAMLs before deploying Nginx</p>
<p>As per docs:
Initialize your user as a cluster-admin with the following command:</p>
<pre><code>kubectl create clusterrolebinding cluster-admin-binding \
  --clusterrole cluster-admin \
  --user $(gcloud config get-value account)
</code></pre>
<p>Download YAML</p>
<pre><code>$ wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.35.0/deploy/static/provider/cloud/deploy.yaml
</code></pre>
<p>Edit <code>LoadBalancer</code> service and add <code>loadBalancerIP: &lt;your-reserved-ip&gt;</code> like below:</p>
<pre><code># Source: ingress-nginx/templates/controller-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    helm.sh/chart: ingress-nginx-2.13.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.35.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: LoadBalancer
  loadBalancerIP: 34.66.79.1x8             #This line
  externalTrafficPolicy: Local
  ports:
</code></pre>
<p>Deploy it <code>kubectl apply -f deploy.yaml</code>. Service output below:</p>
<pre><code>$ kubectl get svc -A
NAMESPACE       NAME                                 TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)                      AGE
default         kubernetes                           ClusterIP      10.8.0.1     &lt;none&gt;        443/TCP                      6h6m
ingress-nginx   ingress-nginx-controller             LoadBalancer   10.8.5.165   &lt;pending&gt;     80:31226/TCP,443:31161/TCP   17s
ingress-nginx   ingress-nginx-controller-admission   ClusterIP      10.8.9.216   &lt;none&gt;        443/TCP                      18s
                   6h6m
...
</code></pre>
<p>Describe output:</p>
<pre><code>$ kubectl describe svc ingress-nginx-controller -n ingress-nginx
Events:
  Type    Reason                Age   From                Message
  ----    ------                ----  ----                -------
  Normal  EnsuringLoadBalancer  40s   service-controller  Ensuring load balancer
  Normal  EnsuredLoadBalancer   2s    service-controller  Ensured load balancer
</code></pre>
<p>Service with reserved IP:</p>
<pre><code>$ kubectl get svc -n ingress-nginx
NAME                                 TYPE           CLUSTER-IP   EXTERNAL-IP    PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.8.5.165   34.66.79.1X8   80:31226/TCP,443:31161/TCP   2m22s
ingress-nginx-controller-admission   ClusterIP      10.8.9.216   &lt;none&gt;         443/TCP                      2m23s
</code></pre>
<p><strong>In Addition</strong></p>
<p>Also please keep in mind that you should add <code>annotations: kubernetes.io/ingress.class: nginx</code> in your <code>ingress</code> resource when you want force <code>GKE</code> to use <code>Nginx Ingress</code> features, like <a href="https://kubernetes.github.io/ingress-nginx/examples/rewrite/" rel="nofollow noreferrer">rewrite</a>.</p>
