How to create deployment without images and later on, add new images? - kubernetes

I'm new to k8s and I'm trying to learn how to setup deployments.
I'm searching for a way to create a new deployment without any images. Over time, I will add new (0 or more) images (and specify thier desired state). As I don't know what images the deployment will contain in advance, I can't use any existing configuration files.
Is it possible? If yes, how?
If it's possible, a command-line solution will be great.

If you want to start a single instance of nginx, you can do
$ kubectl run nginx --image=nginx
But it is not possible to create any deployments without image.
$ kubectl run demo --image=""
error: --image is required
If you want to edit your existing deployment, then you can run
$ kubectl edit deployments <deployment-name> -n <namespace>
You can also patch container with new image to existing deployments by running following command
$ kubectl patch deployment <deployment-name> -p '{"spec":{"template":{"spec":{"containers":[{"name":"myapp","image":"newimage"}]}}}}'
To replace image of a containers in deployment, run
$ kubectl set image deployment/<deployment-name> <container-name>=<image>

Related

K8s Deploy Yaml with scaling replicas count on the fly

How to upgrade an existing running deployment with yaml deployment file without changing the number of running replicas of that deployment?
So, I need to set the number of replicas on the fly without changing the yaml file.
It is like running kubectl apply -f deployment.yaml along with kubectl scale --replicas=3 both together, or in another wards to apply deployment yaml changes with keeping the numebr of running replicas the same as it is.
For example: I have a running deployment which already scaled its pods to 5 replicas, need to change deployment parameters within CD (like upgrade container image, change environment variabls, .. etc) without manualy check the #running pods and update the yaml with it, how can achieve this?
Use the kubectl edit command
kubectl edit (RESOURCE/NAME | -f FILENAME)
E.g. kubectl edit deployment.apps/webapp-deployment
It will open an editor. You can update the value for number of replicas in the editor and save.
Refer the documentation section - Editing resources
https://kubernetes.io/docs/reference/kubectl/cheatsheet/#editing-resources

Using kubectl set image to update image of initContainer

Currently, to update a k8s deployment image, we use the kubectl set image command like this:
kubectl set image deployment/deployment_name container=url_to_container
While this command updates the URL used for the main container in the deployment, it does not update the URL for the initContainer also set within the deployment.
Is there a similar kubectl command I can use to update the initContainer to the same URL?
Since the accepted answer, the team developed the ability to set image for Kubernetes init containers. Using the same command, simply use the init container name for the container part of the command you supplied.
kubectl set image deployment/deployment_name myInitContainer=url_to_container
In case you want to update both container images in a single command, use:
kubectl set image deployment/deployment_name myInitContainer=url_to_container container=url_to_container
The documentation seems to suggests that only containers are concerned.
Maybe you could switch to kubectl patch ?
(I know it's more tedious...)
kubectl patch deployment/deployment_name --patch "{\"spec\": {\"template\": {\"spec\": {\"initContainers\": [{\"name\": \"container_name\",\"image\": \"url_to_container\"}]}}}}"
The snippet above is based on solution provided by #Hiruma. Therefore, here I removed the empty spaces on the json argument and added a namespace example.
I did that because I faced issues when I was writing a pipeline for drone.io.
kubectl patch deployment deployment_name -n namespace_name -p "{\"spec\":{\"template\":{\"spec\":{\"initContainers\":[{\"name\":\"deployment_name\",\"image\":\"url_to_container"}]}}}}"

How to delete and recreate pods using yaml file in kubernetes

I have a yaml file which I can use to create pods. I am using the dashboard so I can simply select yaml file and it will create pods. Pod will start the container and container will run the docker image. So now lets say I have done some changes in the docker image and want to deploy it again. For this, I will delete the already running pod and will upload the yaml file.
Instead of deleting and uploading yaml file again, is there any keyword available which will delete the already running pod/deployment and will recreate it.
Thanks
If you are using this for development you might get away with
containers:
- image: my/app:dev
imagePullPolicy: Always
With this, whenever your pod is recreated, you will get fresh image version.
That said, you need to use something like Deployment to have a pod restarted automaticaly, and then you can just kubectl delete my-pod-xxxxx-yyy to wipe old one and in few sec get the fresh, current one.
For prod, don't do that please. Just use tagged images and apply changed image to your Deployment with kubectl apply -f my.yaml or preferably something like Helm (but that is more complicated topic for starters)
I can't remember the StackOverflow question where I first saw this method, but here it is again:
kubectl --namespace thenamespace get pod thepod -o yaml | kubectl replace --save-config -f -
You can do that with all k8s resources.

How to restart the pods even if there no change to the config

I build docker images on one server and then load it onto to the nodes(using docker save and docker load cmds).
Then I make change to the dep_config file to pull it locally instead of repo.(by setting imagepullpolicy).
After that step I do "kubectl apply -f dep_config.yml".
Now, the pod restarts only for the 1st time but subsequent load of images and apply of config file, the pods dont restart.
Is there way I can restart the pod with "kubectl apply" even if there is no change in the config_deploy.yml file.
A common practice is to change a non-used label of the deployment using the patch command
kubectl patch deployment your-deployment -p \
"{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"$(date +%s)\"}}}}}"
Basically you can change anything that's inside the pod template, even things, like in this example, that no one notices.

Redeploying a Google Container Controller when the repository Image Changes

Is there any way for me to replicate the behavior I get on cloud.docker where a service can be redeployed either manually with the latest image or automatically when the repository image is updated?
Right now I'm doing something like this manually in a shell script with my controller and service files:
kubectl delete -f ./ticketing-controller.yaml || true
kubectl delete -f ./ticketing-service.yaml || true
kubectl create -f ./ticketing-controller.yaml
kubectl create -f ./ticketing-service.yaml
Even that seems a bit heavy handed, but works fine. I'm really missing the autoredeploy feature I have on cloud.docker.
Deleting the controller yaml file itself won't delete the actual controller in kubernetes unless you have a special configuration to do so. If you have more than 1 instance running, deleting the controller probably isn't what you would want because it would delete all the instances of your running application. What you really want to do is perform a rolling update of your application that incrementally replaces containers running the old image with containers running the new one.
You can do this manually by:
For a Deployment controller update the yaml file image and execute kubectl apply.
For a ReplicationController update the yaml file and execute kubectl rollingupdate. See: http://kubernetes.io/docs/user-guide/rolling-updates/
With v1.3 you will be able to use kubectl set image
Alternatively you could use a PaaS to automatically push the image when it is updated in the repo. Here is an incomplete list of a few Paas options:
Red Hat OpenShift
Spinnaker
Deis Workflow
According to Kubernetes documentation:
Let’s say you were running version 1.7.9 of nginx:
$ kubectl run my-nginx --image=nginx:1.7.9 --replicas=3
deployment "my-nginx" created
To update to version 1.9.1, simply change
.spec.template.spec.containers[0].image from nginx:1.7.9 to
nginx:1.9.1, with the kubectl commands.
$ kubectl edit deployment/my-nginx
That’s it! The Deployment will declaratively update the deployed nginx
application progressively behind the scene. It ensures that only a
certain number of old replicas may be down while they are being
updated, and only a certain number of new replicas may be created
above the desired number of pods.