How To Check Web Service Is Up And Running
Authentication between microservices using Kubernetes identities
Published in December 2020
If your infrastructure consists of several applications interacting with each other, you lot might have faced the issue of securing communications betwixt services to forbid unauthenticated requests.
Imagine having two apps:
- An API
- A information shop
You lot might want the data store merely to respond to requests to the API and reject requests from anywhere else.
How would the data store make up one's mind to allow or deny the request?
A popular approach is to asking and pass identity tokens to every call within services.
So instead of issuing a request to the information store directly, you might demand to go through an Authentication service first, think a token and employ that to authenticate your asking to the data store.
There is a specific context associated with the token that allows the data store to accept a token from the API service and to reject it from elsewhere.
This context is used to permit or deny the request.
You have several options when it comes to implementing this authentication machinery:
- You could use static tokens that don't expire. In this case, in that location is no demand for running a dedicated authentication server.
- You could gear up an OAuth server.
- You could curl out your authentication and authorisation mechanism such equally common TLS certificates.
All the hallmark and authorisation servers have to do is to:
- Authenticate the caller - The caller should accept a valid and verifiable identity.
- Generate a token with a limited scope, validity and the desired audience.
- Validate a token - Service to service advice is allowed only if the token is legit for the ii services involved.
Examples of defended software that allows you to implement hallmark and authorisation infrastructure are tools such equally Keycloak or Dex.
When yous use Keycloack, you first:
- Login using your email and countersign — your identity is verified.
- A valid session is created for your user. The session might describe what groups you belong to.
- Every request is validated and you will be asked to log in once more when it's invalid.
The same applies to 2 apps inside your infrastructure.
- A backend component makes a request to Keycloack with its API primal and secret to generate a session token.
- The backend makes a request to the second app using the session token.
- The second app retrieves the token from the asking and validates information technology with Keycloak.
- If the token is valid, it replies to the request.
You lot might non accept noticed, but Kubernetes offers the aforementioned primitives for implementing authentication and authority with Service Accounts, Roles and RoleBindings.
In Kubernetes, you assign identities using Service Accounts.
Users and Pods tin can utilise those identities as a machinery to authenticate to the API and effect requests.
Service Accounts are and then linked to Roles that grant admission to resources.
If a Role grants access to create and delete Pods, y'all won't be able to ameliorate Secrets, or create ConfigMaps — for example.
Could you utilise Service Accounts as a machinery to authenticate requests between apps in the cluster?
What if the Kubernetes API could be used as an Authentication and Authorisation server?
Let'southward try that.
Creating the cluster
You will need access to a Kubernetes cluster with the Service Account Volume projection feature enabled.
Don't worry if you lot don't know what a Service Account Volume is — you will learn more about it subsequently on in the article.
The Service Account Volume projection feature requires the Kubernetes API server to be running with specific API flags.
The support for different managed Kubernetes providers may vary.
However, yous tin beginning a local cluster with the volume projection characteristic enabled in minikube with:
bash
minikube get-go \ --extra-config=apiserver.service-business relationship-signing-key-file=/var/lib/minikube/certs/sa.central \ --extra-config=apiserver.service-business relationship-central-file=/var/lib/minikube/certs/sa.pub \ --extra-config=apiserver.service-account-issuer=kubernetes/serviceaccount \ --extra-config=apiserver.service-account-api-audiences=api
You should also clone this repository as information technology contains the demo source code that will be referred to in the article.
You will now deploy 2 services:
- You will refer to these services as the API service and the Data store.
- They are written in the Go programming language, and they communicate via HTTP.
- Each service runs in its namespaces and use defended Service Accounts identities.
- The information store replies to requests successfully but when the caller has a valid identity, else it rejects the request with an fault.
Deploying the API component
The API service is a headless web awarding listening on port 8080.
When you brand a request to it, the API component:
- Issues an HTTP GET request to the Data store with its Service Account identity.
- Forrard the response.
You lot tin deploy the app and betrayal information technology as a Service in the cluster with:
bash
kubectl apply -f service_accounts/api/deployment.yaml namespace/api created serviceaccount/api created deployment.apps/app created service/app created
Yous can retrieve the URL of the API service with:
fustigate
minikube --namespace api service app --url http://192.168.99.101:31541
If you lot consequence a asking to that app, volition you get a successful response?
Let's try that:
bash
curl http://192.168.99.101:31541 Get "http://app.information-shop.svc.cluster.local" : dial tcp: lookup app.data-store.svc.cluster.local: no such host
The error is expected since y'all haven't deployed the data store yet.
Go on the last open.
Open a new terminal to carry out the next ready of steps.
Deploying the Data store
The Data shop service is another headless web application listening on port 8081.
When a client makes any request to it, the Information store:
- Looks for a token in the request header. If there isn't one, information technology replies with an HTTP 401 fault response.
- Checks the token with the Kubernetes API for its validity. If it's invalid, it replies with an HTTP 403 response.
- Finally, when the token is valid, it replies to the original request.
Y'all can create the data store with:
fustigate
kubectl apply -f service_accounts/information-store/deployment.yaml namespace/data-store created serviceaccount/data-store created clusterrolebinding.rbac.authorization.k8s.io/role-tokenreview-binding created deployment.apps/app created service/app created
Now, utilise curl
to make a asking to the API service over again:
fustigate
curl http://192.168.99.101:31541 Hullo from data store. You have been authenticated
The data store service successfully verified the token and replied to the API.
The API forwards the request to y'all.
What if you make a asking directly to the Information store?
Retrieve the URL of the Data store with:
bash
minikube --namespace data-store service app --url http://192.168.64.28:31690
Let's use curl
to make a request to information technology:
fustigate
curl http://192.168.64.28:31690 X-Client-Id not supplied
Information technology does not piece of work.
Merely you could supply a dummy X-Client-Id
header:
bash
ringlet -H 'X-Customer-Id: dummy' http://192.168.64.28:31690 Invalid token
Excellent!
It does not work!
You protected the data shop from unauthenticated access using Kubernetes and Service Accounts.
You can only brand requests to it if you have a valid token.
But how does all of that piece of work? Let'south discover out.
Under the hood
Service Accounts are a manner to associate your Kubernetes workloads with an identity.
You lot tin can combine a Service Account with a Role and a RoleBinding to define what or who tin can admission what resource in a cluster.
For example, when you lot want to restrict reading Secrets only to admin users in the cluster, yous can do and so using a Service Account.
Service Accounts aren't just for users, though.
You can cosign humans as well as applications in the cluster.
If you lot desire your applications to list all the available Pods in the cluster, you will need to create a Service Account that is associated with read-only access to the Pod API.
When you deployed two apps earlier, y'all also created ii Service Accounts:
fustigate
kubectl get serviceaccount --namespace api Proper noun SECRETS Historic period api 1 4m5s default ane 4m5s kubectl go serviceaccount --namespace data-store Proper noun SECRETS AGE default ane 6m4s data-store ane 6m4s
Those Service Account are the identities associated with the apps, but they don't define what permissions are granted.
For that, yous might need to listing the Role and ClusterRoles:
bash
kubectl become rolebindings,clusterrolebindings \ --all-namespaces \ -o custom-columns= 'KIND:kind,Function:metadata.name,SERVICE_ACCOUNTS:subjects[?(@.kind=="ServiceAccount")].proper name' KIND ROLE SERVICE_ACCOUNTS RoleBinding kube-proxy <none> ClusterRoleBinding cluster-admin <none> ClusterRoleBinding kubeadm:get-nodes <none> ClusterRoleBinding role-tokenreview-bounden information-store # truncated
The command above uses kubectl custom columns to filter the output of
kubectl go
.
The table shows what RoleBinding is linked to a Role (and what ClusterRoleBinding is linked to a ClusterRole).
The only component that has any Role is the Data shop.
There's no Function or Rolebinding for the API.
How come you lot tin take a Service Account without a Role and RoleBinding?
The API app has an empty Service Business relationship that doesn't have any sort of permission.
However, you tin use that Service Account identity to cosign the request to the Kubernetes API (just y'all can't create, update, delete, etc. resources).
What near the Information store?
What kind of access does information technology have?
Let's review the ClusterRoleBinding with:
bash
kubectl draw clusterrolebinding role-tokenreview-binding Name: part-tokenreview-binding Labels: <none> Annotations: <none> Office: Kind: ClusterRole Proper name: system:auth-delegator Subjects: Kind Name Namespace ---- ---- --------- ServiceAccount data-shop data-store
From the output above, yous can tell that the ClusterRoleBinding links the data-store
Service Account to the system:auth-delegator
ClusterRole.
What permissions grants the ClusterRole?
Permit's find out with:
bash
kubectl describe clusterrole organisation:auth-delegator Proper noun: system:auth-delegator Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- tokenreviews.hallmark.k8s.io [ ] [ ] [create] subjectaccessreviews.authorization.k8s.io [ ] [ ] [create]
The arrangement:auth-delegator
ClusterRole has the permissions to telephone call the Token Review API.
What kind of permission is that?
You lot tin use kubectl with the tin can-i
subcommand and the impersonation --every bit
flag to test permissions:
bash
kubectl auth can-i create deployments --as=data-store --namespace data-store no kubectl auth tin can-i listing pods --equally=information-store --namespace information-shop no kubectl auth can-i delete services --as=information-shop --namespace data-store no
You tin can go along querying all Kubernetes resources, simply the Service Account has merely one permission.
bash
kubectl auth tin-i create tokenreviews --every bit=sa-test-one yes
What'southward a TokenReview?
Issuing requests to the Kubernetes API
The Kubernetes API verifies Service Account identities.
In particular, at that place's a specific component in charge of validating and rejecting them: the Token Review API.
The Token Review API accepts tokens and returns if they are valid or not — yes, it's that elementary.
Allow'southward manually validate the identity for the API component against the Token Review API.
Information technology'due south the Token Review API, and then you might need a token.
What token, though?
Every time y'all create a Service Business relationship, Kubernetes creates a Secret.
The Secret holds the token for the Service Business relationship, and you can utilise that token to call the Kubernetes API.
That's the token that should exist validated confronting the Token Review API.
And so allow's retrieve the token for the API Service Account with:
bash
kubectl --namespace api describe serviceaccount api Name: api Mountable secrets: api-token-lxcb4 Tokens: api-token-lxcb4
Then to inspect the Underground object, you can issue the following control:
bash
kubectl --namespace api describe surreptitious api-token-lxcb4 Name: api-token-lxcb4 Type: kubernetes.io/service-account-token Data == == ca.crt: 1111 bytes namespace: 3 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6…
The token
object in the Data is a base64 encoded object representing a JSON web token payload.
It's time to verify the token.
To verify the validity of the token, yous demand to create a TokenReview resource:
token.yaml
kind : TokenReview apiVersion : authentication.k8s.io/v1 metadata : name : test spec : token : eyJhbGciOiJS…
You lot can validate the request with:
bash
kubectl employ -o yaml -f token.yaml
Delight find the flag
-o yaml
that displays the output of thekubectl apply
command.
When you issue the command, the response should look every bit follows:
apiVersion : authentication.k8s.io/v1 kind : TokenReview metadata : proper name : examination spec : token : eyJhbGciOiJS… condition : audiences : - api authenticated : truthful user : groups : - arrangement:serviceaccounts - system:serviceaccounts:api - organisation:authenticated uid : 7df3a132-c9fe-48d1-9fa5-b654c3156977 username : arrangement:serviceaccount:api:api
The disquisitional data in the response is in the status object with the following fields:
- Authenticated: the field is fix to
true
, which means the token was successfully validated. - In user object you lot tin can detect the following backdrop:
- The username corresponding to the service business relationship used by the Pod -
arrangement:serviceaccount:examination:sa-examination-1
. - The uid for organisation user ID of the current user.
- The username corresponding to the service business relationship used by the Pod -
- Groups includes the groups that the user belongs to.
- Audiences contains a list of audiences that the token is intended for. In this example, only the
api
is a valid audience.
Excellent, yous just verified the Service Account token!
You know that:
- The token is valid.
- The identity of the caller (the API Service Business relationship).
- The groups that the caller belongs to.
Since you can validate and verify any token, you could leverage the mechanism in your Information Shop component to authenticate and authorise requests!
Let's take a look at how you could include the above logic in your apps using the Kubernetes Become client.
Implementation of the services
Here's how the two services interact with each other and the Kubernetes API:
- At startup, an API component reads the Service Business relationship token and keeps it in memory.
- The API component calls the data store passing the token every bit an HTTP header — i.e.
X-Customer-Id
. - When the data store receives a request, it reads the token from the
10-Client-Id
header and issues a request to the Token Review API to check its validity. - If the response is authenticated, the data store component replies with a successful message, otherwise a 401 fault.
The post-obit diagram represents the higher up call flow:
First, let'southward look at the implementation of the API service.
You can notice the application code in the file service_accounts/api/main.become
.
The Service Business relationship Token is automatically mounted in /var/run/secrets/kubernetes.io/serviceaccount/token
and you could read its value with:
main.become
func readToken ( ) { b, err := ioutil. ReadFile ( "/var/run/secrets/kubernetes.io/serviceaccount/token" ) if err != nil { panic (err) } serviceToken = string (b) }
And then, the Service Token is passed on to the telephone call to the Secret store service in the X-Client-Id
HTTP header:
main.go
func handleIndex (w http.ResponseWriter, r *http.Request) { … client := &http.Customer{ } req, err := http. NewRequest ( "Become" , serviceConnstring, nil ) if err != nil { panic (err) } req.Header. Add ( "X-Client-Id" , serviceToken) resp, err := client. Do (req) …
Every bit soon every bit the reply from the Secret store is received, it is so sent back as a response:
main.go
… if err != nil { http. Mistake (w, err. Error ( ) , http.StatusInternalServerError) render } else { defer resp.Body. Shut ( ) body, _ := ioutil. ReadAll (resp.Body) io. WriteString (w, string (trunk) ) }
The following YAML manifest is used to deploy the API service:
deployment.yaml
apiVersion : v1 kind : Namespace metadata : proper noun : api --- apiVersion : v1 kind : ServiceAccount metadata : name : api namespace : api --- apiVersion : apps/v1 kind : Deployment metadata : name : app namespace : api spec : replicas : i selector : matchLabels : app : api template : metadata : labels : app : api spec : serviceAccount : api containers : - proper noun : app prototype : amitsaha/k8s-sa-volume-demo-api:sa- 1 env : - name : LISTEN_ADDR value : ":8080" - proper name : DATA_STORE_CONNSTRING value : "http://app.data-shop.svc.cluster.local" ports : - containerPort : 8080 --- apiVersion : v1 kind : Service metadata : name : app namespace : api spec : type : NodePort selector : app : api ports : - port : 8080 targetPort : 8080
You will notice that in that location is zip special about the Deployment manifest above autonomously from having a Service Account associated with it.
Let's movement onto the data shop service.
You can discover the complete application in service_accounts/data-store/main.go
.
The data shop service does ii primal things:
- It retrieves the value of the
X-Client-Id
header from the incoming asking. - It then invokes the Kubernetes Token Review API to bank check if the token is valid.
Step (1) is performed by the following lawmaking:
main.get
clientId := r.Header. Get ( "X-Client-Id" ) if len (clientId) == 0 { http. Fault (w, "Ten-Client-Id not supplied" , http.StatusUnauthorized) return }
And then, pace (two) is performed using the Kubernetes Go customer.
Start, we create a ClientSet
object:
primary.go
config, err := rest. InClusterConfig ( ) clientset, err := kubernetes. NewForConfig (config)
The InClusterConfig()
function automatically reads the Service Account Token for the Pod, and hence you do not have to specify the path manually.
Then, you construct a TokenReview
object specifying the token yous desire to validate in the Token
field:
main.go
tr := authv1.TokenReview{ Spec: authv1.TokenReviewSpec{ Token: clientId, } , }
Finally, you can create a TokenReview
request with:
main.go
result, err := clientset. AuthenticationV1 ( ) . TokenReviews ( ) . Create (ctx, &tr, metav1.CreateOptions{ } )
The post-obit YAML manifest volition create the various resources needed for the data store service:
deployment.yaml
apiVersion : v1 kind : Namespace metadata : name : data-store --- apiVersion : v1 kind : ServiceAccount metadata : name : data-store namespace : information-shop --- apiVersion : rbac.authorization.k8s.io/v1 kind : ClusterRoleBinding metadata : name : function-tokenreview-bounden roleRef : apiGroup : rbac.authorization.k8s.io kind : ClusterRole name : organisation:auth-delegator subjects : - kind : ServiceAccount proper noun : information-shop namespace : data-store --- apiVersion : apps/v1 kind : Deployment metadata : name : app namespace : information-shop spec : replicas : 1 selector : matchLabels : app : information-store template : metadata : labels : app : data-store spec : serviceAccount : information-store containers : - name : app image : amitsaha/k8s-sa-book-demo-ss:sa- one env : - name : LISTEN_ADDR value : ":8081" ports : - containerPort : 8081 --- apiVersion : v1 kind : Service metadata : proper noun : app namespace : data-store spec : selector : app : data-store ports : - protocol : TCP port : eighty targetPort : 8081
Compared to the API service, the data store service requires a ClusterRoleBinding resource to be created, which assembly the information-store
Service Account to the system:auth-delegator
ClusterRole.
Go back to the terminal session where you lot deployed the information store service and inspect the logs:
bash
kubectl --namepsace data-store logs <data-store-pod-id> 2020/11/26 03:17:43 { "authenticated" : true, "user" : { "username" : "organisation:serviceaccount:api:api", "uid" : "a693c26c-1b2e-47d0-a026-21802365f8d4", "groups" : [ "system:serviceaccounts", "system:serviceaccounts:api", "organization:authenticated" ] }, "audiences" : [ "api" ] }
The output is a Go construction version of the JSON response you saw earlier.
Thus, yous meet how the API component reads the Service Business relationship Token and passes it to the Data shop equally a mode to authenticate itself.
The Data shop service retrieves the token and checks it with the Kubernetes API.
When valid, the Data shop component allows the request from the API service to be processed.
The implementation works well, only information technology suffers from three drawbacks:
Ane Hush-hush for every Service Account
When you create a Service Business relationship, Kubernetes creates a companion Secret object with a token.
You use the token to cosign with the Kubernetes API.
In this example, you tin inspect the Service Account and discover the token with:
fustigate
kubectl --namespace api describe serviceaccount api Name: api Namespace: api Mountable secrets: api-token-ttr8q Tokens: api-token-ttr8q
Which matches the Secret object in the namespace:
bash
kubectl go secrets --namespace api NAME Blazon api-token-ttr8q kubernetes.io/service-account-token default-token-vppc9 kubernetes.io/service-account-token
However, any workload that can read a hugger-mugger in a namespace can also read the Service Account tokens in the same namespace.
In other words, you could take whatsoever other Pod using the aforementioned Service Account to cosign against the Kubernetes API — effectively impersonating someone else.
Unfortunately, at that place's no mechanism to restrict access to a subset of Secrets in a namespace.
The application has access to all of them, or none of them.
Yous could create a namespace for every app and store a Service Account in it, simply that's frequently overkilled.
Long live the Service Business relationship's token
The tokens associated with a Service Account are long-lived and exercise not expire.
In other words, once yous have access to one of them, y'all can use information technology forever (or until the administrator deletes the Secret associated with the token).
You could manually rotate identities by manually removing and re-assigning Service Accounts.
If it sounds similar a lot of work, information technology's because it is.
No audience binding of the tokens
As a cluster administrator, you cannot acquaintance a token with a specific audience.
Anyone with access to the Service Account token tin cosign with the Kubernetes API and is authorised to communicate with any other service running inside the cluster.
The destination service doesn't have whatever style to verify whether the token information technology was presented with was meant for itself at all.
As an example, imagine buying a ticket for a flight from London to New York.
If you buy a ticket from British Airways, you lot tin't employ the ticket to board a Virgin Atlantic flying.
Your ticket is leap to a particular audience (British Airways).
But in the example of Kubernetes, the same ticket (token) tin be used with whatever airline (audience).
You could solve both challenges past implementing solutions such as mutual TLS or using a JWT based solution with a key authority server.
All the same, in Kubernetes, you can use the Service Account Token Book Project characteristic to create fourth dimension-bound and audition-specific Service Account Tokens which do not persist in the cluster shop.
The Kubernetes API server acts as the cardinal authority server, and y'all don't accept to worry about expiring tokens.
This feature was introduced in Kubernetes 1.12 and gained further improvements in 1.thirteen and provides a more than secure alternative to workload-specific service accounts.
This will be promoted to a GA feature in the upcoming Kubernetes one.20 release.
In the next part of the article, yous will re-implement the same lawmaking for authenticating apps using the Service Account Token Book Projection.
Information technology's a good idea to clean upwards the two namespaces with:
bash
kubectl delete namespace api namespace "api" deleted kubectl delete namespace data-shop namespace "data-store" deleted
Inter-Service authentication using Service Account Token Volume Projection
The Service Account Tokens made available to workloads via the Service Account Token Volume Projection (ProjectedServiceAccountToken
) are time-limited, audience leap and are not associated with surreptitious objects.
If a Pod is deleted or the Service Account is removed, these tokens become invalid, thus preventing whatsoever misuse.
A serviceAccountToken
book projection is one of the projected
volume types.
A projected volume is a book that mounts several existing volumes into the same directory.
When this volume blazon is added to a Pod, the Service Business relationship Token is mounted on the filesystem — in the same way that the Service Account Tokens are mounted.
There's a difference though.
The kubelet automatically rotates the token when it's well-nigh to elapse.
In addition, you can configure the path at which yous want this token to be available.
Allow's come across how you tin improve the API component to include the Service Account Token Volume Projection.
The API component
You can read the Service Account Token mounted via book project with:
main.become
b, err := ioutil. ReadFile ( "/var/run/secrets/tokens/api-token" ) serviceToken = string (b)
Annotation how the path to the Service Account Token is different from the previous case (i.east. it used to be /var/run/secrets/kubernetes.io/serviceaccount/token
).
Since the Service Account Token Volume Projection feature relies on the token being refreshed periodically by the kubelet, information technology is recommended to re-read the token every v minutes in the app.
You can accomplish this via a ticker in Get as follows:
main.go
ticker := time. NewTicker ( 300 * fourth dimension.Second) washed := brand ( chan bool ) go func ( ) { for { select { case <-done: return case <-ticker.C: readToken ( ) } } } ( )
The readToken()
role reads the file, /var/run/secrets/tokens/api-token
and sets the global variable, serviceToken
to the token value.
If y'all are non familiar with Get'south ticker, think of a ticker every bit a background thread which runs a part at periodic intervals.
You tin find the entire application code in service_accounts_volume_projection/api/chief.go
.
Now, let's deploy this service.
You will apply that image in the deployment manifest (service_accounts_volume_projection/api/deployment.yaml
):
deployment.yaml
apiVersion : v1 kind : Namespace metadata : name : api --- apiVersion : v1 kind : ServiceAccount metadata : name : api namespace : api --- apiVersion : apps/v1 kind : Deployment metadata : name : app namespace : api spec : replicas : i selector : matchLabels : app : api template : metadata : labels : app : api spec : serviceAccount : api volumes : - name : api-token projected : sources : - serviceAccountToken : path : api-token expirationSeconds : 600 audience : data-shop containers : - name : app paradigm : amitsaha/k8s-sa-volume-demo-api:sa- 2 env : - name : LISTEN_ADDR value : ":8080" - name : DATA_STORE_CONNSTRING value : "http://app.information-store.svc.cluster.local" ports : - containerPort : 8080 volumeMounts : - mountPath : /var/run/secrets/tokens name : api-token --- apiVersion : v1 kind : Service metadata : name : app namespace : api spec : blazon : NodePort selector : app : api ports : - port : 8080 targetPort : 8080
A book named api-token
of projected
type will be created with the source beingness serviceAccountToken
.
The book defines three boosted backdrop:
- The
path
where the token will be available inside the configured volume. - The
audience
field specifies what the intended audition for the token is (if not specified, it defaults toapi
). - The
expirationSeconds
betoken how long a token is valid for - the minimum is 600 seconds or x minutes.
Please notice how the audience
field specifies that this Service Account Token is allowed to communicate only with services that identify themselves as a data-store
.
If y'all omit data-store
as an audience in the Secret store component, the API won't be able to talk to it — it's not its audition!
Note that if you are deploying a Pod to use this feature in a cluster with Pod Security Policies enforced, you will demand to ensure that the
projected
book blazon is allowed.
You can create a new API deployment with:
fustigate
kubectl apply -f service_accounts_volume_projection/api/deployment.yaml namespace/api created serviceaccount/api created deployment.apps/app created service/app created
Call up the URL of the API service with:
bash
minikube --namespace api service app --url http://192.168.99.101:31541
Y'all can consequence a request with:
bash
curl http://192.168.99.101:31541 Get "http://app.data-store.svc.cluster.local" : dial tcp: lookup app.data-store.svc.cluster.local: no such host
This is expected as the data shop is non yet deployed.
Keep the concluding open up.
Side by side, let's modify and deploy the data store service.
Data Store
The token review payload for the information store will now be every bit follows:
main.go
tr := authv1.TokenReview{ pec: authv1.TokenReviewSpec{ Token: clientId, Audiences: [ ] string { "data-store" } , } , }
Now, in the TokenReview object, the Information store explicitly passes data-store
as the audition.
If the token doesn't include information-shop
as an audition, the Token Review API will not authorise the request.
In other words, the Information store service tin assert the identity of the caller and validate that the incoming request token was meant for the data shop service.
You lot tin find the entire application code in service_accounts_volume_projection/data-store/main.go
.
Adjacent, allow'southward deploy this service.
Yous tin can create the deployment with:
fustigate
kubectl apply -f service_accounts_volume_projection/information-store/deployment.yaml namespace/data-store created serviceaccount/data-store created clusterrolebinding.rbac.say-so.k8s.io/role-tokenreview-binding created deployment.apps/app created service/app created
Let's cheque if the service is upwards and running correctly:
bash
kubectl --namespace data-store depict service app Name: app Namespace: data-store Labels: <none> Selector: app =data-shop Type: ClusterIP IP: x.106.239.243 Port: <unset> lxxx/TCP TargetPort: 8081/TCP Endpoints: 172.18.0.5:8081
The value of Endpoints
in the output in a higher place tells us that app is now upward and running.
Now, use curl
to brand a request to the API service again:
bash
scroll http://192.168.99.101:31541 Hello from information store. You lot have been authenticated
Yous should inspect the logs of the Clandestine shop with:
bash
kubectl --namespace information-shop logs <pod id> 2020/11/26 02:04:51 { UID:ec7c304f-9722-4d1b-9f67-d3ce32cd8d4c, "authenticated" : true, Groups:[organisation:serviceaccounts system:serviceaccounts:api system:authenticated], "user" : { Extra:map[string]ExtraValue{authentication.kubernetes.io/pod-proper name: "username" : "system:serviceaccount:api:api", [app-65d954658c-dbbr5], "uid" : "0d32dccd-3d84-4955-b6e8-bbc362debb52", hallmark.kubernetes.io/pod-uid: [1b37a3f4-54f1-419c-b435-affce3f4a0f3],},}, "groups" : [ Mistake:,Audiences:[data-store],} "system:serviceaccounts", "arrangement:serviceaccounts:api", "system:authenticated" ], "extra" : { "authentication.kubernetes.io/pod-name" : [ "app-649cfb884b-hxzzj" ], "authentication.kubernetes.io/pod-uid" : [ "a4c967a0-2b57-4f1f-aabc-6aea2dc15098" ] } }, "audiences" : [ "data-store" ] }
In you switch to the logs of the API service, yous should meet the following lines that demonstrate when the Service Account Token is re-read from the filesystem:
bash
2020/08/26 05:03:43 Refreshing service account token 2020/08/26 05:xiii:42 Refreshing service business relationship token 2020/08/26 05:eighteen:42 Refreshing service account token
Summary
Service Account Token Volume project allows you to associate non-global, fourth dimension-bound and audience bound service tokens to your Kubernetes workloads.
In this article, you saw an case of using it for authentication between your services and how information technology is a better alternative to using the default Service Account Tokens.
Kubernetes native software such as Linkerd and Istio are embracing it for their internal communication and managed Kubernetes service providers such as GKE and AWS EKS are using this project volume type to enable more robust pod identity systems.
Learn more
- Kubernetes Hallmark
- Kubernetes Service Account Token Book Projection
Don't miss the side by side commodity!
Exist the showtime to be notified when a new commodity or Kubernetes experiment is published.
*We'll never share your email address, and you can opt-out at whatsoever time.
Source: https://learnk8s.io/microservices-authentication-kubernetes
Posted by: kisertany1937.blogspot.com
0 Response to "How To Check Web Service Is Up And Running"
Post a Comment