As you might have heard, Knative
0.7 was out last week.
One of the notable changes in this release is that Knative Serving API
progressed from v1alpha
to v1beta
. While you can still use the old
v1alpha1
API, if you want to update to v1beta
, you need to rewrite your
Knative service definition files. The new API also allows named revisions,
silent latest deploys and a better traffic splitting configuration. In this
post, I want to outline some of these changes.
More compact service definition
In previous version of Knative, if you wanted to deploy a simple Knative service and route 100% traffic to it, you had to use runLatest
block as follows:
apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
name: helloworld
namespace: default
spec:
runLatest:
configuration:
revisionTemplate:
spec:
container:
image: docker.io/meteatamel/helloworld:v1
env:
- name: TARGET
value: "v1"
In the new version, the same service definition looks like this:
apiVersion: serving.knative.dev/v1beta1
kind: Service
metadata:
name: helloworld
namespace: default
spec:
template:
spec:
containers:
- image: docker.io/meteatamel/helloworld:v1
env:
- name: TARGET
value: "v1"
Notice that there’s no runLatest
or configuration
and revisionTemplate
is simply called template
now. This allows a more compact service definition file.
Named revisions
In the previous version, when you deployed a change to your Knative Service, you’d get random revision numbers like this:
$ kubectl get revision
NAME
revision.serving.knative.dev/helloworld-c4pmt
revision.serving.knative.dev/helloworld-vkvjt
This is usually OK but made traffic splitting configuration a little cumbersome (more on this later).
In the new version, you still get random revision numbers by default but you can also give your revisions a predictable name. For example, take a look at this service definition file with a revision name:
apiVersion: serving.knative.dev/v1beta1
kind: Service
metadata:
name: helloworld
namespace: default
spec:
template:
metadata:
name: helloworld-v1
spec:
containers:
- image: docker.io/meteatamel/helloworld:v1
env:
- name: TARGET
value: "v1"
traffic:
- tag: current
**revisionName: helloworld-v1**
percent: 100
- tag: latest
latestRevision: true
percent: 0
When you deploy, you get the revision name you specified:
$ kubectl get revision
NAME SERVICE NAME GENERATION
helloworld-f4xvr helloworld-f4xvr 2
helloworld-ln8rv helloworld-ln8rv 3
**helloworld-v1 helloworld-v1 4 **
helloworld-z9clz helloworld-z9clz 1
Ability to deploy latest revision silently
In the previous example, you probably noticed the latest
configuration:
traffic:
- tag: current
revisionName: helloworld-v1
percent: 100
**- tag: latest
latestRevision: true
percent: 0**
When you deploy service, it will deploy the latest revision (under a randomly named revision id) but helloworld-v1
will be the one getting all the traffic. In other words, you silently deployed the latest revision. The main url [http://helloworld.default.example.com](http://helloworld.default.example.com)
will point to helloworld-v1
revision but you can also access the latest revision under [http://latest-helloworld.default.example.com](http://latest-helloworld.default.example.com%29)
This is useful if you want to deploy some code and test it out before rolling out to users.
More robust traffic splitting configuration
In the previous version of Knative, when you wanted to split traffic between current and candidate revisions, you had to do create a release and define a rollout percentage, something like this:
apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
name: helloworld
namespace: default
spec:
release:
# First revision is traffic target "current"
# Second revision is traffic target "candidate"
revisions: \["helloworld-xyzss", "helloworld-zyxss"\]
rolloutPercent: 20 # 20% traffic to route to "candidate"
configuration:
revisionTemplate:
spec:
container:
image: docker.io/meteatamel/helloworld:v1
env:
- name: TARGET
value: "v4"
This was problematic because the candidate revision id was not known before the initial deployment. You had to apply this configuration to get the candidate version deployed, get the random revision id for the deployed candidate revision and do another deploy again with that revision id to apply traffic splitting. Not ideal.
In the latest version of Knative, you can use named revisions in traffic splitting:
apiVersion: serving.knative.dev/v1beta1
kind: Service
metadata:
name: helloworld
namespace: default
spec:
template:
metadata:
name: helloworld-v4
spec:
containers:
- image: docker.io/meteatamel/helloworld:v1
env:
- name: TARGET
value: "v4"
traffic:
- tag: current
**revisionName: helloworld-v1**
percent: 50
- tag: candidate
**revisionName: helloworld-v4**
percent: 50
- tag: latest
latestRevision: true
percent: 0
This is definitely less cumbersome and more clear way of defining traffic splitting.
That’s all I wanted to cover with Knative Serving 0.7. If you want to try out Knative 0.7, I tested and updated my Knative Tutorial with 0.7 instructions, so check it out.