how to make already exposed service not to be exposed? - kubernetes

I deployed a (LoadBalancer) service for a pod on my minikube cluster, then exposed it via minikube service [my_service] command. Now I tried to "turn off the exposure" but couldn't find any way to do this, except deleting it what I would like to avoid. Is it possible to just turn off the exposure, not deleting (and redeploying) the existing already exposed service?

Background
In Kubernetes documentation regarding ServiceTypes, you can find information that if you want to expose your cluster outside you have to use NodePort or LoadBalancer.
If you want to keep your service/application in cluster, you should use ClusterIP:
Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default ServiceType.
Depends on your version, you can edit it or use workaround. For example in K8s 1.16 you won't be able as some errors might occurs.
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.8.0.1 <none> 443/TCP 3d20h
my-nginx LoadBalancer 10.8.14.224 34.121.77.108 80:32039/TCP 3m16s
$ kubectl patch service my-nginx -p '{"spec":{"type":"ClusterIP"}}'
The Service "my-nginx" is invalid: spec.ports[0].nodePort: Forbidden: may not be used when `type` is 'ClusterIP'
Solutions
However as you are using Minikube so I guess you are using newer version (1.20), so you can change it using:
kubectl edit
kubectl edit svc <yourSvcName> and change type to ClusterIP.
It will open Vi editor, where you can change spec.type to ClusterIP or just remove it as default type for Kubernetes service is ClusterIP so if it won't be specified, Kubernetes will automatically use ClusterIP.
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 25s
my-nginx LoadBalancer 10.107.129.201 <pending> 80:30173/TCP 8s
minikube-new:~$ kubectl edit svc my-nginx
service/my-nginx edited
sekreta#minikube-new:~$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 46s
my-nginx ClusterIP 10.107.129.201 <none> 80/TCP 29s
kubectl patch
$ kubectl patch service <yourServiceName> -p '{"spec":{"type":"ClusterIP"}}'
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10m
my-nginx LoadBalancer 10.107.129.201 <pending> 80:30456/TCP 2m
minikube-new:~$ kubectl patch service my-nginx -p '{"spec":{"type":"ClusterIP"}}'
service/my-nginx patched
minikube-new:~$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10m
my-nginx ClusterIP 10.107.129.201 <none> 80/TCP 3m
kubectl apply
You can edit your Yaml and remove spec.type or have 2 Yamls with ClusterIP and LoadBalancer and switch them depends on your needs.
$ kubectl apply -f svc.yaml
service/my-nginx configured
minikube-new:~$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22m
my-nginx ClusterIP 10.111.237.133 <none> 80/TCP 16s
Use some 3rd party software to make changes in your cluster like Helm and using templates.

Related

minikube - not able to access EXTERNAL-IP

I am using minikube on Windows 10 with docker driver.
I installed dvwa-web by following this guide: https://github.com/cytopia/docker-dvwa/tree/master/k8s
Got it installed, and this is the output:
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dvwa-mysql-service ClusterIP 10.104.172.238 <none> 3306/TCP 69s
dvwa-web-service LoadBalancer 10.106.62.70 192.168.49.20 8081:30789/TCP 69s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7m41s
The tutorial says I can access it through: http://192.168.49.20:8081
However, I could not when I tried.
when I issue command minikube service dvwa-web-service --url , I get this:
http://127.0.0.1:14176
and I can access it.
What is the problem? why I cannot access the app through EXTERNAL-IP?
Thanks.

kubectl patch returning service not found

I have deployed pihole on my k3s cluster using this helm chart https://github.com/MoJo2600/pihole-kubernetes.
(I used this tutorial)
I now have my services but they dont have external IPs:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
pihole-web ClusterIP 10.43.58.197 <none> 80/TCP,443/TCP 11h
pihole-dns-udp NodePort 10.43.248.252 <none> 53:30451/UDP 11h
pihole-dns-tcp NodePort 10.43.248.144 <none> 53:32260/TCP 11h
pihole-dhcp NodePort 10.43.96.49 <none> 67:30979/UDP 11h
I have tried to assing the IPs manually with this command:
kubectl patch svc pihole-dns-tcp -p '{"spec":{"externalIPs":["192.168.178.210"]}}'
But when executing the command i'm getting this error:
Error from server (NotFound): services "pihole-dns-tcp" not found
Any Ideas for a fix?
Thank you in advance :)
Looks Like "pihole-dns-tcp" is in a different namespace to the namespace where patch command is being ran.
As per the article you have shared , it seems like service pihole-dns-tcp is in pihole . So the command should be
kubectl patch svc pihole-dns-tcp -n pihole -p '{"spec":{"externalIPs":["192.168.178.210"]}}'

Change the IP address of my LoadBalancer on GKE

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?
GKE lb IP address change
I have verified this on my GKE test cluster.
When you Reserving a static external IP address it isn't assigned to any of your VMs. Depends on how you created cluster/reserved ip (standard or premium) you can get error like below:
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
In this scenario I've used cluster based in us-central-1c and reserved IP as Network Service Tier: Premium, Type: Regional and used region where my cluster is based - us-central-1. My ExternalIP: 34.66.79.1X8
NOTE Reserved IP must be in the same reagion as your cluster
Option 1: - Use Helm chart
Deploy Nginx
helm install nginx-ingress stable/nginx-ingress --set controller.service.loadBalancerIP=34.66.79.1X8,rbac.create=true
Service output:
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.8.0.1 <none> 443/TCP 5h49m
nginx-ingress-controller LoadBalancer 10.8.5.158 <pending> 80:31898/TCP,443:30554/TCP 27s
nginx-ingress-default-backend ClusterIP 10.8.13.209 <none> 80/TCP 27s
Service describe output:
$ 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
Final output:
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.8.0.1 <none> 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 <none> 80/TCP 35s
Option 2 - Editing Nginx YAMLs before deploying Nginx
As per docs:
Initialize your user as a cluster-admin with the following command:
kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole cluster-admin \
--user $(gcloud config get-value account)
Download YAML
$ wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.35.0/deploy/static/provider/cloud/deploy.yaml
Edit LoadBalancer service and add loadBalancerIP: <your-reserved-ip> like below:
# 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:
Deploy it kubectl apply -f deploy.yaml. Service output below:
$ kubectl get svc -A
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.8.0.1 <none> 443/TCP 6h6m
ingress-nginx ingress-nginx-controller LoadBalancer 10.8.5.165 <pending> 80:31226/TCP,443:31161/TCP 17s
ingress-nginx ingress-nginx-controller-admission ClusterIP 10.8.9.216 <none> 443/TCP 18s
6h6m
...
Describe output:
$ 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
Service with reserved IP:
$ 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 <none> 443/TCP 2m23s
In Addition
Also please keep in mind that you should add annotations: kubernetes.io/ingress.class: nginx in your ingress resource when you want force GKE to use Nginx Ingress features, like rewrite.

How to get FQDN DNS name of a kubernetes service?

How to get a full FQDN of the service inside Kubernetes?
➜ k get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
airflow-flower-service ClusterIP 172.20.119.107 <none> 5555/TCP 20d app=edna-airflow
airflow-service ClusterIP 172.20.76.63 <none> 80/TCP 20d app=edna-airflow
backend-service ClusterIP 172.20.39.154 <none> 80/TCP 20d app=edna-backend
so how to query internal Kubernetes DNS to get the FQDN of the backend-service for example?
Go inside any pod in the same namespace with kubectl exec -ti <your pod> bash and then run nslookup <your service> which will typically be, unless you change some configurations in the cluster to: yourservice.yournamespace.svc.cluster.local

How to assign an IP to istio-ingressgateway on localhost?

I am using kubespray to run a kubernetes cluster on my laptop. The cluster is running on 7 VMs and the roles of the VM's spread as follows:
NAME STATUS ROLES AGE VERSION
k8s-1 Ready master 2d22h v1.16.2
k8s-2 Ready master 2d22h v1.16.2
k8s-3 Ready master 2d22h v1.16.2
k8s-4 Ready master 2d22h v1.16.2
k8s-5 Ready <none> 2d22h v1.16.2
k8s-6 Ready <none> 2d22h v1.16.2
k8s-7 Ready <none> 2d22h v1.16.2
I've installed https://istio.io/ to build a microservices environment.
I have 2 services running and like to access from outside:
k get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
greeter-service ClusterIP 10.233.50.109 <none> 3000/TCP 47h
helloweb ClusterIP 10.233.8.207 <none> 3000/TCP 47h
and the running pods:
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
default greeter-service-v1-8d97f9bcd-2hf4x 2/2 Running 0 47h 10.233.69.7 k8s-6 <none> <none>
default greeter-service-v1-8d97f9bcd-gnsvp 2/2 Running 0 47h 10.233.65.3 k8s-2 <none> <none>
default greeter-service-v1-8d97f9bcd-lkt6p 2/2 Running 0 47h 10.233.68.9 k8s-7 <none> <none>
default helloweb-77c9476f6d-7f76v 2/2 Running 0 47h 10.233.64.3 k8s-1 <none> <none>
default helloweb-77c9476f6d-pj494 2/2 Running 0 47h 10.233.69.8 k8s-6 <none> <none>
default helloweb-77c9476f6d-tnqfb 2/2 Running 0 47h 10.233.70.7 k8s-5 <none> <none>
The problem is, I can not access the services from outside, because I do not have the EXTERNAL IP address(remember the cluster is running on my laptop).
k get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.233.61.112 <pending> 15020:31311/TCP,80:30383/TCP,443:31494/TCP,15029:31383/TCP,15030:30784/TCP,15031:30322/TCP,15032:30823/TCP,15443:30401/TCP 47h
As you can see, the column EXTERNAL-IP the value is <pending>.
The question is, how to assign an EXTERNAL-IP to the istio-ingressgateway.
First of all, you can't make k8s to assign you an external IP address, as LoadBalancer service is Cloud Provider specific. You could push your router external IP address to be mapped to it, I guess, but it is not trivial.
To reach the service, you can do this:
kubectl edit svc istio-ingressgateway -n istio-system
Change the type of the service from LoadBalancer to ClusterIp. You can also do NodePort. Actually you can skip this step, as LoadBalancer service already contains NodePort and ClusterIp. It is just to get rid of that pending status.
kubectl port-forward svc/istio-ingressgateway YOUR_LAPTOP_PORT:INGRESS_CLUSTER_IP_PORT -n istio-system
I don't know to which port you want to access from your localhost. Say 80, you can do:
kubectl port-forward svc/istio-ingressgateway 8080:80 -n istio-system
Now port 8080 of your laptop (localhost:8080) will be mapped to the port 80 of istio-ingressgateway service.
By default, there is no way Kubernetes can assign external IP to LoadBalancer service.
This service type needs infrastructure support which works in cloud offerings like GKE, AKS, EKS etc.
As you are running this cluster inside your laptop, deploy MetalLB Load Balancer to get EXTERNAL-IP
It's not possible as Suresh explained.
But if you want to access from your laptop you can use in your service type: NodePort, which gives you access from outside the cluster.
You should first obtain the IP of your cluster, then create your service with something like this:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
type: NodePort
ports:
- name: http
protocol: TCP
port: 3000
targetPort: 3000
nodePort: 30000
After that, you can access from your laptop with: http://cluster-ip:30000
There is no need to create an ingress for that.
You should use a port in range (30000-32767), as stated below:
If you set the type field to NodePort, the Kubernetes control plane allocates a port from a range specified by --service-node-port-range flag (default: 30000-32767).
If you are using minikube, just run:
$ minikube tunnel
$ k get svc -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.111.187.167 127.0.0.1 15021:31949/TCP,80:32215/TCP,443:30585/TCP 9m48s