What is the meaning of this kubernetes UI error message? - kubernetes

I am running 3 ubuntu server VMs on my local machine and trying to manage with kubernetes.
The UI does not start by itself when using the start script, so I tried to start up the UI manually using:
kubectl create -f addons/kube-ui/kube-ui-rc.yaml --namespace=kube-system
kubectl create -f addons/kube-ui/kube-ui-svc.yaml --namespace=kube-system
The first command succeeds then I get the following for the second command:
error validating "addons/kube-ui/kube-ui-svc.yaml": error validating
data: [field nodePort: is required, field port: is required]; if you
choose to ignore these errors, turn validation off with
--validate=false
So I try editing the default kube-ui-scv file by adding nodePort to the config:
apiVersion: v1
kind: Service
metadata:
name: kube-ui
namespace: kube-system
labels:
k8s-app: kube-ui
kubernetes.io/cluster-service: "true"
kubernetes.io/name: "KubeUI"
spec:
selector:
k8s-app: kube-ui
ports:
- port: 80
targetPort: 8080
nodePort: 30555
But then I get another error after the edit or adding in nodePort:
The Service "kube-ui" is invalid. spec.ports[0].nodePort: invalid
value '30555': cannot specify a node port with services of type
ClusterIP
I cannot get the ui running at my master nodes IP. kubectl get nodes returns correct information. Thanks.

I believe you're running into https://github.com/kubernetes/kubernetes/issues/8901 with the first error, can you set it to 0? Setting NodePort with a service.Type=ClusterIP doesn't make sense, so the second error is legit.

Related

Kubernetes spec.ports required value error

I am running minikube version v1.15.1 on Windows 10 Home.
I started minikube using VirtualBox.
Below is my yaml file
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP
selector:
component: web
ports:
- port: 3000
targetPort: 3000
I am running the command kubectl apply -f filename.yaml for creating the service. Getting error The Service "my-service" is invalid: spec.ports: Required value
I referred documentation and can see that the syntax is correct. Other places i referred were
i. https://github.com/kubernetes/kubernetes/issues/8619 which is having an issue opened for the same. It is closed and requested to follow up on stackoverflow.
ii. The Service "php" is invalid: spec.ports: Required value this thread didn't help me as OP had a syntax error in the file.
Any suggestions would be helpful. I just started learning Kubernetes and it's my first attempt.

Kubernetes service responding on different port than assigned port

I've deployed few services and found one service to be behaving differently to others. I configured it to listen on 8090 port (which maps to 8443 internally), but the request works only if I send on port 8080. Here's my yaml file for the service (stripped down to essentials) and there is a deployment which encapsulates the service and container
apiVersion: v1
kind: Service
metadata:
name: uisvc
namespace: default
labels:
helm.sh/chart: foo-1
app.kubernetes.io/name: foo
app.kubernetes.io/instance: rb-foo
spec:
clusterIP: None
ports:
- name: http
port: 8090
targetPort: 8080
selector:
app.kubernetes.io/component: uisvc
After installing the helm, when I run kubectl get svc, I get the following output
fooaccess ClusterIP None <none> 8888/TCP 119m
fooset ClusterIP None <none> 8080/TCP 119m
foobus ClusterIP None <none> 6379/TCP 119m
uisvc ClusterIP None <none> 8090/TCP 119m
However, when I ssh into one of the other running containers and issue a curl request on 8090, I get "Connection refused". If I curl to "http://uisvc:8080", then I am getting the right response. The container is running a spring boot application which by default listens on 8080. The only explanation I could come up with is somehow the port/targetPort is being ignored in this config and other pods are directly reaching the spring service inside.
Is this behaviour correct? Why is it not listening on 8090? How should I make it work this way?
Edit: Output for kubectl describe svc uisvc
Name: uisvc
Namespace: default
Labels: app.kubernetes.io/instance=foo-rba
app.kubernetes.io/managed-by=Helm
app.kubernetes.io/name=rba
helm.sh/chart=rba-1
Annotations: meta.helm.sh/release-name: foo
meta.helm.sh/release-namespace: default
Selector: app.kubernetes.io/component=uisvc
Type: ClusterIP
IP: None
Port: http 8090/TCP
TargetPort: 8080/TCP
Endpoints: 172.17.0.8:8080
Session Affinity: None
Events: <none>
This is expected behavior since you used headless service.
Headless Services are used for service discovery mechanism so instead of returning single DNS A records, the DNS server will return multiple A records for your service each pointing to the IP of an individual pods that backs the service. So you do simple DNS A records lookup and get the IP of all of the pods that are part of the service.
Since headless service doesn't create iptables rules but creates dns records instead, you can interact directly with your pod instead of a proxy. So If you resolve <servicename:port> you will get <podN_IP:port> and then your connection will go to the pod directly. As long as all of this is in the same namespace you don`t have resolve it by full dns name.
With several pods, DNS will give you all of them and just put in the random order (or in RR order). The order depends on the DNS server implementation and settings.
For more reading please visit:
Services-netowrking/headless-services
This stack questions with great answer explaining how headless services work

Kunernetes/kustomize Service endpoints abnormal behavior

We're using kustomize with kubernetes on our project.
I'm trying to implement access to external service using IP as mentioned in this link
https://medium.com/#ManagedKube/kubernetes-access-external-services-e4fd643e5097
Here's my service
---
kind: Service
apiVersion: v1
metadata:
name: pgsql
spec:
ports:
- protocol: TCP
port: 5432
targetPort: 5432
name: "pg"
selector: {}
---
apiVersion: v1
kind: Endpoints
metadata:
name: pgsql
subsets:
- addresses:
- ip: 1.1.1.1
ports:
- port: 5432
name : "pg"
When I apply with kubectl command (kubectl apply -k ...) I have a warning
Warning: kubectl apply should be used on resource created by either
kubectl create --save-config or kubectl apply
However, this warning does not avoid endpoints and service creation.
kubectl get endpoints
NAME ENDPOINTS AGE
pgsql 172.12.xx.yy:5432 3m27s
Unfortunately, the ip address is different from the one I put in my yml (1.1.1.1)
If I apply a second time
kubectl apply -k ...
kubectl get endpoints
NAME ENDPOINTS AGE
pgsql 1.1.1.1:5432 10s
I do not have the warning above anymore.
The endpoint is the one expected.
I expect endpoint address to be the exact one (1.1.1.1:5432) from the first apply.
Any suggestions?
Thanks
It probably comes from the empty selector. Could you try to remove it completely?
This is supposed to work only if your service doesn't have any selector

Google Kubernetes Ingress health check always failing

I have configured a web application pod exposed via apache on port 80. I'm unable to configure a service + ingress for accessing from the internet. The issue is that the backend services always report as UNHEALTHY.
Pod Config:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
name: webapp
name: webapp
namespace: my-app
spec:
replicas: 1
selector:
matchLabels:
name: webapp
template:
metadata:
labels:
name: webapp
spec:
containers:
- image: asia.gcr.io/my-app/my-app:latest
name: webapp
ports:
- containerPort: 80
name: http-server
Service Config:
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
type: NodePort
selector:
name: webapp
ports:
- protocol: TCP
port: 50000
targetPort: 80
Ingress Config:
kind: Ingress
metadata:
name: webapp-ingress
spec:
backend:
serviceName: webapp-service
servicePort: 50000
This results in backend services reporting as UNHEALTHY.
The health check settings:
Path: /
Protocol: HTTP
Port: 32463
Proxy protocol: NONE
Additional information: I've tried a different approach of exposing the deployment as a load balancer with external IP and that works perfectly. When trying to use a NodePort + Ingress, this issue persists.
With GKE, the health check on the Load balancer is created automatically when you create the ingress. Since the HC is created automatically, so are the firewall rules.
Since you have no readinessProbe configured, the LB has a default HC created (the one you listed). To debug this properly, you need to isolate where the point of failure is.
First, make sure your pod is serving traffic properly;
kubectl exec [pod_name] -- wget localhost:80
If the application has curl built in, you can use that instead of wget.
If the application has neither wget or curl, skip to the next step.
get the following output and keep track of the output:
kubectl get po -l name=webapp -o wide
kubectl get svc webapp-service
You need to keep the service and pod clusterIPs
SSH to a node in your cluster and run sudo toolbox bash
Install curl:
apt-get install curl`
Test the pods to make sure they are serving traffic within the cluster:
curl -I [pod_clusterIP]:80
This needs to return a 200 response
Test the service:
curl -I [service_clusterIP]:80
If the pod is not returning a 200 response, the container is either not working correctly or the port is not open on the pod.
if the pod is working but the service is not, there is an issue with the routes in your iptables which is managed by kube-proxy and would be an issue with the cluster.
Finally, if both the pod and the service are working, there is an issue with the Load balancer health checks and also an issue that Google needs to investigate.
As Patrick mentioned, the checks will be created automatically by GCP.
By default, GKE will use readinessProbe.httpGet.path for the health check.
But if there is no readinessProbe configured, then it will just use the root path /, which must return an HTTP 200 (OK) response (and that's not always the case, for example, if the app redirects to another path, then the GCP health check will fail).

Redirection Stateful pod in Kubernetes

I am using stateful in kubernetes.
I write an application which will have leader and follower (using Go)
Leader is for writing and reading.
Follower is just for reading.
In the application code, I used "http.Redirect(w, r, url, 307)" function to redirect the writing from follower to leader.
if I use a jump pod to test the application (try to access the app to read and write), my application can work well, the follower can redirect to the leader
kubectl run -i -t --rm jumpod --restart=Never --image=quay.io/mhausenblas/jump:0.2 -- sh
But when I deploy a service (to access from outside).
apiVersion: v1
kind: Service
metadata:
name: service-name
spec:
selector:
app: app-name
ports:
- port: 80
targetPort: 9876
And access to application by this link:
curl -L -XPUT -T /tmp/put-name localhost:8001/api/v1/namespaces/default/services/service-name/proxy/
Because service will randomly select a pod each time we access to the application. When it accesses to leader, it work well (no problem happen), But if it accesses to the follower, the follower will need to redirect to leader, I met this error:
curl: (6) Could not resolve host: pod-name.svc-name.default.svc.cluster.local
What I tested:
I can use this link to access when I used jump pod
I accessed to per pod, look up the DNS. I can find the DNS name by "nslookup" command
I tried to fix the IP of leader in my code. In my code, the follower will redirect to a IP (not a domain like above). But It still met this error:
curl: (7) Failed to connect to 10.244.1.71 port 9876: No route to host
Anybody know this problem. Thank you!
In order for pod DNS to work you must create headless service:
apiVersion: v1
kind: Service
metadata:
name: svc-name-headless
spec:
clusterIP: None
selector:
app: app-name
ports:
- port: 80
targetPort: 9876
And then in StatefulSet spec you must refer to this service:
spec:
serviceName: svc-name-headless
Read more here: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#stable-network-id
Alternatively you may specify what particular pod will be selected by Service like that:
apiVersion: v1
kind: Service
metadata:
name: svc-name
spec:
selector:
statefulset.kubernetes.io/pod-name: pod-name-0
ports:
- port: 80
targetPort: 9876
When you are accessing your cluster services from outside, a DNS names reserved normally for inner cluster use (e.g. pod-name.svc-name.default.svc.cluster.local) are not recognized by clients (e.g. Web browser).
Context:
You are trying to expose access to PODs, controlled by StatefullSet with service of ClusterIP type
Solution:
Change ClusterIP (assumed by default when not specified) to NodePort or LoadBalancer