Skip to content

Commit

Permalink
kubectl: Support scaling deployments
Browse files Browse the repository at this point in the history
This commit adds support for using kubectl scale to scale deployments. Makes use of the
deployments/scale endpoint instead of updating deployment.spec.replicas directly.
  • Loading branch information
0xmichalis committed Nov 25, 2015
1 parent a7425bf commit 99fc358
Show file tree
Hide file tree
Showing 11 changed files with 548 additions and 190 deletions.
23 changes: 13 additions & 10 deletions docs/man/man1/kubectl-scale.1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

.SH NAME
.PP
kubectl scale \- Set a new size for a Replication Controller.
kubectl scale \- Set a new size for a Replication Controller, Job, or Deployment.


.SH SYNOPSIS
Expand All @@ -13,7 +13,7 @@ kubectl scale \- Set a new size for a Replication Controller.

.SH DESCRIPTION
.PP
Set a new size for a Replication Controller.
Set a new size for a Replication Controller, Job, or Deployment.

.PP
Scale also allows users to specify one or more preconditions for the scale action.
Expand All @@ -25,11 +25,11 @@ scale is sent to the server.
.SH OPTIONS
.PP
\fB\-\-current\-replicas\fP=\-1
Precondition for current size. Requires that the current size of the replication controller match this value in order to scale.
Precondition for current size. Requires that the current size of the resource match this value in order to scale.

.PP
\fB\-f\fP, \fB\-\-filename\fP=[]
Filename, directory, or URL to a file identifying the replication controller to set a new size
Filename, directory, or URL to a file identifying the resource to set a new size

.PP
\fB\-o\fP, \fB\-\-output\fP=""
Expand Down Expand Up @@ -148,16 +148,19 @@ scale is sent to the server.

.nf
# Scale replication controller named 'foo' to 3.
$ kubectl scale \-\-replicas=3 replicationcontrollers foo
$ kubectl scale \-\-replicas=3 rc/foo

# Scale a replication controller identified by type and name specified in "foo\-controller.yaml" to 3.
$ kubectl scale \-\-replicas=3 \-f foo\-controller.yaml
# Scale a resource identified by type and name specified in "foo.yaml" to 3.
$ kubectl scale \-\-replicas=3 \-f foo.yaml

# If the replication controller named foo's current size is 2, scale foo to 3.
$ kubectl scale \-\-current\-replicas=2 \-\-replicas=3 replicationcontrollers foo
# If the deployment named mysql's current size is 2, scale mysql to 3.
$ kubectl scale \-\-current\-replicas=2 \-\-replicas=3 deployment/mysql

# Scale multiple replication controllers.
$ kubectl scale \-\-replicas=5 rc/foo rc/bar
$ kubectl scale \-\-replicas=5 rc/foo rc/bar rc/baz

# Scale job named 'cron' to 3.
$ kubectl scale \-\-replicas=3 job/cron

.fi
.RE
Expand Down
4 changes: 2 additions & 2 deletions docs/user-guide/kubectl/kubectl.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ kubectl
* [kubectl replace](kubectl_replace.md) - Replace a resource by filename or stdin.
* [kubectl rolling-update](kubectl_rolling-update.md) - Perform a rolling update of the given ReplicationController.
* [kubectl run](kubectl_run.md) - Run a particular image on the cluster.
* [kubectl scale](kubectl_scale.md) - Set a new size for a Replication Controller.
* [kubectl scale](kubectl_scale.md) - Set a new size for a Replication Controller, Job, or Deployment.
* [kubectl version](kubectl_version.md) - Print the client and server version information.

###### Auto generated by spf13/cobra on 24-Nov-2015
###### Auto generated by spf13/cobra on 25-Nov-2015

<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl.md?pixel)]()
Expand Down
23 changes: 13 additions & 10 deletions docs/user-guide/kubectl/kubectl_scale.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ Documentation for other releases can be found at

## kubectl scale

Set a new size for a Replication Controller.
Set a new size for a Replication Controller, Job, or Deployment.

### Synopsis


Set a new size for a Replication Controller.
Set a new size for a Replication Controller, Job, or Deployment.

Scale also allows users to specify one or more preconditions for the scale action.
If --current-replicas or --resource-version is specified, it is validated before the
Expand All @@ -53,23 +53,26 @@ kubectl scale [--resource-version=version] [--current-replicas=count] --replicas

```
# Scale replication controller named 'foo' to 3.
$ kubectl scale --replicas=3 replicationcontrollers foo
$ kubectl scale --replicas=3 rc/foo
# Scale a replication controller identified by type and name specified in "foo-controller.yaml" to 3.
$ kubectl scale --replicas=3 -f foo-controller.yaml
# Scale a resource identified by type and name specified in "foo.yaml" to 3.
$ kubectl scale --replicas=3 -f foo.yaml
# If the replication controller named foo's current size is 2, scale foo to 3.
$ kubectl scale --current-replicas=2 --replicas=3 replicationcontrollers foo
# If the deployment named mysql's current size is 2, scale mysql to 3.
$ kubectl scale --current-replicas=2 --replicas=3 deployment/mysql
# Scale multiple replication controllers.
$ kubectl scale --replicas=5 rc/foo rc/bar
$ kubectl scale --replicas=5 rc/foo rc/bar rc/baz
# Scale job named 'cron' to 3.
$ kubectl scale --replicas=3 job/cron
```

### Options

```
--current-replicas=-1: Precondition for current size. Requires that the current size of the replication controller match this value in order to scale.
-f, --filename=[]: Filename, directory, or URL to a file identifying the replication controller to set a new size
--current-replicas=-1: Precondition for current size. Requires that the current size of the resource match this value in order to scale.
-f, --filename=[]: Filename, directory, or URL to a file identifying the resource to set a new size
-o, --output="": Output mode. Use "-o name" for shorter output (resource/name).
--replicas=-1: The new desired number of replicas. Required.
--resource-version="": Precondition for resource version. Requires that the current resource version match this value in order to scale.
Expand Down
19 changes: 19 additions & 0 deletions hack/test-cmd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ runTests() {
hpa_min_field=".spec.minReplicas"
hpa_max_field=".spec.maxReplicas"
hpa_cpu_field=".spec.cpuUtilization.targetPercentage"
job_parallelism_field=".spec.parallelism"
deployment_replicas=".spec.replicas"

# Passing no arguments to create is an error
! kubectl create
Expand Down Expand Up @@ -873,6 +875,23 @@ __EOF__
# Clean-up
kubectl delete rc redis-{master,slave} "${kube_flags[@]}"

### Scale a job
kubectl create -f docs/user-guide/job.yaml "${kube_flags[@]}"
# Command
kubectl scale --replicas=2 job/pi
# Post-condition: 2 replicas for pi
kube::test::get_object_assert 'job pi' "{{$job_parallelism_field}}" '2'
# Clean-up
kubectl delete job/pi "${kube_flags[@]}"
### Scale a deployment
kubectl create -f examples/extensions/deployment.yaml "${kube_flags[@]}"
# Command
kubectl scale --current-replicas=3 --replicas=1 deployment/nginx-deployment
# Post-condition: 1 replica for nginx-deployment
kube::test::get_object_assert 'deployment nginx-deployment' "{{$deployment_replicas}}" '1'
# Clean-up
kubectl delete deployment/nginx-deployment "${kube_flags[@]}"

### Expose replication controller as service
# Pre-condition: 2 replicas
kube::test::get_object_assert 'rc frontend' "{{$rc_replicas_field}}" '2'
Expand Down
20 changes: 19 additions & 1 deletion pkg/apis/extensions/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ package extensions

import (
"fmt"

"sort"

"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/util/sets"
)
Expand Down Expand Up @@ -65,3 +65,21 @@ func PodSelectorAsSelector(ps *PodSelector) (labels.Selector, error) {
sort.Sort(labels.ByKey(selector))
return selector, nil
}

// ScaleFromDeployment returns a scale subresource for a deployment.
func ScaleFromDeployment(deployment *Deployment) *Scale {
return &Scale{
ObjectMeta: api.ObjectMeta{
Name: deployment.Name,
Namespace: deployment.Namespace,
CreationTimestamp: deployment.CreationTimestamp,
},
Spec: ScaleSpec{
Replicas: deployment.Spec.Replicas,
},
Status: ScaleStatus{
Replicas: deployment.Status.Replicas,
Selector: deployment.Spec.Selector,
},
}
}
18 changes: 16 additions & 2 deletions pkg/client/unversioned/conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ func ControllerHasDesiredReplicas(c Interface, controller *api.ReplicationContro

// JobHasDesiredParallelism returns a condition that will be true if the desired parallelism count
// for a job equals the current active counts or is less by an appropriate successful/unsuccessful count.
func JobHasDesiredParallelism(c Interface, job *extensions.Job) wait.ConditionFunc {
func JobHasDesiredParallelism(c ExtensionsInterface, job *extensions.Job) wait.ConditionFunc {

return func() (bool, error) {
job, err := c.Extensions().Jobs(job.Namespace).Get(job.Name)
job, err := c.Jobs(job.Namespace).Get(job.Name)
if err != nil {
return false, err
}
Expand All @@ -62,3 +62,17 @@ func JobHasDesiredParallelism(c Interface, job *extensions.Job) wait.ConditionFu
return progress == 0, nil
}
}

// DeploymentHasDesiredReplicas returns a condition that will be true if and only if
// the desired replica count for a deployment equals its updated replicas count.
// (non-terminated pods that have the desired template spec).
func DeploymentHasDesiredReplicas(c ExtensionsInterface, deployment *extensions.Deployment) wait.ConditionFunc {

return func() (bool, error) {
deployment, err := c.Deployments(deployment.Namespace).Get(deployment.Name)
if err != nil {
return false, err
}
return deployment.Status.UpdatedReplicas == deployment.Spec.Replicas, nil
}
}
5 changes: 5 additions & 0 deletions pkg/client/unversioned/testclient/testclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,11 @@ func (c *Fake) SwaggerSchema(version string) (*swagger.ApiDeclaration, error) {
return &swagger.ApiDeclaration{}, nil
}

// NewSimpleFakeExp returns a client that will respond with the provided objects
func NewSimpleFakeExp(objects ...runtime.Object) *FakeExperimental {
return &FakeExperimental{Fake: NewSimpleFake(objects...)}
}

type FakeExperimental struct {
*Fake
}
Expand Down
27 changes: 15 additions & 12 deletions pkg/kubectl/cmd/scale.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,26 @@ type ScaleOptions struct {
}

const (
scale_long = `Set a new size for a Replication Controller.
scale_long = `Set a new size for a Replication Controller, Job, or Deployment.
Scale also allows users to specify one or more preconditions for the scale action.
If --current-replicas or --resource-version is specified, it is validated before the
scale is attempted, and it is guaranteed that the precondition holds true when the
scale is sent to the server.`
scale_example = `# Scale replication controller named 'foo' to 3.
$ kubectl scale --replicas=3 replicationcontrollers foo
$ kubectl scale --replicas=3 rc/foo
# Scale a replication controller identified by type and name specified in "foo-controller.yaml" to 3.
$ kubectl scale --replicas=3 -f foo-controller.yaml
# Scale a resource identified by type and name specified in "foo.yaml" to 3.
$ kubectl scale --replicas=3 -f foo.yaml
# If the replication controller named foo's current size is 2, scale foo to 3.
$ kubectl scale --current-replicas=2 --replicas=3 replicationcontrollers foo
# If the deployment named mysql's current size is 2, scale mysql to 3.
$ kubectl scale --current-replicas=2 --replicas=3 deployment/mysql
# Scale multiple replication controllers.
$ kubectl scale --replicas=5 rc/foo rc/bar`
$ kubectl scale --replicas=5 rc/foo rc/bar rc/baz
# Scale job named 'cron' to 3.
$ kubectl scale --replicas=3 job/cron`
)

// NewCmdScale returns a cobra command with the appropriate configuration and flags to run scale
Expand All @@ -63,7 +66,7 @@ func NewCmdScale(f *cmdutil.Factory, out io.Writer) *cobra.Command {
Use: "scale [--resource-version=version] [--current-replicas=count] --replicas=COUNT (-f FILENAME | TYPE NAME)",
// resize is deprecated
Aliases: []string{"resize"},
Short: "Set a new size for a Replication Controller.",
Short: "Set a new size for a Replication Controller, Job, or Deployment.",
Long: scale_long,
Example: scale_example,
Run: func(cmd *cobra.Command, args []string) {
Expand All @@ -74,13 +77,13 @@ func NewCmdScale(f *cmdutil.Factory, out io.Writer) *cobra.Command {
},
}
cmd.Flags().String("resource-version", "", "Precondition for resource version. Requires that the current resource version match this value in order to scale.")
cmd.Flags().Int("current-replicas", -1, "Precondition for current size. Requires that the current size of the replication controller match this value in order to scale.")
cmd.Flags().Int("current-replicas", -1, "Precondition for current size. Requires that the current size of the resource match this value in order to scale.")
cmd.Flags().Int("replicas", -1, "The new desired number of replicas. Required.")
cmd.MarkFlagRequired("replicas")
cmd.Flags().Duration("timeout", 0, "The length of time to wait before giving up on a scale operation, zero means don't wait.")
cmdutil.AddOutputFlagsForMutation(cmd)

usage := "Filename, directory, or URL to a file identifying the replication controller to set a new size"
usage := "Filename, directory, or URL to a file identifying the resource to set a new size"
kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
return cmd
}
Expand Down Expand Up @@ -127,11 +130,11 @@ func RunScale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri

resourceVersion := cmdutil.GetFlagString(cmd, "resource-version")
if len(resourceVersion) != 0 && len(infos) > 1 {
return fmt.Errorf("cannot use --resource-version with multiple controllers")
return fmt.Errorf("cannot use --resource-version with multiple resources")
}
currentSize := cmdutil.GetFlagInt(cmd, "current-replicas")
if currentSize != -1 && len(infos) > 1 {
return fmt.Errorf("cannot use --current-replicas with multiple controllers")
return fmt.Errorf("cannot use --current-replicas with multiple resources")
}
precondition := &kubectl.ScalePrecondition{Size: currentSize, ResourceVersion: resourceVersion}
retry := kubectl.NewRetryParams(kubectl.Interval, kubectl.Timeout)
Expand Down
Loading

0 comments on commit 99fc358

Please sign in to comment.