July 27, 2022

OpenShift 4.10 I: S2I, start-build, BuildConfig and Deployment

$ oc new-app --name=php-helloworld --image-stream=php:7.3 https://github.com/magnuskkarlsson/DO180-apps#s2i --context-dir=php-helloworld

$ oc start-build buildconfig.build.openshift.io/nodejs-dev

$ oc logs -f buildconfig.build.openshift.io/nodejs-dev
...
Push successful

$ oc logs -f deployment.apps/nodejs-dev

OpenShift 4.10 I: Create an OCP Application from Image, S2I, Template

From Image

$ oc new-project myproj01

$ oc new-app --name=httpd-24 --image=registry.access.redhat.com/ubi8/httpd-24 --labels app=httpd-24

$ oc get all

$ oc logs pod/httpd-24-9fb54567d-n9slj

$ oc expose service/httpd-24

$ oc get all

$ curl http://httpd-24-ch06s03.apps-crc.testing/

$ oc exec pod/httpd-24-9fb54567d-n9slj -- ps -aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
1000650+       1  0.0  0.2 391296 21980 ?        Ss   19:54   0:00 httpd -D FOREGROUND

$ oc describe pod/httpd-24-9fb54567d-n9slj

Source-to-Image (S2I)

$ oc new-project myproj03

$ oc get is -n openshift

$ oc new-app --name=ruby-hello-world --labels app=myapp --image-stream=ruby https://github.com/openshift/ruby-hello-world

$ oc get all

$ oc logs -f pod/ruby-hello-world-1-build

$ oc describe pod/ruby-hello-world-1-build

$ oc describe service/ruby-hello-world

$ oc expose service/ruby-hello-world

$ curl http://ruby-hello-world-myproj03.apps-crc.testing/

$ oc get buildconfig
NAME               TYPE     FROM   LATEST
ruby-hello-world   Source   Git    1

$ oc start-build ruby-hello-world

From Template

$ oc new-project myproj02

$ oc get templates -n openshift

$ oc get templates -n openshift | grep mysql
mysql-ephemeral                                 MySQL database service, without persistent storage. For more information abou...   8 (3 generated)   3
mysql-persistent                                MySQL database service, with persistent storage. For more information about u...   9 (3 generated)   4

$ oc describe template mysql-persistent -n openshift

$ oc new-app --name=app-db --template=mysql-persistent \
  --param MYSQL_USER=myuser \
  --param MYSQL_PASSWORD=redhat123 \
  --param MYSQL_ROOT_PASSWORD=redhat123 \
  --param MYSQL_DATABASE=items \
  --labels app=app-db

$ oc get events

$ oc describe service/mysql
Name:              mysql
Namespace:         myproj02
Labels:            app=app-db
                   template=mysql-persistent-template
Annotations:       openshift.io/generated-by: OpenShiftNewApp
                   template.openshift.io/expose-uri: mysql://{.spec.clusterIP}:{.spec.ports[?(.name=="mysql")].port}
Selector:          name=mysql
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.217.4.67
IPs:               10.217.4.67
Port:              mysql  3306/TCP
TargetPort:        3306/TCP
Endpoints:         10.217.0.106:3306
Session Affinity:  None
Events:            <none>

$ oc get pvc
NAME    STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mysql   Bound    pv0023   100Gi      RWO,ROX,RWX                   2m59s

$ oc describe pvc mysql
Name:          mysql
Namespace:     myproj02
StorageClass:  
Status:        Bound
Volume:        pv0023
Labels:        app=app-db
               template=mysql-persistent-template
Annotations:   openshift.io/generated-by: OpenShiftNewApp
               pv.kubernetes.io/bind-completed: yes
               pv.kubernetes.io/bound-by-controller: yes
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      100Gi
Access Modes:  RWO,ROX,RWX
VolumeMode:    Filesystem
Used By:       mysql-1-qncwj
Events:        <none>

$ oc port-forward pod/mysql-1-qncwj 3306:3306

$ mysql --host=127.0.0.1 --port=3306 --user=myuser --password=redhat123 --database=items --execute="show databases;"

OpenShift 4.10 I: OCP Manifest/Custom Resources Documentation

$ oc api-resources 
NAME                                  SHORTNAMES       APIVERSION                                    NAMESPACED   KIND
bindings                                               v1                                            true         Binding
componentstatuses                     cs               v1                                            false        ComponentStatus
configmaps                            cm               v1                                            true         ConfigMap
endpoints                             ep               v1                                            true         Endpoints
...

$ oc explain pod
KIND:     Pod
VERSION:  v1

DESCRIPTION:
     Pod is a collection of containers that can run on a host. This resource is
     created by clients and scheduled onto hosts.

FIELDS:
   apiVersion	<string>
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

   kind	<string>
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

   metadata	<Object>
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

   spec	<Object>
     Specification of the desired behavior of the pod. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

   status	<Object>
     Most recently observed status of the pod. This data may not be up to date.
     Populated by the system. Read-only. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

$ oc explain pod.spec 
KIND:     Pod
VERSION:  v1

RESOURCE: spec <Object>

DESCRIPTION:
     Specification of the desired behavior of the pod. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

     PodSpec is a description of a pod.

FIELDS:
   activeDeadlineSeconds	<integer>
     Optional duration in seconds the pod may be active on the node relative to
     StartTime before the system will actively try to mark it failed and kill
     associated containers. Value must be a positive integer.

   affinity	<Object>
     If specified, the pod's scheduling constraints
...

$ oc explain pod.spec --recursive 
KIND:     Pod
VERSION:  v1

RESOURCE: spec <Object>

DESCRIPTION:
     Specification of the desired behavior of the pod. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

     PodSpec is a description of a pod.

FIELDS:
   activeDeadlineSeconds	<integer>
   affinity	<Object>
      nodeAffinity	<Object>
         preferredDuringSchedulingIgnoredDuringExecution	<[]Object>
            preference	<Object>
               matchExpressions	<[]Object>
                  key	<string>
                  operator	<string>
                  values	<[]string>
               matchFields	<[]Object>
                  key	<string>
                  operator	<string>
                  values	<[]string>
            weight	<integer>
         requiredDuringSchedulingIgnoredDuringExecution	<Object>
...

OpenShift 4.10 I: Create an OCP Application

First create a new OCP project.

$ oc new-project myapp

Create an application from an image.

$ oc new-app --name=todonodejs \
  --image=quay.io/redhattraining/do180-todonodejs-12 \
  --env MYSQL_ENV_MYSQL_DATABASE=tododb \
  --env MYSQL_ENV_MYSQL_USER=user1 \
  --env MYSQL_ENV_MYSQL_PASSWORD=redhat123 \
  --labels app=todonodejs

Create an application based on source code in a git repository - Source-to-Image (S2I).

$ oc new-app --name=nodejs-dev \
  --image-stream=nodejs:16-ubi8 \
  https://github.com/magnuskkarlsson/DO180-apps#troubleshoot-review \
  --context-dir=nodejs-app

Create an application from an existing template.

$ oc new-app --name=mysql --template=mysql-persistent \
  --param MYSQL_USER=user1 \
  --param MYSQL_PASSWORD=redhat123 \
  --param MYSQL_ROOT_PASSWORD=redhat123 \
  --param MYSQL_DATABASE=tododb \
  --labels app=todonodejs

OpenShift 4.10 I: Custom Container Images without Dockerfile/Containerfile

$ podman run -d --name httpd-24 -p 8080:8080 registry.access.redhat.com/ubi9/httpd-24

$ podman exec httpd-24 /bin/bash -c 'echo "custom httpd image" < /var/www/html/index.html'

$ curl http://127.0.0.1:8080/ 
custom httpd image

$ podman diff httpd-24

$ podman commit --author 'Magnus K Karlsson' httpd-24 httpd-24-custom

$ podman images
REPOSITORY                                       TAG         IMAGE ID      CREATED        SIZE
localhost/httpd-24-custom                        latest      0eb89261860f  2 minutes ago  387 MB

$ podman tag localhost/httpd-24-custom quay.io/magnus_k_karlsson/httpd-24-custom:1.0

$ podman images
REPOSITORY                                       TAG         IMAGE ID      CREATED        SIZE
localhost/httpd-24-custom                        latest      0eb89261860f  5 minutes ago  387 MB
quay.io/magnus_k_karlsson/httpd-24-custom        1.0         0eb89261860f  5 minutes ago  387 MB

$ podman login quay.io
Username: magnus_k_karlsson 
Password: 
Login Succeeded!

$ podman push quay.io/magnus_k_karlsson/httpd-24-custom:1.0

$ podman pull quay.io/magnus_k_karlsson/httpd-24-custom:1.0

$ podman run -d --name httpd-24-custom -p 18080:8080 quay.io/magnus_k_karlsson/httpd-24-custom:1.0
4ca8325b0670b1b1175e8eaac442987f4cfa7f37d677eeec8dbbde9f1d0ec77e
$ curl http://127.0.0.1:18080/
custom httpd image

$ podman stop -a

$ podman rm -a

$ podman save -o httpd-24-custom.tar localhost/httpd-24-custom

$ podman rmi -a

$ podman load -i httpd-24-custom.tar

$ podman run -d --name httpd-24-custom -p 8080:8080 localhost/httpd-24-custom

$ podman logs httpd-24-custom
$ curl http://127.0.0.1:8080/
custom httpd image

OpenShift 4.10 I: Common podman commands

$ podman pull registry.access.redhat.com/ubi9/httpd-24:latest
$ podman images registry.access.redhat.com/ubi9/httpd-24:latest
$ podman rmi registry.access.redhat.com/ubi9/httpd-24:latest
$ skopeo inspect docker://registry.access.redhat.com/ubi9/httpd-24:latest
$ podman inspect registry.access.redhat.com/ubi9/httpd-24:latest

$ podman search --list-tags registry.access.redhat.com/ubi9/httpd-24

$ podman run -d --name httpd-24 -p 8080:8080 registry.access.redhat.com/ubi9/httpd-24:latest 

$ podman exec -it httpd-24 /bin/bash

$ podman ps -a
$ podman logs httpd-24
$ podman inspect httpd-24

$ podman top httpd-24
$ podman stats

$ podman stop httpd-24
$ podman start httpd-24
$ podman restart httpd-24

$ podman kill httpd-24
$ podman rm httpd-24

$ podman kill -s [SIGTERM|SIGINT|SIGKILL] httpd-24
$ kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
...

Use first SIGTERM, then try SIGINT; and only if both fail, to try again with SIGKILL.

$ podman run --rm -it registry.access.redhat.com/ubi9/ubi:latest /bin/bash

$ podman commit 

$ podman save -o mysql.tar registry.redhat.io/rhel8/mysql-80
$ podman load -i mysql.tar

$ podman history 

OpenShift 4.10 I: Understand rootless Container

$ podman search ubi
NAME                                                DESCRIPTION
registry.access.redhat.com/ubi7                     The Universal Base Image is designed and engineered to be the base layer for 
registry.access.redhat.com/ubi7/ubi                 The Universal Base Image is designed and engineered to be the base layer 
registry.access.redhat.com/ubi8/ubi                 Provides the latest release of the Red Hat Universal Base Image 8
registry.access.redhat.com/ubi8                     The Universal Base Image is designed and engineered to be the base layer 
registry.access.redhat.com/ubi9/ubi                 rhcc_registry.access.redhat.com_ubi9/ubi
registry.access.redhat.com/ubi9                     rhcc_registry.access.redhat.com_ubi9

$ podman run --name as-user --rm --interactive --tty registry.access.redhat.com/ubi9/ubi:latest /bin/bash

[root@60e643438db3 /]# whoami 
root
[root@60e643438db3 /]# id
uid=0(root) gid=0(root) groups=0(root)
[root@60e643438db3 /]# sleep 1000

From another terminal window, run 

$ ps -aux | grep 'sleep 1000'
student    23933  0.0  0.0   5300  1368 pts/0    S+   12:18   0:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000

$ sudo podman run --name as-root --rm --interactive --tty registry.access.redhat.com/ubi9/ubi:latest /bin/bash

[root@ff6d34b2a1e0 /]# whoami 
root
[root@ff6d34b2a1e0 /]# id
uid=0(root) gid=0(root) groups=0(root)
[root@ff6d34b2a1e0 /]# sleep 1000

From another terminal window, run 

$ ps -aux | grep 'sleep 1000'
root       24134  0.0  0.0   5300  1368 pts/0    S+   12:24   0:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000