How to create a kubernetes workload and expose it in same command line? - kubernetes

In a kubernetes cluster we can create a workload and expose it in two separate commands.
kubectl run deployment-name --image=imagename
kubectl expose deployment deployment-name [--port=port --type=type --name=name]
Could we do it in one command?

This could be achieved by the below command. It will create a workload and also expose it in same time.
kubectl run nginx-digital --image=nginx --expose=true --port=80
The above command will create a deployment nginx-digital and also expose it with ClusterIP service with name nginx-digital at port 80.

Related

What are the best solutions to replace kubernetes port-forward

I am working on rancher server, k3s to improve my knowledge on these solutions.
I want to expose container services on LAN network, this is why I used kubectl port-forward.
kubectl port-forward --namespace=ns-name --address LAN-IP service/hello 30104:8080
But I can see in several web resources that is not a reliable solution, just for local testing purpose.
I tried to replace them by ingress but I am a bit lost between ingress, DNS and nginx-ingress in addition to rancher component.
I understood than load balancer need a cloud provider, to have a public IP for instance, and handle the <pending> state of load balancer.
Can you highlight me on how replace port-forward in LAN without a cloud provider?
[edit #Rajesh Dutta]
I already use NodePort, but, without port-forward the service is exposed as NODE_IP:PORT, not LAN_IP:PORT. My need is to join it from outside of the cluster.
So this is what i did :
1 - create deployment
kubectl create deployment hello --image=gcr.io/google-samples/node-hello:1.0 --port=8080 --replicas=2
2 - expose deployment(create service)
kubectl expose deployment hello --type=NodePort
3 - forward service
kubectl port-forward --namespace=ns-name --address local-ip service/hello 30104:8080
IP schema
Now, considering that i will have several service, i would find the best ways to replace port-forward.
To start with I would recommend to use NodePort service. This will expose your application to a NodePort(30000-32767). Later if you want you can choose to switch to ingress.
Assuming that you are trying with a deployment type object
command:
kubectl expose deployment deployment-name --type=NodePort --port=8080 --target-port=<rancher server port>

How to get kubernetes service as spec yaml after has been `exposed`?

I'm very new to kubernetes and I find it a bit confusing and to understand I'd like to know what exactly kubectl expose deployment xxx--type=LoadBalancer --name=xxx does. So I was wondering if is possible to extract this service to yaml spec definition somehow.
I understand that Im creating a service, but not sure how he figures out all the ports automatically. I'd like to have the same thing in a file to run it like kubectl apply -f ./service.yaml.
kubectl expose doesnot assign ports automatically. If any port defination mentioned in deploymwnt yaml then only it uses the port. otherwise it will give error like :
error: couldn't find port via --port flag or introspection
to assign port on run use:
kubectl expose deployment xxx --type=NodePort --name=xxx --port=80 --target-port=8080
you can get the yaml by running this:
kubectl get service xxx -o yaml

Check working of an service in kubernetes

I create a pod to test my service in kubernetes. But i didn't get anythings. Here is my command
kubectl run --generator=run-pod/v1 nginx-resolver --image=nginx
kubectl expose pod nginx-resolver --name=nginx-resolver-service --port=80 --target-port=80 --type=ClusterIP
kubectl run --generator=run-pod/v1 test-nslookup --image=busybox:1.28 --rm -it -- nslookup nginx-resolver-service
Please help me explain why. Thanks
Run the following command and get things what you are thinking wrong about this cmd.
$ kubectl run --help
Create and run a particular image, possibly replicated.
Creates a deployment or job to manage the created container(s).
Examples:
# Start a single instance of nginx.
kubectl run nginx --image=nginx
# Start a single instance of hazelcast and let the container expose port 5701 .
kubectl run hazelcast --image=hazelcast --port=5701
...
So, kubectl run cmd creates a deployment or a job
If it is a deployment, it creates (a) first, a replicaset, (b) then Pod(s).
If it is a job, it creates a Pod.
But you are trying to expose a Pod which name is not the correct one. You can see the name of the Pod that is/are created by the cmd kubectl run.
$ kubectl get pods --namespace=<namespace> | grep "nginx-resolver"
$ kubectl get pods --namespace=<namespace> | grep "test-nslookup"
Then use those names to expose Pod.
You can optionally expose your Deployment. To do so, see the help of $ kubectl expose deployment --help. Run:
$ kubectl expose deployment --help
Expose a resource as a new Kubernetes service.
Looks up a deployment, service, replica set, replication controller or pod by name and uses the selector for that
resource as the selector for a new service on the specified port. A deployment or replica set will be exposed as a
service only if its selector is convertible to a selector that service supports, i.e. when the selector contains only
the matchLabels component. Note that if no port is specified via --port and the exposed resource has multiple ports, all
will be re-used by the new service. Also if no labels are specified, the new service will re-use the labels from the
resource it exposes.
Possible resources include (case insensitive):
pod (po), service (svc), replicationcontroller (rc), deployment (deploy), replicaset (rs)
Examples:
...
# Create a service for an nginx deployment, which serves on port 80 and connects to the containers on port 8000.
kubectl expose deployment nginx --port=80 --target-port=8000
...
If you want to see the log interactively, you need to set the --restart option of your test-nslookup pod to Never or OnFailure. Otherwise, kubernetes will just restart your pod indefinitely and you won't see anything.
So your last command should be :
kubectl run --generator=run-pod/v1 test-nslookup --image=busybox:1.28 -it --restart=OnFailure -- nslookup nginx-resolver-service
Why ?
Probably because of this issue.
It seems to have a delay of 5s before kubectl run actually print something.
So in order to do it without changing the restart option, you'll need to change your command like this (beware of the sleep 7, so you'll have to wait 7seconds before seeing the logs) :
kubectl run --generator=run-pod/v1 test-nslookup --image=busybox:1.28 -it --rm -- sh -c 'sleep 7; nslookup nginx-resolver-service'

Exposing kubernetes service locally (without minikube)

I'm using lxc/lxd to play with the kubenetes cluster.
Is there a way to expose a deployed service locally without using minikube, so that I could access it from the local machine?
I can access it from any of the nodes in the cluster but not from outside.
Do you want to acccess the pod being served by the service? if yes, you can use kubectl port-forward to connect to your pod and access it locally
Here is an example:
If you have a service which forwards all the requests to a pod ( nginx ) at port number 80 you can configure it to your local port as follows
kubectl port-forward -n default nginx-5767f4d585-hgtfj 8081:80
Here is the syntax of the same
kubectl port-forward -n NAMESPACE ${POD} local-port:pod-port
If you want to connect to your service directly, you need to do it via kubectl proxy
Here is a reference
Hope it helps.

How to start a pod in command line without deployment in kubernetes?

I want to debug the pod in a simple way, therefore I want to start the pod without deployment.
But it will automatically create a deployment
$ kubectl run nginx --image=nginx --port=80
deployment "nginx" created
So I have to create the nginx.yaml file
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
And create the pod like below, then it creates pod only
kubectl create -f nginx.yaml
pod "nginx" created
How can I specify in the command line the kind:Pod to avoid deployment?
// I run under minikue 0.20.0 and kubernetes 1.7.0 under Windows 7
kubectl run nginx --image=nginx --port=80 --restart=Never
--restart=Always: The restart policy for this Pod. Legal values [Always, OnFailure, Never]. If set to Always
a deployment is created, if set to OnFailure a job is created, if set to Never, a regular pod is created. For the latter two --replicas must be 1. Default Always [...]
see official document https://kubernetes.io/docs/user-guide/kubectl-conventions/#generators
Now there are two ways one can create pod through command line.
kubectl run nginx --image=nginx --restart=Never
OR
kubectl run --generator=run-pod/v1 nginx1 --image=nginx
See official documentation.
https://kubernetes.io/docs/reference/kubectl/conventions/#generators
Use generators for this, default kubectl run will create a deployment object. If you want to override this behavior use "run-pod/v1" generator.
kubectl run --generator=run-pod/v1 nginx1 --image=nginx
You may refer the link below for better understanding.
https://kubernetes.io/docs/reference/kubectl/conventions/#generators
I'm relatively new to kubernetes, but it seems it has evolved quite a bit since this question was asked. As of its latest versions(I'm running v1.16) generators are deprecated and they are completely removed in v1.18.
See the corresponding ticket and the release notes.
Release notes explicitly say:
Remove all the generators from kubectl run. It will now only create
pods.
I've tested kubectl run with various --restart flags and never got any deployments created. What we do have now is called "naked" Pod. And while you might be tempted to use it, it goes against k8s best practices:
Don’t use naked Pods (that is, Pods not bound to a ReplicaSet or
Deployment) if you can avoid it. Naked Pods will not be rescheduled in
the event of a node failure.
When you are using "kubectl run nginx --image=nginx --port=80" it creates a deployment by default.
To create a pod you have two options.
kubectl run --generator=run-pod/v1 nginx --image=nginx --port=80
kubectl create pod nginx --image=nginx --port=80