Now i have Pods as Kubernetes structs wiht the help of the command
pods , err := clientset.CoreV1().Pods("namespace_String").List(context.TODO(), metav1.ListOptions{})
now i do i get it as individual yaml files
which command should i use
for i , pod := range pods.Items{
if i==0{
t := reflect.TypeOF(&pod)
for j := 0; j<t.NumMethod(); j++{
m := t.Method(j)
fmt.Println(m.Name)
}
}
}
this function will print the list of functions in the pod item which should i use
Thanks for the answer
The yaml is just a representation of the Pod object in the kubernetes internal storage in etcd. With your client-go what you have got is the Pod instance, of the type v1.Pod. So you should be able to work with this object itself and get whatever you want, for example p.Labels() etc. But if for some reason, you are insisting on getting a yaml, you can do that via:
import (
"sigs.k8s.io/yaml"
)
b, err := yaml.Marshal(pod)
if err != nil {
// handle err
}
log.Printf("Yaml of the pod is: %q", string(b))
Note that yaml library coming here is not coming from client-go library. The documentation for the yaml library can be found in: https://pkg.go.dev/sigs.k8s.io/yaml#Marshal
Instead of yaml if you want to use json, you can simply use the Marshal function https://pkg.go.dev/k8s.io/apiserver/pkg/apis/example/v1#Pod.Marshal provided by the v1.Pod struct itself, like any other Go object.
To get individual pod using client-go:
pod, err := clientset.CoreV1().Pods("pod_namespace").Get(context.TODO(),"pod_name", metav1.GetOptions{})
if err!=nil {
log.Fatalln(err)
}
// do something with pod
Related
We are using the Go helm.sh/helm/v3/pkg/action package to install Helm charts.
We are able to pass installation values to Helm chart Run functions via map[string]interface{}, as in Samples on kubernetes helm golang client:
rel, err := client.Run(myChart, vals)
if err != nil {
log.Println(err)
panic(err)
}
But we have a values.yaml file also which was passed as -f values.yaml when installing charts from the CLI.
Is there a way to pass these values.yaml files via the action Go package during installation (client.Run())?
Or do we need to unmarshal the YAML file and pass that also as map:
data2 := make(map[string]interface{})
yfile2, err := ioutil.ReadFile("./utils/values.yaml")
fmt.Println(err)
err = yaml.Unmarshal(yfile2, &data2)
One straightforward thing to do could be to reuse the helm.sh/helm/v3/pkg/cli/values package. This has the logic to handle the -f option (and also --set and its variants) and return a unified map[string]interface{}. This could look like:
import (
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/cli/values"
"helm.sh/helm/v3/pkg/getter"
)
envSettings := cli.New()
providers := getter.All(envSettings)
options := values.Options{
ValueFiles: []string{"./utils/values.yaml"},
}
theValues := options.MergeValues(providers)
Now theValues is the map[string]interface{} that results from reading those files. You can customize the values further if required (as Go data) and then pass that to install.Run().
I am beginner in golang and started working on backend RBAC application to manage access of Kubernetes cluster, we have a monitoring stack that is behind proxy serves prometheus , thanos and grafana URL. I am not able to add conditions to check HTTP status using httptest. I have to add condition if pods are up and running else print the error.
rq := httptest.NewRequest("GET", "/", nil)
rw := httptest.NewRecorder()
proxy.ServeHTTP(rw, rq)
if rw.Code != 200 && monitoringArgs.selector == "PROMETHEUS" {
fmt.Printf("Target pods are in error state, please check with 'oc get pods -n %s -l %s'", monitoringArgs.namespace, monitoringArgs.selector)
}
How can I added condition for all three prometheus/grafana/Thanos
You can use the restart count of POD also in logic something like
pods, err := clientset.CoreV1().Pods(namespace).List(metav1.ListOptions{
LabelSelector: "app=myapp",
})
// check status for the pods - to see Probe status
for _, pod := range pods.Items {
pod.Status.Conditions // use your custom logic here
for _, container := range pod.Status.ContainerStatuses {
container.RestartCount // use this number in your logic
}
}
Im using the following code to install chart that is bounded in my source code (eg. in my app/chart/chart1 in my go bin app), Now I need to move the chart to git repository or to artifactory,
My question is how can I install the chart from outside my program?
This is the code I use which works for bundled chart
I use the helm3 loader package which works when I have the chart bundled in my app
chart, err := loader.Load(“chart/chart1”)
https://pkg.go.dev/helm.sh/helm/v3#v3.5.4/pkg/chart/loader
Should I load it somehow with an http call or helm have some built in functionality ? we need some efficient way to handle it
It seems that helm during its upgrade/install commands checks first a couple of different locations which you can see getting called here. The content of that function is here.
And then continues here with loader.Load
You can use something like this for installing nginx chart
myChart, err := loader.Load("https://charts.bitnami.com/bitnami/nginx-8.8.4.tgz")
...
install := action.NewInstall(m.actionConfig)
install.ReleaseName = "my-release"
...
myRelease, err := install.Run(myChart, myValues)
It would be similar to:
helm install my-release https://charts.bitnami.com/bitnami/nginx-8.8.4.tgz
loader.load checks only for files and directories. If you want to use URL helm sdk provides LocateChart method in Install interface. Here is an example:
settings := cli.New()
actionConfig := new(action.Configuration)
if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), log.Printf); err != nil {
log.Printf("%+v", err)
os.Exit(1)
}
client := action.NewInstall(actionConfig)
chrt_path, err := client.LocateChart("https://github.com/kubernetes/ingress-nginx/releases/download/helm-chart-4.0.6/ingress-nginx-4.0.6.tgz", settings); if err != nil {
panic(err)
}
myChart, err := loader.Load(chrt_path); if err != nil {
panic(err)
}
Then you can simple setup install options and call client.Run method.
I made a demo with kubernetes/go-client where i tried to list pods from my cluster.
config, err := rest.InClusterConfig()
if err != nil {
panic(err.Error())
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
fmt.Fprint(w, "There are d pods in the cluster\n", len(pods.Items))
I created serviceaccount token to assign to the pod where this code is running in.
But when code is executed pods.Items has no pods.
I deployed this pod inside minikube. When I launch some kubectl command for listing pods, this way I can get resources so it is no t permissions problems.
I wonder what is happening and how i can fix it.
Repository https://github.com/srpepperoni/inframanager.git
Image is pushed into: https://hub.docker.com/r/jaimeyh/inframanager
The endpoint I have problems with is this one :
mux.HandleFunc("/getPods", GetPodsFromNamespace)
You need to check if the err on the last line is non-nil.
pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
OK, there is the problem. pods is forbidden: User "system:serviceaccount:mis-pruebas:sa-prueba-go" cannot list resource "pods" in API group "" at the cluster scope
As the error message indicates, the ServiceAccount does not have permission to list pods at cluster scope. You need to create Role and bind it to the ServiceAccount.
The article Using RBAC Authorization even has a role example for how to create such a role.
I am creating Kubernetes POD with Golang. Iam trying to set DeletionGracePeriodSeconds but after creating pod, the pod has 30 in this field while I am setting 25.
Name of the pod is OK, so after creating the POD it has name that I assigned in code.
func setupPod(client *Client, ns string, name string, labels map[string]string) (*v1.Pod, error) {
seconds := func(i int64) *int64 { return &i }(25)
pod := &v1.Pod{}
pod.Name = name
pod.Namespace = ns
pod.SetDeletionGracePeriodSeconds(seconds) //it is 25 seconds under debugger
pod.DeletionGracePeriodSeconds = seconds
pod.Spec.Containers = []v1.Container{v1.Container{Name: "ubuntu", Image: "ubuntu", Command: []string{"sleep", "30"}}}
pod.Spec.NodeName = "node1"
if labels != nil {
pod.Labels = labels
}
_, err := client.client.CoreV1().Pods(ns).Create(client.context, pod, metav1.CreateOptions{})
return pod, err
}
DeletionGracePeriodSeconds is read-only and hence you can not change it. You should instead set terminationGracePeriodSeconds and kubernetes will set the DeletionGracePeriodSeconds accordingly. You can verify that by getting the value and printing it.
From the API docs
Number of seconds allowed for this object to gracefully terminate
before it will be removed from the system. Only set when
deletionTimestamp is also set. May only be shortened. Read-only.
podSpec := &v1.Pod{
Spec: v1.PodSpec{
TerminationGracePeriodSeconds: <Your-Grace-Period>
},
}
_, err = clientset.CoreV1().Pods("namespacename").Create(context.TODO(), podSpec, metav1.CreateOptions{})