How can I set a node to unschedulable status via the Kubernetes api? - kubernetes

I am attempting to emulate the behavior of kubectl patch. I'm sending an HTTP PATCH with a json payload of the following:
{
"apiVersion": "v1",
"kind": "Node",
"metadata": {
"name": "my-node-hostname"
},
"spec": {
"unschedulable": true
}
}
However, no matter how I seem to tweak this JSON, I keep getting a 415 and the following JSON status back:
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "the server responded with the status code 415 but did not return more information",
"details": {},
"code": 415
}
Even with debug on kube-apiserver set to 1000, I get no feedback about why the payload is wrong!
Is there a particular format that one should use in the JSON payload sent via PATCH to enable this to work?

After a helpful member of the Kubernetes Slack channel mentioned I could get the payload from kubectl patch via the --verbose flag, it turns out that Kubernetes expects to get "Content-Type: application/strategic-merge-patch+json" when you are sending the PATCH payload.

Related

PUT k8s deployment returns 404

According to the Replacement section of Kubernetes API reference v1.24 I should be able to create a deployment with a PUT /apis/apps/v1/namespaces/{namespace}/deployments/{name} HTTP request. The success response here is 201 Created. However, when I try the following, I get a 404 Not Found which is of course correct but unwanted: PUT requests should be treated as Create statements if the resource does not yet exist as documented. Updating a deployment does work (and returns the expected 200 OK HTTP response). Is there any documentation regarding this? Or is the request somehow incorrect? Ty.
➜ ~ curl --request PUT \
--url http://localhost:8080/apis/apps/v1/namespaces/ns/deployments/nginx-deployment \
--header 'content-type: application/json' \
--data '{
"apiVersion":"apps/v1",
"kind":"Deployment",
"metadata":{
"name":"nginx-deployment",
"labels":{
"app":"nginx"
}
},
"spec": {
"replicas" : 3,
"selector": {
"matchLabels" : {
"app":"nginx"
}
},
"template" : {
"metadata" : {
"labels" : {
"app":"nginx"
}
},
"spec":{
"containers":[
{
"name":"ngnix",
"image":"nginx:1.7.9",
"ports":[
{
"containerPort": 80
}
]
}
]
}
}
}
}'
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "deployments.apps \"nginx-deployment\" not found",
"reason": "NotFound",
"details": {
"name": "nginx-deployment",
"group": "apps",
"kind": "deployments"
},
"code": 404
}%
According to the documentation you provided,
PUT /apis/apps/v1/namespaces/{namespace}/deployments/{name}
is meant to "replace the specified Deployment", while a Deployment is created with a POST:
create a Deployment
HTTP Request
POST /apis/apps/v1/namespaces/{namespace}/deployments
You are correct that the documentation also states:
For PUT requests, Kubernetes internally classifies these as either create or update based on the state of the existing object
so there seems to be a contradiction, but the Deployment API spec states that POST should be used to create a deployment and PUT to update it.

Kubernetes API server filtering by field - in request time

I'm trying to get all the secrets in the cluster of type helm.sh/release.v1:
$ curl -X GET $APISERVER/api/v1/secrets --header "Authorization: Bearer $TOKEN" --insecure
{
"kind": "SecretList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/secrets",
"resourceVersion": "442181"
},
"items": [
{
"metadata": {
...
},
"data": {
...
},
"type": "helm.sh/release.v1"
},
{
"metadata": {
...
},
"data": {
...
},
"type": "kubernetes.io/service-account-token"
},
{
"metadata": {
...
},
"data": {
...
},
"type": "kubernetes.io/service-account-token"
},
...
}
I can use the command above and then filter by myself (jq or whatever) but I wonder if there's an option to filter in the API by adding query parameters or something, for example (didn't work):
curl -X GET $APISERVER/api/v1/secrets?type=<value>
any idea how to filter by specific field? (type) can I also request specific fields in the response (if I don't care about the data for instance)?
I'm going to use HTTP requests from my application (python) that runs
within a pod in the cluster. I am trying to be more efficient and ask
only for what I need (only specific type and not all secrets in the
cluster)
If your application is written in Python, maybe it's a good idea to use Kubernetes Python Client library to get the secrets ?
If you want to get all the secrets in the cluster of type helm.sh/release.v1, you can do it with the following Python code:
from kubernetes import client , config
config.load_kube_config()
v1 = client.CoreV1Api()
list_secrets = v1.list_secret_for_all_namespaces(field_selector='type=helm.sh/release.v1')
If you also want to count them, use:
print(len(list_secrets.items))
to print secret's name use:
print(list_secrets.items[0].metadata.name)
to retrieve it's data:
print(list_secrets.items[0].data)
and so on...
More details, including arguments that can be used with this method, you can find here (just search for list_secret_for_all_namespaces):
# **list_secret_for_all_namespaces**
> V1SecretList list_secret_for_all_namespaces(allow_watch_bookmarks=allow_watch_bookmarks, _continue=_continue, field_selector=field_selector, label_selector=label_selector, limit=limit, pretty=pretty, resource_version=resource_version, timeout_seconds=timeout_seconds, watch=watch)

How to resolve dns problem in Kubernetes?

I've a very strange error in my kubernetes configuration.
When I'm trying to connect to KubeDNS (I'm using minikube) I have the following error:
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "services \"kube-dns:dns\" is forbidden: User \"system:anonymous\" cannot get resource \"services/proxy\" in API group \"\" in the namespace \"kube-system\"",
"reason": "Forbidden",
"details": {
"name": "kube-dns:dns",
"kind": "services"
},
"code": 403
}
I read something about RCAD but I can't find anything that explaine clearly what must I do.
Can anyone help me?

how can i use RestApi to update deployment in k8s?

I want to use the RestApi to update the deployment.
and I test it with postman, but always got 415 back.
the info is as follows:
type:
PATCH
url: https://k8sClusterUrl:6443/apis/extensions/v1beta1/namespaces/ns/deployments/peer0
header:
Authorization: bearer token
Content-Type:application/json
body:
{
"kind": "Deployment",
"spec":
{
"template":
{
"spec":
{
"containers":[
{
"$setElementOrder/volumeMounts":[{"mountPath":"/host/var/run/"},{"mountPath":"/mnt"}],
"name":"peer0",
"image":"hyperledger/fabric-peer:x86_64-1.1.0"}
]
}
}
}
}
response:
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "the server responded with the status code 415 but did not return more information",
"details": {},
"code": 415
}
I have muti-containers in this pod, and only want to apply for the specific container: peer0.
Any different for the $setElementOrder var?
415 is invalid media type.
In this case, you should be setting the media type as application/json+patch+json (you can see this in the documentation here)
You can try using body and using Content-Type to application/json-patch+json, method PATCH:
[{
"op" : "replace",
"path" : "/spec/template/spec/container/0/$setElementOrder/volumeMounts",
"value" : "<value you want to replace>"
}]

Fail to patch rc by api?

Kubernetes verison: 1.02
PATCH /api/v1/namespaces/default/replicationcontrollers/test
body
{"spec":
{"replicas": 3}
}
response
'{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "the server responded with the status code 415 but did not return more information",
"details": {},
"code": 415
}'
Is this a bug for API?
For PATCH to work you need to send one of the accepted content-type header values.
Your example uses a merge patch, so you should send:
Content-Type: application/merge-patch+json