Why can't load balancer connect to service in GKE? - kubernetes

I am deploying an application on GKE cluster and try to deploy a load balancer to make clients able to call this application.
My application spec is:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: default
spec:
replicas: 1
selector:
matchLabels:
name: api
template:
metadata:
labels:
name: api
spec:
serviceAccountName: docker-sa
containers:
- name: api
image: zhaoyi0113/rancher-go-api
ports:
- containerPort: 8080
apiVersion: v1
kind: Service
metadata:
name: api
annotations:
cloud.google.com/neg: '{"ingress": true}'
spec:
selector:
name: api
ports:
- port: 80
targetPort: 8080
protocol: TCP
type: NodePort
It listens on the port 8080 and a service open port 80 and use the targetPort 8080 to connect to the application.
And I have a ingress spec:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: sidecar
namespace: default
spec:
defaultBackend:
service:
name: api
port:
number: 80
After deploy, I am able to see the ip address from kubectl get ingress. But when I send a request to the ip, I got 502 error.
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
sidecar <none> * 107.178.245.193 80 28m
$ kubectl describe ingress sidecar
Name: sidecar
Labels: <none>
Namespace: default
Address: 107.178.245.193
Default backend: api:80 (10.0.1.14:8080)
Rules:
Host Path Backends
---- ---- --------
* * api:80 (10.0.1.14:8080)
Annotations: ingress.kubernetes.io/backends: {"k8s1-5ae02eec-default-api-80-28d7bbec":"Unknown"}
ingress.kubernetes.io/forwarding-rule: k8s2-fr-krllp0c9-default-sidecar-9a9n4r5m
ingress.kubernetes.io/target-proxy: k8s2-tp-krllp0c9-default-sidecar-9a9n4r5m
ingress.kubernetes.io/url-map: k8s2-um-krllp0c9-default-sidecar-9a9n4r5m
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 29m loadbalancer-controller UrlMap "k8s2-um-krllp0c9-default-sidecar-9a9n4r5m" created
Normal Sync 28m loadbalancer-controller TargetProxy "k8s2-tp-krllp0c9-default-sidecar-9a9n4r5m" created
Normal Sync 28m loadbalancer-controller ForwardingRule "k8s2-fr-krllp0c9-default-sidecar-9a9n4r5m" created
Normal IPChanged 28m loadbalancer-controller IP is now 107.178.245.193
Normal Sync 3m51s (x7 over 29m) loadbalancer-controller Scheduled for sync
Below is the curl error response:
$ curl -i http://107.178.245.193/health
HTTP/1.1 502 Bad Gateway
Content-Type: text/html; charset=UTF-8
Referrer-Policy: no-referrer
Content-Length: 332
Date: Tue, 16 Aug 2022 10:40:31 GMT
<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>502 Server Error</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Server Error</h1>
<h2>The server encountered a temporary error and could not complete your request.<p>Please try again in 30 seconds.</h2>
<h2></h2>
</body></html>
When I describe the service api, I got below error:
$ kubectl describe service api
Name: api
Namespace: default
Labels: <none>
Annotations: cloud.google.com/neg: {"ingress": true}
cloud.google.com/neg-status: {"network_endpoint_groups":{"80":"k8s1-29362abf-default-api-80-f2f1248a"},"zones":["australia-southeast2-a"]}
field.cattle.io/publicEndpoints: [{"port":30084,"protocol":"TCP","serviceName":"default:api","allNodes":true}]
Selector: name=api
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.3.253.54
IPs: 10.3.253.54
Port: <unset> 80/TCP
TargetPort: 8080/TCP
NodePort: <unset> 30084/TCP
Endpoints: 10.0.1.17:8080
Session Affinity: None
External Traffic Policy: Cluster
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning AttachFailed 7s neg-controller Failed to Attach 2 network endpoint(s) (NEG "k8s1-29362abf-default-api-80-f2f1248a" in zone "australia-southeast2-a"): googleapi: Error 400: Invalid value for field 'resource.ipAddress': '10.0.1.18'. Specified IP address 10.0.1.18 doesn't belong to the (sub)network default or to the instance gke-gcp-cqrs-gcp-cqrs-node-pool-6b30ca5c-41q8., invalid
Warning RetryFailed 7s neg-controller Failed to retry NEG sync for "default/api-k8s1-29362abf-default-api-80-f2f1248a--/80-8080-GCE_VM_IP_PORT-L7": maximum retry exceeded
Does anyone know what could be the root course?

I created a new GKE cluster and tried setting up the same resources you are configuring. However, I used the following image for the container gcr.io/google-samples/hello-app:1.0. Everything else remains the same - leaving the gcp-setup.yaml file I used below for reference.
gcp-setup.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: default
spec:
replicas: 1
selector:
matchLabels:
name: api
template:
metadata:
labels:
name: api
spec:
containers:
- name: api
image: gcr.io/google-samples/hello-app:1.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: api
annotations:
cloud.google.com/neg: '{"ingress": true}'
spec:
selector:
name: api
ports:
- port: 80
targetPort: 8080
protocol: TCP
type: NodePort
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: sidecar
namespace: default
spec:
defaultBackend:
service:
name: api
port:
number: 80
There is also a small thing I had to change in your configuration, which is the annotation block - when I first tried to apply your configuration, I got the below error. Hence, I had to adjust the annotation entry to be annotations.
> kubectl apply -f gcp-setup.yaml
deployment.apps/api created
error: error validating "gcp-setup.yaml": error validating data: ValidationError(Service.metadata): unknown field "annotation" in io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta; if you choose to ignore these errors, turn validation off with --validate=false
Afterwards, I was able to successfully provision all of the resources, and your configuration worked perfectly fine. It took around 3 minutes I believe for the Ingress resource to get an IP address assigned (masked as XX.XXX.XXX.XX below).
> kubectl get pods
NAME READY STATUS RESTARTS AGE
api-7d6fdd9845-8dwqc 1/1 Running 0 7m13s
> kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
api NodePort 10.36.4.150 <none> 80:30142/TCP 7m1s
kubernetes ClusterIP 10.36.0.1 <none> 443/TCP 12m
> kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
sidecar <none> * XX.XXX.XXX.XX 80 7m18s
> kubectl describe ingress
Name: sidecar
Namespace: default
Address: XX.XXX.XXX.XX
Default backend: api:80 (10.32.0.10:8080)
Rules:
Host Path Backends
---- ---- --------
* * api:80 (10.32.0.10:8080)
Annotations: ingress.kubernetes.io/backends: {"k8s1-05f3ce8b-default-api-80-82dd4d72":"HEALTHY"}
ingress.kubernetes.io/forwarding-rule: k8s2-fr-9k4w4ytx-default-sidecar-9m5g4dex
ingress.kubernetes.io/target-proxy: k8s2-tp-9k4w4ytx-default-sidecar-9m5g4dex
ingress.kubernetes.io/url-map: k8s2-um-9k4w4ytx-default-sidecar-9m5g4dex
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 7m13s loadbalancer-controller UrlMap "k8s2-um-9k4w4ytx-default-sidecar-9m5g4dex" created
Normal Sync 7m10s loadbalancer-controller TargetProxy "k8s2-tp-9k4w4ytx-default-sidecar-9m5g4dex" created
Normal Sync 6m59s loadbalancer-controller ForwardingRule "k8s2-fr-9k4w4ytx-default-sidecar-9m5g4dex" created
Normal IPChanged 6m59s loadbalancer-controller IP is now XX.XXX.XXX.XX
Normal Sync 28s (x6 over 8m3s) loadbalancer-controller Scheduled for sync
After the Ingress resource became healthy, I was able to navigate in my browser to the assigned IP address XX.XXX.XXX.XX and got a successful response back from the workload I deployed (gcr.io/google-samples/hello-app:1.0).
Browser Output
Hello, world!
Version: 1.0.0
Hostname: api-7d6fdd9845-8dwqc
As a conclusion, make sure to update your Service definition from metadata.annotation to metadata.annotations. It was the only change I had to do to make your configuration work. Furthermore, I recommend turning resource definition validation on to make sure that you catch such errors when defining new resources.
If the error still persists, I would recommend running kubectl describe ingress sidecar and analyze the output, assuming it is related to the Ingress resource definition.
EDIT1
To make sure that this is not a zone-related issue, I provisioned a VPC-native, Public cluster in the same zone that you are using (australia-southeast2-a). I then applied the same configuration, and it was successful, thus ruling out the zone-related topic.
Based on the additional information you included in the post, my best guess for some potential root causes for the Service error you're getting when running kubectl describe service would be:
Your GKE cluster is not VPC-native - I see this is a core requirement to be able to leverage NEG
Your GKE cluster has been provisioned as a Private cluster, and as a consequence, NEG tries to assign an IP address from the available Private subnet ranges. This would explain the 10.0.1.18 IP address that NEG tries to assign to the resource definition

Related

Kubernates Nginx-Ingress rule not working

I installed the ingress controller using the following command:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/cloud/deploy.yaml
And the result of kubectl get pods --namespace=ingress-nginx is:
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-x4mss 0/1 Completed 0 28m
ingress-nginx-admission-patch-jn9cz 0/1 Completed 1 28m
ingress-nginx-controller-8574b6d7c9-k4jbj 1/1 Running 0 28m
For kubectl get service ingress-nginx-controller --namespace=ingress-nginx I get:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.106.134.128 localhost 80:32294/TCP,443:30997/TCP 30m
As for my deployment and service I have the following:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: app
name: app
namespace: namespace
spec:
replicas: 1
selector:
matchLabels:
app: app
template:
labels:
app: app
spec:
containers:
- image: image
name: app
ports:
- containerPort: 5000
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: app-service
namespace: namespace
spec:
type: ClusterIP
selector:
app: app
ports:
- name: app-service
port: 5000
targetPort: 5000
My Ingress is as follows:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
namespace: namespace
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: com.host.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 5000
My pod and service are both running fine.
The result of running kubectl describe pod command is:
Name: app-6b9f7fc47b-sh6nc
Namespace: namespace
Priority: 0
Service Account: default
Node: docker-desktop/192.168.65.4
Start Time: Wed, 30 Nov 2022 16:22:04 -0500
Labels: app=app
pod-template-hash=6b9f7fc47b
Status: Running
IP: 10.1.0.237
IPs:
IP: 10.1.0.237
Controlled By: ReplicaSet/app-6b9f7fc47b
Containers:
app:
Container ID: docker://ba77235d044c24b0f1391c56a2e8653a598a5c130ea4d15ff3b41cd96659fd4a
Image: image
Image ID: docker://sha256:912cb58ab1c3f2dd628c0b7db4d7f9ac6df4efbe4fcb86979b6a84614db8a675
Port: 5000/TCP
Host Port: 0/TCP
State: Running
Started: Wed, 30 Nov 2022 16:22:05 -0500
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-8pmjz (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-8pmjz:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 29m default-scheduler Successfully assigned namespace/app-6b9f7fc47b-sh6nc to docker-desktop
Normal Pulled 29m kubelet Container image "image" already present on machine
Normal Created 29m kubelet Created container app
Normal Started 29m kubelet Started container app
Running the following command kubectl get ingress --all-namespaces yields:
NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE
namespace ingress nginx com.host.com 80 7s
I have tried using different ports, changing the controller, using a load balance type instead of cluster ip and yet nothing works when it comes to trying to make the ingress rule work. I have set the ingress-controller external ip as com.host.com in my hosts file as well. Furthermore, I am using docker-desktop as my node, however, I'm having this issue on minikube as well. Any help is appreciated.
Your container's containerPort is 3000 while your service targetPort is 5000. Make sure that your service' targetPort, your container's containerPort and last but not least the listening port of your app are all the same.
Update:
So I guess it turned out that the problem is with name resolution.
com.host.com is not resolvable on your machine.
Using the localhost or 127.0.0.1 didn't match the host from the ingress rule -> that's why the default 404 handler was chosen.
So either fix name resolution or remove the host from the ingress rule.
Bear in mind that the ingress controller will only update the IP of the ingress if the mapped service is up and ready. Your ingress shows that it's using app-service on port 5000 as its backend service, but your question does not show a listing of the pods on the namespace namespace where it appears your application pods are. Please could you add that to the question -- it is possible that either your pods aren't coming up successfully, or they're listening on a different port to 5000
UPDATE
Please also try the following:
You're specifying that the container uses port 5000. But is it actually using 5000? try:
kubectl exec -it -n namespace app-6b9f7fc47b-sh6nc -- bash (or sh depending on what the default shell is for your app)
and then try curl localhost:5000 to see if it responds.
Check the ingress controller logs:
kubectl logs -f -n ingress-nginx and see if there's any log messages that might help you identify what's going on.

Should Kubernetes host nodes be able to access services running in the cluster?

I am running:
Kubernetes v1.19.7 (On-premise, VMs. Provisioned via Kubespray)
MetalLB
Calico
nginx-ingress
Summary: Services are refusing to respond when queried from the host nodes. Is this even supposed to work? If not I can stop banging my head against this particular wall...
I am able to access service.foo.com from anywhere on my local network, however if I try to use something like cURL to make a request to service.foo.com from any of the host nodes I get "Connection refused" errors (but I can ping the service with no issue). I get the same behavior from within any pod running on the k8s cluster.
This is making things particularly difficult since I'm trying to set up and OIDC provider to use for gating access to the k8s dashboard, and host node needs to be able to query the provider.
Network Setup:
kube service addresses: 10.233.0.0/18
pods cidr: 10.233.64.0/18
MetalLB config:
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 172.16.31.75-172.16.31.79
Ingress Controller Service described
Name: foo-com-ic-nginx-ingress
Namespace: default
Labels: app.kubernetes.io/instance=foo-com-ic
app.kubernetes.io/managed-by=Helm
app.kubernetes.io/name=foo-com-ic-nginx-ingress
helm.sh/chart=nginx-ingress-0.8.0
Annotations: <none>
Selector: app=foo-com-ic-nginx-ingress
Type: LoadBalancer
IP Families: <none>
IP: 10.233.48.18
IPs: <none>
IP: 172.16.31.76
LoadBalancer Ingress: 172.16.31.76
Port: http 80/TCP
TargetPort: 80/TCP
NodePort: http 31445/TCP
Endpoints: 10.233.105.18:80
Port: https 443/TCP
TargetPort: 443/TCP
NodePort: https 31173/TCP
Endpoints: 10.233.105.18:443
Session Affinity: None
External Traffic Policy: Local
HealthCheck NodePort: 30406
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal nodeAssigned 9m4s (x4 over 43m) metallb-speaker announcing from node "node4"
Service Ingress described
Name: my-service
Namespace: default
Address: 172.16.31.76
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
SNI routes service.foo.com
Rules:
Host Path Backends
---- ---- --------
service.foo.com / my-service:80 (10.233.96.27:80)
Annotations: kubernetes.io/ingress.class: service.com
meta.helm.sh/release-name: my-service
meta.helm.sh/release-namespace: default
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal AddedOrUpdated 46m (x2 over 46m) nginx-ingress-controller Configuration for default/my-service was added or updated
Just in case someone comes across this issue while researching their own, I was eventually able to work around this. By chance I noticed that I could cURL the service from the node that the ingress controller pod was running on.
My work-around then was to change my ingress controller's installation kind from "deployment" to "daemonset". Now that the ingress controller pod runs on every node I am able to access the service from every node in the cluster.

Kubernetes service is configured but get connection refused

I have service configurd on my kuberntes cluster but when I try to curl ip:port I get connection refused
the following service configured :
apiVersion: v1
kind: Service
metadata:
name: frontend
namespace: production
spec:
type: NodePort
selector:
app: frontend
ports:
- name: control-center-web
port: 8008
protocol: TCP
targetPort: 8008
$ kubectl describe svc frontend
Name: frontend
Namespace: production
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"frontend","namespace":"production"},"spec":{"ports":[{"name":...
Selector: app=frontend
Type: NodePort
IP: <ip>
Port: control-center-web 8008/TCP
TargetPort: 8008/TCP
NodePort: control-center-web 7851/TCP
Endpoints: <none>
Session Affinity: None
External Traffic Policy: Cluster
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Type 14m service-controller LoadBalancer -> NodePort
Why do I keep getting connection refuse for ip and port that I took from the svc?
The Endpoints in service has got None instead of IPs of the pods. This happens when the selector in service app: frontend does not match with the selector in pod spec,

Google Kubernetes Engine Ingress doesn't work

Create ingress followed the guide of 'Kubernetes in Action' book on GKE, but the ingress doesn't work, can' be accessed from the public IP address of Ingress.
Create the replicaset to create pod.
Create Service. (followed the nodeport method on 'Kubernetes in Action').
Create ingress.
ReplicaSet, Service, Ingress are created successfully, nodeport can be accessed from the public IP address, no UNHEALTHY in ingress.
replicaset:
apiVersion: apps/v1beta2
kind: ReplicaSet
metadata:
name: kubia
spec:
replicas: 3
selector:
matchLabels:
app: kubia
template:
metadata:
labels:
app: kubia
spec:
containers:
- name: kubia
image: sonyfaye/kubia
Service:
apiVersion: v1
kind: Service
metadata:
name: kubia-nodeport
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
nodePort: 30123
selector:
app: kubia
Ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: kubia
spec:
rules:
- host: kubia.example.com
http:
paths:
- path: /
backend:
serviceName: kubia-nodeport
servicePort: 80
The nodeport itself can be accessed from public IP addresses.
C:\kube>kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.59.240.1 <none> 443/TCP 8d
kubia-nodeport NodePort 10.59.253.10 <none> 80:30123/TCP 20h
C:\kube>kubectl get node
NAME STATUS ROLES AGE VERSION
gke-kubia-default-pool-08dd2133-qbz6 Ready <none> 8d v1.12.8-gke.6
gke-kubia-default-pool-183639fa-18vr Ready <none> 8d v1.12.8-gke.6
gke-kubia-default-pool-42725220-43q8 Ready <none> 8d v1.12.8-gke.6
C:\kube>kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
gke-kubia-default-pool-08dd2133-qbz6 Ready <none> 8d v1.12.8-gke.6 10.140.0.17 35.201.224.238 Container-Optimized OS from Google 4.14.119+ docker://17.3.2
gke-kubia-default-pool-183639fa-18vr Ready <none> 8d v1.12.8-gke.6 10.140.0.18 35.229.152.12 Container-Optimized OS from Google 4.14.119+ docker://17.3.2
gke-kubia-default-pool-42725220-43q8 Ready <none> 8d v1.12.8-gke.6 10.140.0.16 34.80.225.64 Container-Optimized OS from Google 4.14.119+ docker://17.3.2
C:\kube>curl http://34.80.225.64:30123
You've hit kubia-j2lnr
But the ingress can't be accessed from outside.
hosts file:
34.98.92.110 kubia.example.com
C:\kube>kubectl describe ingress
Name: kubia
Namespace: default
Address: 34.98.92.110
Default backend: default-http-backend:80 (10.56.0.7:8080)
Rules:
Host Path Backends
---- ---- --------
kubia.example.com
/ kubia-nodeport:80 (10.56.0.14:8080,10.56.1.6:8080,10.56.3.4:8080)
Annotations:
ingress.kubernetes.io/backends: {"k8s-be-30123--c4addd497b1e0a6d":"HEALTHY","k8s-be-30594--c4addd497b1e0a6d":"HEALTHY"}
ingress.kubernetes.io/forwarding-rule: k8s-fw-default-kubia--c4addd497b1e0a6d
ingress.kubernetes.io/target-proxy: k8s-tp-default-kubia--c4addd497b1e0a6d
ingress.kubernetes.io/url-map: k8s-um-default-kubia--c4addd497b1e0a6d
Events:
<none>
C:\kube>curl http://kubia.example.com
curl: (7) Failed to connect to kubia.example.com port 80: Timed out
C:\kube>telnet kubia.example.com 80
Connecting To kubia.example.com...
C:\kube>telnet 34.98.92.110 80
Connecting To 34.98.92.110...Could not open connection to the host, on port 80: Connect failed
Tried from intranet.
curl 34.98.92.110 IP can get some resule, and 80 port of 34.98.92.110 is accessible from intranet.
C:\kube>kubectl exec -it kubia-lrt9x bash
root#kubia-lrt9x:/# curl http://kubia.example.com
curl: (6) Could not resolve host: kubia.example.com
root#kubia-lrt9x:/# curl http://34.98.92.110
default backend - 404root#kubia-lrt9x:/# curl http://34.98.92.110
default backend - 404root#kubia-lrt9x:/#
root#kubia-lrt9x:/# curl http://10.56.0.7:8080
default backend - 404root#kubia-lrt9x:/#
Does anybody know how to debug this?
The nodeport is been added to the firewall, or else nodeport is not accessible. The Ingress IP seems don't need to be added to the firewall.
Try to expose replicaset to be able to connect from the outside:
$ kubectl expose rs hello-world --type=NodePort --name=my-service
remember to first delete service kubia-nodeport and delete selector and section with service in Ingress configuration file and then apply changes using kubectl apply command.
More information you can find here: exposing-externalip.
Useful doc: kubectl-expose.

Set static external IP for my load balancer on GKE

I am trying to set up a static external IP for my load balancer on GKE but having no luck. Here is my Kubernetes service config file:
kind: Service
apiVersion: v1
metadata:
name: myAppService
spec:
selector:
app: myApp
ports:
- protocol: TCP
port: 3001
targetPort: 3001
type: LoadBalancer
loadBalancerIP: *********
This doesn't work. I expect to see my external IP as ********* but it just says pending:
➜ git:(master) kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ********* <none> 443/TCP 5m
myAppService ********* <pending> 3001:30126/TCP 5m
More details:
➜ git:(master) kubectl describe services
Name: kubernetes
Namespace: default
Labels: component=apiserver
provider=kubernetes
Annotations: <none>
Selector: <none>
Type: ClusterIP
IP: *********
Port: https 443/TCP
Endpoints: *********
Session Affinity: ClientIP
Events: <none>
Name: myAppService
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=myApp
Type: LoadBalancer
IP: *********
Port: <unset> 3001/TCP
NodePort: <unset> 30126/TCP
Endpoints:
Session Affinity: None
Events:
FirstSeen LastSeen Count From SubObjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
5m 20s 7 service-controller Normal CreatingLoadBalancer Creating load balancer
5m 19s 7 service-controller Warning CreatingLoadBalancerFailed Error creating load balancer (will retry): Failed to create load balancer for service default/myAppService: Cannot EnsureLoadBalancer() with no hosts
Any ideas?
I've encountered the same problem, but after reading the docs carefully, it turned out that I was just reserving the static IP incorrectly.
A service of type LoadBalancer creates a network load balancer, which is regional. Therefore, also the static IP address you reserve needs to be regional also (in the regoin of your cluster).
When I changed to this solution, everything worked fine for me...
This got me stuck as well, I hope someone finds this helpful.
In addition to what Dirk said, if you happen to reserve a global static IP address as oppose to a regional one; you need to use Ingres as describe here in documentation: Configuring Domain Names with Static IP Addresses specifically step 2b.
So basically you reserve the static ip gcloud compute addresses create helloweb-ip --global
and add an Ingres:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: helloweb
# this is where you you add your reserved ip
annotations:
kubernetes.io/ingress.global-static-ip-name: helloweb-ip
labels:
app: hello
spec:
backend:
serviceName: helloweb-backend
servicePort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: helloweb-backend
labels:
app: hello
spec:
type: NodePort
selector:
app: hello
tier: web
ports:
- port: 8080
targetPort: 8080
The doc also describe how to assign a static ip if you choose type "LoadBalancer" under step 2a.