aws-iam-authenticator: heptio-authenticator occassionally returns Unauthorized when used in a kubernetes go client
Issue:
I have a sample HTTP server that listens on /. When / is called, the handler simply authenticates with eks cluster using the Heptio-authenticator-module and returns to the user the number of pods running in that cluster.For authentication I use the kubernetes go client.
Also note that for every new request on / I create a new kuberentes config so there is no config reuse between requests.
I observed that after ~15 min the eks authentication fails with a Unauthorized error which is unexpected as I am creating generating a new kuberenets config object for every request which should result in a token generated for every request.
Also the immediate request to / (after unauthorized request) seems to be successful again which is more confusing.
Attached is a snippet of my code and logs
- First request: success curl -v -s localhost:9000/ log output:
There are 2 pods in the cluster
- Second request: success curl -v -s localhost:9000/ log output:
There are 2 pods in the cluster
- Third request after ~15 min: failed curl -v -s localhost:9000/ log output:
2018/08/10 14:10:27 http: panic serving [::1]:63678: Unauthorized
goroutine 11 [running]:
- Fourth request: success curl -v -s localhost:9000/ log output:
There are 2 pods in the cluster
package main
import (
//"flag"
"fmt"
//"path/filepath"
//"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
//"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/client-go/kubernetes"
//_ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
restclient "k8s.io/client-go/rest"
capi "k8s.io/client-go/tools/clientcmd/api"
"net/http"
)
var (
endpoint string = "REDACTED"
)
func getClientSet() *kubernetes.Clientset {
awsenv := capi.ExecEnvVar{
Name: "AWS_PROFILE",
Value: "dv",
}
config := &restclient.Config{
Host: endpoint,
TLSClientConfig: restclient.TLSClientConfig{
//CAData: clusterCert,
CAFile: "REDACTED",
},
ExecProvider: &capi.ExecConfig{
Command: "heptio-authenticator-aws",
Args: []string{"token", "-i", "dev-v1"},
APIVersion: "client.authentication.k8s.io/v1alpha1",
Env: []capi.ExecEnvVar{awsenv},
},
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
return clientset
}
func getClusterCredentials(w http.ResponseWriter, r *http.Request) {
clientset := getClientSet()
fmt.Println(clientset)
pods, err := clientset.CoreV1().Pods("local").List(metav1.ListOptions{})
if err != nil {
panic(err.Error())
}
fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
fmt.Fprintf(w, "There are %d pods in the cluster\n", len(pods.Items))
}
func main() {
http.HandleFunc("/", getClusterCredentials)
http.ListenAndServe(":9000", nil)
}
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 16 (5 by maintainers)
No, client-go does recognize expiration time, we just don’t pass it along. I’ll take a stab at a PR for it though!
I believe my app is experiencing something similar. Some noteworthy points from what I’m observing:
Let me know if there’s anything else that would be helpful to provide, although the code here seems to capture what we observe quite well!
Yea I just realized that I believe we are not so I’m trying to upgrade right now and see if it fixes it, I’ll report back. Thanks for getting back so quickly! @wesleyk
Ah sorry. Not paying attention. I find it interesting that you see a difference between role and user authentication… Let me see if I observe this as well.
Yes very strange. For now my workaround is to retry the request if I get Unauthorized response and is working alright so far.