This tutorial guides you through the process of deploying a simple service onto k8s using a hspec (HyScale Service Spec) and the hyscale command line tool.
To deploy your container image to K8s using hyscale, first prepare a short declarative spec file (hspec) as shown below.
If you do not already have an image or if you want hyscale to build the image for you, there are 2 other possible starting points described later in this document:
- You have either the source code (eg. php files) or binaries (eg. war file) for your service.
- You have a Docker file for your service.
The hyscale tool reads the supplied hspec and performs the necessary actions needed for deployment to k8s such as preparing a dockerfile, building the docker image and generating the various k8s manifests needed to satisfy the items declared in the hspec.
For the complete hspec reference, see here.
Preparing your first (and basic) service spec ("hspec")
Lets assume you have an image to deploy. Here is a basic service spec for deploying a tomcat image. This spec specifies some volumes needed, a port to be exposed outside the cluster and a http healthcheck.
myservice.hspec
name: myservice # any identifier for your service image: registry: registry.hub.docker.com name: library/tomcat tag: 8.5.0-jre8 volumes: - name: tomcat-logs-dir # any identifier for your volume path: /usr/local/tomcat/logs size: 1Gi # for using a non-default storage-class, specify as follows: # storageClass: <storage-class-name> external: true # this will make the service accessible outside the cluster (via a LoadBalancer type IP). Default is "false" ports: - port: 8080/tcp healthCheck: httpPath: /docs/images/tomcat.gif
Additional things you can specify in your service spec
Config Properties
props: JAVA_HOME: /usr/local/java TOMCAT_HOME: /usr/local/tomcat propsVolumePath: /usr/local/data/config/tomcat.props # This is default path if this directive is not specified
On deploy, these props go into a K8s ConfigMap and get injected as environment variables into the container. If propsVolumePath is specified, the ConfigMap is also mounted as a volume attached to the pod and the service code can then read these props from the file path specified.
Secrets
secrets: MYSQL_PASSWORD:XXXXXX
This works similar to the config properties above except that these go into K8s Secrets. If secretsVolumePath is specified, the secrets will be mounted as a volume and available at the path location inside the container.
If you already have secrets in K8s that you manage separately, you could specify just the name as follows. HyScale expects these to be present within a secret name "-" which should have been pre-created within the cluster.
secrets: - MYSQL_PASSWORD
Auto-Scale (HPA)
replicas: min: 1 max: 4 cpuThreshold: 30%
Logging & other Agents (sidecars)
agents: - name: fluentd # any identified for your agent/sidecar image: quay.io/fluentd_elasticsearch/fluentd props: FLUENTD_ARGS: --no-supervisor -vv volumes: - mountPath: /mnt/log attach: tomcat-logs # this is the name of the main service's volume to be mounted into this agent/sidecar
This will deploy the specified image as a sidecar alongside your main service container. The attach
directive above specifies the identifier of the main service volume to be mounted into the sidecar.
Miscellaneous
replicas: 3 # specify fixed number of replica pods needed, if you haven't specified auto-scaling as above memory: 2G # minimum memory to be requested for your service cpu: 3 startCommands: <start-command with args> # command+args in k8s yaml, overrides ENTRYPOINT+CMD
Using HyScale to build your image (optional)
Building from source / binaries
To start from source, or binaries for compiled languages, place this buildSpec snippet under the image directive:
image: # target registry, image name & tag go here as previously shown # images built by hyscale using the buildSpec below will be pushed to this target registry # hyscale relies on docker daemon to build images buildSpec: stackImage: tomcat:8.5.0-jre8 artifacts: - name: myservice # any identifier for your artifact source: target/myservice.war destination: /usr/local/tomcat/webapps/
Where:
stackImage
is the base stack image that your code depends on and can be specified in the format registry-url/name:tag
source
is the relative path to the artifacts including the filename, relative to your hspec file. This can be a zip file but not a folder.
destination
specifies the absolute path inside the container where the artifacts should be placed.
Building from a Dockerfile
image: # target registry, image name & tag go here as previously shown # images built by hyscale using the buildSpec below will be pushed to this target registry # hyscale relies on docker daemon to build images dockerfile: {}
Hyscale will look for a “Dockerfile” in the same directory as the hspec file. If your Dockerfile is in a different path or if you need to specify a target stage (in a multi-stage Dockerfile) or some build arguments, use the directives dockerfilePath, target and buildArgs respectively.
Specifying over-rides for different environments
Managing configuration differences across environments is necessary, so a hspec alone may not be sufficient across all environments. Environment specific configurations can be achieved through profiles as shown in the example below.
Stage profile for myservice can be like
stage-myservice.hprof
environment: stage overrides: myservice volumes: - name: tomcat-logs-dir size: 2Gi replicas: min: 1 max: 4 cpuThreshold: 30%
Deploy the service to K8s
To deploy, invoke the hyscale deploy command:
hyscale deploy service -f `<myservice.hspec>` -n `<my-namespace>` -a `<my-app-name>`
where my-app-name
is any identifier for your app and my-namespace
is the namespace within the cluster. HyScale will attempt to create this namespace for you if it doesn't already exist.
To deploy with a profile override, invoke the following deploy command:
hyscale deploy service -f `<myservice.hspec>` -n `<my-namespace>` -a `<my-app-name>` -p `<stage-myservice.hprof>`
To view the status of your deployment:
hyscale get service status -s `<myservice>` -n `<my-namespace>` -a `<my-app-name>`
where myservice
is the name of your service (same as your hspec file name without the .hspec extension)
To view logs:
hyscale get service logs -s `<myservice>` -n `<my-namespace>` -a `<my-app-name>`
For all possible commands, see App-Centric Ops & Commands