Allow custom CA certificate when flag --api-server is specified (#4807)
This commit is contained in:
parent
833d0e98a3
commit
19d596b72b
4 changed files with 30 additions and 5 deletions
|
@ -44,6 +44,10 @@ func parseFlags() (bool, *controller.Configuration, error) {
|
||||||
Takes the form "protocol://address:port". If not specified, it is assumed the
|
Takes the form "protocol://address:port". If not specified, it is assumed the
|
||||||
program runs inside a Kubernetes cluster and local discovery is attempted.`)
|
program runs inside a Kubernetes cluster and local discovery is attempted.`)
|
||||||
|
|
||||||
|
rootCAFile = flags.String("certificate-authority", "",
|
||||||
|
`Path to a cert file for the certificate authority. This certificate is used
|
||||||
|
only when the flag --apiserver-host is specified.`)
|
||||||
|
|
||||||
kubeConfigFile = flags.String("kubeconfig", "",
|
kubeConfigFile = flags.String("kubeconfig", "",
|
||||||
`Path to a kubeconfig file containing authorization and API server information.`)
|
`Path to a kubeconfig file containing authorization and API server information.`)
|
||||||
|
|
||||||
|
@ -289,5 +293,9 @@ Takes the form "<host>:port". If not provided, no admission controller is starte
|
||||||
ValidationWebhookKeyPath: *validationWebhookKey,
|
ValidationWebhookKeyPath: *validationWebhookKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if *apiserverHost != "" {
|
||||||
|
config.RootCAFile = *rootCAFile
|
||||||
|
}
|
||||||
|
|
||||||
return false, config, nil
|
return false, config, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,9 @@ import (
|
||||||
discovery "k8s.io/apimachinery/pkg/version"
|
discovery "k8s.io/apimachinery/pkg/version"
|
||||||
"k8s.io/apiserver/pkg/server/healthz"
|
"k8s.io/apiserver/pkg/server/healthz"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
|
certutil "k8s.io/client-go/util/cert"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
|
|
||||||
"k8s.io/ingress-nginx/internal/file"
|
"k8s.io/ingress-nginx/internal/file"
|
||||||
|
@ -69,7 +71,7 @@ func main() {
|
||||||
klog.Fatal(err)
|
klog.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
kubeClient, err := createApiserverClient(conf.APIServerHost, conf.KubeConfigFile)
|
kubeClient, err := createApiserverClient(conf.APIServerHost, conf.RootCAFile, conf.KubeConfigFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handleFatalInitError(err)
|
handleFatalInitError(err)
|
||||||
}
|
}
|
||||||
|
@ -173,12 +175,24 @@ func handleSigterm(ngx *controller.NGINXController, exit exiter) {
|
||||||
// If neither apiserverHost nor kubeConfig is passed in, we assume the
|
// If neither apiserverHost nor kubeConfig is passed in, we assume the
|
||||||
// controller runs inside Kubernetes and fallback to the in-cluster config. If
|
// controller runs inside Kubernetes and fallback to the in-cluster config. If
|
||||||
// the in-cluster config is missing or fails, we fallback to the default config.
|
// the in-cluster config is missing or fails, we fallback to the default config.
|
||||||
func createApiserverClient(apiserverHost, kubeConfig string) (*kubernetes.Clientset, error) {
|
func createApiserverClient(apiserverHost, rootCAFile, kubeConfig string) (*kubernetes.Clientset, error) {
|
||||||
cfg, err := clientcmd.BuildConfigFromFlags(apiserverHost, kubeConfig)
|
cfg, err := clientcmd.BuildConfigFromFlags(apiserverHost, kubeConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if apiserverHost != "" && rootCAFile != "" {
|
||||||
|
tlsClientConfig := rest.TLSClientConfig{}
|
||||||
|
|
||||||
|
if _, err := certutil.NewPool(rootCAFile); err != nil {
|
||||||
|
klog.Errorf("Expected to load root CA config from %s, but got err: %v", rootCAFile, err)
|
||||||
|
} else {
|
||||||
|
tlsClientConfig.CAFile = rootCAFile
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.TLSClientConfig = tlsClientConfig
|
||||||
|
}
|
||||||
|
|
||||||
klog.Infof("Creating API client for %s", cfg.Host)
|
klog.Infof("Creating API client for %s", cfg.Host)
|
||||||
|
|
||||||
client, err := kubernetes.NewForConfig(cfg)
|
client, err := kubernetes.NewForConfig(cfg)
|
||||||
|
|
|
@ -34,7 +34,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCreateApiserverClient(t *testing.T) {
|
func TestCreateApiserverClient(t *testing.T) {
|
||||||
_, err := createApiserverClient("", "")
|
_, err := createApiserverClient("", "", "")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("Expected an error creating REST client without an API server URL or kubeconfig file.")
|
t.Fatal("Expected an error creating REST client without an API server URL or kubeconfig file.")
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,9 +49,12 @@ const (
|
||||||
|
|
||||||
// Configuration contains all the settings required by an Ingress controller
|
// Configuration contains all the settings required by an Ingress controller
|
||||||
type Configuration struct {
|
type Configuration struct {
|
||||||
APIServerHost string
|
APIServerHost string
|
||||||
|
RootCAFile string
|
||||||
|
|
||||||
KubeConfigFile string
|
KubeConfigFile string
|
||||||
Client clientset.Interface
|
|
||||||
|
Client clientset.Interface
|
||||||
|
|
||||||
ResyncPeriod time.Duration
|
ResyncPeriod time.Duration
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue