'How to merge kubectl config file with ~/.kube/config?
Is there a simple kubectl
command to take a kubeconfig
file (that contains a cluster+context+user) and merge it into the ~/.kube/config file as an additional context?
Solution 1:[1]
Do this:
export KUBECONFIG=~/.kube/config:~/someotherconfig
kubectl config view --flatten
You can then pipe that out to a new file if needed.
Solution 2:[2]
If you find yourself doing this a lot... There is now also the krew
plugin package manager for kubectl
.
The krew
plugin "konfig" can help you manage your ~/.kube/config
file.
Using the konfig
plugin the syntax will be:
kubectl konfig import -s new.yaml
To install krew
: https://github.com/kubernetes-sigs/krew
To install konfig
: kubectl krew install konfig
Solution 3:[3]
Using multiple kubeconfigs
at once
Sometimes you have a bunch of small kubeconfig files (e.g. one per cluster) but you want to use them all at once, with tools like kubectl
or kubectx that work with multiple contexts at once.
To do that, you need a “merged” kubeconfig file. In the section "Merging kubeconfig files" below, we explain how you can merge the kubeconfigs into a single file, but you can also merge them in-memory.
By specifying multiple files in KUBECONFIG
environment variable, you can temporarily stitch kubeconfig files together and use them all in kubectl
.
#
# Kubeconfig in-memory merge
#
export KUBECONFIG=file1:file2
kubectl get pods --context=cluster-1
kubectl get pods --context=cluster-2
#
# For your example
# merging your kubeconfig file w/ $HOME/.kube/config (w/ cp backup)
#
cp $HOME/.kube/config $HOME/.kube/config.backup.$(date +%Y-%m-%d.%H:%M:%S)
KUBECONFIG= $HOME/.kube/config:file2: kubectl config view --merge --flatten > \
~/.kube/merged_kubeconfig && mv ~/.kube/merged_kubeconfig ~/.kube/config
kubectl get pods --context=cluster-1
kubectl get pods --context=cluster-2
Merging kubeconfig files
Since kubeconfig files are structured YAML files, you can’t just append them to get one big kubeconfig file, but kubectl
can help you merge these files:
#
# Merging your kubeconfig file w/ $HOME/.kube/config (w/ cp backup)
#
cp $HOME/.kube/config $HOME/.kube/config.backup.$(date +%Y-%m-%d.%H:%M:%S)
KUBECONFIG=$HOME/.kube/config:file2:file3 kubectl config view --merge --flatten > \
~/.kube/merged_kubeconfig && mv ~/.kube/merged_kubeconfig ~/.kube/config
kubectl get pods --context=cluster-1
kubectl get pods --context=cluster-2
Extracting a context from a kubeconfig file
Let’s say you followed the before merging kubeconfig files and have a merged kubeconfig file in $HOME/.kube/config
. Now you want to extract a cluster’s information to a portable kubeconfig file that only has the parts you need to connect to that cluster.
Run:
KUBECONFIG=$HOME/.kube/config kubectl config view \
--minify --flatten --context=context-1 > $HOME/.kube/config-context-1
#
# using --kubeconfig flag
#
kubectl get pods --kubeconfig=$HOME/.kube/config-context-1
#
# or
# using `KUBECONFIG` environment variable
#
KUBECONFIG=$HOME/.kube/config-context-1 kubectl get pods
#
# or
# keep using kubeconfig file at $HOME/.kube/config (which has the merged context)
#
kubectl get pods --context=cluster-1
In this command, we extract data about context-1
from $HOME/.kube/config
to config-context-1
file. The --minify
flag allows us to extract only info about that context, and the --flatten
flag allows us to keep the credentials unredacted.
ref article: https://ahmet.im/blog/mastering-kubeconfig/
Solution 4:[4]
If you want to merge two config files in a single one
I found this way (not sure if this is the simplest)
# Add the two config files to the env var
export KUBECONFIG=~/.kube/config:~/Desktop/configFile2.yaml
# Review that you have two configurations in one view
kubectl config view
# View the raw config and output to a new file
kubectl config view --raw > /tmp/config
Then copy the new config file where you want, also do not forget to unset KUBECONFIG
the env variable
Solution 5:[5]
It's possible, follow the steps:
create a backup from your config file:
cp ~/.kube/config-bkp
create a file with your new config file:
vi ~/.kube/new-config
merge them into config:
KUBECONFIG=~/.kube/config:~/.kube/new-config kubectl config view --flatten > ~/.kube/config
To see the available contexts use:
kubectl config get-contexts
To change the context use:
kubectl config use-context YOUR-CONTEXT-NAME
Solution 6:[6]
You can follow these instruction if you want to have some structure in your ~/.kube
directory.
- Add the following snippet to your
~/.bashrc
- Add config files under
~/.kube/config.d
separately. - call
update_kubeconfigs
, or open new terminal
update_kubeconfigs
just looks at ~/.kube/config.d
directory and if there were any files newer than the current config file under ~/.kube/config
, it updates it.
function update_kubeconfigs() {
[ ! -d "$HOME/.kube/config.d" ] && mkdir $HOME/.kube/config.d -p -v
# Will run only if there are new files in the config directory
local new_files=$(find $HOME/.kube/config.d/ -newer $HOME/.kube/config -type f | wc -l)
if [[ $new_files -ne "0" ]]; then
local current_context=$(kubectl config current-context) # Save last context
local kubeconfigfile="$HOME/.kube/config" # New config file
cp -a $kubeconfigfile "${kubeconfigfile}_$(date +"%Y%m%d%H%M%S")" # Backup
local kubeconfig_files="$kubeconfigfile:$(ls $HOME/.kube/config.d/* | tr '\n' ':')"
KUBECONFIG=$kubeconfig_files kubectl config view --merge --flatten > "$HOME/.kube/tmp"
mv "$HOME/.kube/tmp" $kubeconfigfile && chmod 600 $kubeconfigfile
export KUBECONFIG=$kubeconfigfile
kubectl config use-context $current_context --namespace=default
fi
}
# This will call each time you source .bashrc, remove it if you want to call it manually each time
update_kubeconfigs
Removing files form ~/.kube/confing.d
will not invoke the script again. Also as @rafaelrezend pointed out, checkout for name conflicts in the config files, that might cause issues.
Solution 7:[7]
Going forward, I do not recommend merging kubeconfig files using kubectl.
- it is a manual effort as seen above (set environment variables etc.)
- has the disadvantage that when using this context via "kubectl config use-context" it WRITES the current context to the kubeconfig file. Thus, this influences other terminal sessions that use a context from the same kubeconfig file (they all suddenly point to the same context).
Instead, I would recommend using a tool that circumvents such issues by e.g recursively search & displays all available contexts for kubeconfig files and works on a temporary copy.
Checkout kubeswitch (the tool I wrote to deal with > 1000 kubeconfig files) and this section explaining how it works.
If you look for a tool that also does namespace switching and other related things, take a look at "kubie".
Solution 8:[8]
As mentioned in the comment by @talarczykco on the top answer, piping back to the same ~/.kube/config
will only write the second file and you will lose the original content!
Here is a safer way to first capture the full output then pipe.
Note must surround the variable kubeconfig
with "
otherwise you lose all newlines!
konfig=$(KUBECONFIG=~/.kube/config:new-config.yaml kubectl config view --flatten)
echo "$konfig" > ~/.kube/config
Solution 9:[9]
If you prefer a CLI tool I can highly recommend: KubeCM, which is also able to merge, switch, add...
kubecm add -f ./your_new_config
You would be asked either to merge into ~/.kube/config
or create a .yml file in your current folder.
Solution 10:[10]
Since I have many Kubernetes conf files in the ~/.kube
directory, I simply chain them tot the KUBECONFIG
env variable in the ~/.zshrc
file:
export KUBECONFIG=$HOME/.kube/config
for conf in ~/.kube/*.conf; do
export KUBECONFIG=$KUBECONFIG:$conf
done
Solution 11:[11]
To dynamically merge multiple config files in you .bashrc:
export KUBECONFIG=/Users/<user>/.kube/config:/Users/<user>/.kube/other.config
source <(kubectl completion bash)
After fresh source, verify:
kubectl config view
Solution 12:[12]
If you use bash you can use this to simply add the configs:
function kmerge() {
DATE=$(date +"%Y%m%d%H%M")
KUBECONFIG=~/.kube/config:$1 kubectl config view --flatten > ~/.kube/mergedkub && mv ~/.kube/config ~/.kube/config-$DATE && mv ~/.kube/mergedkub ~/.kube/config
}
Then just use "kmerge $newConfigfile" to add this. Be aware the clusternames etc. should be different from existing config entries!
Solution 13:[13]
I keep the yaml files for each cluster separate and then combine them with this python script:
import argparse
import yaml
parser = argparse.ArgumentParser()
parser.add_argument('files', metavar='YAMLFILES', type=argparse.FileType('r'), nargs='*')
args = parser.parse_args()
y = {'apiVersion': 'v1', 'kind': 'Config', 'clusters': [],'contexts': [],
'current-context': None, 'preferences': {}, 'users': []}
for a in args.files:
f = yaml.load(a, Loader=yaml.Loader)
y['clusters'].append(f['clusters'][0])
y['contexts'].append(f['contexts'][0])
y['users'].append(f['users'][0])
y['current-context'] = f['contexts'][0]['name']
print(yaml.dump(y, Dumper=yaml.Dumper))
Solution 14:[14]
Zsh users can use a =(...)
process substitution to generate a temporary merged configuration file, and copy it to ~/.kube/config
all in one line:
cp =(KUBECONFIG=~/.kube/config:~/.kube/config.other kubectl config view --flatten) ~/.kube/config
Going a step further, we can hold the configuration file in our system clipboard and use a nested process substitution that reads it. Just make sure that the clipboard content is the actual configuration file before pressing Enter:
cp =(KUBECONFIG=~/.kube/config:<(pbpaste) kubectl config view --flatten) ~/.kube/config
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow