How does Helm keep track of which Kubernetes cluster it installs to? - kubernetes

If I am using kubectx and switch kube config contexts into another cluster e.g. "Production" and run a helm uninstall, how does Helm know which cluster I am referring to?
If I run the helm list command is it only referring to what's installed on my local machine and not per Kubernetes cluster?

Helm will default to using whatever your current Kubernetes context is, as specified in the $HOME/.kube/config file.
There is standard support in the Kubernetes API libraries to read data out of this file (or an alternative specified by a $KUBECONFIG environment variable). If you're writing Go, see the documentation for the k8s.io/client-go/tools/clientcmd package. While kubectx does a bunch of things, its core uses that API to do essentially the same thing as running kubectl config use-context ....
If you want Helm to use a non-default context, there is a global option to specify it:
kubectx production
helm list
kubectx development
helm --kube-context production list

Related

Kubernetes single deployment yaml file for spinning up the application

I am setting up kubernetes for an application with 8 microservices,activemq,postgres,redis and mongodb.
After the entire configuration of pods and deployment ,is there any way to create a single master deployment yaml file which will create the entire set of services,replcas etc for the entire application.
Note:I will be using multiple deployment yaml files,statefulsets etc for all above mentioned services.
You can use this script:
NAMESPACE="your_namespace"
RESOURCES="configmap secret daemonset deployment service hpa"
for resource in ${RESOURCES};do
rsrcs=$(kubectl -n ${NAMESPACE} get -o json ${resource}|jq '.items[].metadata.name'|sed "s/\"//g")
for r in ${rsrcs};do
dir="${NAMESPACE}/${resource}"
mkdir -p "${dir}"
kubectl -n ${NAMESPACE} get -o yaml ${resource} ${r} > "${dir}/${r}.yaml"
done
done
Remember to specify what resources you want exported in the script.
More info here
Is there any way to create a single master deployment yaml file which will create the entire set of services,replicas etc for the entire application.
Since you already mentioned kubernetes-helm why don't you actually used it for that exact purpose? In short helm is sort of package manager for Kubernetes, some say similar to yum or apt. It deploys charts which you can actually refer to as packed application. Its pack of all your pre-configured applications which can be deploy as one unit. It's not entirely one file but more collection of files that build so called helm chart.
What are the helm charts?
Well they are basically K8s yaml manifest combined into a single package that can be installed to your cluster. And installing the package is just as simple as running single command such as helm install. Once done the charts are highly reusable which reduces the time for creating dev, test and prod environments.
As an example of a complex helm chart deploying multiple resources you many want to check Stackstorm.
Basically once deployed without any custom config this chart will deploy 2 replicas for each component of StackStorm as well as backends like RabbitMQ, MongoDB and Redis.

Helm Umbrella Chart, dependency on remote Chart

I am new to Helm Kubernetes. I am currently using a list of bash commands to create a local Minikube cluster with many containers installed. In order to alleviate the manual burden we were thinking of creating an (umbrella) Helm Chart to execute the whole list of commands.
Between the commands that I would need to run in the Chart there are few (cleanup) kubectl deletes, i.e. :
kubectl delete all,configmap --all -n system --force --grace-period=0
and also some helm installs, i.e.:
helm repo add bitnami https://charts.bitnami.com/bitnami && \
helm install postgres bitnami/postgresql --set postgresqlPassword=test,postgresqlDatabase=test && \
Question1: is it possible to include kubectl command in my Helm Chart?
Question2: is it possible to add a dependency from a Chart only remotely available? I.e. the dependency from postgres above.
Question3: If you think Helm is not the correct tool for doing this, what would you suggest instead?
Thank you
You can't embed imperative kubectl commands in a Helm chart. An installed Helm chart keeps track of a specific set of Kubernetes resources it owns; you can helm delete the release, and that will delete that specific set of things. Similarly, if you have an installed Helm chart, you can helm upgrade it, and the new chart contents will replace the old ones.
For the workflow you describe – you're maintaining a developer environment based on Minikube, and you want to be able to start clean – there are two good approaches to take:
helm delete the release(s) that are already there, which will uninstall their managed Kubernetes resources; or
minikube delete the whole "cluster" (as a single container or VM), and then minikube start a new empty "cluster".

How to find the associated service account for Helm?

Prior to Helm 3, it was possible to associate a service account in helm initialization via
helm init --service-account tiller
But since helm init is now deprecated, how can we find out which service account is the Helm associated with?
Helm 3 will have the same permissions according to the default config in ~/.kube/config or another config if specified in your system environment variable $KUBECONFIG or overridden using the following command options
--kube-context string name of the kubeconfig context to use
--kubeconfig string path to the kubeconfig file
With Tiller gone, the security model for Helm is radically simplified. Helm 3 now supports all the modern security, identity, and authorization features of modern Kubernetes. Helm’s permissions are evaluated using your kubeconfig file. Cluster administrators can restrict user permissions at whatever granularity they see fit. — Changes since Helm 2: Removal of Tiller

Common config in Kubernetes ConfigMap

Kubernetes already provides a way to manage configuration with ConfigMap.
However, I have a question/problem here.
If I have multiple applications with different needs deployed in Kubernetes, all these deployments might share and access some common config variables. Is it possible for ConfigMap to use a common config variable?
There are two ways to do that.
Kustomize - Customization of kubernetes YAML configurations (developed as kubernetes sigs, and had been integrated into kubectl command line). But currently it isn't mature enough if compare with helm chart
https://github.com/kubernetes-sigs/kustomize
Helm chart - The Kubernetes Package Manager. Its vaules.yaml can define the vaule for same configuration files (in your case, they are configmap) with variables.
https://helm.sh/

How to switch kubectl clusters between gcloud and minikube

I have Kubernetes working well in two different environments, namely in my local environment (MacBook running minikube) and as well as on Google's Container Engine (GCE, Kubernetes on Google Cloud). I use the MacBook/local environment to develop and test my YAML files and then, upon completion, try them on GCE.
Currently I need to work with each environment individually: I need to edit the YAML files in my local environment and, when ready, (git) clone them to a GCE environment and then use/deploy them. This is a somewhat cumbersome process.
Ideally, I would like to use kubectl from my Macbook to easily switch between the local minikube or GCE Kubernetes environments and to easily determine where the YAML files are used. Is there a simple way to switch contexts to do this?
You can switch from local (minikube) to gcloud and back with:
kubectl config use-context CONTEXT_NAME
to list all contexts:
kubectl config get-contexts
You can create different enviroments for local and gcloud and put it in separate yaml files.
List contexts
kubectl config get-contexts
Switch contexts
kubectl config set current-context MY-CONTEXT
A faster shortcut to the standard kubectl commands is to use kubectx:
List contexts: kubectx
Equivalent to kubectl config get-contexts
Switch context (to foo): kubectx foo
Equivalent to kubectl config use-context foo
To install on macOS: brew install kubectx
The kubectx package also includes a similar tool for switching namespaces called kubens.
These two are super convenient if you work in multiple contexts and namespaces regularly.
More info: https://ahmet.im/blog/kubectx/
If you're looking for a GUI-based solution for Mac and have the Docker Desktop installed, you can use the Docker Menu Bar icon. Here you can find "Kubernetes" menu with all the contexts you have in your kubeconfig and easily switch between them.
To get all context
C:\Users\arun>kubectl config get-contexts
To get current context
C:\Users\arun>kubectl config current-context
To switch context
C:\Users\arun>kubectl config use-context <any context name from above list>
Latest 2020 answer is here,
A simple way to switch between kubectl context,
kubectl top nodes **--context=**context01name
kubectl top nodes --context=context02name
You can also store the context name as env like
context01name=gke_${GOOGLE_CLOUD_PROJECT}_us-central1-a_standard-cluster-1
I got bored of typing this over and over so I wrote a simple bash utility to switch contexts
You can find it here https://github.com/josefkorbel/kube-switch
The canonical answer of switching/reading/manipulating different kubernetes environments (aka kubernetes contexts) is, as Mark mentioned, to use kubectl config, see below:
$ kubectl config
Modify kubeconfig files using subcommands like "kubectl config set current-context my-context"
Available Commands:
current-context Displays the current-context
delete-cluster Delete the specified cluster from the kubeconfig
delete-context Delete the specified context from the kubeconfig
get-clusters Display clusters defined in the kubeconfig
get-contexts Describe one or many contexts
rename-context Renames a context from the kubeconfig file.
set Sets an individual value in a kubeconfig file
set-cluster Sets a cluster entry in kubeconfig
set-context Sets a context entry in kubeconfig
set-credentials Sets a user entry in kubeconfig
unset Unsets an individual value in a kubeconfig file
use-context Sets the current-context in a kubeconfig file
view Display merged kubeconfig settings or a specified kubeconfig file
Usage:
kubectl config SUBCOMMAND [options]
Behind the scene, there is a ~/.kube/config YAML file that stores all the available contexts with their corresponding credentials and endpoints for each contexts.
Kubectl off the shelf doesn't make it easy to manage different kubernetes contexts as you probably already know. Rather than rolling your own script to manage all that, a better approach is to use a mature tool called kubectx, created by a Googler named "Ahmet Alp Balkan" who's on Kubernetes / Google Cloud Platform developer experiences Team that builds tooling like this. I highly recommend it.
https://github.com/ahmetb/kubectx
$ kctx --help
USAGE:
kubectx : list the contexts
kubectx <NAME> : switch to context <NAME>
kubectx - : switch to the previous context
kubectx <NEW_NAME>=<NAME> : rename context <NAME> to <NEW_NAME>
kubectx <NEW_NAME>=. : rename current-context to <NEW_NAME>
kubectx -d <NAME> [<NAME...>] : delete context <NAME> ('.' for current-context)
(this command won't delete the user/cluster entry
that is used by the context)
kubectx -h,--help : show this message
TL;DR: I created a GUI to switch Kubernetes contexts via AppleScript. I activate it via shift-cmd-x.
I too had the same issue. It was a pain switching contexts by the command line. I used FastScripts to set a key combo (shift-cmd-x) to run the following AppleScript (placed in this directory: $(HOME)/Library/Scripts/Applications/Terminal).
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
do shell script "/usr/local/bin/kubectl config current-context"
set curcontext to result
do shell script "/usr/local/bin/kubectl config get-contexts -o name"
set contexts to paragraphs of result
choose from list contexts with prompt "Select Context:" with title "K8s Context Selector" default items {curcontext}
set scriptArguments to item 1 of result
do shell script "/usr/local/bin/kubectl config use-context " & scriptArguments
display dialog "Switched to " & scriptArguments buttons {"ok"} default button 1
Cloning the YAML files across repos for different environments is definitely ideal. What you to do is templatize your YAML files - by extracting the parameters which differ from environment to environment.
You can, of course, use some templating engine and separate the values in a YAML and produce the YAML for a specific environment. But this is easily doable if you adopt the Helm Charts. To take a look at some sample charts go to stable directory at this Github repo
To take an example of the Wordpress chart, you could have two different commands for two environments:
For Dev:
helm install --name dev-release --set \
wordpressUsername=dev_admin, \
wordpressPassword=dev_password, \
mariadb.mariadbRootPassword=dev_secretpassword \
stable/wordpress
It is not necessary to pass these values on CLI though, you can store the values in a file called aptly values.yml and you could have different files for different environments
You will need some work in converting to Helm chart standards, but the effort will be worth it.
Check also the latest (docker 19.03) docker context command.
Ajeet Singh Raina ) illustrates it in "Docker 19.03.0 Pre-Release: Fast Context Switching, Rootless Docker, Sysctl support for Swarm Services"
A context is essentially the configuration that you use to access a particular cluster.
Say, for example, in my particular case, I have 4 different clusters – mix of Swarm and Kubernetes running locally and remotely.
Assume that I have a default cluster running on my Desktop machine , 2 node Swarm Cluster running on Google Cloud Platform, 5-Node Cluster running on Play with Docker playground and a single-node Kubernetes cluster running on Minikube and that I need to access pretty regularly.
Using docker context CLI I can easily switch from one cluster(which could be my development cluster) to test to production cluster in seconds.
$ sudo docker context --help
Usage: docker context COMMAND
Manage contexts
Commands:
create Create a context
export Export a context to a tar or kubeconfig file
import Import a context from a tar file
inspect Display detailed information on one or more contexts
ls List contexts
rm Remove one or more contexts
update Update a context
use Set the current docker context
Run 'docker context COMMAND --help' for more information on a command.
For example:
[:)Captain'sBay=>sudo docker context ls
NAME DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock https://127.0.0.1:16443 (default) swarm
swarm-context1
I use kubeswitch (disclaimer: I wrote the tool) that can be used just like kubectx, but is designed for a large number of kubeconfig files.
If you have to deal with hundreds or thousands of kubeconfig files, this tool might be useful to you, otherwise kubectx or kubectl config use-context might be sufficient.
For instance, it adds capabilities like reading from vault, hot reload while searching, and an index to speed up subsequent searches.
You can install it from here.
EDIT: now also includes support for GKE directly. So you can use and discover kubeconfig files without having to manually download and update them.
In case you might be looking for a simple way to switch between different contexts maybe this will be of help.
I got inspired by kubectx and kswitch scripts already mentioned, which I can recommend for most use-cases. They are helping with solving the switching task, but are breaking for me on some bigger or less standard configurations of ~/.kube/config. So I created a sys-exec invocation wrapper and a short-hand around kubectl.
If you call k without params you would see an intercepted prompt to switch context.
Switch kubectl to a different context/cluster/namespace.
Found following options to select from:
>>> context: [1] franz
>>> context: [2] gke_foo_us-central1-a_live-v1
>>> context: [3] minikube
--> new num [?/q]:
Further, k continues to act as a short-hand. The following is equivalent:
kubectl get pods --all-namespaces
k get pods -A
k p -A
yes, i think this is what your asking about. To view your current config, use kubectl config view. kubectl loads and merges config from the following locations (in order)
--kubeconfig=/path/to/.kube/config command line flag
KUBECONFIG=/path/to/.kube/config env variable
$HOME/.kube/config - The DEFAULT
i use --kubeconfig since i switch alot between multiple clusters. its slightly cumbersome but it works well.
see these for more info.
https://kubernetes.io/docs/tasks/administer-cluster/share-configuration/ and https://kubernetes.io/docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig/