In this example we will be running the Skipper server on the local machine and deploying to minikube also running on the local machine.
Note | |
---|---|
The upgrade approach in 1.0 M1 does not handle correctly the routing of http traffic between versions, so take what is below with a grain of salt. The Spring Cloud Deployer for Kubernetes creates a service, replication controller, and pod for the app (or optionally a Deployment) This is not an issue for apps that communicate via Messaging middleware. Treat the current M1 release as a WIP. |
Start the Skipper server with the option --spring.config.location=skipper.yml
where the YAML is shown below.
spring: cloud: skipper: server: enableLocalPlatform: false platform: kubernetes: accounts: minikube: namespace: default
The repo list
command shows the experimental
and local
repositories, since they are configured by default.
skipper:>repo list ╔════════════╤═══════════════════════════════════════════════════════════╤═════╤═════╗ ║ Name │ URL │Local│Order║ ╠════════════╪═══════════════════════════════════════════════════════════╪═════╪═════╣ ║experimental│http://skipper-repository.cfapps.io/repository/experimental│false│0 ║ ║local │http://d4d6d1b6-c7e5-4226-69ec-01d4:7577 │true │1 ║ ╚════════════╧═══════════════════════════════════════════════════════════╧═════╧═════╝
and the search
command shows
skipper:>search ╔═════════════════╤═══════╤════════════════════════════════════════════════════════════════════════════════╗ ║ Name │Version│ Description ║ ╠═════════════════╪═══════╪════════════════════════════════════════════════════════════════════════════════╣ ║helloworld │1.0.1 │The app has two endpoints, /about and /greeting in Portuguese. Maven resource. ║ ║helloworld │1.0.0 │The app has two endpoints, /about and /greeting in English. Maven resource. ║ ║helloworld-docker│1.0.1 │The app has two endpoints, /about and /greeting in Portuguese. Docker resource.║ ║helloworld-docker│1.0.0 │The app has two endpoints, /about and /greeting in English. Docker resource. ║ ╚═════════════════╧═══════╧════════════════════════════════════════════════════════════════════════════════╝
The command platform list
shows which platforms the server has been configured with, in this case just one Kubernetes namespace. Disabling the local platform with the property enableLocalPlatform = false
is why the default local
platform does not appear.
skipper:>platform list ╔════════╤══════════╤══════════════════════════════════════════════════════════════════════════════════════╗ ║ Name │ Type │ Description ║ ╠════════╪══════════╪══════════════════════════════════════════════════════════════════════════════════════╣ ║minikube│kubernetes│master url = [https://192.168.99.100:8443/], namespace = [default], api version = [v1]║ ╚════════╧══════════╧══════════════════════════════════════════════════════════════════════════════════════╝
Let’s install the Hello World app, specifically, the Docker based artifact.
skipper:>install --release-name helloworldk8s --package-name helloworld-docker --package-version 1.0.0 --platform-name minikube --properties spec.deploymentProperties.spring.cloud.deployer.kubernetes.createNodePort=32123 Released helloworldk8s. Now at version v1.
If you do not specify --platform-name minikube
the command will fail since the command property defaults to a platform named default
. Instead of specifying it, you can register this Kubernetes Platform account in the manifest with the name default
instead of minikube
.
You can monitor the process using the status command
.
skipper:>status --release-name helloworldk8s ╔═══════════════╤══════════════════════════════════════════════════════════════════════════════════════════════════╗ ║Last Deployed │Wed Oct 25 17:34:24 EDT 2017 ║ ║Status │DEPLOYED ║ ║Platform Status│The applications are being deployed. ║ ║ │[helloworldk8s-helloworld-docker-v1], State = [helloworldk8s-helloworld-docker-v1-cch68=deploying]║ ╚═══════════════╧══════════════════════════════════════════════════════════════════════════════════════════════════╝
Eventually the Platform Status will say All applications have been successfully deployed.
Note that the status DEPLOYED
above indicates that Skipper has told the platform to deploy. Skipper does not keep track of the intermediate states 'deploying' or 'deleting'.
A kubectl pods
command will now have a new listing for this deployed application
$ kubectl get pods NAME READY STATUS RESTARTS AGE helloworldk8s-helloworld-docker-v1-g8j39 0/1 Running 0 37s $ kubectl get service NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE helloworldk8s-helloworld-docker-v1 10.0.0.202 <nodes> 8080:32123/TCP 41s kubernetes 10.0.0.1 <none> 443/TCP 57m
To get the URL of this app on minikube
$ minikube service --url helloworldk8s-helloworld-docker-v1 http://192.168.99.100:32123
You can now curl the greeting
endpoint and the about
endpoint.
$ curl http://192.168.99.100:32123/greeting Hello World! $ curl http://192.168.99.100:32123/about Hello World v1.0.0.RELEASE
The name of the application is based on the convention <release-name>-<package-name>-v<incrementing-counter>. This will need to change in future releases in order to handle routing correctly.
The package provides a means to template the application version, application properties and deployment properties that are used to deploy the application to Kubernetes. The manifest get
command shows the final YAML file which is passed off to the Spring Cloud Deployer Library.
skipper:>manifest get --release-name helloworldk8s --- # Source: template.yml apiVersion: skipper/v1 kind: SpringBootApp metadata: name: helloworld-docker spec: resource: docker:springcloud/spring-cloud-skipper-samples-helloworld:1.0.0.RELEASE applicationProperties: deploymentProperties: spring.cloud.deployer.kubernetes.createNodePort: 32123
The manifest is in a Kubernetes Resource file inspired format. By looking at the manifest you can see which Docker images was used and which properties were set before the final push to Kubernetes. The metadata values that are present will be used in the next release to support searching for releases based on those values.
Since it is somewhat awkward to specify multiple flattened out YAML values for the --properties
argument in the shell, you can also specify the location of a YAML file when installing or upgrading.
We will use a YAML file when we will update the release. This application contains a Spring Boot
@ConfigurationProperty
named helloworld.greeting
, so we will set that along with a standard Spring Boot property endpoints.sensitive=false
. We will also bump the memory up to 2G.
spec: applicationProperties: endpoints.sensitive: false helloworld.greeting: yo deploymentProperties: spring.cloud.deployer.kubernetes.createNodePort: 32124 spring.cloud.deployer.memory: 2048m
The upgrade
command
skipper:>upgrade --release-name helloworldk8s --package-name helloworld-docker --package-version 1.0.0 --file /home/mpollack/helloworld-upgrade-k8s.yml helloworldk8s has been upgraded. Now at version v2.
This will start another instance of the hello world application. If you do not specify --package-version
it will pick
the latest version of the helloworld-docker
package. You do not need to specify the --platform-name
as it will
always be where the current application was deployed.
the kubectl get all
command shows
$ kubectl get all NAME READY STATUS RESTARTS AGE po/helloworldk8s-helloworld-docker-v1-g8j39 1/1 Running 0 2m po/helloworldk8s-helloworld-docker-v2-jz85l 0/1 Running 0 50s NAME DESIRED CURRENT READY AGE rc/helloworldk8s-helloworld-docker-v1 1 1 1 2m rc/helloworldk8s-helloworld-docker-v2 1 1 0 50s NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE svc/helloworldk8s-helloworld-docker-v1 10.0.0.202 <nodes> 8080:32123/TCP 2m svc/helloworldk8s-helloworld-docker-v2 10.0.0.154 <nodes> 8080:32124/TCP 51s svc/kubernetes 10.0.0.1 <none> 443/TCP 59m
At this point Skipper is looking to see if the health endpoint of the Boot application is ok.
The property spring.cloud.skipper.server.strategies.healthcheck.timeoutInMillis
is the maximum time the upgrade process will wait for a healthy app.
The default value is 5 minutes.
Skipper will fail the deployment if it is not healthy within that time.
The property spring.cloud.skipper.server.strategies.healthcheck.sleepInMillis
is how long to sleep between health checks.
The current upgrade strategy is very simple, if the new app is healthy, the old app is removed. There is not a rolling upgrade option, all new apps are deployed, checked for health, and then previous versions removed. More flexible upgrade strategies are planned along with the introduction of the Spring Cloud State Machine project to orchestrate the update process.
You can now curl the greeting
endpoint and the about
endpoint.
$ curl http://192.168.99.100:32124/greeting yo $ curl http://192.168.99.100:32124/about Hello World v1.0.0.RELEASE
The list
command shows you the current DEPLOYED
and DELETED
release for every release name.
In this case there is just one entry
skipper:>list ╔═════════════╤═══════╤════════════════════════════╤════════╤═════════════════╤═══════════════╤═════════════╤═══════════════╗ ║ Name │Version│ Last updated │ Status │ Package Name │Package Version│Platform Name│Platform Status║ ╠═════════════╪═══════╪════════════════════════════╪════════╪═════════════════╪═══════════════╪═════════════╪═══════════════╣ ║helloworldk8s│2 │Wed Oct 25 17:36:16 EDT 2017│DEPLOYED│helloworld-docker│1.0.0 │minikube │ ║ ╚═════════════╧═══════╧════════════════════════════╧════════╧═════════════════╧═══════════════╧═════════════╧═══════════════╝
You can get the full history of the release using the history
command.
skipper:>history --release-name helloworldk8s ╔═══════╤════════════════════════════╤════════╤═════════════════╤═══════════════╤════════════════╗ ║Version│ Last updated │ Status │ Package Name │Package Version│ Description ║ ╠═══════╪════════════════════════════╪════════╪═════════════════╪═══════════════╪════════════════╣ ║2 │Wed Oct 25 17:36:16 EDT 2017│DEPLOYED│helloworld-docker│1.0.0 │Upgrade complete║ ║1 │Wed Oct 25 17:34:24 EDT 2017│DELETED │helloworld-docker│1.0.0 │Delete complete ║ ╚═══════╧════════════════════════════╧════════╧═════════════════╧═══════════════╧════════════════╝
A more typical upgrade process is not to change application properties, but to change the version of the application because the code has change. We will now upgrade the release to use a new Docker artifact, version 1.0.1, which also corresponds to version 1.0.1 of the helloworld Skipper package. In this case we will not add any additional properties other than the NodePort.
skipper:>upgrade --release-name helloworldk8s --package-name helloworld-docker --package-version 1.0.1 --properties spec.deploymentProperties.spring.cloud.deployer.kubernetes.createNodePort=32125 Released helloworldk8s. Now at version v3.
Note that the the current release’s property values such as using 2G, or the greeting being yo
are not carried over.
In a future release we will introduce a --reuse-properties
command that will carry the current release properties over to the next release to be made.
You can monitor the status of the upgrade using the status
command
skipper:>status --release-name helloworldk8s ╔═══════════════╤══════════════════════════════════════════════════════════════════════════════════════════════════╗ ║Last Deployed │Wed Oct 25 17:41:33 EDT 2017 ║ ║Status │DEPLOYED ║ ║Platform Status│All applications have been successfully deployed. ║ ║ │[helloworldk8s-helloworld-docker-v3], State = [helloworldk8s-helloworld-docker-v3-sb59j=deployed] ║ ╚═══════════════╧══════════════════════════════════════════════════════════════════════════════════════════════════╝
And a curl command shows
$ curl http://192.168.99.100:32125/greeting Olá Mundo! $ curl http://192.168.99.100:32125/about Hello World v1.0.1.RELEASE
Our history now looks like
skipper:>history --release-name helloworldk8s ╔═══════╤════════════════════════════╤════════╤═════════════════╤═══════════════╤════════════════╗ ║Version│ Last updated │ Status │ Package Name │Package Version│ Description ║ ╠═══════╪════════════════════════════╪════════╪═════════════════╪═══════════════╪════════════════╣ ║3 │Wed Oct 25 17:41:33 EDT 2017│DEPLOYED│helloworld-docker│1.0.1 │Upgrade complete║ ║2 │Wed Oct 25 17:36:16 EDT 2017│DELETED │helloworld-docker│1.0.0 │Delete complete ║ ║1 │Wed Oct 25 17:34:24 EDT 2017│DELETED │helloworld-docker│1.0.0 │Delete complete ║ ╚═══════╧════════════════════════════╧════════╧═════════════════╧═══════════════╧════════════════╝
Next we will use the rollback
command to deploy an older version of the application.
Since we have the manifest for that version, we have all we need to redeploy an earlier release.
skipper:>rollback --release-name helloworldk8s --release-version 2
helloworldk8s has been rolled back. Now at version v4.
The history now shows a new v4
version, even though it is identical to the v2
version.
skipper:>history --release-name helloworldk8s ╔═══════╤════════════════════════════╤════════╤═════════════════╤═══════════════╤════════════════╗ ║Version│ Last updated │ Status │ Package Name │Package Version│ Description ║ ╠═══════╪════════════════════════════╪════════╪═════════════════╪═══════════════╪════════════════╣ ║4 │Wed Oct 25 17:44:25 EDT 2017│DEPLOYED│helloworld-docker│1.0.0 │Upgrade complete║ ║3 │Wed Oct 25 17:41:33 EDT 2017│DELETED │helloworld-docker│1.0.1 │Delete complete ║ ║2 │Wed Oct 25 17:36:16 EDT 2017│DELETED │helloworld-docker│1.0.0 │Delete complete ║ ║1 │Wed Oct 25 17:34:24 EDT 2017│DELETED │helloworld-docker│1.0.0 │Delete complete ║ ╚═══════╧════════════════════════════╧════════╧═════════════════╧═══════════════╧════════════════╝
The curl commands show
$ curl http://192.168.99.100:32124/greeting yo $ curl http://192.168.99.100:32124/about Hello World v1.0.0.RELEASE