Author

Author


Rajesh Kumar

Rajesh Kumar

DevOps@RajeshKumar.xyz

DevOps@RajeshKumar.xyz

Support my work @Patron! Support my work @Patron!

Contents


APIs and Access

Exercise 5.1: Configuring TLS Access

Overview

Using the Kubernetes API, kubectl makes API calls for you. With the appropriate TLS keys you could run curl as well use a golang client. Calls to the kube-apiserver get or set a PodSpec, or desired state. If the request represents a new state the Kubernetes Control Plane will update the cluster until the current state matches the specified state. Some end states may require multiple requests. For example, to delete a ReplicaSet, you would first set the number of replicas to zero, then delete the ReplicaSet.

An API request must pass information as JSON. kubectl converts .yaml to JSON when making an API request on your behalf. The API request has many settings, but must include apiVersion, kind and metadata, and spec settings to declare what kind of container to deploy. The spec fields depend on the object being created. We will begin by configuring remote access to the kube-apiserver then explore more of the API.

Configuring TLS Access

  1. Begin by reviewing the kubectl configuration file. We will use the three certificates and the API server address.
    
    	student@lfs458-node-1a0a:~$ less ~/.kube/config
    	<output_omitted>
    
    
  2. We will set the certificates as variables. You may want to double-check each parameter as you set it. Begin with setting the client-certificate-data key.
    
    	student@lfs458-node-1a0a:~$ export client=$(grep client-cert ~/.kube/config |cut -d" " -f 6)
    	
    	student@lfs458-node-1a0a:~$ echo $client
    	LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM4akNDQWRxZ0F3SUJ
    	BZ0lJRy9wbC9rWEpNdmd3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0
    	ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB4TnpFeU1UTXhOelEyTXpKY
    	UZ3MHhPREV5TVRNeE56UTJNelJhTURReApGekFWQmdOVkJBb1REbk41YzNS
    	<output_omitted>
    	
    
    
  3. Almost the same command, but this time collect the client-key-data as the key variable.
    
    	student@lfs458-node-1a0a:~$ export key=$(grep client-key-data ~/.kube/config |cut -d " " -f 6)
    	student@lfs458-node-1a0a:~$ echo $key
    	<output_omitted>
    
  4. Finally set the auth variable with the certificate-authority-data key
    
    	student@lfs458-node-1a0a:~$ export auth=$(grep certificate-authority-data ~/.kube/config |cut -d " " -f 6)
    	student@lfs458-node-1a0a:~$ echo $auth
    	<output_omitted>
    
    	
    
  5. Now encode the keys for use with curl.
    
    	student@lfs458-node-1a0a:~$ echo $client | base64 -d - > ./client.pem
    	
    	student@lfs458-node-1a0a:~$ echo $key | base64 -d - > ./client-key.pem
    	
    	student@lfs458-node-1a0a:~$ echo $auth | base64 -d - > ./ca.pem
    	
    
  6. Pull the API server URL from the config file.
    
    	student@lfs458-node-1a0a:~$ kubectl config view |grep server
    			server: https://10.128.0.3:6443
    
    	
    
  7. Use curl command and the encoded keys to connect to the API server.
    
    	student@lfs458-node-1a0a:~$ curl --cert ./client.pem \
    			--key ./client-key.pem \
    			--cacert ./ca.pem \
    			https://10.128.0.3:6443/api/v1/pods
    	{
    			"kind": "PodList",
    			"apiVersion": "v1",
    			"metadata": {
    			"selfLink": "/api/v1/pods",
    			"resourceVersion": "239414"
    	},
    	<output_omitted>
    
    	
    
  8. If the previous command was successful, create a JSON file to create a new pod. Remember to look for this file in the tarball output, it can save you some typing.
    
    	student@lfs458-node-1a0a:~$ vim curlpod.json
    	{
    		"kind": "Pod",
    		"apiVersion": "v1",
    		"metadata":{
    		"name": "curlpod",
    		"namespace": "default",
    		"labels": {
    		"name": "examplepod"
    		}
    		},
    		"spec": {
    			"containers": [{
    				"name": "nginx",
    				"image": "nginx",
    				"ports": [{"containerPort": 80}]
    			
    			}]
    		}
    	}
    	
    
  9. The previous curl command can be used to build a XPOST API call. There will be a lot of output, including the scheduler and taints involved. Read through the output. In the last few lines the phase will probably show Pending, as it’s near the beginning of the creation process.
    
    	student@lfs458-node-1a0a:~$ curl --cert ./client.pem \
    		--key ./client-key.pem --cacert ./ca.pem \
    		https://10.128.0.3:6443/api/v1/namespaces/default/pods \
    		-XPOST -H’Content-Type: application/json’ \
    		-d@curlpod.json
    	{
    		"kind": "Pod",
    		"apiVersion": "v1",
    		"metadata": {
    		"name": "curlpod",
    	<output_omitted>
    
    	
    
  10. Verify the new pod exists and shows a Running status.
    
    	student@lfs458-node-1a0a:~$ kubectl get pods
    	NAME   READY STATUS RESTARTS AGE
    	curlpod 1/1 Running    0     45s
    	
    

Exercise 5.2: Explore API Calls

  1. One way to view what a command does on your behalf is to use strace. In this case, we will look for the current endpoints, or targets of our API calls.
    
    	student@lfs458-node-1a0a:~$ kubectl get endpoints
    	NAME 		ENDPOINTS 		AGE
    	kubernetes 10.128.0.3:6443  3h
    
    
    	
    
  2. Run this command again, preceded by strace. You will get a lot of output. Near the end you will note several openat functions to a local directory, /home/student/.kube/cache/discovery/10.128.0.3_6443. If you cannot find the lines, you may want to redirect all output to a file and grep for them.
    
    	student@lfs458-node-1a0a:~$ strace kubectl get endpoints
    	execve("/usr/bin/kubectl", ["kubectl", "get", "endpoints"], [/*....
    	....
    	openat(AT_FDCWD, "/home/student/.kube/cache/discovery/10.128.0.3_6443..
    	<output_omitted>
    
    
    	
    
  3. Change to the parent directory and explore. Your endpoint IP will be different, so replace the following with one suited to your system.
    
    	student@lfs458-node-1a0a:~$ cd /home/student/.kube/cache/discovery/
    	
    	student@lfs458-node-1a0a:~/.kube/cache/discovery$ ls
    	10.128.0.3_6443
    	
    	student@lfs458-node-1a0a:~/.kube/cache/discovery$ cd 10.128.0.3_6443/
    
    	
    
  4. View the contents. You will find there are directories with various configuration information for kubernetes.
    
    	student@lfs458-node-1a0a:~/.kube/cache/discovery/10.128.0.3_6443$ ls
    	admissionregistration.k8s.io      batch             policy
    	apiextensions.k8s.io        certificates.k8s.io   rbac.authorization.k8s.io
    	apiregistration.k8s.io      coordination.k8s.io   scheduling.k8s.io
    	apps                        crd.projectcalico.org servergroups.json
    	authentication.k8s.io       events.k8s.io         storage.k8s.io
    	authorization.k8s.io        extensions               v1
    	autoscaling                 networking.k8s.io
    
    
  5. Use the find command to list out the subfiles. The prompt has been modified to look better on this page.
    
    	student@lfs458-node-1a0a:./10.128.0.3_6443$ find .
    	.
    	./events.k8s.io
    	./events.k8s.io/v1beta1
    	./events.k8s.io/v1beta1/serverresources.json
    	./apps
    	./apps/v1
    	./apps/v1/serverresources.json
    	./apps/v1beta1
    	./apps/v1beta1/serverresources.json
    	<output_omitted>
    
    
    	
    
  6. View the objects available in version 1 of the API. For each object, or kind:, you can view the verbs or actions for that object, such as create seen in the following example. Note the prompt has been truncated for the command to fit on one line. Some are HTTP verbs, such as GET, others are product specific options, not standard HTTP verbs.
    
    	student@lfs458-node-1a0a:.$ python -m json.tool v1/serverresources.json
    	{
    		"apiVersion": "v1",
    		"groupVersion": "v1",
    		"kind": "APIResourceList",
    		"resources": [
    		{
    			"kind": "Binding",
    			"name": "bindings",
    			"namespaced": true,
    			"singularName": "",
    			"verbs": [
    			"create"
    			]
    		},
    	<output_omitted>
    	
    
  7. Some of the objects have shortNames, which makes using them on the command line much easier. Locate the shortName for endpoints.
    
    	student@lfs458-node-1a0a:.$ python -m json.tool v1/serverresources.json | less
    	.
    		{
    		"kind": "Endpoints",
    		"name": "endpoints",
    		"namespaced": true,
    		"shortNames": [
    		"ep"
    		],
    		"singularName": "",
    		"verbs": [
    		"create",
    		"delete",
    		
    
  8. Use the shortName to view the endpoints. It should match the output from the previous command.
    
    	student@lfs458-node-1a0a:.$ kubectl get ep
    	NAME        ENDPOINTS     AGE
    	kubernetes 10.128.0.3:6443 3h
    	
    
  9. We can see there are 37 objects in version 1 file.
    
    	student@lfs458-node-1a0a:.$ python -m json.tool v1/serverresources.json | grep kind
    		"kind": "APIResourceList",
    			"kind": "Binding",
    			"kind": "ComponentStatus",
    			"kind": "ConfigMap",
    			"kind": "Endpoints",
    			"kind": "Event",
    	<output_omitted>
    	
    
  10. Looking at another file we find nine more.
    
    	student@lfs458-node-1a0a:$ python -m json.tool \
    			apps/v1beta1/serverresources.json | grep kind
    		"kind": "APIResourceList",
    			"kind": "ControllerRevision",
    			"kind": "Deployment",
    	<output_omitted>
    
    	
    
  11. Delete the curlpod to recoup system resources
    
    	student@lfs458-node-1a0a:$ kubectl delete po curlpod
    	pod "curlpod" deleted
    
    	
    
  12. Take a look around the other files in this directory as time permits.

Avail Rajesh Kumar as trainer at 50% Discount
Puppet Online Training
Puppet Classroom TrainingEnroll Now