Deploy separate k8s manifest files - kubernetes

I have a Spring boot application and I deploy the application to Kubernetes using a single k8s.yml manifest file via Github actions. This k8s.yml manifest contains Secrets, Service, Ingress, Deployment configurations. I was able to deploy the application successfully as well. Now I plan to separate the Secrets, Service, Ingress, Deployment configurations into a separate file as secrets.yml, service.yml, ingress.yml and deployment.yml.
Previously I use the below command for deployment
kubectl: 1.5.4
command: |
sed -e 's/$SEC/${{ secrets.SEC }}/g' -e 's/$APP/${{ env.APP_NAME }}/g' -e 's/$ES/${{ env.ES }}/g' deployment.yml | kubectl apply -f -
Now after the separation I use the below commands
kubectl: 1.5.4
command: |
kubectl apply -f secrets.yml
kubectl apply -f service.yml
sed -e 's/$ES/${{ env.ES }}/g' ingress.yml | kubectl apply -f -
sed -e 's/$SEC/${{ secrets.SEC }}/g' -e 's/$APP/${{ env.APP_NAME }}/g' deployment.yml | kubectl apply -f -
But some how the application is not deploying correctly, I would like to know if the command which I am using is correct or not

You can consider perform the sed first, then apply all files kubectl apply -f . instead of going one by one. Append --recursive if you have files in sub folder to apply, too.

Like the other answer says, you can ask kubectl to apply all files recursively in a directory.
Now the sed replaces are soon going to become overwhelming as the resources and configuration grow.
That is why kubctl comes with integrated kustomize support:
https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/
In short:
Break up all kubernetes resources into smaller files/components, put them in a directory.
Place a file called kustomization.yaml in same directory.
In the kustomization.yaml configure which file you want to apply, in which order, and also do some on-the-fly edits.
And apply with -k flag:
kubectl apply -k <kustomization_directory>

Related

no matches for kind "Kustomization" in version "kustomize.config.k8s.io/v1beta1"

Getting the below error for the command kubectl apply -n prod -f kustomize/kustomization.yaml
error: unable to recognize "kustomize/kustomization.yaml": no matches for kind "Kustomization" in version "kustomize.config.k8s.io/v1beta1"
Please advise.
Firstly I recommend to read official doc: kubernetes-kustomization.
To solve the problem use -k flag instead of -f flag in command:
$ kubectl apply -k <kustomization_directory>
If in your kustomize directory will be only one manifest file (kustomization.yaml) then use $ kubectl apply -k kustomize/ from this directory. Otherwise create new empty directory and put your kustomization.yaml there then execute following command from parent directory $ kubectl apply -k new-directory/
Take a look: kustomize-no-matches, kustomize-kubernetes-no-matches.

Kubernetes apply all files inside a directory, "kubectl apply --all"?

Just wondering, let's say I have X Kubernetes deployment.yaml, pod.yaml, persistedvolumecliam.yaml and service.yaml files inside a directory.
The tutorials would tell us to do the following:
kubectl apply -f frontend-service.yaml,redis-master-service.yaml,redis-slave-service.yaml,frontend-deployment.yaml,redis-master-deployment.yaml,redis-slave-deployment.yaml
Is there a way just to do something like:
kubectl apply all
or
kubectl apply -f *
or some variation thereof to spin all of the kube stuffs within on directory?
You can apply everything inside a directory with kubectl apply -f /path/to/dir. To include subdirectories use the paramter -R, like kubectl apply -R -f /path/to/dir
# Apply resources from a directory
kubectl apply -f dir/
# Process the directory used in -f recursively
kubectl apply -R -f dir/
For more details check the reference documentation.
You can apply a YAML file using kubectl apply recursively in all folders by using the --recursive flag.
Here is the basic syntax once you are in the root folder:
kubectl apply --recursive -f .

How to replace JSON value in kubectl output using go-template?

I have a configMap and I want to create a backup configMap by using the last applied configuration from that.
I use the following command to get the last applied configuration:
kubectl get cm app-map -n app-space \
-o go-template \
--template='{{index .metadata "annotations" "kubectl.kubernetes.io/last-applied-configuration"}}' > backup.json
It returns something like this [the content of backup.json]:
{"kind":"ConfigMap","apiVersion":"v1","metadata":{"name":"app-map","creationTimestamp":null},"data":{"app.yml":"xxxxxxxxx","config.yml":"yyyyyyyyy"}}
Now, I want my backup configMap to have a different name. So, I want to change the .metadata.name from app-map to app-map-backup.
Is there a way I can achieve that with kubectl and -o go-template? I want to have the name changed before I write it to the backup.json file.
I know I can do that using jq but I do not have permission to install jq on the server where I am using kubectl.
you could use kubectl bulk plugin. The below command will replicate your config map
# get resource(s) and create with field(name) change
kubectl bulk configmap app-map -n app-space create name app-mapp-backup
Kubectl bulk is very powerful to use, I suggest to check samples.
You cannot do this just using kubectl. But there are other ways.
You can download statically linked jq binary from official jq website:
wget https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64
chmod +x jq-linux64
and then you can use this binary like following:
kubectl -o go-template [...] | ./jq-linux64 ...
or you can use sed:
kubectl -o go-template [...] | sed 's/"name":"app-map"/"name":"app-map-backup"/'

diff between whats active on cluster versus kustomize

kustomize's docs provides a nice one-liner that compares two different overlays...
diff \
<(kustomize build $OVERLAYS/staging) \
<(kustomize build $OVERLAYS/production)
is there a way to do the same but against what is running within a specific kubernetes namespace and that of a defined overlay on disk?
more specifically, knowing what an kubectl apply -k . would do without actually doing it? using --dry-run just says spits out a list of the objects rather than a real diff.
kustomize build ./ | kubectl diff -f -
In Kustomize version 4.x.x
If you're looking for a way to do this visually, I highly recommend trying the Compare & Sync feature from Monokle:
In the picture above you can see an example where I'm comparing the output of the cluster-install kustomization to the objects in my minikube cluster.
You can easily determine which resources are missing in your cluster and which ones are different.
On top of that, you're not limited to only comparing kustomizations to clusters. You can also compare two clusters, two kustomizations, helm charts, etc.
I'm not sure if this is what you are looking for, but in Kubernetes you have kubectl diff.
It's nicely explained on APIServer dry-run and kubectl diff.
You can use option -k, --kustomize which does:
Process the kustomization directory. This flag can't be used together with -f or -R.
Or maybe something similar to one-liner to set context for specific namespace:
$ kubectl config set-context staging --user=cluster-admin --namespace=staging
$ kubectl config set-context prod --user=cluster-admin --namespace=prod
Once you have context setup you could use them maybe in a following way:
kubectl config use-context staging; cat patched_k8s.yaml | kubectl config use-context prod; kubectl diff -f -
This is just an example which I did not tested.
Try this kustomize command, currently in alpha:
KUSTOMIZE_ENABLE_ALPHA_COMMANDS=true kustomize resources diff -k your/kustomize/overlay
via https://kubernetes.slack.com/archives/C9A5ALABG/p1582738327027200?thread_ts=1582695987.023600&cid=C9A5ALABG
I have a small function on my shell config to do this:
kdiff() {
overlay="${1}"
kustomize build ${overlay} \
| kubectl diff -f - ${#:2} \
| sed '/kubectl.kubernetes.io\/last-applied-configuration/,+1 d' \
| sed -r "s/(^\+[^\+].*|^\+$)/$(printf '\e[0;32m')\1$(printf '\e[0m')/g" \
| sed -r "s/(^\-[^\-].*|^\-$)/$(printf '\e[0;31m')\1$(printf '\e[0m')/g"
}
It drops the last-applied-configuration annotation and adds some color.

Dynamically create the configmap yaml file

Background : I have close to 15 *.properties files in different location. I need to create configmap for each properties files.
Currently I am manually creating configmap yaml files using
kubectl create configmap app-properties --from-file= /path/app.properties.
Mount and everything thing is working fine.
Requirement : As soon we add any new key/value to properties file, it should get reflected in configmap yaml file. Can I dynamically create configmap yaml using some "include files".
You could watch the properties files for modifications and recreate the ConfigMap whenever they change.
To do so, there are different tools for macOS and Linux.
Linux
On Linux, you can watch files for changes with inotifywait. You could do something along the following lines:
Create the file monitor.sh:
#!/bin/bash
FILE=$1
inotifywait -m -e modify "$FILE" |
while read; do
kubectl create configmap "$(basename $FILE)" --from-file="$FILE" --dry-run -o yaml | kubectl apply -f -
done
Then execute it for each properties file:
./monitor.sh /path/app.properties
This will generate an updated ConfigMap YAML manifest with kubectl create and apply it with kubectl apply every time the /path/app.properties file is modified.
You can install inotifywait with:
sudo apt-get install inotify-tools
macOS
On macOS, you can use fswatch to watch for file modifications.
Create the file monitor.sh:
#!/bin/bash
FILE=$1
fswatch "$FILE" |
while read; do
kubectl create configmap "$(basename $FILE)" --from-file="$FILE" --dry-run -o yaml | kubectl apply -f -
done
Then execute it for each properties file:
./monitor.sh /path/app.properties
This will generate an updated ConfigMap YAML manifest with kubectl create and apply it with kubectl apply every time the /path/app.properties file is modified.
You can install fswatch with:
brew install fswatch
Note
fswatch might also be available on Linux (sudo apt-get install fswatch), in which case you can use the monitor.sh script for macOS on Linux too. However, you might need to use fswatch -o (with the -o option) to ensure only a single output line.