I have a deployment with 2 replicas. I can access the pods via curl.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
I created a service.
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
I was expecting to be able to access the pods through the service via the EndPoints but the result I get is.
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "forbidden: User \"system:anonymous\" cannot get path \"/\"",
"reason": "Forbidden",
"details": {
},
"code": 403
}
Can someone help me understand what is going on here better?
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d23h
nginx-service ClusterIP 10.109.19.46 <none> 80/TCP 22h
curl --insecure https://PUBLICIP:6443
The easiest way is to expose the service as "NodePort"
using kubectl
,
Initially, you have to delete the existing service,
kubectl delete svc nginx-service //if you have a namespace -n yourNameSpace
Then expose your deployment as "NodePort" as following,
kubectl expose deployment nginx-deployment --port=80 --type=NodePort --name=nginx-service //if you have a namespace -n yourNameSpace
Now the "NodePort" service has been created and you could curl to the service through,
curl NODE_IP:NODE_PORT
With your command you're trying to access the /
path of the Kubernetes API, but it fails because you're not supplying any credentials to the request:
curl --insecure https://PUBLICIP:6443
But anyway, if you want to access the Pods behind the Service, you don't need to access the Kubernetes API, but you need to access the exposed Service.
A ClusterIP service as in your example (the default) cannot be accessed from outside the cluster. If you want to access the Service from outside the cluster, you need to create, for example, a NodePort Service:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort
And then you can access the Service (and thus the Pods behind it) through the IP address and NodePort of one of the worker nodes:
curl NODE_IP:NODE_PORT
You can get the NODE_IP
of one of the nodes with kubectl get nodes -o wide
and the NODE_PORT
of the Service with kubectl get svc nginx-service
.
The curl
command you are using will hit the Kubernetes API server
(defaults to 6443
port) ; NOT the service you created.
The nginx-service
you created will create a ClusterIP
service, which will not be accessible from outside. You have to use either NodePort
or LoadBalancer
type service.
To access your service, you can try below (using NodePort
)
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort
Then get the NodePort
from kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d23h
nginx-service NodePort 10.109.19.46 <none> 80:32474/TCP 22h <<<-- (NodePort is 32474)
You can use any node's IP and the port 32474 combinations to access the service.
Eg:-
curl http://192.168.10.10:32474