A REST based API for managing Kraken and Kubernetes actions.
Go directly to the API Documentation and Specification section.
Internally the krak8s API server must have access to the current state of the cluster under management. This state is provided by the Kraken config YAML file (more on this later) and the generated cluster manifests that Kraken relies on. This data all, by default, lives under the directory tree rooted at .kraken
.
In our example, we have a cluster named geograph
.
$ pwd
/Users/sostheim/tmp/geograph/.kraken
$ ls -1F
config.yaml
datastore.jso
geograph/
help.txt
The help.txt
is a list of useful commands for managing the cluster. The file datastore.json
is the snapshot of the API services active object model (more on this later). Everything else, the config.yaml
file and the directory geograph/
, represents the current active state for the cluster.
The krak8s API manages this state by making updates to the config.yaml
file that get reflected in the geograph/
manifest when the Kraken tool chain is applied to the configuration file.
For the krak8s API service to work with the Kraken configuration file, see reference here: Kraken Configuration File Format, we need to insert a couple of markers to the YAML file. The markers are necessary elements that allow the API to determine exactly where to make it's insertions for the elements of the configuration it will manage.
The following sections explain how to add the markers to a file by hand. Attached here is an example default generated Kraken configuration file for reference.
The first marker we'll add is for the Helm Services. The point to insert the marker is at the very end of the section for definitions.helmConfigs
. There should be an existing section for the defaultHelm
, and typically a section for the Helm configs for the current cluster, e.g. geographHelm
would be the section for an example cluster named geograph
. We add the marker as the very last line the current cluster Helm configuration section. The line text must be, exactly:
# |--> SERVICES_MARKER <--|--> DO NOT REMOVE: REQUIRED FOR FOR CONFIG AUTOMATION <--|
The second marker we'll add is for the Node Pools. The point to insert the marker is at the very end of the section for deployment.clusters[0].nodePools
. As the last line of this section, we insert the following marker. The line text must be, exactly:
# |--> NODE_POOL_MARKER <--|--> DO NOT REMOVE: REQUIRED FOR FOR CONFIG AUTOMATION <--|
The krak8s API service commits every change to the state of the API object model to an external datastore snapshot named datastore.json
. This is the persistent backup of the API server state. So long as this file remains in tact between runs of the API service, the API services state will be maintained.
Very simply, whenever the API service starts up, it looks for the presence of the file datastore.json
. If the file is found, it initializes it's internal state from this file. If the file is not found, is empty, or if the file contains only the valid JSON object {}
, then the API service will initialize to a default new state.
All of these artifacts should be managed as a durable asset of the system. This means that these directories and files should be one of the folling:
- reside locally and be managed by some external backup solution for the admin workstation
- reside as part of a persistent volume/object store that's life time is decoupled from the container or Pod's lifetime
- reside in a transient volume but be persistently backed up using the companion project git-archivist.
For persistent deployments running in a Kubernetes cluster Deployment Pod, the following Helm Chart is provided: Chart krak8s API. The chart deploys git-archivist
as an Init Container to download the state repository specified. When the init container is complete, two containers are added to the Pod: git-archivist
as a long running syncronization service for the Git repository, and krak8s
as the API service.
A deployment of krak8s requires network connectivity to the Kubernetes API server. The Kubernetes API server can be accessed via kubectl proxy
for development, but this is not recommended for production deployments. For normal operation, the standard access via kubeconfig
or the Kubernetes API Server endpoint is supported.
The krak8s service can run as a static binary, a container image under a container runtime, or in a Kubernetes Pod. Regardless of the runtime environment, krak8s has a number of command line options that define how it operates.
$ ./krak8s --help
Usage of ./krak8s:
--alsologtostderr log to standard error as well as files
--debug enable debug output
--dry-run don't actually execute backend commands
--health-check enable health checking for API service
--kraken-command k2 command to run to execute kraken operations, either k2, or `k2cli` only (default "k2")
--kraken-config-dir string kraken configuration yaml directory path (default "${HOME}/.kraken")
--kraken-config-file string kraken configuration yaml file name (default "config.yaml")
--kraken-kubeconfig string kraken confiuration yaml: deployment.clusters[0].nodePools.kubeConfig (default "defaultKube")
--kraken-nodepool-keypair string kraken configuration yaml: deployment.clusters[0].nodePools.keyPair (default "defaultKeyPair")
--kubeconfig string absolute path to the kubeconfig file
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
--log_dir string If non-empty, write log files in this directory
--logtostderr log to standard error instead of files
--proxy string kubctl proxy server running at the given url
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
-v, --v Level log level for V logs
--version display version info and exit
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
Without going into an explanation of all of the parameters, many of which should have sufficient explanation in the help provided, of particular interest to controlling the operation of krak8s are the following:
--debug - Allow generation of additional output for debugging purposes.
--dry-run - Prevent any backend services from being executed against the live cluster.
--health-check - Allows external service monitors to check the health of the krak8s
service.
--kubeconfig - Use the referenced kubeconfig for credentialed access to the cluster.
--proxy - Use the kubectl proxy
URL for access to the cluster. See for example using kubectl proxy.
--kraken-command - The command to run to execute kraken operations, this can only be either k2
, or k2cli
--kraken-config-dir - The Kraken configuration yaml directory path (default "${HOME}/.kraken")
--kraken-config-file - The Kraken configuration yaml file name (default "config.yaml")
--kraken-kubeconfig - Value for Kraken confiuration yaml: deployment.clusters[0].nodePools.kubeConfig (default "defaultKube")
--kraken-nodepool-keypair - Value for Kraken configuration yaml: deployment.clusters[0].nodePools.keyPair (default "defaultKeyPair")
krak8s is configurable through command line configuration flags, and through a subset of environment variables. Any configuration value set on the command line takes precedence over the same value from the environment.
The format of the environment variable for a flag is composed of the prefix KRAK8S_
and the remaining text of the flag in all uppercase with all hyphens replaced by underscores. Fore example, --example-flag
would map to KRAK8S_EXAMPLE_FLAG
.
Not every flag can be set via an environment variable. This is due to the fact that the set of flags is an aggregate of those that belong to krak8s and 3rd party Go packages. The set of flags that do have corresponding environment variable support are listed below:
- --debug
- --dry-run
- --health-check
- --kraken-command
- --kraken-config-dir
- --kraken-config-file
- --kraken-kubeconfig
- --kraken-nodepool-keypair
- --kubeconfig
- --proxy
krak8s makes direct use of the Kraken infrastructure tools. The Kraken infrastructure tools themselves have a number of environment variables that enable the tool chain to directly utilize AWS resources on behalf of the user. In addition, the tools expect to find all of the configuration files in a standard location, or to be informed, via environment variable, of the location. See, for full reference, the Kraken documentation for Preparing the Environment. The critical values are represented here for quick reference:
KRAKEN=${HOME}/.kraken # This is the default output directory for Kraken
SSH_ROOT=${HOME}/.ssh
AWS_ROOT=${HOME}/.aws
AWS_CONFIG=${AWS_ROOT}/config # Use these files when using the aws provider
AWS_CREDENTIALS=${AWS_ROOT}/credentials
SSH_KEY=${SSH_ROOT}/id_rsa # This is the default rsa key configured
SSH_PUB=${SSH_ROOT}/id_rsa.pub
For deployments running in a Kubernetes cluster Deployment Pod, the Helm Chart: Chart krak8s API manages providing all of the required environment variables to the application.
The best option for deploying the krak8s API service is via helm chart. There is a chart provided for just this purpose here: krak8s's API Helm Chart
The following steps assume that you have a working Golang development environment on your local machine or in a container that you use for the same purpose.
- Clone the Repository
The Goa Design framework for building micro-services and REST APIs has a very specific path requirement for projects based on it. In particular, a Goa project must be based at $GOPATH\src\<project-name>
for the code generator to work properly.
$ echo $GOPATH
/Users/sostheim/work
$ git clone https://github.com/samsung-cnct/krak8s.git ${GOPATH}/src/krak8s
Cloning into '/Users/sostheim/work/src/krak8s'...
remote: Counting objects: 2870, done.
remote: Compressing objects: 100% (320/320), done.
remote: Total 2870 (delta 183), reused 324 (delta 99), pack-reused 2438
Receiving objects: 100% (2870/2870), 6.91 MiB | 1.23 MiB/s, done.
Resolving deltas: 100% (1282/1282), done.
- Project Make Targets
The tools necessary to build and deploy the project are all bundled in the Makefile.
- Make Dependencies
The project has only two dependencies to build and run (cutting a release is discussed separately below). These are the Gox Go Cross Compiler, and the Godep dependency tool for go.
$ make deps
go get github.com/mitchellh/gox
go get github.com/tools/godep
The project maintains a /vendor
directory of all the other dependencies of the project pinned to the requisite version.
- Make the Project
The default target for the Makefile is the build:
target. This is a convenience to prevent building an unwanted target. You should, as a general practices, always specify the build target on the command line.
$ make build
go build -ldflags "-X main.MajorMinorPatch=0.2.91 \
-X main.ReleaseType=alpha \
-X main.GitCommit=fbcb8984a595eb8e563992392d2e088339ca6aab"
Note that the build automatically pulls the last Git Commit SHA-1 to tag the build output with, along with a SemVer version number and release type that are populated as defined in the Makefile itself.
- Copy the Template File The project contains a Go template file that must be present in the working directory that the program is executed in. Simply copy the file to the working directory from the repository.
For example, if you want to run the program in the same directory in which it was built, the project root directory, then simply run the following command:
$ pwd
/Users/sostheim/work/src/krak8s
$ cp commands/node_pool.tmpl .
That's it. The project can now be run locally with a command string similar to the following.
./krak8s --alsologtostderr --kubeconfig /Users/sostheim/.kube/config --kraken-kubeconfig meteorKube --kraken-nodepool-keypair meteorKeyPair --kraken-config-file config.yaml --kraken-config-dir /Users/sostheim/.kraken --debug --dry-run
In the example above, several of the default values are specified on the command line, and could be omitted. They are shown here for completeness.
NOTE: In this example, we have supplied both the --debug
and --dry-run
flags. This is solely for the purpose of development and integration testing. These flags must be removed to run the API service in a production environment where real changes to an active Kubernetes cluster are going to be performed. As noted above in the description of the Configuration Flags, the presence of the debug and dry run flags allow additional output to be generated, and allows the API to be exercised without affecting the live cluster.
The following steps assume that you have a working Golang development environment on your local macos
machine.
- Project Make Target: Push
As before, the tools necessary to build and deploy the project are all bundled in the Makefile.
- Make Push
The command below will cross compile for the amd64
target and push the image to the project's CNCT Quay Repository.
$ make push
go get github.com/mitchellh/gox
go get github.com/tools/godep
gox -ldflags "-X main.MajorMinorPatch=0.2.91 \
-X main.ReleaseType=alpha \
-X main.GitCommit=fbcb8984a595eb8e563992392d2e088339ca6aab -w" \
-osarch="linux/amd64" \
-output "build/{{.OS}}_{{.Arch}}/krak8s" \
./...
Number of parallel builds: 7
--> linux/amd64: krak8s
--> linux/amd64: krak8s/tool/krak8s-cli
docker build --rm --pull --tag quay.io/samsung_cnct/krak8s:latest .
Sending build context to Docker daemon 108.3MB
Step 1/8 : FROM quay.io/samsung_cnct/k2:latest
latest: Pulling from samsung_cnct/k2
[ . . . Clipped Command Output Text ... ]
latest: digest: sha256:98bbaa5d2139616aa92913d883607584111e2330898ab69a160e7092537cb65d size: 44545
Note 1: When building for yourself, you will need to substitute a Docker Image Repository that you have write access to in place of the Samsung Quay.io repository.
Note 2: This is NOT a fully statically linked binary. There are shared library dependencies that must be resolved on the target system when the binary runs. This is intentional to allow the container to run locally on your Docker for Mac for testing.
As before, the following steps also assume that you have a working Golang development environment on your local machine or in a container that you use for the same purpose.
- Project Make Target: Push Static
As before, the tools necessary to build and deploy the project are all bundled in the Makefile. Here however, the build tool chain assumes that the build, tag, and push are all being executed on the same architecture as the deployment target architecture. In this case that architecture is amd64
. As such we can pass the flags to statically link against the system libraries for deployment as standalone binary. All other elements remain the same.
- Make Push Static
As before, the command shown below will cross compile for the amd64
target and push the image to the project's CNCT Quay Repository.
$ make push_static
go get github.com/mitchellh/gox
go get github.com/tools/godep
gox -ldflags "-X main.MajorMinorPatch=0.2.91 \
-X main.ReleaseType=alpha \
-X main.GitCommit=fbcb8984a595eb8e563992392d2e088339ca6aab -w \
-linkmode external -extldflags -static" \
-osarch="linux/amd64" \
-output "build/{{.OS}}_{{.Arch}}/krak8s" \
./...
Number of parallel builds: 7
--> linux/amd64: krak8s
--> linux/amd64: krak8s/tool/krak8s-cli
docker build --rm --pull --tag quay.io/samsung_cnct/krak8s:latest .
Sending build context to Docker daemon 108.3MB
Step 1/8 : FROM quay.io/samsung_cnct/k2:latest
latest: Pulling from samsung_cnct/k2
[ . . . Clipped Command Output Text ... ]
latest: digest: sha256:98bbaa5d2139616aa92913d883607584111e2330898ab69a160e7092537cb65d size: 44545
Note 3: As before, when building for yourself, you will need to substitute a Docker Image Repository that you have write access to in place of the Samsung Quay.io repository.
Install github-release from https://github.com/c4milo/github-release
Create a github personal access token with repo read/write permissions and export it as GITHUB_TOKEN
Adjust VERSION and TYPE variables in the Makefile as needed
Run make release