mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-06 10:43:56 +00:00
kubeadm: add support for patching a corednsdeployment target
This commit is contained in:
parent
925cb2be30
commit
1329935739
@ -468,7 +468,7 @@ type HostPathMount struct {
|
||||
type Patches struct {
|
||||
// Directory is a path to a directory that contains files named "target[suffix][+patchtype].extension".
|
||||
// For example, "kube-apiserver0+merge.yaml" or just "etcd.json". "target" can be one of
|
||||
// "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration".
|
||||
// "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration", "corednsdeployment".
|
||||
// "patchtype" can be one of "strategic" "merge" or "json" and they match the patch formats supported by kubectl.
|
||||
// The default "patchtype" is "strategic". "extension" must be either "json" or "yaml".
|
||||
// "suffix" is an optional string that can be used to determine which patches are applied
|
||||
|
@ -438,7 +438,7 @@ type HostPathMount struct {
|
||||
type Patches struct {
|
||||
// Directory is a path to a directory that contains files named "target[suffix][+patchtype].extension".
|
||||
// For example, "kube-apiserver0+merge.yaml" or just "etcd.json". "target" can be one of
|
||||
// "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration".
|
||||
// "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration", "corednsdeployment".
|
||||
// "patchtype" can be one of "strategic" "merge" or "json" and they match the patch formats supported by kubectl.
|
||||
// The default "patchtype" is "strategic". "extension" must be either "json" or "yaml".
|
||||
// "suffix" is an optional string that can be used to determine which patches are applied
|
||||
|
@ -487,7 +487,7 @@ type HostPathMount struct {
|
||||
type Patches struct {
|
||||
// Directory is a path to a directory that contains files named "target[suffix][+patchtype].extension".
|
||||
// For example, "kube-apiserver0+merge.yaml" or just "etcd.json". "target" can be one of
|
||||
// "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration".
|
||||
// "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration", "corednsdeployment".
|
||||
// "patchtype" can be one of "strategic" "merge" or "json" and they match the patch formats supported by kubectl.
|
||||
// The default "patchtype" is "strategic". "extension" must be either "json" or "yaml".
|
||||
// "suffix" is an optional string that can be used to determine which patches are applied
|
||||
|
@ -99,7 +99,7 @@ func AddPatchesFlag(fs *pflag.FlagSet, patchesDir *string) {
|
||||
const usage = `Path to a directory that contains files named ` +
|
||||
`"target[suffix][+patchtype].extension". For example, ` +
|
||||
`"kube-apiserver0+merge.yaml" or just "etcd.json". ` +
|
||||
`"target" can be one of "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration". ` +
|
||||
`"target" can be one of "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration", "corednsdeployment". ` +
|
||||
`"patchtype" can be one of "strategic", "merge" or "json" and they match the patch formats ` +
|
||||
`supported by kubectl. The default "patchtype" is "strategic". "extension" must be either ` +
|
||||
`"json" or "yaml". "suffix" is an optional string that can be used to determine ` +
|
||||
|
@ -84,10 +84,10 @@ func NewAddonPhase() workflow.Phase {
|
||||
}
|
||||
}
|
||||
|
||||
func getInitData(c workflow.RunData) (*kubeadmapi.InitConfiguration, clientset.Interface, io.Writer, error) {
|
||||
func getInitData(c workflow.RunData) (*kubeadmapi.InitConfiguration, clientset.Interface, string, io.Writer, error) {
|
||||
data, ok := c.(InitData)
|
||||
if !ok {
|
||||
return nil, nil, nil, errors.New("addon phase invoked with an invalid data struct")
|
||||
return nil, nil, "", nil, errors.New("addon phase invoked with an invalid data struct")
|
||||
}
|
||||
cfg := data.Cfg()
|
||||
var client clientset.Interface
|
||||
@ -95,26 +95,27 @@ func getInitData(c workflow.RunData) (*kubeadmapi.InitConfiguration, clientset.I
|
||||
if !printManifest {
|
||||
client, err = data.Client()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, "", nil, err
|
||||
}
|
||||
}
|
||||
|
||||
out := data.OutputWriter()
|
||||
return cfg, client, out, err
|
||||
patchesDir := data.PatchesDir()
|
||||
return cfg, client, patchesDir, out, err
|
||||
}
|
||||
|
||||
// runCoreDNSAddon installs CoreDNS addon to a Kubernetes cluster
|
||||
func runCoreDNSAddon(c workflow.RunData) error {
|
||||
cfg, client, out, err := getInitData(c)
|
||||
cfg, client, patchesDir, out, err := getInitData(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return dnsaddon.EnsureDNSAddon(&cfg.ClusterConfiguration, client, out, printManifest)
|
||||
return dnsaddon.EnsureDNSAddon(&cfg.ClusterConfiguration, client, patchesDir, out, printManifest)
|
||||
}
|
||||
|
||||
// runKubeProxyAddon installs KubeProxy addon to a Kubernetes cluster
|
||||
func runKubeProxyAddon(c workflow.RunData) error {
|
||||
cfg, client, out, err := getInitData(c)
|
||||
cfg, client, _, out, err := getInitData(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ func runControlPlane() func(c workflow.RunData) error {
|
||||
return errors.Wrap(err, "couldn't complete the static pod upgrade")
|
||||
}
|
||||
|
||||
if err := upgrade.PerformAddonsUpgrade(client, cfg, data.OutputWriter()); err != nil {
|
||||
if err := upgrade.PerformAddonsUpgrade(client, cfg, data.PatchesDir(), data.OutputWriter()); err != nil {
|
||||
return errors.Wrap(err, "failed to perform addons upgrade")
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ import (
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/klog/v2"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
@ -42,6 +43,7 @@ import (
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/image"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/patches"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -85,7 +87,7 @@ func deployedDNSReplicas(client clientset.Interface, replicas int32) (*int32, er
|
||||
}
|
||||
|
||||
// EnsureDNSAddon creates the CoreDNS addon
|
||||
func EnsureDNSAddon(cfg *kubeadmapi.ClusterConfiguration, client clientset.Interface, out io.Writer, printManifest bool) error {
|
||||
func EnsureDNSAddon(cfg *kubeadmapi.ClusterConfiguration, client clientset.Interface, patchesDir string, out io.Writer, printManifest bool) error {
|
||||
var replicas *int32
|
||||
var err error
|
||||
if !printManifest {
|
||||
@ -97,10 +99,10 @@ func EnsureDNSAddon(cfg *kubeadmapi.ClusterConfiguration, client clientset.Inter
|
||||
var defaultReplicas int32 = coreDNSReplicas
|
||||
replicas = &defaultReplicas
|
||||
}
|
||||
return coreDNSAddon(cfg, client, replicas, out, printManifest)
|
||||
return coreDNSAddon(cfg, client, replicas, patchesDir, out, printManifest)
|
||||
}
|
||||
|
||||
func coreDNSAddon(cfg *kubeadmapi.ClusterConfiguration, client clientset.Interface, replicas *int32, out io.Writer, printManifest bool) error {
|
||||
func coreDNSAddon(cfg *kubeadmapi.ClusterConfiguration, client clientset.Interface, replicas *int32, patchesDir string, out io.Writer, printManifest bool) error {
|
||||
// Get the YAML manifest
|
||||
coreDNSDeploymentBytes, err := kubeadmutil.ParseTemplate(CoreDNSDeployment, struct {
|
||||
DeploymentName, Image, ControlPlaneTaintKey string
|
||||
@ -115,6 +117,14 @@ func coreDNSAddon(cfg *kubeadmapi.ClusterConfiguration, client clientset.Interfa
|
||||
return errors.Wrap(err, "error when parsing CoreDNS deployment template")
|
||||
}
|
||||
|
||||
// Apply patches to the CoreDNS Deployment
|
||||
if len(patchesDir) != 0 {
|
||||
coreDNSDeploymentBytes, err = applyCoreDNSDeploymentPatches(coreDNSDeploymentBytes, patchesDir, out)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not apply patches to the CoreDNS Deployment")
|
||||
}
|
||||
}
|
||||
|
||||
// Get the config file for CoreDNS
|
||||
coreDNSConfigMapBytes, err := kubeadmutil.ParseTemplate(CoreDNSConfigMap, struct{ DNSDomain, UpstreamNameserver, StubDomain string }{
|
||||
DNSDomain: cfg.Networking.DNSDomain,
|
||||
@ -377,3 +387,27 @@ func setCorefile(client clientset.Interface, coreDNSCorefileName string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// applyCoreDNSDeploymentPatches reads patches from a directory and applies them over the input coreDNSDeploymentBytes
|
||||
func applyCoreDNSDeploymentPatches(coreDNSDeploymentBytes []byte, patchesDir string, output io.Writer) ([]byte, error) {
|
||||
patchManager, err := patches.GetPatchManagerForPath(patchesDir, patches.KnownTargets(), output)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
patchTarget := &patches.PatchTarget{
|
||||
Name: patches.CoreDNSDeployment,
|
||||
StrategicMergePatchObject: apps.Deployment{},
|
||||
Data: coreDNSDeploymentBytes,
|
||||
}
|
||||
if err := patchManager.ApplyPatchesToTarget(patchTarget); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
coreDNSDeploymentBytes, err = yaml.JSONToYAML(patchTarget.Data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return coreDNSDeploymentBytes, nil
|
||||
}
|
||||
|
@ -865,7 +865,7 @@ metadata:
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
out := &bytes.Buffer{}
|
||||
var replicas int32 = 3
|
||||
if err := coreDNSAddon(tt.args.cfg, tt.args.client, &replicas, out, tt.args.printManifest); (err != nil) != tt.wantErr {
|
||||
if err := coreDNSAddon(tt.args.cfg, tt.args.client, &replicas, "", out, tt.args.printManifest); (err != nil) != tt.wantErr {
|
||||
t.Errorf("coreDNSAddon() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
@ -1148,7 +1148,7 @@ metadata:
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
out := &bytes.Buffer{}
|
||||
if err := EnsureDNSAddon(tt.args.cfg, tt.args.client, out, tt.args.printManifest); (err != nil) != tt.wantErr {
|
||||
if err := EnsureDNSAddon(tt.args.cfg, tt.args.client, "", out, tt.args.printManifest); (err != nil) != tt.wantErr {
|
||||
t.Errorf("EnsureDNSAddon() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.InitCon
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
if err := PerformAddonsUpgrade(client, cfg, out); err != nil {
|
||||
if err := PerformAddonsUpgrade(client, cfg, patchesDir, out); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.InitCon
|
||||
}
|
||||
|
||||
// PerformAddonsUpgrade performs the upgrade of the coredns and kube-proxy addons.
|
||||
func PerformAddonsUpgrade(client clientset.Interface, cfg *kubeadmapi.InitConfiguration, out io.Writer) error {
|
||||
func PerformAddonsUpgrade(client clientset.Interface, cfg *kubeadmapi.InitConfiguration, patchesDir string, out io.Writer) error {
|
||||
unupgradedControlPlanes, err := unupgradedControlPlaneInstances(client, cfg.NodeRegistration.Name)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to determine whether all the control plane instances have been upgraded")
|
||||
@ -147,7 +147,7 @@ func PerformAddonsUpgrade(client clientset.Interface, cfg *kubeadmapi.InitConfig
|
||||
metav1.NamespaceSystem)
|
||||
} else {
|
||||
// Upgrade CoreDNS
|
||||
if err := dns.EnsureDNSAddon(&cfg.ClusterConfiguration, client, out, false); err != nil {
|
||||
if err := dns.EnsureDNSAddon(&cfg.ClusterConfiguration, client, patchesDir, out, false); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
|
@ -75,8 +75,12 @@ func (ps *patchSet) String() string {
|
||||
)
|
||||
}
|
||||
|
||||
// KubeletConfiguration defines the kubeletconfiguration patch target.
|
||||
const KubeletConfiguration = "kubeletconfiguration"
|
||||
const (
|
||||
// KubeletConfiguration defines the kubeletconfiguration patch target.
|
||||
KubeletConfiguration = "kubeletconfiguration"
|
||||
// CoreDNSDeployment defines the corednsdeployment patch target.
|
||||
CoreDNSDeployment = "corednsdeployment"
|
||||
)
|
||||
|
||||
var (
|
||||
pathLock = &sync.RWMutex{}
|
||||
@ -100,6 +104,7 @@ var (
|
||||
kubeadmconstants.KubeControllerManager,
|
||||
kubeadmconstants.KubeScheduler,
|
||||
KubeletConfiguration,
|
||||
CoreDNSDeployment,
|
||||
}
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user