Getting started
Introduction
Kubernetes/OKD/Openshift can be very overwhelming at first, with many new concepts and vocabulary to learn. We strongly advise you to watch the videos Containers 101 and Containers for dummies. To really grasp what the possibilities are, you need to play around and read up on the material, see below for a list of additional resources.
Kubernetes and OKD are very alike, but some small differences exist, e.g.:
- Kubernetes uses Namespace, OKD uses Project
- Kubernetes uses Ingress, OKD uses Route
Other keywords/core objects can be found here
All Kubernetes objects can be used in OKD without any issues.
Core things you need to do to get started with our container platform after access has been established:
- Log into paas2 console or paas3 console and look around. Everything can be done in the GUI.
-
A standard namespace/project often has the following core components:
-
Deployment: a manifest that describes which containers will run in your pod
- Service: an object that makes Pods available on the network so that clients can interact with it
- Route: allows you to expose your service at a public URL. It can be secured or unsecured, depending on the network security configuration of your application.
When you have become familiar with OKD, we advise to use ArgoCD, which provides a GitOps workflow and a declarative continuous delivery tool for Kubernetes/OKD/Openshift. You will have full control of your applications through this and be able to roll back deployments very easily when mistakes occur.
Using the command line
It is often faster to do tasks in the terminal and easier to comprehend how your application is working in OKD.
Getting the binary
Go to https://github.com/okd-project/okd/releases and expand "Assets" for the latest release. Linux users will typically want the file named openshift-client-linux-amd64-rhel9-*. It contains a single binary oc which works on all recent distros.
Logging in
First log in to the web console. Click on your username in top right corner and choose "Copy login command". Click "Display Token" to view a token which is valid for 24 hours.
A convenience function for your .bashrc to jump to this page:
oc_token() {
local paas=${1-paas3}
xdg-open "https://oauth-openshift.apps.${paas}.rlnc.eu/oauth/authorize?client_id=openshift-browser-client&redirect_uri=https%3A%2F%2Foauth-openshift.apps.${paas}.rlnc.eu%2Foauth%2Ftoken%2Fdisplay&response_type=code"
}
oc login
The Display Token web page will give you a command you can copy-paste into your shell.
Registry login
The same token can be used to log into OKD's registry.
podman and docker are interchangable. On Linux podman is recommended.
$ podman login registry.apps.paas3.rlnc.eu
Username: <anything, can be empty>
Password: sha256~8ys…YpY
Login Succeeded!
Work with container images
Container images can be retrieved from public registries like quay.io, docker.io and gcr.io or private registries like gitlab, if you develop your own applications. Custom images can also be stored in the internal OKD registry if needed.
There are many ways to achieve this, we advise generally in most use cases to use private registries like gitlab to host your own container images.
Examples
Deploy images in your private gitlab registry (using buildkit)
Add the following in your gitlab pipeline: (.gitlab-ci.yml).
stages:
- build-image
build:
stage: build-image
image: containers.redpill-linpro.com/cloud/k8s/buildah-rootless:latest
variables:
STORAGE_DRIVER: overlay
BUILDAH_FORMAT: docker
BUILDAH_ISOLATION: chroot
KUBERNETES_SERVICE_ACCOUNT_OVERWRITE: "buildah-sa"
before_script:
# Log in to the GitLab container registry
- buildah login -u "$CI_REGISTRY_USER" --password $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- buildah images
- buildah build -f Dockerfile -t $IMAGE_TAG
- buildah images
- buildah push $IMAGE_TAG
only:
- main
Deploy a image to OKD's internal registry
variables:
DEST_TAG: registry.apps.paas3.rlnc.eu/namespace/image:latest
stages:
- deploy
Deploy:
stage: deploy
image:
name: quay.io/containers/skopeo:latest
entrypoint: [""]
script:
- printf 'Copying image to %s\n' ${DEST_TAG}
- skopeo copy --dest-tls-verify=false --src-creds "${CI_REGISTRY_USER}:${CI_REGISTRY_PASSWORD}" --dest-creds "gitlab:${OCTOKEN}" docker://${IMAGE_TAG} docker://${DEST_TAG}
The ${OCTOKEN} is a CI/CD variable we have added in our gitlab project. This token is a non-expiry token generated by connecting a secret to the relevant service account.
Use a external registry in your deployment
An external image registry could be hosted at various locations. For Redpill Linpro's gitlab instance it is for example called containers.redpill-linpro.com.
To use this image, the deployment needs access via a imagePullSecret configuration. Ad-Hoc create one:
kubectl create secret docker-registry $SECRETNAME \
--docker-server=$REGISTRY \
--docker-username=$TOKENU \
--docker-password=$TOKENP \
-n $NAMESPACE
error: unable to decode "secret.yaml": json: cannot unmarshal string into Go value of type unstructured.detector, try this:
oc create secret docker-registry "$SECRETNAME" \
--docker-server="$REGISTRY" \
--docker-username="$TOKENU" \
--docker-password="$TOKENP" \
-n "$NAMESPACE" \
--dry-run=client -o yaml > secretparsed.yaml
apiVersion: v1
kind: Secret
metadata:
name: my-registry-secret
namespace: <optional>
data:
.dockerconfigjson: <base64-encoded-docker-config-json>
type: kubernetes.io/dockerconfigjson
Then in your deployment add a reference(example):
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: my-container
image: externalregistry.com/development/incident-program
imagePullSecrets:
- name: <secret-name>
Point to a ImageStream in a Deployment
If you are using a Deployment, you can run the following to trigger automatic redeployments when your "ImageStream" gets a new image:
oc set triggers deployment/<name of deployment> --from-image=<containerimage>:latest -c <container name>
and add the folowing under "annotations":
Push locally built image to internal OKD registry
-
Create an empty
ImageStreamin your namespace -
Login to the internal OKD registry. See above for method.
-
Add a tag to your local image with correct remote path (ie.,
registry.apps.paas3.rlnc.eu/). -
Push to internal OKD registry
Work with persistent volumes
We advise against using persistent volumes (PV), it is often better to use a separate database or S3 storage for persisting state. However, if you have a use case, here is an example of how to use it.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: claim1
namespace: <your namespace>
spec:
accessModes:
- ReadWriteOnce
storageClassName: rlcs-ssd
resources:
requests:
storage: 1Gi
Then you can point to this claim in your deployment:
No special permissions are needed to use this functionality. There is currently no support for ReadWriteMany to these volumes(RWX) which means that only one node can mount the volume at a time. Keep this in mind when designing a deployment using PVs.
Work with ArgoCD
This is a very basic "getting started with ArgoCD", for more depth, see upstream documentation
For customers with a dedicated ArgoCD instance, you need to create the following resources in your ArgoCD GUI:
-
Create your own ArgoCD project if desirable. If not, the "default" one will be used.
Settings→Projects→+NEW PROJECT -
Create an ArgoCD application. It is advised to start with a "Manual" sync policy and change it to "Automatic" when you comfortable with your app/setup.
Applications→+NEW APPExample:
-
Add your remote git repository with a token of your remote gitRepo (
read_repositoryandread_registrypermissions on your token should suffice)Settings→Repositories→+CONNECT REPO→VIA HTTP/HTTPSFill inn
ProjectandRepository URL, leaveUsernameempty, and enter Git token intoPassword. ClickConnect.
Work with KSOPS/Mozilla SOPS
For customers with a dedicated ArgoCD instance, for an additional cost, we can offer the Kustomize SOPS plugin which can be used to decrypt resources encrypted with SOPS.
On the Cluster, Redpill Linpro will:
- Deploy GitOps operator
- Generate a private/public key with the
agebinary - Create a secret in the ArgoCD namespace of the customer that stores the public and private keys
- Customize the Argo CD instance to use the Kustomize SOPS plugin
- Push the Public key into the git repository/or send it securely to the customer
Developers/the customer will:
- Create a Secret on their local console
- Download the public key to encrypt the secret with SOPS CLI
- Generate KSOPS YAML with the encrypted secret and push to their Git repository
Requirements for the developer/Customer
Download the following binaries to your client machine: (Decrypting locally is only possible if you have the private key stored on your client machine, which is not advised)
Configure SOPS
-
SOPS is configured via .sops.yaml
For this example and testing, KSOPS relies on the SOPS creation rules defined in .sops.yaml. To make encrypted secrets more readable, we suggest using the following encryption regex to only encrypt data and stringData values. This leaves non-sensitive fields, like the secret's name, unencrypted and human readable.
-
Create a Resource (local Kubernetes Secret)
-
Encrypt the Resources with SOPS CLI (Specific SOPS configuration in .sops.yaml)
All changes to the yaml file after encryption will give data integrity errors, so re-encrypt if you want to add stuff!
-
Define KSOPS kustomize Generator(Create a local Kubernetes Secret)
-
Create an
kustomization.yaml(example) -
Run ArgoCD
Troubleshooting
Sanity Checks
-
Validate ksops command is in your path
-
If you prefer to not install ksops to your path, make sure the path to the executable in the generator manifest is relative to the manifests files
-
Running
kustomize build --enable-alpha-plugins --enable-exec . | oc diff -f -will not work locally since you need the private key to decrypt your encrypted values. A typical error output of this would be:failed to evaluate function: error decrypting file "secret.sops.yaml" from manifest.Files: trouble decrypting file: Error getting data key: 0 successful groups required, got 0unable to generate manifests: error decrypting file "secret.sops.yaml" from manifest.Files: trouble decrypting file: Error getting data key: 0 successful groups required, got 0Error: couldn't execute function: exit status 1 -
If the following annotation is not configured with correct indentation
you will get the following error output:
Failed to load target state: failed to generate manifest for source 1 of 1: rpc error: code = Unknown desc = Manifest generation error (cached): `kustomize build <path to cached source>/k8s --enable-alpha-plugins --enable-exec` failed exit status 1: Error: accumulating resources: accumulation err='accumulating resources from 'test': '<path to cached source>/' must resolve to a file': recursed accumulation of path '<path to cached source>/k8s/test': loading generator plugins: failed to load generator: unable to find plugin root - tried: ('<no value>'; homed in $KUSTOMIZE_PLUGIN_HOME), ('/.config/kustomize/plugin'; homed in $XDG_CONFIG_HOME), ('/.config/kustomize/plugin'; homed in default value of $XDG_CONFIG_HOME), ('/kustomize/plugin'; homed in home directory)
Recommended reading
-
In particular:
- Containers
- Workloads (
Deployment,ReplicaSet,StatefulSet,DaemonSet,Job)
All resources are objects with some operations in common:
- kubectl and kustomize book
- KSOPS upstream documentation
- ArgoCD upstream documentation