-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Apiserver nodes #10722
Apiserver nodes #10722
Conversation
Skipping CI for Draft Pull Request. |
a437632
to
3b501c2
Compare
dd1ca83
to
67cebaf
Compare
/cc @rifelpet |
/milestone v1.21 |
ef1275a
to
f6377e4
Compare
I've done this in the past based on CloudWatch metrics for CPU utilization. It was hard to get it right, given the many-minute delay in new machines starting up and being ready to serve. I found that often the CPU usage among the three or more API servers was inconsistent; one of them may be much more busy than the rest. I had been using the average utilization across the machines in the ASGs. Also, though I may have been doing something incorrectly, I recall that setting the CPU usage threshold correctly in CloudWatch required me to know how many CPUs were available on these machines. It wasn't possible to express something like "60% of the available CPUs" so that the rules would work irrespective of the machine type. If I recall correctly, the policy worked something like this:
|
Yeah, so where I work we never used ASG policies at all, but wrote our own custom controller that watch various sources (in our case, is there an upcoming game in an important league etc) or prometheus. Since we have metrics-server as an addon, we could let kops-controller just watch the metrics API (or scrape prom metrics such as API and set the desired flag. Either way, that is for a follow-up :) |
All changes that would affect current clusters is now behind feature flag (as proven by passing the Ready to merge from my side. |
75b2307
to
06d6540
Compare
/retest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a few small suggestions and asked a few questions, but this looks like it's going to work, with some room left for improvement in the future.
@@ -75,7 +75,7 @@ kops rolling-update cluster [flags] | |||
--force Force rolling update, even if no changes | |||
-h, --help help for cluster | |||
--instance-group strings List of instance groups to update (defaults to all if not specified) | |||
--instance-group-roles strings If specified, only instance groups of the specified role will be updated (e.g. Master,Node,Bastion) | |||
--instance-group-roles strings If specified, only instance groups of the specified role will be updated (e.g. Master,Apiserver,Node,Bastion) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we write "Apiserver" for role name for kops rolling-update cluster, but write "APIServer" for the role name for kops create instancegroup?
@@ -36,7 +36,7 @@ kops create instancegroup [flags] | |||
--edit If true, an editor will be opened to edit default values. (default true) | |||
-h, --help help for instancegroup | |||
-o, --output string Output format. One of json|yaml | |||
--role string Type of instance group to create (Node,Master,Bastion) (default "Node") | |||
--role string Type of instance group to create (Master,APIServer,Node,Bastion) (default "Node") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we write "APIServer" for the role name for kops create instancegroup, but write "Apiserver" for role name for kops rolling-update cluster?
cmd/kops/rollingupdatecluster.go
Outdated
@@ -189,7 +188,7 @@ func NewCmdRollingUpdateCluster(f *util.Factory, out io.Writer) *cobra.Command { | |||
cmd.Flags().DurationVar(&options.PostDrainDelay, "post-drain-delay", options.PostDrainDelay, "Time to wait after draining each node") | |||
cmd.Flags().BoolVarP(&options.Interactive, "interactive", "i", options.Interactive, "Prompt to continue after each instance is updated") | |||
cmd.Flags().StringSliceVar(&options.InstanceGroups, "instance-group", options.InstanceGroups, "List of instance groups to update (defaults to all if not specified)") | |||
cmd.Flags().StringSliceVar(&options.InstanceGroupRoles, "instance-group-roles", options.InstanceGroupRoles, "If specified, only instance groups of the specified role will be updated (e.g. Master,Node,Bastion)") | |||
cmd.Flags().StringSliceVar(&options.InstanceGroupRoles, "instance-group-roles", options.InstanceGroupRoles, "If specified, only instance groups of the specified role will be updated (e.g. Master,Apiserver,Node,Bastion)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we write "Apiserver" for role name for kops rolling-update cluster, but write "APIServer" for the role name for kops create instancegroup?
@@ -63,7 +63,8 @@ func TestBuildNodeLabels(t *testing.T) { | |||
expected: map[string]string{ | |||
RoleLabelMaster16: "", | |||
RoleLabelControlPlane20: "", | |||
RoleLabelName15: RoleMasterLabelValue15, | |||
//RoleLabelAPIServer16: "", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to leave this commented?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. The test runs without APIServerNodes feature flag. Will remove the comment when we remove/enable the ff by defult
@@ -188,7 +194,7 @@ func NewCmdRollingUpdateCluster(f *util.Factory, out io.Writer) *cobra.Command { | |||
cmd.Flags().DurationVar(&options.PostDrainDelay, "post-drain-delay", options.PostDrainDelay, "Time to wait after draining each node") | |||
cmd.Flags().BoolVarP(&options.Interactive, "interactive", "i", options.Interactive, "Prompt to continue after each instance is updated") | |||
cmd.Flags().StringSliceVar(&options.InstanceGroups, "instance-group", options.InstanceGroups, "List of instance groups to update (defaults to all if not specified)") | |||
cmd.Flags().StringSliceVar(&options.InstanceGroupRoles, "instance-group-roles", options.InstanceGroupRoles, "If specified, only instance groups of the specified role will be updated (e.g. Master,Apiserver,Node,Bastion)") | |||
cmd.Flags().StringSliceVar(&options.InstanceGroupRoles, "instance-group-roles", options.InstanceGroupRoles, "If specified, only instance groups of the specified role will be updated ("+strings.Join(allRoles, ",")+")") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clever!
4905fe3
to
3953c62
Compare
/retest |
3953c62
to
51c42bd
Compare
…r nodes Ensure apiserver role can only be used on AWS (because of firewalling) Apply api-server label to CP as well Consolidate node not ready validation message Guard apiserver nodes with a feature flag Rename Apiserver role to APIServer Add an integration test for apiserver nodes Rename Apiserver role to APIServer Enumerate all roles in rolling update docs Apply suggestions from code review Co-authored-by: Steven E. Harris <[email protected]>
51c42bd
to
20bd724
Compare
} | ||
nodeLabels[RoleLabelName15] = RoleAPIServerLabelValue15 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the idea that this is overridden in the isControlPlane
case
This LGTM - thanks for the tweaks and the feature flag (which lets us tweak some of the last unsettled points, like |
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: justinsb, seh The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/retest we should definitely get an e2e job setup to test this |
This PR introduces an additional node role that only runs kube-apiserver.
The control plane nodes still run kube-apiserver for bootstrapping the cluster and get dns-controller running. Then the additional api-servers join the cluster at the same time as worker nodes.
In order to distinguish API vs etcd clusters, new etcd cluster-specific DNS entries are created and used by apiserver nodes.
Current implementation grants apiserver nodes access to S3 to self-provision certs. Technically kube-controller could provision these certs, but that would require changes to kube-controller so it only provisions kube-apiserver certs to apiserver role.
Apiservers also reuse the master SG, but should really have a tighter dedicated SG at some point.
Future improvements could be being able to attach ASG scaling policies to it so these ASG scales with load.