Rollout restart statefulset using kubectl proxy - kubernetes

I have started kubectl proxy from within my pods and am able to access kubernetes APIs. I have a need to restart my statefulset.
Using kubectl, I would done this:
kubectl rollout restart statefulset my-statefulset
However, I would like to do this using the REST APIs. For instance, I can delete my pods, using this:
curl -XDELETE localhost:8080/api/v1/namespaces/default/pods
Is there any equivalent REST endpoint that I can use to rollout restart a statefulset?

I run your command kubectl rollout restart statefulset my-statefulset --v 10 and notice the output logs.
I figured out kubectl makes a patch request when I apply above command. And I am able to do that patch request using curl like following
curl -k --data '{"spec":{"template":{"metadata":{"annotations":{"kubectl.kubrnetes.io/restartedAt":"'"$(date +%Y-%m-%dT%T%z)"'"}}}}}'\
-XPATCH -H "Accept: application/json, */*" -H "Content-Type: application/strategic-merge-patch+json"\
localhost:8080/apis/apps/v1/namespaces/default/statefulsets/my-statefulset

Related

Kubernetes: How to get other pods' name from within a pod?

I'd like to find out the other pods' name running in the same single-host cluster. All pods are single-application containers. I have pod A (written in Java) that acts as a TCP/IP server and a few other pods (written in C++) connect to the server.
In pod A, I can get IP address of clients (other pods). How do I get their pods' name? I can't run kubectl commands because pod A has no kubectl installed.
Thanks,
You can directly call kube-apiserver with cURL.
First you need to have a serviceaccount binded to clusterrole to be able to send requests to apiserver.
kubectl create clusterrole listpods --verb=get,list,watch --resource=pods
kubectl create clusterrolebinding listpods --clusterrole=listpods --serviceaccount=default:default
Get a shell inside a container
kubectl exec -it deploy/YOUR_DEPLOYMENT -- sh
Define necessary parameters for your cURL, run below commands inside container
APISERVER=https://kubernetes.default.svc
SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
TOKEN=$(cat ${SERVICEACCOUNT}/token)
CACERT=${SERVICEACCOUNT}/ca.crt
Send pods list request to apiserver
curl -s -k -H "Authorization: Bearer $TOKEN" -H 'Accept: application/json' $APISERVER/api/v1/pods | jq "[ .items[] | .metadata.name ]"
Done ! It will return you a json list of "kubectl get pods"
For more examples, you can check OpenShift RestAPI Reference. Also, if you are planning to do some programmatic stuff, I advice you to checkout official kubernetes-clients.
Credits for jq improvement to #moonkotte

how to "stop" and "start" kubernetes API deployments /pod

I have a requirement to stop deployment by label name and start it again, via the API
also I need to do that for a group of deployments so I added label for each of them
so i know how to filter the deploymnet by desire label. but I found that if I would like to stop deployment from running, I do need to scale it down and changed the replica number to 0
is there any other option to do that via API? because now I should need to keep the replica for start (scale-up again) but this is a parameter that not easy to keep in a lifecycle of a service
so now the best option that I found is smth like :
PAYLOAD='[{"op":"replace","path":"/spec/replicas","value":"3"}]'
curl -X PATCH -d$PAYLOAD -H 'Content-Type: application/json-patch+json' $API_URL
but I am asking if there is smth else and if there is a group "stop /start" like in docker swarm that you can just run docker stack rm for example
If you would like to run kubectl scale deployments mydeployment --replicas=0 via API call, you can run below command
$ curl -k \
-X PUT \
-d #- \
-H "Authorization: Bearer $TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
https://$ENDPOINT/apis/apps/v1/namespaces/$NAMESPACE/deployments/$NAME/scale <<'EOF'
{
"kind": "Scale",
"apiVersion": "apps/v1beta1",
...
}
EOF
More examples can be found in Openshift RestAPI documentations.
How about a solution where you store number of replicas in annoatation:
export DEPLOYMENT_NAME=xxx
kubectl annotate deployments $DEPLOYMENT_NAME replicas-before=$(kubectl get deployments.apps $DEPLOYMENT_NAME -ojsonpath="{.spec.replicas}")
kubectl scale deployment --replicas 0 $DEPLOYMENT_NAME
kubectl scale deployment --replicas $(kubectl get deployments.apps nginx -ojsonpath="{.metadata.annotations.replicas-before}") $DEPLOYMENT_NAME
This does not require additional saving the state externally. You save the current state in an annotation in this example called replicas-before, and then scale down the deployment to 0. If you want to restore the number or replicas, just read the replicas from annotation and scale the deployment up to this value.
I know you asked for a solution using k8s api. Just run the kubectl command with -v=10 and see what api requests are being sent.

kubernetes restart all the pods using REST api

I need to update all the pods(rolling updates), with env variable changes
I am not using kubectl, but using REST api.
Right not i am deleting the service and pods; And then recreating both services and pods. (It usually take around minutes, and there is downtime). Wanted similar with rolling update, without downtime.
If you want to restart all pod attached to a deployment, then you can do that by running
$ curl -k --data '{"spec":{"template":{"metadata":{"annotations":{"kubectl.kubrnetes.io/restartedAt":"'"$(date +%Y-%m-%dT%T%z)"'"}}}}}' -XPATCH -H "Accept: application/json, */*" -H "Content-Type: application/strategic-merge-patch+json" localhost:8001/apis/extensions/v1beta1/namespaces/default/deployments/mydeployment
Use deployment instead of pods.
Deployment has DeploymentStrategy , maxUnavailable, maxSurge using which you can achieve zero downtime upgrade.
For changing env just change it the deployment yaml and apply it to the cluster. It will rollout the deployment without any downtime.
Kubectl internally calls rest api exposed by Kubernetes API Server. You could check what rest call being sent by kubectl by increasing the verbosity. Once you know the rest api being called you could call those apis as well.
kubectl rollout restart deployment/frontend -v=10

Is it possible to execute kubectl commands via curl?

is it possible to execute kubectl commands as a curl by simply hitting GKE kube master api for some resources and get json back ?
Kubernetes is an entirely API-based system ,to interact with the Kubernetes API you need a ServiceAccount (obtained through a Cluster Role and a RoleBinding).
Here you can find the documentation for Google Kubernetes Engine API: https://cloud.google.com/kubernetes-engine/docs/reference/rest
Also as side note, might be usefully:
https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/#accessing-the-kubernetes-api
Kubernetes is REST API based and can be called via curl.
https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/#accessing-the-kubernetes-api
Kubectl internally does curl to Kubernetes API which can be verified via running below command and searching for curl and you can execute the same curl command. In the below example kubectl is using certificate for authentication and executing curl against Kubernetes API.
kubectl get nodes --v=10
curl -k -v -XGET -H "Accept: application/json;as=Table;v=v1beta1;g=meta.k8s.io, application/json" -H "User-Agent: kubectl/v1.17.0 (darwin/amd64) kubernetes/70132b0" 'https://127.0.0.1:32768/api/v1/nodes?limit=500'
But to call Kubernetes REST API you can either use a client certificate or a JWT bearer token. A service account which has a bearer token is the recommended way to communicate to Kubernetes API from a pod.
Kubernetes API.

Kubernetes Engine API delete pod

I need to delete POD on my GCP kubernetes cluster. Actually in Kubernetes Engine API documentation I can find only REST api's for: projects.locations.clusters.nodePools, but nothing for PODs.
The GKE API is used to manage the cluster itself on an infrastructure level. To manage Kubernetes resources, you'd have to use the Kubernetes API. There are clients for various languages, but of course you can also directly call the API.
Deleting a Pod from within another or the same Pod:
PODNAME=ubuntu-xxxxxxxxxx-xxxx
curl https://kubernetes/api/v1/namespaces/default/pods/$PODNAME \
-X DELETE -k \
-H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
From outside, you'd have to use the public Kubernetes API server URL and a valid token. Here's how you get those using kubectl:
APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
TOKEN=$(kubectl get secret $(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 --decode )
Here's more official information on accessing the Kubernetes API server.