Address comments in review

- start cleaning up `cmd/manual.go`
- refine progress and error messages
- add missing blank lines after the license headers
- run `gofmt -s -w`
- do not set fake cloud provider
- add a note on why we cannot remove `HostNetwork: true` from `kube-discovery` pod just yet
- taint master and use `role=master`, set tolerations and affinity for `kube-discovery`
- parametrise log-level flag for all components
This commit is contained in:
Ilya Dmitrichenko 2016-09-02 11:19:38 +02:00
parent a82c490315
commit 1c132fe974
No known key found for this signature in database
GPG Key ID: E7889175A6C0CEB9
13 changed files with 220 additions and 98 deletions

View File

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"os" "os"
"path" "path"
"runtime"
"strings" "strings"
"github.com/spf13/pflag" "github.com/spf13/pflag"
@ -42,11 +43,14 @@ func getEnvParams() map[string]string {
envParams := map[string]string{ envParams := map[string]string{
"prefix": globalPrefix, "prefix": globalPrefix,
"host_pki_path": path.Join(globalPrefix, "pki"), "host_pki_path": path.Join(globalPrefix, "pki"),
"hyperkube_image": "gcr.io/google_containers/hyperkube:v1.4.0-alpha.3", // TODO find a way to specify image versions for all of these...
"hyperkube_image": fmt.Sprintf("gcr.io/google_containers/hyperkube-%s:%s", runtime.GOARCH, "v1.4.0-alpha.3"),
"discovery_image": "dgoodwin/kubediscovery:latest", "discovery_image": "dgoodwin/kubediscovery:latest",
"etcd_image": fmt.Sprintf("gcr.io/google_containers/etcd-%s:%s", runtime.GOARCH, "2.2.5"),
"component_loglevel": "--v=4",
} }
for k, _ := range envParams { for k := range envParams {
if v := os.Getenv(fmt.Sprintf("KUBE_%s", strings.ToUpper(k))); v != "" { if v := os.Getenv(fmt.Sprintf("KUBE_%s", strings.ToUpper(k))); v != "" {
envParams[k] = v envParams[k] = v
} }

View File

@ -17,8 +17,7 @@ limitations under the License.
package kubeadmapi package kubeadmapi
type BootstrapParams struct { type BootstrapParams struct {
// A struct with methods that implement Discover() // TODO this is mostly out of date and bloated now, let's revisit this soon
// kubeadm will do the CSR dance
Discovery *OutOfBandDiscovery Discovery *OutOfBandDiscovery
EnvParams map[string]string EnvParams map[string]string
} }

View File

@ -91,6 +91,10 @@ func RunInit(out io.Writer, cmd *cobra.Command, args []string, params *kubeadmap
return err return err
} }
if err := kubemaster.UpdateMasterRoleLabelsAndTaints(client); err != nil {
return err
}
if err := kubemaster.CreateDiscoveryDeploymentAndSecret(params, client, caCert); err != nil { if err := kubemaster.CreateDiscoveryDeploymentAndSecret(params, client, caCert); err != nil {
return err return err
} }

View File

@ -27,12 +27,12 @@ import (
kubemaster "k8s.io/kubernetes/pkg/kubeadm/master" kubemaster "k8s.io/kubernetes/pkg/kubeadm/master"
kubenode "k8s.io/kubernetes/pkg/kubeadm/node" kubenode "k8s.io/kubernetes/pkg/kubeadm/node"
kubeadmutil "k8s.io/kubernetes/pkg/kubeadm/util" kubeadmutil "k8s.io/kubernetes/pkg/kubeadm/util"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
netutil "k8s.io/kubernetes/pkg/util/net" netutil "k8s.io/kubernetes/pkg/util/net"
// TODO: cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
) )
var ( var (
manual_done_msgf = dedent.Dedent(` manual_init_done_msgf = dedent.Dedent(`
Master initialization complete: Master initialization complete:
* Static pods written and kubelet's kubeconfig written. * Static pods written and kubelet's kubeconfig written.
@ -48,6 +48,14 @@ var (
kubeadm manual bootstrap join-node --ca-cert-file <path-to-ca-cert> \ kubeadm manual bootstrap join-node --ca-cert-file <path-to-ca-cert> \
--token %s --api-server-urls https://%s:443/ --token %s --api-server-urls https://%s:443/
`) `)
manual_join_done_msgf = dedent.Dedent(`
Node join complete:
* Certificate signing request sent to master and response
received.
* Kubelet informed of new secure connection details.
Run 'kubectl get nodes' on the master to see this node join.
`)
) )
// TODO --token here becomes Discovery.BearerToken and not Discovery.GivenToken // TODO --token here becomes Discovery.BearerToken and not Discovery.GivenToken
@ -92,11 +100,29 @@ func NewCmdManualBootstrapInitMaster(out io.Writer, params *kubeadmapi.Bootstrap
Will create TLS certificates and set up static pods for Kubernetes master Will create TLS certificates and set up static pods for Kubernetes master
components. components.
`), `),
RunE: func(cmd *cobra.Command, args []string) error { Run: func(cmd *cobra.Command, args []string) {
err := RunManualBootstrapInitMaster(out, cmd, args, params)
cmdutil.CheckErr(err)
},
}
params.Discovery.ApiServerURLs = "http://127.0.0.1:8080/" // On the master, assume you can talk to the API server
cmd.PersistentFlags().StringVarP(&params.Discovery.ApiServerDNSName, "api-dns-name", "", "",
`(optional) DNS name for the API server, will be encoded into
subjectAltName in the resulting (generated) TLS certificates`)
cmd.PersistentFlags().StringVarP(&params.Discovery.ListenIP, "listen-ip", "", "",
`(optional) IP address to listen on, in case autodetection fails.`)
cmd.PersistentFlags().StringVarP(&params.Discovery.BearerToken, "token", "", "",
`(optional) Shared secret used to secure bootstrap. Will be generated and displayed if not provided.`)
return cmd
}
func RunManualBootstrapInitMaster(out io.Writer, cmd *cobra.Command, args []string, params *kubeadmapi.BootstrapParams) error {
if params.Discovery.ListenIP == "" { if params.Discovery.ListenIP == "" {
ip, err := netutil.ChooseHostInterface() ip, err := netutil.ChooseHostInterface()
if err != nil { if err != nil {
return fmt.Errorf("Unable to autodetect IP address [%s], please specify with --listen-ip", err) return fmt.Errorf("<cmd/join> unable to autodetect IP address [%s], please specify with --listen-ip", err)
} }
params.Discovery.ListenIP = ip.String() params.Discovery.ListenIP = ip.String()
} }
@ -116,31 +142,16 @@ func NewCmdManualBootstrapInitMaster(out io.Writer, params *kubeadmapi.Bootstrap
} }
for name, kubeconfig := range kubeconfigs { for name, kubeconfig := range kubeconfigs {
if err := kubeadmutil.WriteKubeconfigIfNotExists(params, name, kubeconfig); err != nil { if err := kubeadmutil.WriteKubeconfigIfNotExists(params, name, kubeconfig); err != nil {
out.Write([]byte(fmt.Sprintf("Unable to write admin for master:\n%s\n", err))) return err
return nil
} }
} }
// TODO use templates to reference struct fields directly as order of args is fragile // TODO use templates to reference struct fields directly as order of args is fragile
fmt.Fprintf(out, manual_done_msgf, fmt.Fprintf(out, manual_init_done_msgf,
params.Discovery.BearerToken, params.Discovery.BearerToken,
params.Discovery.ListenIP, params.Discovery.ListenIP,
) )
return nil return nil
},
}
params.Discovery.ApiServerURLs = "http://127.0.0.1:8080/" // On the master, assume you can talk to the API server
cmd.PersistentFlags().StringVarP(&params.Discovery.ApiServerDNSName, "api-dns-name", "", "",
`(optional) DNS name for the API server, will be encoded into
subjectAltName in the resulting (generated) TLS certificates`)
cmd.PersistentFlags().StringVarP(&params.Discovery.ListenIP, "listen-ip", "", "",
`(optional) IP address to listen on, in case autodetection fails.`)
cmd.PersistentFlags().StringVarP(&params.Discovery.BearerToken, "token", "", "",
`(optional) Shared secret used to secure bootstrap. Will be generated and displayed if not provided.`)
return cmd
} }
func NewCmdManualBootstrapJoinNode(out io.Writer, params *kubeadmapi.BootstrapParams) *cobra.Command { func NewCmdManualBootstrapJoinNode(out io.Writer, params *kubeadmapi.BootstrapParams) *cobra.Command {
@ -149,37 +160,8 @@ func NewCmdManualBootstrapJoinNode(out io.Writer, params *kubeadmapi.BootstrapPa
Short: "Manually bootstrap a node 'out-of-band', joining it into a cluster with extant control plane", Short: "Manually bootstrap a node 'out-of-band', joining it into a cluster with extant control plane",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
if params.Discovery.CaCertFile == "" { err := RunManualBootstrapJoinNode(out, cmd, args, params)
out.Write([]byte(fmt.Sprintf("Must specify --ca-cert-file (see --help)\n"))) cmdutil.CheckErr(err)
return
}
if params.Discovery.ApiServerURLs == "" {
out.Write([]byte(fmt.Sprintf("Must specify --api-server-urls (see --help)\n")))
return
}
kubeconfig, err := kubenode.PerformTLSBootstrapFromParams(params)
if err != nil {
out.Write([]byte(fmt.Sprintf("Failed to perform TLS bootstrap: %s\n", err)))
return
}
//fmt.Println("recieved signed certificate from the API server, will write `/etc/kubernetes/kubelet.conf`...")
err = kubeadmutil.WriteKubeconfigIfNotExists(params, "kubelet", kubeconfig)
if err != nil {
out.Write([]byte(fmt.Sprintf("Unable to write config for node:\n%s\n", err)))
return
}
out.Write([]byte(dedent.Dedent(`
Node join complete:
* Certificate signing request sent to master and response
received.
* Kubelet informed of new secure connection details.
Run 'kubectl get nodes' on the master to see this node join.
`)))
}, },
} }
cmd.PersistentFlags().StringVarP(&params.Discovery.CaCertFile, "ca-cert-file", "", "", cmd.PersistentFlags().StringVarP(&params.Discovery.CaCertFile, "ca-cert-file", "", "",
@ -193,3 +175,30 @@ func NewCmdManualBootstrapJoinNode(out io.Writer, params *kubeadmapi.BootstrapPa
return cmd return cmd
} }
func RunManualBootstrapJoinNode(out io.Writer, cmd *cobra.Command, args []string, params *kubeadmapi.BootstrapParams) error {
if params.Discovery.CaCertFile == "" {
fmt.Fprintf(out, "Must specify --ca-cert-file (see --help)\n")
return nil
}
if params.Discovery.ApiServerURLs == "" {
fmt.Fprintf(out, "Must specify --api-server-urls (see --help)\n")
return nil
}
kubeconfig, err := kubenode.PerformTLSBootstrapFromParams(params)
if err != nil {
fmt.Fprintf(out, "Failed to perform TLS bootstrap: %s\n", err)
return err
}
err = kubeadmutil.WriteKubeconfigIfNotExists(params, "kubelet", kubeconfig)
if err != nil {
fmt.Fprintf(out, "Unable to write config for node:\n%s\n", err)
return err
}
fmt.Fprintf(out, manual_join_done_msgf)
return nil
}

View File

@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package kubemaster package kubemaster
import ( import (
@ -35,7 +36,7 @@ func createKubeProxyPodSpec(params *kubeadmapi.BootstrapParams) api.PodSpec {
"/hyperkube", "/hyperkube",
"proxy", "proxy",
"--kubeconfig=/run/kubeconfig", "--kubeconfig=/run/kubeconfig",
COMPONENT_LOGLEVEL, params.EnvParams["component_loglevel"],
}, },
SecurityContext: &api.SecurityContext{Privileged: &privilegedTrue}, SecurityContext: &api.SecurityContext{Privileged: &privilegedTrue},
VolumeMounts: []api.VolumeMount{ VolumeMounts: []api.VolumeMount{
@ -80,6 +81,7 @@ func createKubeProxyPodSpec(params *kubeadmapi.BootstrapParams) api.PodSpec {
func CreateEssentialAddons(params *kubeadmapi.BootstrapParams, client *clientset.Clientset) error { func CreateEssentialAddons(params *kubeadmapi.BootstrapParams, client *clientset.Clientset) error {
kubeProxyDaemonSet := NewDaemonSet("kube-proxy", createKubeProxyPodSpec(params)) kubeProxyDaemonSet := NewDaemonSet("kube-proxy", createKubeProxyPodSpec(params))
SetMasterTaintTolerations(&kubeProxyDaemonSet.Spec.Template.ObjectMeta)
if _, err := client.Extensions().DaemonSets(api.NamespaceSystem).Create(kubeProxyDaemonSet); err != nil { if _, err := client.Extensions().DaemonSets(api.NamespaceSystem).Create(kubeProxyDaemonSet); err != nil {
return fmt.Errorf("<master/addons> failed creating essential kube-proxy addon [%s]", err) return fmt.Errorf("<master/addons> failed creating essential kube-proxy addon [%s]", err)

View File

@ -17,10 +17,12 @@ limitations under the License.
package kubemaster package kubemaster
import ( import (
"encoding/json"
"fmt" "fmt"
"time" "time"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
apierrs "k8s.io/kubernetes/pkg/api/errors"
unversionedapi "k8s.io/kubernetes/pkg/api/unversioned" unversionedapi "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/extensions"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
@ -53,6 +55,7 @@ func CreateClientAndWaitForAPI(adminConfig *clientcmdapi.Config) (*clientset.Cli
if err != nil { if err != nil {
return false, nil return false, nil
} }
// TODO revisit this when we implement HA
if len(cs.Items) < 3 { if len(cs.Items) < 3 {
fmt.Println("<master/apiclient> not all control plane components are ready yet") fmt.Println("<master/apiclient> not all control plane components are ready yet")
return false, nil return false, nil
@ -66,11 +69,32 @@ func CreateClientAndWaitForAPI(adminConfig *clientcmdapi.Config) (*clientset.Cli
} }
} }
fmt.Printf("<master/apiclient> all control plane components are healthy after %s seconds\n", time.Since(start).Seconds()) fmt.Printf("<master/apiclient> all control plane components are healthy after %f seconds\n", time.Since(start).Seconds())
return true, nil
})
fmt.Println("<master/apiclient> waiting for at least one node to register and become ready")
start = time.Now()
wait.PollInfinite(500*time.Millisecond, func() (bool, error) {
nodeList, err := client.Nodes().List(api.ListOptions{})
if err != nil {
fmt.Println("<master/apiclient> temporarily unable to list nodes (will retry)")
return false, nil
}
if len(nodeList.Items) < 1 {
//fmt.Printf("<master/apiclient> %d nodes have registered so far", len(nodeList.Items))
return false, nil
}
n := &nodeList.Items[0]
if !api.IsNodeReady(n) {
fmt.Println("<master/apiclient> first node has registered, but is not ready yet")
return false, nil
}
fmt.Printf("<master/apiclient> first node is ready after %f seconds\n", time.Since(start).Seconds())
return true, nil return true, nil
}) })
// TODO may be also check node status
return client, nil return client, nil
} }
@ -103,9 +127,72 @@ func NewDeployment(deploymentName string, replicas int32, podSpec api.PodSpec) *
} }
} }
func TaintMaster(*clientset.Clientset) error { // It's safe to do this for alpha, as we don't have HA and there is no way we can get
// TODO // more then one node here (TODO find a way to determine owr own node name)
annotations := make(map[string]string) func findMyself(client *clientset.Clientset) (*api.Node, error) {
annotations[api.TaintsAnnotationKey] = "" nodeList, err := client.Nodes().List(api.ListOptions{})
if err != nil {
return nil, fmt.Errorf("unable to list nodes [%s]", err)
}
if len(nodeList.Items) < 1 {
return nil, fmt.Errorf("no nodes found")
}
node := &nodeList.Items[0]
return node, nil
}
func attemptToUpdateMasterRoleLabelsAndTaints(client *clientset.Clientset) error {
n, err := findMyself(client)
if err != nil {
return err
}
n.ObjectMeta.Labels["kubeadm.alpha.kubernetes.io/role"] = "master"
taintsAnnotation, _ := json.Marshal([]api.Taint{{Key: "dedicated", Value: "master", Effect: "NoSchedule"}})
n.ObjectMeta.Annotations[api.TaintsAnnotationKey] = string(taintsAnnotation)
if _, err := client.Nodes().Update(n); err != nil {
if apierrs.IsConflict(err) {
fmt.Println("<master/apiclient> temporarily unable to update master node metadata due to conflict (will retry)")
time.Sleep(500 * time.Millisecond)
attemptToUpdateMasterRoleLabelsAndTaints(client)
} else {
return err
}
}
return nil return nil
} }
func UpdateMasterRoleLabelsAndTaints(client *clientset.Clientset) error {
err := attemptToUpdateMasterRoleLabelsAndTaints(client)
if err != nil {
return fmt.Errorf("<master/apiclient> failed to update master node - %s", err)
}
return nil
}
func SetMasterTaintTolerations(meta *api.ObjectMeta) {
tolerationsAnnotation, _ := json.Marshal([]api.Toleration{{Key: "dedicated", Value: "master", Effect: "NoSchedule"}})
if meta.Annotations == nil {
meta.Annotations = map[string]string{}
}
meta.Annotations[api.TolerationsAnnotationKey] = string(tolerationsAnnotation)
}
func SetMasterNodeAffinity(meta *api.ObjectMeta) {
nodeAffinity := &api.NodeAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: &api.NodeSelector{
NodeSelectorTerms: []api.NodeSelectorTerm{{
MatchExpressions: []api.NodeSelectorRequirement{{
Key: "kubeadm.alpha.kubernetes.io/role", Operator: api.NodeSelectorOpIn, Values: []string{"master"},
}},
}},
},
}
affinityAnnotation, _ := json.Marshal(api.Affinity{NodeAffinity: nodeAffinity})
if meta.Annotations == nil {
meta.Annotations = map[string]string{}
}
meta.Annotations[api.AffinityAnnotationKey] = string(affinityAnnotation)
}

View File

@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package kubemaster package kubemaster
import ( import (
@ -61,7 +62,11 @@ func encodeKubeDiscoverySecretData(params *kubeadmapi.BootstrapParams, caCert *x
func newKubeDiscoveryPodSpec(params *kubeadmapi.BootstrapParams) api.PodSpec { func newKubeDiscoveryPodSpec(params *kubeadmapi.BootstrapParams) api.PodSpec {
return api.PodSpec{ return api.PodSpec{
SecurityContext: &api.PodSecurityContext{HostNetwork: true}, // TODO we should just use map it to a host port // We have to use host network namespace, as `HostPort`/`HostIP` are Docker's
// buisness and CNI support isn't quite there yet (except for kubenet)
// (see https://github.com/kubernetes/kubernetes/issues/31307)
// TODO update this when #31307 is resolved
SecurityContext: &api.PodSecurityContext{HostNetwork: true},
Containers: []api.Container{{ Containers: []api.Container{{
Name: kubeDiscoverynName, Name: kubeDiscoverynName,
Image: params.EnvParams["discovery_image"], Image: params.EnvParams["discovery_image"],
@ -71,6 +76,10 @@ func newKubeDiscoveryPodSpec(params *kubeadmapi.BootstrapParams) api.PodSpec {
MountPath: "/tmp/secret", // TODO use a shared constant MountPath: "/tmp/secret", // TODO use a shared constant
ReadOnly: true, ReadOnly: true,
}}, }},
Ports: []api.ContainerPort{
// TODO when CNI issue (#31307) is resolved, we should add `HostIP: params.Discovery.ListenIP`
{Name: "http", ContainerPort: 9898, HostPort: 9898},
},
}}, }},
Volumes: []api.Volume{{ Volumes: []api.Volume{{
Name: kubeDiscoverySecretName, Name: kubeDiscoverySecretName,
@ -82,8 +91,7 @@ func newKubeDiscoveryPodSpec(params *kubeadmapi.BootstrapParams) api.PodSpec {
} }
func newKubeDiscovery(params *kubeadmapi.BootstrapParams, caCert *x509.Certificate) kubeDiscovery { func newKubeDiscovery(params *kubeadmapi.BootstrapParams, caCert *x509.Certificate) kubeDiscovery {
// TODO pin to master kd := kubeDiscovery{
return kubeDiscovery{
Deployment: NewDeployment(kubeDiscoverynName, 1, newKubeDiscoveryPodSpec(params)), Deployment: NewDeployment(kubeDiscoverynName, 1, newKubeDiscoveryPodSpec(params)),
Secret: &api.Secret{ Secret: &api.Secret{
ObjectMeta: api.ObjectMeta{Name: kubeDiscoverySecretName}, ObjectMeta: api.ObjectMeta{Name: kubeDiscoverySecretName},
@ -91,16 +99,21 @@ func newKubeDiscovery(params *kubeadmapi.BootstrapParams, caCert *x509.Certifica
Data: encodeKubeDiscoverySecretData(params, caCert), Data: encodeKubeDiscoverySecretData(params, caCert),
}, },
} }
SetMasterTaintTolerations(&kd.Deployment.Spec.Template.ObjectMeta)
SetMasterNodeAffinity(&kd.Deployment.Spec.Template.ObjectMeta)
return kd
} }
func CreateDiscoveryDeploymentAndSecret(params *kubeadmapi.BootstrapParams, client *clientset.Clientset, caCert *x509.Certificate) error { func CreateDiscoveryDeploymentAndSecret(params *kubeadmapi.BootstrapParams, client *clientset.Clientset, caCert *x509.Certificate) error {
kd := newKubeDiscovery(params, caCert) kd := newKubeDiscovery(params, caCert)
if _, err := client.Extensions().Deployments(api.NamespaceSystem).Create(kd.Deployment); err != nil { if _, err := client.Extensions().Deployments(api.NamespaceSystem).Create(kd.Deployment); err != nil {
return fmt.Errorf("<master/discovery> failed to create %q deployment", kubeDiscoverynName) return fmt.Errorf("<master/discovery> failed to create %q deployment [%s]", kubeDiscoverynName, err)
} }
if _, err := client.Secrets(api.NamespaceSystem).Create(kd.Secret); err != nil { if _, err := client.Secrets(api.NamespaceSystem).Create(kd.Secret); err != nil {
return fmt.Errorf("<master/discovery> failed to create %q secret", kubeDiscoverySecretName) return fmt.Errorf("<master/discovery> failed to create %q secret [%s]", kubeDiscoverySecretName, err)
} }
fmt.Println("<master/discovery> created essential addon: kube-discovery") fmt.Println("<master/discovery> created essential addon: kube-discovery")

View File

@ -35,7 +35,6 @@ import (
// init master` and `kubeadm manual bootstrap master` can get going. // init master` and `kubeadm manual bootstrap master` can get going.
const ( const (
COMPONENT_LOGLEVEL = "--v=4"
SERVICE_CLUSTER_IP_RANGE = "--service-cluster-ip-range=10.16.0.0/12" SERVICE_CLUSTER_IP_RANGE = "--service-cluster-ip-range=10.16.0.0/12"
CLUSTER_NAME = "--cluster-name=kubernetes" CLUSTER_NAME = "--cluster-name=kubernetes"
MASTER = "--master=127.0.0.1:8080" MASTER = "--master=127.0.0.1:8080"
@ -55,7 +54,7 @@ func WriteStaticPodManifests(params *kubeadmapi.BootstrapParams) error {
"--advertise-client-urls=http://127.0.0.1:2379,http://127.0.0.1:4001", "--advertise-client-urls=http://127.0.0.1:2379,http://127.0.0.1:4001",
"--data-dir=/var/etcd/data", "--data-dir=/var/etcd/data",
}, },
Image: "gcr.io/google_containers/etcd:2.2.1", // TODO parametrise Image: params.EnvParams["etcd_image"],
LivenessProbe: componentProbe(2379, "/health"), LivenessProbe: componentProbe(2379, "/health"),
Name: "etcd-server", Name: "etcd-server",
Resources: componentResources("200m"), Resources: componentResources("200m"),
@ -69,7 +68,6 @@ func WriteStaticPodManifests(params *kubeadmapi.BootstrapParams) error {
"apiserver", "apiserver",
"--address=127.0.0.1", "--address=127.0.0.1",
"--etcd-servers=http://127.0.0.1:2379", "--etcd-servers=http://127.0.0.1:2379",
"--cloud-provider=fake", // TODO parametrise
"--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota", "--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota",
SERVICE_CLUSTER_IP_RANGE, SERVICE_CLUSTER_IP_RANGE,
"--service-account-key-file=/etc/kubernetes/pki/apiserver-key.pem", "--service-account-key-file=/etc/kubernetes/pki/apiserver-key.pem",
@ -78,7 +76,7 @@ func WriteStaticPodManifests(params *kubeadmapi.BootstrapParams) error {
"--tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem", "--tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem",
"--secure-port=443", "--secure-port=443",
"--allow-privileged", "--allow-privileged",
COMPONENT_LOGLEVEL, params.EnvParams["component_loglevel"],
"--token-auth-file=/etc/kubernetes/pki/tokens.csv", "--token-auth-file=/etc/kubernetes/pki/tokens.csv",
}, },
VolumeMounts: []api.VolumeMount{pkiVolumeMount()}, VolumeMounts: []api.VolumeMount{pkiVolumeMount()},
@ -99,7 +97,7 @@ func WriteStaticPodManifests(params *kubeadmapi.BootstrapParams) error {
"--cluster-signing-cert-file=/etc/kubernetes/pki/ca.pem", "--cluster-signing-cert-file=/etc/kubernetes/pki/ca.pem",
"--cluster-signing-key-file=/etc/kubernetes/pki/ca-key.pem", "--cluster-signing-key-file=/etc/kubernetes/pki/ca-key.pem",
"--insecure-experimental-approve-all-kubelet-csrs-for-group=system:kubelet-bootstrap", "--insecure-experimental-approve-all-kubelet-csrs-for-group=system:kubelet-bootstrap",
COMPONENT_LOGLEVEL, params.EnvParams["component_loglevel"],
}, },
VolumeMounts: []api.VolumeMount{pkiVolumeMount()}, VolumeMounts: []api.VolumeMount{pkiVolumeMount()},
LivenessProbe: componentProbe(10252, "/healthz"), LivenessProbe: componentProbe(10252, "/healthz"),
@ -113,7 +111,7 @@ func WriteStaticPodManifests(params *kubeadmapi.BootstrapParams) error {
"scheduler", "scheduler",
"--leader-elect", "--leader-elect",
MASTER, MASTER,
COMPONENT_LOGLEVEL, params.EnvParams["component_loglevel"],
}, },
LivenessProbe: componentProbe(10251, "/healthz"), LivenessProbe: componentProbe(10251, "/healthz"),
Resources: componentResources("100m"), Resources: componentResources("100m"),

View File

@ -175,6 +175,6 @@ func CreatePKIAssets(params *kubeadmapi.BootstrapParams) (*rsa.PrivateKey, *x509
} }
// TODO print a summary of SANs used and checksums (signatures) of each of the certiicates // TODO print a summary of SANs used and checksums (signatures) of each of the certiicates
fmt.Println("<master/pki> created keys and certificates in %q", params.EnvParams["host_pki_path"]) fmt.Printf("<master/pki> created keys and certificates in %q\n", params.EnvParams["host_pki_path"])
return caKey, caCert, nil return caKey, caCert, nil
} }

View File

@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package kubemaster package kubemaster
import ( import (
@ -38,6 +39,8 @@ func generateTokenIfNeeded(params *kubeadmapi.BootstrapParams) error {
return err return err
} }
fmt.Printf("<master/tokens> generated token: %q\n", params.Discovery.GivenToken) fmt.Printf("<master/tokens> generated token: %q\n", params.Discovery.GivenToken)
} else {
fmt.Println("<master/tokens> accepted provided token")
} }
return nil return nil

View File

@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package kubenode package kubenode
import ( import (
@ -43,7 +44,7 @@ func RetrieveTrustedClusterInfo(params *kubeadmapi.BootstrapParams) (*clientcmda
return nil, fmt.Errorf("<node/discovery> failed to consturct an HTTP request [%s]", err) return nil, fmt.Errorf("<node/discovery> failed to consturct an HTTP request [%s]", err)
} }
fmt.Println("<node/discovery> created cluster info discovery client, requesting info from %q", requestURL) fmt.Printf("<node/discovery> created cluster info discovery client, requesting info from %q\n", requestURL)
res, err := http.DefaultClient.Do(req) res, err := http.DefaultClient.Do(req)
if err != nil { if err != nil {

View File

@ -98,6 +98,6 @@ func WriteKubeconfigIfNotExists(params *kubeadmapi.BootstrapParams, name string,
return fmt.Errorf("<util/kubeconfig> failed to write to %q [%s]", filename, err) return fmt.Errorf("<util/kubeconfig> failed to write to %q [%s]", filename, err)
} }
fmt.Println("<util/kubeconfig> created %q", filename) fmt.Printf("<util/kubeconfig> created %q\n", filename)
return nil return nil
} }

View File

@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package kubeadmutil package kubeadmutil
import ( import (
@ -61,8 +62,9 @@ func GenerateToken(params *kubeadmapi.BootstrapParams) error {
func UseGivenTokenIfValid(params *kubeadmapi.BootstrapParams) (bool, error) { func UseGivenTokenIfValid(params *kubeadmapi.BootstrapParams) (bool, error) {
if params.Discovery.GivenToken == "" { if params.Discovery.GivenToken == "" {
return false, nil return false, nil // not given
} }
fmt.Println("<util/tokens> validating provided token")
givenToken := strings.Split(strings.ToLower(params.Discovery.GivenToken), ".") givenToken := strings.Split(strings.ToLower(params.Discovery.GivenToken), ".")
// TODO print desired format // TODO print desired format
// TODO could also print more specific messages in each case // TODO could also print more specific messages in each case