mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-26 05:03:09 +00:00
Merge pull request #41849 from perotinus/kubefedlogs
Automatic merge from submit-queue [Federation] Print out status updates while `kubefed init` is running This is not an ideal final state–it does not address the appearance of hanging during long-running commands, for example–but it provides some level of information when the operations are successful. See #41725. **Release note**: ```release-note Prints out status updates when running `kubefed init` ```
This commit is contained in:
commit
768859404b
@ -24,6 +24,7 @@ go_library(
|
|||||||
"//pkg/kubectl/cmd/templates:go_default_library",
|
"//pkg/kubectl/cmd/templates:go_default_library",
|
||||||
"//pkg/kubectl/cmd/util:go_default_library",
|
"//pkg/kubectl/cmd/util:go_default_library",
|
||||||
"//pkg/version:go_default_library",
|
"//pkg/version:go_default_library",
|
||||||
|
"//vendor/github.com/golang/glog:go_default_library",
|
||||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||||
|
@ -51,6 +51,7 @@ import (
|
|||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/version"
|
"k8s.io/kubernetes/pkg/version"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
@ -276,39 +277,41 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. Create a namespace for federation system components
|
fmt.Fprint(cmdOut, "Creating a namespace for federation system components")
|
||||||
_, err = createNamespace(hostClientset, i.commonOptions.Name, i.commonOptions.FederationSystemNamespace, i.options.dryRun)
|
_, err = createNamespace(hostClientset, i.commonOptions.Name, i.commonOptions.FederationSystemNamespace, i.options.dryRun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
fmt.Fprint(cmdOut, " done\n")
|
||||||
|
|
||||||
// 2. Expose a network endpoint for the federation API server
|
fmt.Fprint(cmdOut, "Creating federation control plane objects (service, credentials, persistent volume claim)")
|
||||||
svc, ips, hostnames, err := createService(hostClientset, i.commonOptions.FederationSystemNamespace, serverName, i.commonOptions.Name, i.options.apiServerAdvertiseAddress, i.options.apiServerServiceType, i.options.dryRun)
|
svc, ips, hostnames, err := createService(hostClientset, i.commonOptions.FederationSystemNamespace, serverName, i.commonOptions.Name, i.options.apiServerAdvertiseAddress, i.options.apiServerServiceType, i.options.dryRun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
glog.V(4).Infof("Created service named %s with IP addresses %v, hostnames %v", svc.Name, ips, hostnames)
|
||||||
|
|
||||||
// 3a. Generate TLS certificates and credentials, and other credentials if needed
|
glog.V(4).Info("Generating TLS certificates and credentials for communicating with the federation API server")
|
||||||
credentials, err := generateCredentials(i.commonOptions.FederationSystemNamespace, i.commonOptions.Name, svc.Name, HostClusterLocalDNSZoneName, serverCredName, ips, hostnames, i.options.apiServerEnableHTTPBasicAuth, i.options.apiServerEnableTokenAuth, i.options.dryRun)
|
credentials, err := generateCredentials(i.commonOptions.FederationSystemNamespace, i.commonOptions.Name, svc.Name, HostClusterLocalDNSZoneName, serverCredName, ips, hostnames, i.options.apiServerEnableHTTPBasicAuth, i.options.apiServerEnableTokenAuth, i.options.dryRun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3b. Create the secret containing the credentials.
|
// Create the secret containing the credentials.
|
||||||
_, err = createAPIServerCredentialsSecret(hostClientset, i.commonOptions.FederationSystemNamespace, serverCredName, i.commonOptions.Name, credentials, i.options.dryRun)
|
_, err = createAPIServerCredentialsSecret(hostClientset, i.commonOptions.FederationSystemNamespace, serverCredName, i.commonOptions.Name, credentials, i.options.dryRun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
glog.V(4).Info("Certificates and credentials generated")
|
||||||
|
|
||||||
// 4. Create a kubeconfig secret
|
glog.V(4).Info("Creating an entry in the kubeconfig file with the certificate and credential data")
|
||||||
_, err = createControllerManagerKubeconfigSecret(hostClientset, i.commonOptions.FederationSystemNamespace, i.commonOptions.Name, svc.Name, cmKubeconfigName, credentials.certEntKeyPairs, i.options.dryRun)
|
_, err = createControllerManagerKubeconfigSecret(hostClientset, i.commonOptions.FederationSystemNamespace, i.commonOptions.Name, svc.Name, cmKubeconfigName, credentials.certEntKeyPairs, i.options.dryRun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
glog.V(4).Info("kubeconfig successfully updated")
|
||||||
|
|
||||||
// 5. Create a persistent volume and a claim to store the federation
|
glog.V(4).Info("Creating a persistent volume and a claim to store the federation API server's state, including etcd data")
|
||||||
// API server's state. This is where federation API server's etcd
|
|
||||||
// stores its data.
|
|
||||||
var pvc *api.PersistentVolumeClaim
|
var pvc *api.PersistentVolumeClaim
|
||||||
if i.options.etcdPersistentStorage {
|
if i.options.etcdPersistentStorage {
|
||||||
pvc, err = createPVC(hostClientset, i.commonOptions.FederationSystemNamespace, svc.Name, i.commonOptions.Name, i.options.etcdPVCapacity, i.options.dryRun)
|
pvc, err = createPVC(hostClientset, i.commonOptions.FederationSystemNamespace, svc.Name, i.commonOptions.Name, i.options.etcdPVCapacity, i.options.dryRun)
|
||||||
@ -316,6 +319,8 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
glog.V(4).Info("Persistent volume and claim created")
|
||||||
|
fmt.Fprint(cmdOut, " done\n")
|
||||||
|
|
||||||
// Since only one IP address can be specified as advertise address,
|
// Since only one IP address can be specified as advertise address,
|
||||||
// we arbitrarily pick the first available IP address
|
// we arbitrarily pick the first available IP address
|
||||||
@ -325,46 +330,50 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error {
|
|||||||
advertiseAddress = ips[0]
|
advertiseAddress = ips[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Create federation API server
|
fmt.Fprint(cmdOut, "Creating federation component deployments")
|
||||||
_, err = createAPIServer(hostClientset, i.commonOptions.FederationSystemNamespace, serverName, i.commonOptions.Name, i.options.image, advertiseAddress, serverCredName, i.options.apiServerEnableHTTPBasicAuth, i.options.apiServerEnableTokenAuth, i.options.apiServerOverrides, pvc, i.options.dryRun)
|
_, err = createAPIServer(hostClientset, i.commonOptions.FederationSystemNamespace, serverName, i.commonOptions.Name, i.options.image, advertiseAddress, serverCredName, i.options.apiServerEnableHTTPBasicAuth, i.options.apiServerEnableTokenAuth, i.options.apiServerOverrides, pvc, i.options.dryRun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
glog.V(4).Info("Successfully created federation API server")
|
||||||
|
|
||||||
sa := &api.ServiceAccount{}
|
sa := &api.ServiceAccount{}
|
||||||
sa.Name = ""
|
sa.Name = ""
|
||||||
// 7. Create deployment for federation controller manager
|
// Create a service account and related RBAC roles if the host cluster has RBAC support.
|
||||||
// The below code either creates the SA and the related roles or skips
|
|
||||||
// creating the same if the RBAC support is not found in the base cluster
|
|
||||||
// TODO: We must evaluate creating a separate service account even when RBAC support is missing
|
// TODO: We must evaluate creating a separate service account even when RBAC support is missing
|
||||||
if rbacAvailable {
|
if rbacAvailable {
|
||||||
// 7a. Create a service account in the host cluster for federation
|
glog.V(4).Info("Creating service account for federation controller manager in the host cluster")
|
||||||
// controller manager.
|
|
||||||
sa, err = createControllerManagerSA(rbacVersionedClientset, i.commonOptions.FederationSystemNamespace, i.commonOptions.Name, i.options.dryRun)
|
sa, err = createControllerManagerSA(rbacVersionedClientset, i.commonOptions.FederationSystemNamespace, i.commonOptions.Name, i.options.dryRun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
glog.V(4).Info("Successfully created federation controller manager service account")
|
||||||
|
|
||||||
// 7b. Create RBAC role and role binding for federation controller
|
glog.V(4).Info("Creating RBAC role and role bindings for the federation controller manager's service account")
|
||||||
// manager service account.
|
|
||||||
_, _, err = createRoleBindings(rbacVersionedClientset, i.commonOptions.FederationSystemNamespace, sa.Name, i.commonOptions.Name, i.options.dryRun)
|
_, _, err = createRoleBindings(rbacVersionedClientset, i.commonOptions.FederationSystemNamespace, sa.Name, i.commonOptions.Name, i.options.dryRun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
glog.V(4).Info("Successfully created RBAC role and role bindings")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7c. Create a dns-provider config secret
|
glog.V(4).Info("Creating a DNS provider config secret")
|
||||||
dnsProviderSecret, err := createDNSProviderConfigSecret(hostClientset, i.commonOptions.FederationSystemNamespace, dnsProviderSecretName, i.commonOptions.Name, dnsProviderConfigBytes, i.options.dryRun)
|
dnsProviderSecret, err := createDNSProviderConfigSecret(hostClientset, i.commonOptions.FederationSystemNamespace, dnsProviderSecretName, i.commonOptions.Name, dnsProviderConfigBytes, i.options.dryRun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
glog.V(4).Info("Successfully created DNS provider config secret")
|
||||||
|
|
||||||
|
glog.V(4).Info("Creating federation controller manager deployment")
|
||||||
|
|
||||||
// 7d. Create federation controller manager deployment.
|
|
||||||
_, err = createControllerManager(hostClientset, i.commonOptions.FederationSystemNamespace, i.commonOptions.Name, svc.Name, cmName, i.options.image, cmKubeconfigName, i.options.dnsZoneName, i.options.dnsProvider, sa.Name, dnsProviderSecret, i.options.controllerManagerOverrides, i.options.dryRun)
|
_, err = createControllerManager(hostClientset, i.commonOptions.FederationSystemNamespace, i.commonOptions.Name, svc.Name, cmName, i.options.image, cmKubeconfigName, i.options.dnsZoneName, i.options.dnsProvider, sa.Name, dnsProviderSecret, i.options.controllerManagerOverrides, i.options.dryRun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
glog.V(4).Info("Successfully created federation controller manager deployment")
|
||||||
|
fmt.Fprint(cmdOut, " done\n")
|
||||||
|
|
||||||
|
fmt.Fprint(cmdOut, "Updating kubeconfig ")
|
||||||
// Pick the first ip/hostname to update the api server endpoint in kubeconfig and also to give information to user
|
// Pick the first ip/hostname to update the api server endpoint in kubeconfig and also to give information to user
|
||||||
// In case of NodePort Service for api server, ips are node external ips.
|
// In case of NodePort Service for api server, ips are node external ips.
|
||||||
endpoint := ""
|
endpoint := ""
|
||||||
@ -378,20 +387,21 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error {
|
|||||||
endpoint = endpoint + ":" + strconv.Itoa(int(svc.Spec.Ports[0].NodePort))
|
endpoint = endpoint + ":" + strconv.Itoa(int(svc.Spec.Ports[0].NodePort))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8. Write the federation API server endpoint info, credentials
|
|
||||||
// and context to kubeconfig
|
|
||||||
err = updateKubeconfig(config, i.commonOptions.Name, endpoint, i.commonOptions.Kubeconfig, credentials, i.options.dryRun)
|
err = updateKubeconfig(config, i.commonOptions.Name, endpoint, i.commonOptions.Kubeconfig, credentials, i.options.dryRun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
fmt.Fprint(cmdOut, " done\n")
|
||||||
|
|
||||||
if !i.options.dryRun {
|
if !i.options.dryRun {
|
||||||
|
fmt.Fprint(cmdOut, "Waiting for federation control plane to come up ")
|
||||||
fedPods := []string{serverName, cmName}
|
fedPods := []string{serverName, cmName}
|
||||||
err = waitForPods(hostClientset, fedPods, i.commonOptions.FederationSystemNamespace)
|
err = waitForPods(hostClientset, fedPods, i.commonOptions.FederationSystemNamespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = waitSrvHealthy(config, i.commonOptions.Name, i.commonOptions.Kubeconfig)
|
err = waitSrvHealthy(config, i.commonOptions.Name, i.commonOptions.Kubeconfig)
|
||||||
|
fmt.Fprint(cmdOut, " done\n")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -276,13 +276,13 @@ func TestInitFederation(t *testing.T) {
|
|||||||
// Actual data passed are tested in the fake secret and cluster
|
// Actual data passed are tested in the fake secret and cluster
|
||||||
// REST clients.
|
// REST clients.
|
||||||
endpoint := getEndpoint(tc.apiserverServiceType, tc.lbIP, tc.advertiseAddress)
|
endpoint := getEndpoint(tc.apiserverServiceType, tc.lbIP, tc.advertiseAddress)
|
||||||
want := fmt.Sprintf("Federation API server is running at: %s\n", endpoint)
|
wantedSuffix := fmt.Sprintf("Federation API server is running at: %s\n", endpoint)
|
||||||
if tc.dryRun != "" {
|
if tc.dryRun != "" {
|
||||||
want = fmt.Sprintf("Federation control plane runs (dry run)\n")
|
wantedSuffix = fmt.Sprintf("Federation control plane runs (dry run)\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
if got := buf.String(); got != want {
|
if got := buf.String(); !strings.HasSuffix(got, wantedSuffix) {
|
||||||
t.Errorf("[%d] unexpected output: got: %s, want: %s", i, got, want)
|
t.Errorf("[%d] unexpected output: got: %s, wanted suffix: %s", i, got, wantedSuffix)
|
||||||
if cmdErrMsg != "" {
|
if cmdErrMsg != "" {
|
||||||
t.Errorf("[%d] unexpected error message: %s", i, cmdErrMsg)
|
t.Errorf("[%d] unexpected error message: %s", i, cmdErrMsg)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user