3

I did a small deployment in K8s using Docker image but it is not showing in deployment but only showing in pods. Reason: It is not creating any default namespace in deployments.

Please suggest:

Following are the commands I used.

$ kubectl run hello-node --image=gcr.io/$DEVSHELL_PROJECT_ID/hello-node:1.0 --port=8080 --namespace=default
pod/hello-node created

$ kubectl get pods
NAME         READY   STATUS    RESTARTS   AGE
hello-node   1/1     Running   0          12s

$ kubectl get pods --all-namespaces
NAMESPACE     NAME                                                       READY   STATUS    RESTARTS   AGE
default       hello-node                                                 1/1     Running   0          9m9s
kube-system   event-exporter-v0.2.5-599d65f456-4dnqw                     2/2     Running   0          23m
kube-system   kube-proxy-gke-hello-world-default-pool-c09f603f-3hq6      1/1     Running   0          23m

$ kubectl get deployments
**No resources found in default namespace.**

$ kubectl get deployments --all-namespaces
NAMESPACE     NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   event-exporter-v0.2.5                      1/1     1            1           170m
kube-system   fluentd-gcp-scaler                         1/1     1            1           170m
kube-system   heapster-gke                               1/1     1            1           170m
kube-system   kube-dns                                   2/2     2            2           170m
kube-system   kube-dns-autoscaler                        1/1     1            1           170m
kube-system   l7-default-backend                         1/1     1            1           170m
kube-system   metrics-server-v0.3.1                      1/1     1            1           170m
NewLearner
  • 59
  • 1
  • 8

2 Answers2

2

Check version of kubectl using kubectl version

From kubectl 1.18 version kubectl run creates only pod and nothing else. To create a deployment use kubectl create deployment or use older version of kubectl

Arghya Sadhu
  • 41,002
  • 9
  • 78
  • 107
2

Arghya Sadhu's answer is correct. In the past kubectl run command indeed created by default a Deployment instead of a Pod. Actually in the past you could use it with so called generators and you were able to specify exactly what kind of resource you want to create by providing --generator flag followed by corresponding value. Currently --generator flag is deprecated and has no effect.

Note that you've got quite clear message after running your kubectl run command:

$ kubectl run hello-node --image=gcr.io/$DEVSHELL_PROJECT_ID/hello-node:1.0 --port=8080 --namespace=default
pod/hello-node created

It clearly says that the Pod hello-node was created. It doesn't mention about a Deployment anywhere.

As an alternative to using imperative commands for creating either Deployments or Pods you can use declarative approach:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-node
  namespace: default
  labels:
    app: hello-node
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-node
  template:
    metadata:
      labels:
        app: hello-node
    spec:
      containers:
      - name: hello-node-container
        image: gcr.io/$DEVSHELL_PROJECT_ID/hello-node:1.0
        ports:
        - containerPort: 8080

Declaration of namespace can be ommitted in this case as by default all resources are deployed into the default namespace.

After saving the file e.g. as nginx-deployment.yaml you just need to run:

kubectl apply -f nginx-deployment.yaml

Update:

Expansion of the environment variables within the yaml manifest actually doesn't work so the following line from the above deployment example cannot be used:

image: gcr.io/$DEVSHELL_PROJECT_ID/hello-node:1.0

The simplest workaround is a fairly simple sed "trick".

First we need to change a bit our project id's placeholder in our deployment definition yaml. It may look like this:

image: gcr.io/{{DEVSHELL_PROJECT_ID}}/hello-node:1.0

Then when applying the deployment definition instead of simple kubectl apply -f deployment.yaml run this one-liner:

sed "s/{{DEVSHELL_PROJECT_ID}}/$DEVSHELL_PROJECT_ID/g" deployment.yaml | kubectl apply -f -

The above command tells sed to search through deployment.yaml document for {{DEVSHELL_PROJECT_ID}} string and each time this string occurs, to substitute it with the actual value of $DEVSHELL_PROJECT_ID environment variable.

mario
  • 9,858
  • 1
  • 26
  • 42
  • 1
    Thanks a lot Mario, quite a great detailed description. Really helpful for a new learner like me. – NewLearner Jun 12 '20 at 17:00
  • Another finding Instead of "image: gcr.io/$DEVSHELL_PROJECT_ID/hello-node:1.0" variable in this line we need to have an actual project ID because kubectl is not able to convert the environment variable under yaml file to an absolute path. I just faced an error. If you think there is an another way of executing the user profile with yaml please suggest. – NewLearner Jun 12 '20 at 23:09
  • Right, moving environment variable into deployment definition definitely isn't a good idea as it won't work. [Here](https://github.com/kubernetes/kubernetes/issues/52787) you can find discussion on this topic and in [this](https://stackoverflow.com/questions/48296082/how-to-set-dynamic-values-with-kubernetes-yaml-file) thread you can read about possible solutions. – mario Jun 15 '20 at 22:59
  • Additionally I updated my answer by adding the example workaround. – mario Jun 15 '20 at 23:27