mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 13:37:30 +00:00
kubeadm: Centralize commonly used paths/constants to the constants pkg
This commit is contained in:
parent
d37f2f1a5d
commit
9a6ef9677a
@ -221,25 +221,27 @@ func (i *Init) Validate(cmd *cobra.Command) error {
|
|||||||
// Run executes master node provisioning, including certificates, needed static pod manifests, etc.
|
// Run executes master node provisioning, including certificates, needed static pod manifests, etc.
|
||||||
func (i *Init) Run(out io.Writer) error {
|
func (i *Init) Run(out io.Writer) error {
|
||||||
|
|
||||||
// PHASE 1: Generate certificates
|
k8sVersion, err := version.ParseSemantic(i.cfg.KubernetesVersion)
|
||||||
err := cmdphases.CreatePKIAssets(i.cfg)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
return fmt.Errorf("couldn't parse kubernetes version %q: %v", i.cfg.KubernetesVersion, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PHASE 1: Generate certificates
|
||||||
|
if err := cmdphases.CreatePKIAssets(i.cfg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// PHASE 2: Generate kubeconfig files for the admin and the kubelet
|
// PHASE 2: Generate kubeconfig files for the admin and the kubelet
|
||||||
err = kubeconfigphase.CreateInitKubeConfigFiles(kubeadmconstants.KubernetesDir, i.cfg)
|
if err := kubeconfigphase.CreateInitKubeConfigFiles(kubeadmconstants.KubernetesDir, i.cfg); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// PHASE 3: Bootstrap the control plane
|
// PHASE 3: Bootstrap the control plane
|
||||||
if err := controlplanephase.WriteStaticPodManifests(i.cfg); err != nil {
|
if err := controlplanephase.WriteStaticPodManifests(i.cfg, k8sVersion, kubeadmconstants.GetStaticPodDirectory()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
adminKubeConfigPath := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.AdminKubeConfigFileName)
|
client, err := kubeadmutil.CreateClientAndWaitForAPI(kubeadmconstants.GetAdminKubeConfigPath())
|
||||||
client, err := kubeadmutil.CreateClientAndWaitForAPI(adminKubeConfigPath)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -258,25 +260,18 @@ func (i *Init) Run(out io.Writer) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := tokenphase.CreateBootstrapConfigMapIfNotExists(client, adminKubeConfigPath); err != nil {
|
if err := tokenphase.CreateBootstrapConfigMapIfNotExists(client, kubeadmconstants.GetAdminKubeConfigPath()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// PHASE 5: Install and deploy all addons, and configure things as necessary
|
// PHASE 5: Install and deploy all addons, and configure things as necessary
|
||||||
|
|
||||||
k8sVersion, err := version.ParseSemantic(i.cfg.KubernetesVersion)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("couldn't parse kubernetes version %q: %v", i.cfg.KubernetesVersion, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the necessary ServiceAccounts
|
// Create the necessary ServiceAccounts
|
||||||
err = apiconfigphase.CreateServiceAccounts(client)
|
if err := apiconfigphase.CreateServiceAccounts(client); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = apiconfigphase.CreateRBACRules(client, k8sVersion)
|
if err := apiconfigphase.CreateRBACRules(client, k8sVersion); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ licenses(["notice"])
|
|||||||
load(
|
load(
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
"@io_bazel_rules_go//go:def.bzl",
|
||||||
"go_library",
|
"go_library",
|
||||||
|
"go_test",
|
||||||
)
|
)
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
@ -29,3 +30,10 @@ filegroup(
|
|||||||
srcs = [":package-srcs"],
|
srcs = [":package-srcs"],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "go_default_test",
|
||||||
|
srcs = ["constants_test.go"],
|
||||||
|
library = ":go_default_library",
|
||||||
|
tags = ["automanaged"],
|
||||||
|
)
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package constants
|
package constants
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -97,6 +98,18 @@ const (
|
|||||||
|
|
||||||
// MinExternalEtcdVersion indicates minimum external etcd version which kubeadm supports
|
// MinExternalEtcdVersion indicates minimum external etcd version which kubeadm supports
|
||||||
MinExternalEtcdVersion = "3.0.14"
|
MinExternalEtcdVersion = "3.0.14"
|
||||||
|
|
||||||
|
// DefaultEtcdVersion indicates the default etcd version that kubeadm uses
|
||||||
|
DefaultEtcdVersion = "3.0.17"
|
||||||
|
|
||||||
|
Etcd = "etcd"
|
||||||
|
KubeAPIServer = "kube-apiserver"
|
||||||
|
KubeControllerManager = "kube-controller-manager"
|
||||||
|
KubeScheduler = "kube-scheduler"
|
||||||
|
KubeProxy = "kube-proxy"
|
||||||
|
|
||||||
|
// SelfHostingPrefix describes the prefix workloads that are self-hosted by kubeadm has
|
||||||
|
SelfHostingPrefix = "self-hosted-"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -119,11 +132,29 @@ var (
|
|||||||
// DefaultTokenUsages specifies the default functions a token will get
|
// DefaultTokenUsages specifies the default functions a token will get
|
||||||
DefaultTokenUsages = []string{"signing", "authentication"}
|
DefaultTokenUsages = []string{"signing", "authentication"}
|
||||||
|
|
||||||
|
// MasterComponents defines the master component names
|
||||||
|
MasterComponents = []string{KubeAPIServer, KubeControllerManager, KubeScheduler}
|
||||||
|
|
||||||
// MinimumControlPlaneVersion specifies the minimum control plane version kubeadm can deploy
|
// MinimumControlPlaneVersion specifies the minimum control plane version kubeadm can deploy
|
||||||
MinimumControlPlaneVersion = version.MustParseSemantic("v1.7.0")
|
MinimumControlPlaneVersion = version.MustParseSemantic("v1.7.0")
|
||||||
)
|
)
|
||||||
|
|
||||||
// BuildStaticManifestFilepath returns the location on the disk where the Static Pod should be present
|
// GetStaticPodDirectory returns the location on the disk where the Static Pod should be present
|
||||||
func BuildStaticManifestFilepath(componentName string) string {
|
func GetStaticPodDirectory() string {
|
||||||
return filepath.Join(KubernetesDir, ManifestsSubDirName, componentName+".yaml")
|
return filepath.Join(KubernetesDir, ManifestsSubDirName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStaticPodFilepath returns the location on the disk where the Static Pod should be present
|
||||||
|
func GetStaticPodFilepath(componentName, manifestsDir string) string {
|
||||||
|
return filepath.Join(manifestsDir, componentName+".yaml")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAdminKubeConfigPath returns the location on the disk where admin kubeconfig is located by default
|
||||||
|
func GetAdminKubeConfigPath() string {
|
||||||
|
return filepath.Join(KubernetesDir, AdminKubeConfigFileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddSelfHostedPrefix adds the self-hosted- prefix to the component name
|
||||||
|
func AddSelfHostedPrefix(componentName string) string {
|
||||||
|
return fmt.Sprintf("%s%s", SelfHostingPrefix, componentName)
|
||||||
}
|
}
|
||||||
|
112
cmd/kubeadm/app/constants/constants_test.go
Normal file
112
cmd/kubeadm/app/constants/constants_test.go
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2017 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package constants
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetStaticPodDirectory(t *testing.T) {
|
||||||
|
expected := "/etc/kubernetes/manifests"
|
||||||
|
actual := GetStaticPodDirectory()
|
||||||
|
|
||||||
|
if actual != expected {
|
||||||
|
t.Errorf(
|
||||||
|
"failed GetStaticPodDirectory:\n\texpected: %s\n\t actual: %s",
|
||||||
|
expected,
|
||||||
|
actual,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetAdminKubeConfigPath(t *testing.T) {
|
||||||
|
expected := "/etc/kubernetes/admin.conf"
|
||||||
|
actual := GetAdminKubeConfigPath()
|
||||||
|
|
||||||
|
if actual != expected {
|
||||||
|
t.Errorf(
|
||||||
|
"failed GetAdminKubeConfigPath:\n\texpected: %s\n\t actual: %s",
|
||||||
|
expected,
|
||||||
|
actual,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetStaticPodFilepath(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
componentName, manifestsDir, expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
componentName: "kube-apiserver",
|
||||||
|
manifestsDir: "/etc/kubernetes/manifests",
|
||||||
|
expected: "/etc/kubernetes/manifests/kube-apiserver.yaml",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: "kube-controller-manager",
|
||||||
|
manifestsDir: "/etc/kubernetes/manifests/",
|
||||||
|
expected: "/etc/kubernetes/manifests/kube-controller-manager.yaml",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: "foo",
|
||||||
|
manifestsDir: "/etc/bar/",
|
||||||
|
expected: "/etc/bar/foo.yaml",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, rt := range tests {
|
||||||
|
actual := GetStaticPodFilepath(rt.componentName, rt.manifestsDir)
|
||||||
|
if actual != rt.expected {
|
||||||
|
t.Errorf(
|
||||||
|
"failed GetStaticPodFilepath:\n\texpected: %s\n\t actual: %s",
|
||||||
|
rt.expected,
|
||||||
|
actual,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddSelfHostedPrefix(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
componentName, expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
componentName: "kube-apiserver",
|
||||||
|
expected: "self-hosted-kube-apiserver",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: "kube-controller-manager",
|
||||||
|
expected: "self-hosted-kube-controller-manager",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: "kube-scheduler",
|
||||||
|
expected: "self-hosted-kube-scheduler",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: "foo",
|
||||||
|
expected: "self-hosted-foo",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, rt := range tests {
|
||||||
|
actual := AddSelfHostedPrefix(rt.componentName)
|
||||||
|
if actual != rt.expected {
|
||||||
|
t.Errorf(
|
||||||
|
"failed AddSelfHostedPrefix:\n\texpected: %s\n\t actual: %s",
|
||||||
|
rt.expected,
|
||||||
|
actual,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,7 @@ go_library(
|
|||||||
srcs = ["images.go"],
|
srcs = ["images.go"],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
"//cmd/kubeadm/app/constants:go_default_library",
|
||||||
"//cmd/kubeadm/app/util:go_default_library",
|
"//cmd/kubeadm/app/util:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -23,7 +23,7 @@ go_test(
|
|||||||
srcs = ["images_test.go"],
|
srcs = ["images_test.go"],
|
||||||
library = ":go_default_library",
|
library = ":go_default_library",
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = ["//cmd/kubeadm/app/apis/kubeadm:go_default_library"],
|
deps = ["//cmd/kubeadm/app/constants:go_default_library"],
|
||||||
)
|
)
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
||||||
|
@ -20,29 +20,19 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
func GetCoreImage(image, repoPrefix, k8sVersion, overrideImage string) string {
|
||||||
KubeEtcdImage = "etcd"
|
|
||||||
KubeAPIServerImage = "apiserver"
|
|
||||||
KubeControllerManagerImage = "controller-manager"
|
|
||||||
KubeSchedulerImage = "scheduler"
|
|
||||||
|
|
||||||
etcdVersion = "3.0.17"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetCoreImage(image string, cfg *kubeadmapi.MasterConfiguration, overrideImage string) string {
|
|
||||||
if overrideImage != "" {
|
if overrideImage != "" {
|
||||||
return overrideImage
|
return overrideImage
|
||||||
}
|
}
|
||||||
repoPrefix := cfg.ImageRepository
|
kubernetesImageTag := kubeadmutil.KubernetesVersionToImageTag(k8sVersion)
|
||||||
kubernetesImageTag := kubeadmutil.KubernetesVersionToImageTag(cfg.KubernetesVersion)
|
|
||||||
return map[string]string{
|
return map[string]string{
|
||||||
KubeEtcdImage: fmt.Sprintf("%s/%s-%s:%s", repoPrefix, "etcd", runtime.GOARCH, etcdVersion),
|
constants.Etcd: fmt.Sprintf("%s/%s-%s:%s", repoPrefix, "etcd", runtime.GOARCH, constants.DefaultEtcdVersion),
|
||||||
KubeAPIServerImage: fmt.Sprintf("%s/%s-%s:%s", repoPrefix, "kube-apiserver", runtime.GOARCH, kubernetesImageTag),
|
constants.KubeAPIServer: fmt.Sprintf("%s/%s-%s:%s", repoPrefix, "kube-apiserver", runtime.GOARCH, kubernetesImageTag),
|
||||||
KubeControllerManagerImage: fmt.Sprintf("%s/%s-%s:%s", repoPrefix, "kube-controller-manager", runtime.GOARCH, kubernetesImageTag),
|
constants.KubeControllerManager: fmt.Sprintf("%s/%s-%s:%s", repoPrefix, "kube-controller-manager", runtime.GOARCH, kubernetesImageTag),
|
||||||
KubeSchedulerImage: fmt.Sprintf("%s/%s-%s:%s", repoPrefix, "kube-scheduler", runtime.GOARCH, kubernetesImageTag),
|
constants.KubeScheduler: fmt.Sprintf("%s/%s-%s:%s", repoPrefix, "kube-scheduler", runtime.GOARCH, kubernetesImageTag),
|
||||||
}[image]
|
}[image]
|
||||||
}
|
}
|
||||||
|
@ -21,15 +21,9 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
type getCoreImageTest struct {
|
|
||||||
i string
|
|
||||||
c *kubeadmapi.MasterConfiguration
|
|
||||||
o string
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
testversion = "v10.1.2-alpha.1.100+0123456789abcdef+SOMETHING"
|
testversion = "v10.1.2-alpha.1.100+0123456789abcdef+SOMETHING"
|
||||||
expected = "v10.1.2-alpha.1.100_0123456789abcdef_SOMETHING"
|
expected = "v10.1.2-alpha.1.100_0123456789abcdef_SOMETHING"
|
||||||
@ -37,38 +31,43 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestGetCoreImage(t *testing.T) {
|
func TestGetCoreImage(t *testing.T) {
|
||||||
var imageTest = []struct {
|
var tests = []struct {
|
||||||
t getCoreImageTest
|
image, repo, version, override, expected string
|
||||||
expected string
|
|
||||||
}{
|
}{
|
||||||
{getCoreImageTest{o: "override"}, "override"},
|
{
|
||||||
{getCoreImageTest{
|
override: "override",
|
||||||
i: KubeEtcdImage,
|
expected: "override",
|
||||||
c: &kubeadmapi.MasterConfiguration{ImageRepository: gcrPrefix}},
|
|
||||||
fmt.Sprintf("%s/%s-%s:%s", gcrPrefix, "etcd", runtime.GOARCH, etcdVersion),
|
|
||||||
},
|
},
|
||||||
{getCoreImageTest{
|
{
|
||||||
i: KubeAPIServerImage,
|
image: constants.Etcd,
|
||||||
c: &kubeadmapi.MasterConfiguration{ImageRepository: gcrPrefix, KubernetesVersion: testversion}},
|
repo: gcrPrefix,
|
||||||
fmt.Sprintf("%s/%s-%s:%s", gcrPrefix, "kube-apiserver", runtime.GOARCH, expected),
|
expected: fmt.Sprintf("%s/%s-%s:%s", gcrPrefix, "etcd", runtime.GOARCH, constants.DefaultEtcdVersion),
|
||||||
},
|
},
|
||||||
{getCoreImageTest{
|
{
|
||||||
i: KubeControllerManagerImage,
|
image: constants.KubeAPIServer,
|
||||||
c: &kubeadmapi.MasterConfiguration{ImageRepository: gcrPrefix, KubernetesVersion: testversion}},
|
repo: gcrPrefix,
|
||||||
fmt.Sprintf("%s/%s-%s:%s", gcrPrefix, "kube-controller-manager", runtime.GOARCH, expected),
|
version: testversion,
|
||||||
|
expected: fmt.Sprintf("%s/%s-%s:%s", gcrPrefix, "kube-apiserver", runtime.GOARCH, expected),
|
||||||
},
|
},
|
||||||
{getCoreImageTest{
|
{
|
||||||
i: KubeSchedulerImage,
|
image: constants.KubeControllerManager,
|
||||||
c: &kubeadmapi.MasterConfiguration{ImageRepository: gcrPrefix, KubernetesVersion: testversion}},
|
repo: gcrPrefix,
|
||||||
fmt.Sprintf("%s/%s-%s:%s", gcrPrefix, "kube-scheduler", runtime.GOARCH, expected),
|
version: testversion,
|
||||||
|
expected: fmt.Sprintf("%s/%s-%s:%s", gcrPrefix, "kube-controller-manager", runtime.GOARCH, expected),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image: constants.KubeScheduler,
|
||||||
|
repo: gcrPrefix,
|
||||||
|
version: testversion,
|
||||||
|
expected: fmt.Sprintf("%s/%s-%s:%s", gcrPrefix, "kube-scheduler", runtime.GOARCH, expected),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, it := range imageTest {
|
for _, rt := range tests {
|
||||||
actual := GetCoreImage(it.t.i, it.t.c, it.t.o)
|
actual := GetCoreImage(rt.image, rt.repo, rt.version, rt.override)
|
||||||
if actual != it.expected {
|
if actual != rt.expected {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"failed GetCoreImage:\n\texpected: %s\n\t actual: %s",
|
"failed GetCoreImage:\n\texpected: %s\n\t actual: %s",
|
||||||
it.expected,
|
rt.expected,
|
||||||
actual,
|
actual,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -45,78 +45,66 @@ const (
|
|||||||
DefaultCloudConfigPath = "/etc/kubernetes/cloud-config"
|
DefaultCloudConfigPath = "/etc/kubernetes/cloud-config"
|
||||||
|
|
||||||
defaultv17AdmissionControl = "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota"
|
defaultv17AdmissionControl = "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota"
|
||||||
|
|
||||||
etcd = "etcd"
|
|
||||||
kubeAPIServer = "kube-apiserver"
|
|
||||||
kubeControllerManager = "kube-controller-manager"
|
|
||||||
kubeScheduler = "kube-scheduler"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// WriteStaticPodManifests builds manifest objects based on user provided configuration and then dumps it to disk
|
// WriteStaticPodManifests builds manifest objects based on user provided configuration and then dumps it to disk
|
||||||
// where kubelet will pick and schedule them.
|
// where kubelet will pick and schedule them.
|
||||||
func WriteStaticPodManifests(cfg *kubeadmapi.MasterConfiguration) error {
|
func WriteStaticPodManifests(cfg *kubeadmapi.MasterConfiguration, k8sVersion *version.Version, manifestsDir string) error {
|
||||||
|
|
||||||
// TODO: Move the "pkg/util/version".Version object into the internal API instead of always parsing the string
|
|
||||||
k8sVersion, err := version.ParseSemantic(cfg.KubernetesVersion)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the required hostpath mounts
|
// Get the required hostpath mounts
|
||||||
mounts := getHostPathVolumesForTheControlPlane(cfg)
|
mounts := getHostPathVolumesForTheControlPlane(cfg)
|
||||||
|
|
||||||
// Prepare static pod specs
|
// Prepare static pod specs
|
||||||
staticPodSpecs := map[string]v1.Pod{
|
staticPodSpecs := map[string]v1.Pod{
|
||||||
kubeAPIServer: componentPod(v1.Container{
|
kubeadmconstants.KubeAPIServer: componentPod(v1.Container{
|
||||||
Name: kubeAPIServer,
|
Name: kubeadmconstants.KubeAPIServer,
|
||||||
Image: images.GetCoreImage(images.KubeAPIServerImage, cfg, cfg.UnifiedControlPlaneImage),
|
Image: images.GetCoreImage(kubeadmconstants.KubeAPIServer, cfg.ImageRepository, cfg.KubernetesVersion, cfg.UnifiedControlPlaneImage),
|
||||||
Command: getAPIServerCommand(cfg, k8sVersion),
|
Command: getAPIServerCommand(cfg, k8sVersion),
|
||||||
VolumeMounts: mounts.GetVolumeMounts(kubeAPIServer),
|
VolumeMounts: mounts.GetVolumeMounts(kubeadmconstants.KubeAPIServer),
|
||||||
LivenessProbe: componentProbe(int(cfg.API.BindPort), "/healthz", v1.URISchemeHTTPS),
|
LivenessProbe: componentProbe(int(cfg.API.BindPort), "/healthz", v1.URISchemeHTTPS),
|
||||||
Resources: componentResources("250m"),
|
Resources: componentResources("250m"),
|
||||||
Env: getProxyEnvVars(),
|
Env: getProxyEnvVars(),
|
||||||
}, mounts.GetVolumes(kubeAPIServer)),
|
}, mounts.GetVolumes(kubeadmconstants.KubeAPIServer)),
|
||||||
kubeControllerManager: componentPod(v1.Container{
|
kubeadmconstants.KubeControllerManager: componentPod(v1.Container{
|
||||||
Name: kubeControllerManager,
|
Name: kubeadmconstants.KubeControllerManager,
|
||||||
Image: images.GetCoreImage(images.KubeControllerManagerImage, cfg, cfg.UnifiedControlPlaneImage),
|
Image: images.GetCoreImage(kubeadmconstants.KubeControllerManager, cfg.ImageRepository, cfg.KubernetesVersion, cfg.UnifiedControlPlaneImage),
|
||||||
Command: getControllerManagerCommand(cfg, k8sVersion),
|
Command: getControllerManagerCommand(cfg, k8sVersion),
|
||||||
VolumeMounts: mounts.GetVolumeMounts(kubeControllerManager),
|
VolumeMounts: mounts.GetVolumeMounts(kubeadmconstants.KubeControllerManager),
|
||||||
LivenessProbe: componentProbe(10252, "/healthz", v1.URISchemeHTTP),
|
LivenessProbe: componentProbe(10252, "/healthz", v1.URISchemeHTTP),
|
||||||
Resources: componentResources("200m"),
|
Resources: componentResources("200m"),
|
||||||
Env: getProxyEnvVars(),
|
Env: getProxyEnvVars(),
|
||||||
}, mounts.GetVolumes(kubeControllerManager)),
|
}, mounts.GetVolumes(kubeadmconstants.KubeControllerManager)),
|
||||||
kubeScheduler: componentPod(v1.Container{
|
kubeadmconstants.KubeScheduler: componentPod(v1.Container{
|
||||||
Name: kubeScheduler,
|
Name: kubeadmconstants.KubeScheduler,
|
||||||
Image: images.GetCoreImage(images.KubeSchedulerImage, cfg, cfg.UnifiedControlPlaneImage),
|
Image: images.GetCoreImage(kubeadmconstants.KubeScheduler, cfg.ImageRepository, cfg.KubernetesVersion, cfg.UnifiedControlPlaneImage),
|
||||||
Command: getSchedulerCommand(cfg),
|
Command: getSchedulerCommand(cfg),
|
||||||
VolumeMounts: mounts.GetVolumeMounts(kubeScheduler),
|
VolumeMounts: mounts.GetVolumeMounts(kubeadmconstants.KubeScheduler),
|
||||||
LivenessProbe: componentProbe(10251, "/healthz", v1.URISchemeHTTP),
|
LivenessProbe: componentProbe(10251, "/healthz", v1.URISchemeHTTP),
|
||||||
Resources: componentResources("100m"),
|
Resources: componentResources("100m"),
|
||||||
Env: getProxyEnvVars(),
|
Env: getProxyEnvVars(),
|
||||||
}, mounts.GetVolumes(kubeScheduler)),
|
}, mounts.GetVolumes(kubeadmconstants.KubeScheduler)),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add etcd static pod spec only if external etcd is not configured
|
// Add etcd static pod spec only if external etcd is not configured
|
||||||
if len(cfg.Etcd.Endpoints) == 0 {
|
if len(cfg.Etcd.Endpoints) == 0 {
|
||||||
|
|
||||||
etcdPod := componentPod(v1.Container{
|
etcdPod := componentPod(v1.Container{
|
||||||
Name: etcd,
|
Name: kubeadmconstants.Etcd,
|
||||||
Command: getEtcdCommand(cfg),
|
Command: getEtcdCommand(cfg),
|
||||||
Image: images.GetCoreImage(images.KubeEtcdImage, cfg, cfg.Etcd.Image),
|
Image: images.GetCoreImage(kubeadmconstants.Etcd, cfg.ImageRepository, "", cfg.Etcd.Image),
|
||||||
// Mount the etcd datadir path read-write so etcd can store data in a more persistent manner
|
// Mount the etcd datadir path read-write so etcd can store data in a more persistent manner
|
||||||
VolumeMounts: []v1.VolumeMount{newVolumeMount(etcdVolumeName, cfg.Etcd.DataDir, false)},
|
VolumeMounts: []v1.VolumeMount{newVolumeMount(etcdVolumeName, cfg.Etcd.DataDir, false)},
|
||||||
LivenessProbe: componentProbe(2379, "/health", v1.URISchemeHTTP),
|
LivenessProbe: componentProbe(2379, "/health", v1.URISchemeHTTP),
|
||||||
}, []v1.Volume{newVolume(etcdVolumeName, cfg.Etcd.DataDir)})
|
}, []v1.Volume{newVolume(etcdVolumeName, cfg.Etcd.DataDir)})
|
||||||
|
|
||||||
staticPodSpecs[etcd] = etcdPod
|
staticPodSpecs[kubeadmconstants.Etcd] = etcdPod
|
||||||
}
|
}
|
||||||
|
|
||||||
manifestsPath := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName)
|
if err := os.MkdirAll(manifestsDir, 0700); err != nil {
|
||||||
if err := os.MkdirAll(manifestsPath, 0700); err != nil {
|
return fmt.Errorf("failed to create directory %q [%v]", manifestsDir, err)
|
||||||
return fmt.Errorf("failed to create directory %q [%v]", manifestsPath, err)
|
|
||||||
}
|
}
|
||||||
for name, spec := range staticPodSpecs {
|
for name, spec := range staticPodSpecs {
|
||||||
filename := filepath.Join(manifestsPath, name+".yaml")
|
filename := kubeadmconstants.GetStaticPodFilepath(name, manifestsDir)
|
||||||
serialized, err := yaml.Marshal(spec)
|
serialized, err := yaml.Marshal(spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to marshal manifest for %q to YAML [%v]", name, err)
|
return fmt.Errorf("failed to marshal manifest for %q to YAML [%v]", name, err)
|
||||||
|
@ -55,21 +55,25 @@ func TestWriteStaticPodManifests(t *testing.T) {
|
|||||||
expectedAPIProbePort int32
|
expectedAPIProbePort int32
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
cfg: &kubeadmapi.MasterConfiguration{},
|
cfg: &kubeadmapi.MasterConfiguration{
|
||||||
expectErr: true,
|
KubernetesVersion: "v1.7.0",
|
||||||
|
},
|
||||||
|
expectErr: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cfg: &kubeadmapi.MasterConfiguration{
|
cfg: &kubeadmapi.MasterConfiguration{
|
||||||
API: kubeadmapi.API{
|
API: kubeadmapi.API{
|
||||||
BindPort: 443,
|
BindPort: 443,
|
||||||
},
|
},
|
||||||
|
KubernetesVersion: "v1.7.0",
|
||||||
},
|
},
|
||||||
expectErr: true,
|
expectErr: false,
|
||||||
expectedAPIProbePort: 443,
|
expectedAPIProbePort: 443,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, rt := range tests {
|
for _, rt := range tests {
|
||||||
actual := WriteStaticPodManifests(rt.cfg)
|
|
||||||
|
actual := WriteStaticPodManifests(rt.cfg, version.MustParseSemantic(rt.cfg.KubernetesVersion), fmt.Sprintf("%s/etc/kubernetes/manifests", tmpdir))
|
||||||
if (actual == nil) && rt.expectErr {
|
if (actual == nil) && rt.expectErr {
|
||||||
t.Error("expected an error from WriteStaticPodManifests but got none")
|
t.Error("expected an error from WriteStaticPodManifests but got none")
|
||||||
continue
|
continue
|
||||||
|
@ -49,36 +49,36 @@ func getHostPathVolumesForTheControlPlane(cfg *kubeadmapi.MasterConfiguration) c
|
|||||||
// HostPath volumes for the API Server
|
// HostPath volumes for the API Server
|
||||||
// Read-only mount for the certificates directory
|
// Read-only mount for the certificates directory
|
||||||
// TODO: Always mount the K8s Certificates directory to a static path inside of the container
|
// TODO: Always mount the K8s Certificates directory to a static path inside of the container
|
||||||
mounts.NewHostPathMount(kubeAPIServer, k8sCertsVolumeName, cfg.CertificatesDir, cfg.CertificatesDir, true)
|
mounts.NewHostPathMount(kubeadmconstants.KubeAPIServer, k8sCertsVolumeName, cfg.CertificatesDir, cfg.CertificatesDir, true)
|
||||||
// Read-only mount for the ca certs (/etc/ssl/certs) directory
|
// Read-only mount for the ca certs (/etc/ssl/certs) directory
|
||||||
mounts.NewHostPathMount(kubeAPIServer, caCertsVolumeName, caCertsVolumePath, caCertsVolumePath, true)
|
mounts.NewHostPathMount(kubeadmconstants.KubeAPIServer, caCertsVolumeName, caCertsVolumePath, caCertsVolumePath, true)
|
||||||
|
|
||||||
// If external etcd is specified, mount the directories needed for accessing the CA/serving certs and the private key
|
// If external etcd is specified, mount the directories needed for accessing the CA/serving certs and the private key
|
||||||
if len(cfg.Etcd.Endpoints) != 0 {
|
if len(cfg.Etcd.Endpoints) != 0 {
|
||||||
etcdVols, etcdVolMounts := getEtcdCertVolumes(cfg.Etcd)
|
etcdVols, etcdVolMounts := getEtcdCertVolumes(cfg.Etcd)
|
||||||
mounts.AddHostPathMounts(kubeAPIServer, etcdVols, etcdVolMounts)
|
mounts.AddHostPathMounts(kubeadmconstants.KubeAPIServer, etcdVols, etcdVolMounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HostPath volumes for the controller manager
|
// HostPath volumes for the controller manager
|
||||||
// Read-only mount for the certificates directory
|
// Read-only mount for the certificates directory
|
||||||
// TODO: Always mount the K8s Certificates directory to a static path inside of the container
|
// TODO: Always mount the K8s Certificates directory to a static path inside of the container
|
||||||
mounts.NewHostPathMount(kubeControllerManager, k8sCertsVolumeName, cfg.CertificatesDir, cfg.CertificatesDir, true)
|
mounts.NewHostPathMount(kubeadmconstants.KubeControllerManager, k8sCertsVolumeName, cfg.CertificatesDir, cfg.CertificatesDir, true)
|
||||||
// Read-only mount for the ca certs (/etc/ssl/certs) directory
|
// Read-only mount for the ca certs (/etc/ssl/certs) directory
|
||||||
mounts.NewHostPathMount(kubeControllerManager, caCertsVolumeName, caCertsVolumePath, caCertsVolumePath, true)
|
mounts.NewHostPathMount(kubeadmconstants.KubeControllerManager, caCertsVolumeName, caCertsVolumePath, caCertsVolumePath, true)
|
||||||
// Read-only mount for the controller manager kubeconfig file
|
// Read-only mount for the controller manager kubeconfig file
|
||||||
controllerManagerKubeConfigFile := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ControllerManagerKubeConfigFileName)
|
controllerManagerKubeConfigFile := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ControllerManagerKubeConfigFileName)
|
||||||
mounts.NewHostPathMount(kubeControllerManager, kubeConfigVolumeName, controllerManagerKubeConfigFile, controllerManagerKubeConfigFile, true)
|
mounts.NewHostPathMount(kubeadmconstants.KubeControllerManager, kubeConfigVolumeName, controllerManagerKubeConfigFile, controllerManagerKubeConfigFile, true)
|
||||||
|
|
||||||
// HostPath volumes for the scheduler
|
// HostPath volumes for the scheduler
|
||||||
// Read-only mount for the scheduler kubeconfig file
|
// Read-only mount for the scheduler kubeconfig file
|
||||||
schedulerKubeConfigFile := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.SchedulerKubeConfigFileName)
|
schedulerKubeConfigFile := filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.SchedulerKubeConfigFileName)
|
||||||
mounts.NewHostPathMount(kubeScheduler, kubeConfigVolumeName, schedulerKubeConfigFile, schedulerKubeConfigFile, true)
|
mounts.NewHostPathMount(kubeadmconstants.KubeScheduler, kubeConfigVolumeName, schedulerKubeConfigFile, schedulerKubeConfigFile, true)
|
||||||
|
|
||||||
// On some systems were we host-mount /etc/ssl/certs, it is also required to mount /etc/pki. This is needed
|
// On some systems were we host-mount /etc/ssl/certs, it is also required to mount /etc/pki. This is needed
|
||||||
// due to symlinks pointing from files in /etc/ssl/certs into /etc/pki/
|
// due to symlinks pointing from files in /etc/ssl/certs into /etc/pki/
|
||||||
if isPkiVolumeMountNeeded() {
|
if isPkiVolumeMountNeeded() {
|
||||||
mounts.NewHostPathMount(kubeAPIServer, caCertsPkiVolumeName, caCertsPkiVolumePath, caCertsPkiVolumePath, true)
|
mounts.NewHostPathMount(kubeadmconstants.KubeAPIServer, caCertsPkiVolumeName, caCertsPkiVolumePath, caCertsPkiVolumePath, true)
|
||||||
mounts.NewHostPathMount(kubeControllerManager, caCertsPkiVolumeName, caCertsPkiVolumePath, caCertsPkiVolumePath, true)
|
mounts.NewHostPathMount(kubeadmconstants.KubeControllerManager, caCertsPkiVolumeName, caCertsPkiVolumePath, caCertsPkiVolumePath, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
return mounts
|
return mounts
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewVolume(t *testing.T) {
|
func TestNewVolume(t *testing.T) {
|
||||||
@ -304,7 +305,7 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
|||||||
Etcd: kubeadmapi.Etcd{},
|
Etcd: kubeadmapi.Etcd{},
|
||||||
},
|
},
|
||||||
vol: map[string][]v1.Volume{
|
vol: map[string][]v1.Volume{
|
||||||
kubeAPIServer: {
|
kubeadmconstants.KubeAPIServer: {
|
||||||
{
|
{
|
||||||
Name: "k8s-certs",
|
Name: "k8s-certs",
|
||||||
VolumeSource: v1.VolumeSource{
|
VolumeSource: v1.VolumeSource{
|
||||||
@ -318,7 +319,7 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
kubeControllerManager: {
|
kubeadmconstants.KubeControllerManager: {
|
||||||
{
|
{
|
||||||
Name: "k8s-certs",
|
Name: "k8s-certs",
|
||||||
VolumeSource: v1.VolumeSource{
|
VolumeSource: v1.VolumeSource{
|
||||||
@ -338,7 +339,7 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
kubeScheduler: {
|
kubeadmconstants.KubeScheduler: {
|
||||||
{
|
{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
VolumeSource: v1.VolumeSource{
|
VolumeSource: v1.VolumeSource{
|
||||||
@ -348,7 +349,7 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
volMount: map[string][]v1.VolumeMount{
|
volMount: map[string][]v1.VolumeMount{
|
||||||
kubeAPIServer: {
|
kubeadmconstants.KubeAPIServer: {
|
||||||
{
|
{
|
||||||
Name: "k8s-certs",
|
Name: "k8s-certs",
|
||||||
MountPath: testCertsDir,
|
MountPath: testCertsDir,
|
||||||
@ -360,7 +361,7 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
|||||||
ReadOnly: true,
|
ReadOnly: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
kubeControllerManager: {
|
kubeadmconstants.KubeControllerManager: {
|
||||||
{
|
{
|
||||||
Name: "k8s-certs",
|
Name: "k8s-certs",
|
||||||
MountPath: testCertsDir,
|
MountPath: testCertsDir,
|
||||||
@ -377,7 +378,7 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
|||||||
ReadOnly: true,
|
ReadOnly: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
kubeScheduler: {
|
kubeadmconstants.KubeScheduler: {
|
||||||
{
|
{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
MountPath: "/etc/kubernetes/scheduler.conf",
|
MountPath: "/etc/kubernetes/scheduler.conf",
|
||||||
@ -398,7 +399,7 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
vol: map[string][]v1.Volume{
|
vol: map[string][]v1.Volume{
|
||||||
kubeAPIServer: {
|
kubeadmconstants.KubeAPIServer: {
|
||||||
{
|
{
|
||||||
Name: "k8s-certs",
|
Name: "k8s-certs",
|
||||||
VolumeSource: v1.VolumeSource{
|
VolumeSource: v1.VolumeSource{
|
||||||
@ -424,7 +425,7 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
kubeControllerManager: {
|
kubeadmconstants.KubeControllerManager: {
|
||||||
{
|
{
|
||||||
Name: "k8s-certs",
|
Name: "k8s-certs",
|
||||||
VolumeSource: v1.VolumeSource{
|
VolumeSource: v1.VolumeSource{
|
||||||
@ -444,7 +445,7 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
kubeScheduler: {
|
kubeadmconstants.KubeScheduler: {
|
||||||
{
|
{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
VolumeSource: v1.VolumeSource{
|
VolumeSource: v1.VolumeSource{
|
||||||
@ -454,7 +455,7 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
volMount: map[string][]v1.VolumeMount{
|
volMount: map[string][]v1.VolumeMount{
|
||||||
kubeAPIServer: {
|
kubeadmconstants.KubeAPIServer: {
|
||||||
{
|
{
|
||||||
Name: "k8s-certs",
|
Name: "k8s-certs",
|
||||||
MountPath: testCertsDir,
|
MountPath: testCertsDir,
|
||||||
@ -476,7 +477,7 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
|||||||
ReadOnly: true,
|
ReadOnly: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
kubeControllerManager: {
|
kubeadmconstants.KubeControllerManager: {
|
||||||
{
|
{
|
||||||
Name: "k8s-certs",
|
Name: "k8s-certs",
|
||||||
MountPath: testCertsDir,
|
MountPath: testCertsDir,
|
||||||
@ -493,7 +494,7 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
|
|||||||
ReadOnly: true,
|
ReadOnly: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
kubeScheduler: {
|
kubeadmconstants.KubeScheduler: {
|
||||||
{
|
{
|
||||||
Name: "kubeconfig",
|
Name: "kubeconfig",
|
||||||
MountPath: "/etc/kubernetes/scheduler.conf",
|
MountPath: "/etc/kubernetes/scheduler.conf",
|
||||||
|
@ -25,19 +25,19 @@ import (
|
|||||||
// mutatePodSpec makes a Static Pod-hosted PodSpec suitable for self-hosting
|
// mutatePodSpec makes a Static Pod-hosted PodSpec suitable for self-hosting
|
||||||
func mutatePodSpec(cfg *kubeadmapi.MasterConfiguration, name string, podSpec *v1.PodSpec) {
|
func mutatePodSpec(cfg *kubeadmapi.MasterConfiguration, name string, podSpec *v1.PodSpec) {
|
||||||
mutators := map[string][]func(*kubeadmapi.MasterConfiguration, *v1.PodSpec){
|
mutators := map[string][]func(*kubeadmapi.MasterConfiguration, *v1.PodSpec){
|
||||||
kubeAPIServer: {
|
kubeadmconstants.KubeAPIServer: {
|
||||||
addNodeSelectorToPodSpec,
|
addNodeSelectorToPodSpec,
|
||||||
setMasterTolerationOnPodSpec,
|
setMasterTolerationOnPodSpec,
|
||||||
setRightDNSPolicyOnPodSpec,
|
setRightDNSPolicyOnPodSpec,
|
||||||
setVolumesOnKubeAPIServerPodSpec,
|
setVolumesOnKubeAPIServerPodSpec,
|
||||||
},
|
},
|
||||||
kubeControllerManager: {
|
kubeadmconstants.KubeControllerManager: {
|
||||||
addNodeSelectorToPodSpec,
|
addNodeSelectorToPodSpec,
|
||||||
setMasterTolerationOnPodSpec,
|
setMasterTolerationOnPodSpec,
|
||||||
setRightDNSPolicyOnPodSpec,
|
setRightDNSPolicyOnPodSpec,
|
||||||
setVolumesOnKubeControllerManagerPodSpec,
|
setVolumesOnKubeControllerManagerPodSpec,
|
||||||
},
|
},
|
||||||
kubeScheduler: {
|
kubeadmconstants.KubeScheduler: {
|
||||||
addNodeSelectorToPodSpec,
|
addNodeSelectorToPodSpec,
|
||||||
setMasterTolerationOnPodSpec,
|
setMasterTolerationOnPodSpec,
|
||||||
setRightDNSPolicyOnPodSpec,
|
setRightDNSPolicyOnPodSpec,
|
||||||
|
@ -32,7 +32,7 @@ func TestMutatePodSpec(t *testing.T) {
|
|||||||
expected v1.PodSpec
|
expected v1.PodSpec
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
component: kubeAPIServer,
|
component: kubeadmconstants.KubeAPIServer,
|
||||||
podSpec: &v1.PodSpec{},
|
podSpec: &v1.PodSpec{},
|
||||||
expected: v1.PodSpec{
|
expected: v1.PodSpec{
|
||||||
NodeSelector: map[string]string{
|
NodeSelector: map[string]string{
|
||||||
@ -45,7 +45,7 @@ func TestMutatePodSpec(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: kubeControllerManager,
|
component: kubeadmconstants.KubeControllerManager,
|
||||||
podSpec: &v1.PodSpec{},
|
podSpec: &v1.PodSpec{},
|
||||||
expected: v1.PodSpec{
|
expected: v1.PodSpec{
|
||||||
NodeSelector: map[string]string{
|
NodeSelector: map[string]string{
|
||||||
@ -58,7 +58,7 @@ func TestMutatePodSpec(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: kubeScheduler,
|
component: kubeadmconstants.KubeScheduler,
|
||||||
podSpec: &v1.PodSpec{},
|
podSpec: &v1.PodSpec{},
|
||||||
expected: v1.PodSpec{
|
expected: v1.PodSpec{
|
||||||
NodeSelector: map[string]string{
|
NodeSelector: map[string]string{
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
@ -35,14 +34,6 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
kubeAPIServer = "kube-apiserver"
|
|
||||||
kubeControllerManager = "kube-controller-manager"
|
|
||||||
kubeScheduler = "kube-scheduler"
|
|
||||||
|
|
||||||
selfHostingPrefix = "self-hosted-"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CreateSelfHostedControlPlane is responsible for turning a Static Pod-hosted control plane to a self-hosted one
|
// CreateSelfHostedControlPlane is responsible for turning a Static Pod-hosted control plane to a self-hosted one
|
||||||
// It achieves that task this way:
|
// It achieves that task this way:
|
||||||
// 1. Load the Static Pod specification from disk (from /etc/kubernetes/manifests)
|
// 1. Load the Static Pod specification from disk (from /etc/kubernetes/manifests)
|
||||||
@ -64,12 +55,9 @@ func CreateSelfHostedControlPlane(cfg *kubeadmapi.MasterConfiguration, client cl
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// The sequence here isn't set in stone, but seems to work well to start with the API server
|
for _, componentName := range kubeadmconstants.MasterComponents {
|
||||||
components := []string{kubeAPIServer, kubeControllerManager, kubeScheduler}
|
|
||||||
|
|
||||||
for _, componentName := range components {
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
manifestPath := buildStaticManifestFilepath(componentName)
|
manifestPath := kubeadmconstants.GetStaticPodFilepath(componentName, kubeadmconstants.GetStaticPodDirectory())
|
||||||
|
|
||||||
// Load the Static Pod file in order to be able to create a self-hosted variant of that file
|
// Load the Static Pod file in order to be able to create a self-hosted variant of that file
|
||||||
podSpec, err := loadPodSpecFromFile(manifestPath)
|
podSpec, err := loadPodSpecFromFile(manifestPath)
|
||||||
@ -116,17 +104,17 @@ func buildDaemonSet(cfg *kubeadmapi.MasterConfiguration, name string, podSpec *v
|
|||||||
// Return a DaemonSet based on that Spec
|
// Return a DaemonSet based on that Spec
|
||||||
return &extensions.DaemonSet{
|
return &extensions.DaemonSet{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: addSelfHostedPrefix(name),
|
Name: kubeadmconstants.AddSelfHostedPrefix(name),
|
||||||
Namespace: metav1.NamespaceSystem,
|
Namespace: metav1.NamespaceSystem,
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
"k8s-app": addSelfHostedPrefix(name),
|
"k8s-app": kubeadmconstants.AddSelfHostedPrefix(name),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Spec: extensions.DaemonSetSpec{
|
Spec: extensions.DaemonSetSpec{
|
||||||
Template: v1.PodTemplateSpec{
|
Template: v1.PodTemplateSpec{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
"k8s-app": addSelfHostedPrefix(name),
|
"k8s-app": kubeadmconstants.AddSelfHostedPrefix(name),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Spec: *podSpec,
|
Spec: *podSpec,
|
||||||
@ -151,17 +139,7 @@ func loadPodSpecFromFile(manifestPath string) (*v1.PodSpec, error) {
|
|||||||
return &staticPod.Spec, nil
|
return &staticPod.Spec, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildStaticManifestFilepath returns the location on the disk where the Static Pod should be present
|
|
||||||
func buildStaticManifestFilepath(componentName string) string {
|
|
||||||
return filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName, componentName+".yaml")
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildSelfHostedWorkloadLabelQuery creates the right query for matching a self-hosted Pod
|
// buildSelfHostedWorkloadLabelQuery creates the right query for matching a self-hosted Pod
|
||||||
func buildSelfHostedWorkloadLabelQuery(componentName string) string {
|
func buildSelfHostedWorkloadLabelQuery(componentName string) string {
|
||||||
return fmt.Sprintf("k8s-app=%s", addSelfHostedPrefix(componentName))
|
return fmt.Sprintf("k8s-app=%s", kubeadmconstants.AddSelfHostedPrefix(componentName))
|
||||||
}
|
|
||||||
|
|
||||||
// addSelfHostedPrefix adds the self-hosted- prefix to the component name
|
|
||||||
func addSelfHostedPrefix(componentName string) string {
|
|
||||||
return fmt.Sprintf("%s%s", selfHostingPrefix, componentName)
|
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -543,17 +544,17 @@ func TestBuildDaemonSet(t *testing.T) {
|
|||||||
dsBytes []byte
|
dsBytes []byte
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
component: kubeAPIServer,
|
component: kubeadmconstants.KubeAPIServer,
|
||||||
podBytes: []byte(testAPIServerPod),
|
podBytes: []byte(testAPIServerPod),
|
||||||
dsBytes: []byte(testAPIServerDaemonSet),
|
dsBytes: []byte(testAPIServerDaemonSet),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: kubeControllerManager,
|
component: kubeadmconstants.KubeControllerManager,
|
||||||
podBytes: []byte(testControllerManagerPod),
|
podBytes: []byte(testControllerManagerPod),
|
||||||
dsBytes: []byte(testControllerManagerDaemonSet),
|
dsBytes: []byte(testControllerManagerDaemonSet),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: kubeScheduler,
|
component: kubeadmconstants.KubeScheduler,
|
||||||
podBytes: []byte(testSchedulerPod),
|
podBytes: []byte(testSchedulerPod),
|
||||||
dsBytes: []byte(testSchedulerDaemonSet),
|
dsBytes: []byte(testSchedulerDaemonSet),
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user