This appendix provides an example showing you the complete process for deploying and running your active standby pair of TimesTen databases in the Kubernetes cluster. After the databases are up and running, the example demonstrates how the Operator controls and manages the databases. If the active database fails, the Operator performs the necessary tasks to failover to the standby database, making that standby database the active one. The example concludes with procedures to delete the TimesTen databases and to stop the Operator.
Before starting the example, ensure you have:
Completed the prerequisites. See "Prerequisites" for information on the required prerequisites.
To set up the environment, perform these steps from your Linux development host:
Perform these steps to download the full distribution of TimesTen and then unpack the TimesTen Operator distribution that is embedded within it. Perform all steps from your Linux development host.
From the directory of your choice:
Create one subdirectory into which you will download the TimesTen full distribution. For example, create the installation_dir
subdirectory. (The installation_dir
directory is used in the remainder of this chapter.)
Create a second subdirectory into which you will unpack the TimesTen Operator distribution. For example, create the kube_files
subdirectory. (This kube_files
directory is used in the remainder of this chapter.)
% mkdir -p installation_dir % mkdir -p kube_files
You are now ready to download and unpack the TimesTen full distribution.
Navigate to installation_dir
.
% cd installation_dir
Download the TimesTen full distribution into this directory. As an example, download the t
imesten1814110.server.linux8664.zip
file, (the 18.1.4.11.0
full distribution for Linux 64-bit).
From the installation_dir
, use the ZIP utility to unpack the TimesTen distribution.
% unzip timesten1814110.server.linux8664.zip Archive: /timesten/installation/timesten1814110.server.linux8664.zip creating: tt18.1.4.11.0/ creating: tt18.1.4.11.0/ttoracle_home/ ... creating: tt18.1.4.11.0/kubernetes/ ...
You successfully unpacked the TimesTen full distribution.
Note that the installation_dir
/tt18.1.4.11.0/kubernetes
directory is created. The operator.zip
file is located in this directory. For example, this is a sample directory structure after unpacking the distribution.
% pwd
installation_dir/tt18.1.4.11.0
% dir
3rdparty include lib oraclescripts README.html ttoracle_home
bin info network PERL startup
grid kubernetes nls plsql support
Navigate to the kube_files
directory and unpack the operator.zip
file into it. In this example, unpack the installation_dir
/tt18.1.4.11.0/kubernetes
/operator.zip
file.
% cd kube_files % unzip installation_dir/tt18.1.4.11.0/kubernetes/operator.zip [...UNZIP OUTPUT...]
You successfully unpacked the installation_dir
/tt18.1.4.11.0/kubernetes/operator.zip
file into the kube_files
directory.
Review the directory structure. Later in this chapter, you will modify some of the files in these subdirectories. This example shows the most important subdirectories and files, which can change from release to release.
README.md deploy/crd.yaml deploy/operator.yaml deploy/service_account.yaml operator/Dockerfile operator/timestenclassic-operator ttimage/agent2 ttimage/.bashrc ttimage/create1.sql ttimage/create2.sql ttimage/Dockerfile ttimage/get1.sql ttimage/pausecq.sql ttimage/repcreate.sql ttimage/repduplicate.sql ttimage/runsql,sql ttimage/starthost.pl ttimage/.ttdotversion ttimage/.ttdrop
Note:
This directory tree must persist through the lifetime of the TimesTen Operator.In addition, do not delete the TimesTen full distribution file (t
imesten1814110.server.linux8664.zip
, in this example). You need to copy this file into the:
/operator
directory to build the Operator image and push the image to the image registry. See "Build the Operator image" for details.
/ttimage
directory to build the TimesTen image and push the image to the image registry. See "Build the TimesTen image" for details.
You successfully downloaded and unpacked the TimesTen Operator distribution.
The Operator runs by using a Kubernetes service account. This service account needs permissions and privileges in your namespace. These permissions and privileges are granted through a role. The s
ervice_account.yaml
file adds the service account and the role to your namespace, and grants the service account the privileges that are specified in the role. The service_account.yaml
file is provided in the operator.zip
file you previously unpacked.
Note:
The provided role gives thetimestenclassic-operator
broad permissions within your namespace. Examine the permissions provided in the service_account.yaml
file to see if the permissions need to be modified. If so, modify the permissions before running the commands in this example.Perform these steps:
Navigate to the kube_files
/deploy
directory.
% cd kube_files/deploy
Create the service account.
% kubectl create -f service_account.yaml role.rbac.authorization.k8s.io/timestenclassic-operator created serviceaccount/timestenclassic-operator created rolebinding.rbac.authorization.k8s.io/timestenclassic-operator created
The service_account.yaml
file created the timestenclassic-operator
service account and the timestenclassic-operator
role in your namespace, and granted the service account the privileges specified in the role.
Navigate to the kube_files
/deploy
directory, and then use the kubectl
create
command to create the TimesTenClassic customized resource definition (CRD) in your Kubernetes cluster.
% cd kube_files/deploy
% kubectl create -f crd.yaml
customresourcedefinition.apiextensions.k8s.io/
timestenclassics.timesten.oracle.com created
You successfully added the TimesTenClassic object type to your Kubernetes cluster.
Kubernetes Operators are Pods that run a customized image. Before you can run the Operator, you must build this image and push it to your image registry.
The files needed to create the image are provided in the kube_files
/operator
directory (part of the ZIP file you previously unpacked). In the kube_files
/operator
directory are the Dockerfile
and the binaries needed to create the Operator image.
To build the Operator image and push it to your registry, perform these steps:
Navigate to the kube_files
/operator
directory, and copy the TimesTen distribution into it. This example assumes you downloaded the timesten1814110.server.linux8664.zi
p
distribution into the installation_dir
directory. See "Download the TimesTen Operator" for information. Then, verify the timesten1814110.server.linux8664.zi
p
file is in the kube_files
/operator
directory.
% cd kube_files/operator % cp installation_dir/timesten1814110.server.linux8664.zip . % ls -a Dockerfile timesten1814110.server.linux8664.zip timestenclassic-operator
Navigate to the kube_files
/operator
directory (if not already in this directory) and use the docker
command to build the Operator image. You can choose any name for ttclassic-operator:3
(represented in bold in this example). Note that the output may change from release to release.
% cd kube_files/operator % docker build -t ttclassic-operator:3 . Sending build context to Docker daemon 478.6MB Step 1/7 : FROM container-registry.oracle.com/os/oraclelinux:7 ---> d788eca028a0 Step 2/7 : ARG TT_DISTRO=timesten1814110.server.linux8664.zip ---> Using cache ---> a259a93fe906 Step 3/7 : RUN yum -y install openssl unzip && /usr/sbin/useradd -d /tt-operator -m -u 1001 -s /bin/nologin -U tt-operator ---> Using cache ---> e3f1427246ab Step 4/7 : COPY --chown=tt-operator:tt-operator timestenclassic-operator /usr/local/bin/timestenclassic-operator ---> Using cache ---> 6ccad53230f0 Step 5/7 : COPY --chown=tt-operator:tt-operator $TT_DISTRO /tt-operator/ $TT_DISTRO ---> 5cd31705485a Step 6/7 : USER tt-operator ---> Running in 6a773ddac5dd Removing intermediate container 6a773ddac5dd ---> 875ee38ebc75 Step 7/7 : ENTRYPOINT ["/usr/local/bin/timestenclassic-operator"] ---> Running in fed0f6c94c2f Removing intermediate container fed0f6c94c2f ---> 10dde79e1617 Successfully built 10dde79e1617 Successfully tagged ttclassic-operator:3
Use the docker
command to tag the Operator image.
Replace phx.ocir.io/youraccount
with the location of your image registry. (phx.ocir.io/youraccount
is represented in bold in this example.)
Replace ttclassic-operator:3
with the name you chose in the previous step. (ttclassic-operator
is represented in bold in this example.)
% docker tag ttclassic-operator:3 phx.ocir.io/youraccount/ttclassic-operator:3
Use the docker
command to push the Operator image to your registry.
Replace phx.ocir.io/youraccount
with the location of your image registry. (phx.ocir.io/youraccount
is represented in bold in this example.)
Replace ttclassic-operator:3
with the name you chose in the previous steps. (ttclassic-operator:3
is represented in bold in this example.)
% docker push phx.ocir.io/youraccount/ttclassic-operator:3 The push refers to repository [phx.ocir.io/youraccount/ttclassic-operator] 46458e9fc890: Pushed 471a399f0540: Pushed 9e51a2b82af3: Pushed 2f915858a916: Layer already exists 3: digest: sha256:9b941f12e3d52298b9b38f7766ddcdfb1d011857a990ff01a8adafd32f3d3e8d size: 1166
You successfully built the Operator image and pushed it to your image registry.
To deploy the Operator, you first customize it for your namespace and then deploy it. As a final step, you can verify the Operator is running. See "Deploying the Operator" for information.
To customize the Operator for your namespace, navigate to the kube_files
/deploy
directory, and edit the operator.yaml
file. This file is provided in the distribution that you previously unpacked. See "Downloading TimesTen and the TimesTen Operator" for details.
Modify these fields represented in bold (in the operator.yaml
file below):
replicas:
1
Replace 1
with the number of copies of the Operator that you would like to run. 1
is acceptable for development and testing. However, you can run more than one replica for high availability purposes.
Replace sekret
with the name of the image pull secret that Kubernetes uses to pull images from your registry.
Replace phx.ocir.io/youraccount
with the location of your image registry.
Replace ttclassic-operator:3
with the name you chose in the previous steps.
% cd kube_files/deploy % vi operator.yaml apiVersion: apps/v1 kind: Deployment metadata: name: timestenclassic-operator spec: replicas: 1 selector: matchLabels: name: timestenclassic-operator template: metadata: labels: name: timestenclassic-operator spec: serviceAccountName: timestenclassic-operator imagePullSecrets: - name: sekret containers: - name: timestenclassic-operator image: phx.ocir.io/youraccount/ttclassic-operator:3 command: - timestenclassic-operator imagePullPolicy: Always env: - name: WATCH_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: OPERATOR_NAME value: "timestenclassic-operator" - name: GODEBUG value: "x509ignoreCN=0"
Use the kubectl
create
command to define the Operator to your namespace and to start the Operator.
% kubectl create -f operator.yaml deployment.apps/timestenclassic-operator created
You deployed the Operator. The Operator should now be running.
Use the kubectl
get
pods
command to verify the Operator is running. If the STATUS
field has a value of Running
, the Operator is running.
% kubectl get pods NAME READY STATUS RESTARTS AGE timestenclassic-operator-f84766548-5bzch 1/1 Running 0 37s
You verified that the Operator is running.
Before you can start TimesTen in your Kubernetes cluster, you must first package TimesTen as a container image and then push the image to your image registry. The files that you need to do this are provided in the kube_files
directory tree. See "Building the TimesTen image" for information.
To create the TimesTen container image, perform these steps:
Navigate to the kube_files
/ttimage
directory, and copy the TimesTen distribution into it. This example assumes you downloaded the timesten1814110.server.linux8664.zi
p
distribution into the installation_dir
directory. See "Download the TimesTen Operator" for information. Then, verify the timesten1814110.server.linux8664.zi
p
file is in the kube_files
/ttimage
directory.
% cd kube_files/ttimage % cp installation_dir/timesten1814110.server.linux8664.zip . % ls *.zip timesten1814110.server.linux8664.zip
Navigate to the kube_files
/ttimage
directory (if not already in this directory). Edit the Dockerfile
, replacing timesten1814110.server.linux8664.zip
with the name of your TimesTen full distribution. If your TimesTen distribution is timesten1814110.server.linux8664.zip
, no modification is necessary. If not, the modification you need to make is represented in bold. Note: The TimesTen full distribution must be 18.1.4.11.0
or later.
% cd kube_files/ttimage % vi Dockerfile # Copyright (c) 2019, 2021, Oracle and/or its affiliates. FROM container-registry.oracle.com/os/oraclelinux:7 ARG TT_DISTRO=timesten1814110.server.linux8664.zip RUN yum -y install tar gzip vim curl unzip libaio util-linux RUN groupadd -g 333 oracle RUN useradd -M -d /tt/home/oracle -s /bin/bash -u 333 -g oracle oracle RUN install -d -m 0750 -o oracle -g oracle /home/oracle COPY --chown=oracle:oracle $TT_DISTRO /home/oracle/ COPY --chown=oracle:oracle .bashrc starthost.pl .ttdrop .ttdotversion agent2 create1.sql create2.sql get1.sql repcreate.sql repduplicate.sql runsql.sql pausecg.sql /home/oracle/ # Uncomment the following line if you are using the optional non-root installation procedure. # USER 333 ENTRYPOINT "/home/oracle/starthost.pl"
Use the docker
command to build the TimesTen container image. Replace tt1814110
with a name of your choosing (represented in bold, in the docker
build
command below). Note that the output may change from release to release.
% docker build -t tt1814110:3 . Sending build context to Docker daemon 445.8MB Step 1/9 : FROM container-registry.oracle.com/os/oraclelinux:7 ---> d788eca028a0 Step 2/9 : ARG TT_DISTRO=timesten1814110.server.linux8664.zip ---> Using cache ---> a259a93fe906 Step 3/9 : RUN yum -y install tar gzip vim curl unzip libaio util-linux ---> Using cache ---> ac676b5376f3 Step 4/9 : RUN groupadd -g 333 oracle ---> Using cache ---> ce16920f085c Step 5/9 : RUN useradd -M -d /tt/home/oracle -s /bin/bash -u 333 -g oracle oracle ---> Using cache ---> 0319814aca1c Step 6/9 : RUN install -d -m 0750 -o oracle -g oracle /home/oracle ---> Using cache ---> c8612b53398a Step 7/9 : COPY --chown=oracle:oracle $TT_DISTRO /home/oracle/ ---> 31cae98b71fd Step 8/9 : COPY --chown=oracle:oracle .bashrc starthost.pl .ttdrop .ttdotversion agent2 create1.sql create2.sql get1.sql repcreate.sql repduplicate.sql runsql.sql pausecg.sql /home/oracle/ ---> e50eb99c9b54 Step 9/9 : ENTRYPOINT "/home/oracle/starthost.pl" ---> Running in 0b41efd38837 Removing intermediate container 0b41efd38837 ---> 171245e546d5 Successfully built 171245e546d5 Successfully tagged tt1814110:3
Use the docker
command to tag the TimesTen container image. Replace the following, represented in bold, in the docker
tag
command below.
tt1814110:3
with the name you chose in the previous step.
p
hx.ocir.io/youraccount
with the location of your image registry.
% docker tag tt1814110:3 phx.ocir.io/youraccount/tt1814110:3
Use the docker
command to push the TimesTen container image to your registry. Replace the following, represented in bold, in the docker
push
command below.
p
hx.ocir.io/youraccount
with the location of your image registry.
tt1814110:3
with the name you chose previously.
% docker push phx.ocir.io/youraccount/tt1814110:3 The push refers to repository [phx.ocir.io/youraccount/tt1814110] 97a0f250b2fe: Pushed 650b003a3ad4: Pushed b8de51528854: Pushed 62192d26e325: Pushed 7dfe13e9b5a4: Pushed d8570fce965c: Pushed 2f915858a916: Layer already exists 3: digest: sha256:a6ac313394229eb2256d4a56fbcd8e2eda50ea2cc21991fa76f11701f2299710 size: 1788
You successfully built the TimesTen container image. It is pushed to your image registry.
This section creates the sample
ConfigMap. This ConfigMap contains the db.ini
, the adminUser
, and the schema.sql
metadata files. This ConfigMap will be referenced when you define the TimesTenClassic object. See "Understanding the configuration metadata and the Kubernetes facilities" for information on the configuration files and the ConfigMap facility.
On your Linux development host:
From the directory of your choice, create an empty subdirectory for the metadata files. This example creates the cm_sample
subdirectory. (The cm_sample
directory is used in the remainder of this example to denote this directory.)
% mkdir -p cm_sample
Navigate to the ConfigMap directory.
% cd cm_sample
Create the db.ini
file in this ConfigMap directory (cm_sample
, in this example). In this db.ini
file, define the PermSize
and DatabaseCharacterSet
connection attributes.
vi db.ini
PermSize=200 DatabaseCharacterSet=AL32UTF8
Create the adminUser
file in this ConfigMap directory (cm_sample
in this example). In this adminUser
file, create the scott
user with the tiger
password.
vi adminUser
scott/tiger
Create the schema.sql
file in this ConfigMap directory (cm_sample
in this example). In this schema.sql
file, define the s
sequence and the emp
table for the scott
user. The Operator will automatically initialize your database with these object definitions.
vi schema.sql
create sequence scott.s; create table scott.emp ( id number not null primary key, name char(32) );
Create the ConfigMap. The files in the cm_sample
directory are included in the ConfigMap and, later, will be available in the TimesTen containers.
In this example:
The name of the ConfigMap is sample
. Replace sample
with a name of your choosing. (sample
is represented in bold in this example.)
This example uses cm_sample
as the directory where the files that will be copied into the ConfigMap reside. If you use a different directory, replace cm_sample
with the name of your directory. (cm_sample
is represented in bold in this example.)
Use the kubectl
create
command to create the ConfigMap:
% kubectl create configmap sample --from-file=cm_sample configmap/sample created
You successfully created and deployed the sample
ConfigMap.
Use the kubectl
describe
command to verify the contents of the ConfigMap. (sample
, in this example.)
% kubectl describe configmap sample Name: sample Namespace: mynamespace Labels: <none> Annotations: <none> Data ==== adminUser: ---- scott/tiger db.ini: ---- PermSize=200 DatabaseCharacterSet=AL32UTF8 schema.sql: ---- create sequence scott.s; create table scott.emp ( id number not null primary key, name char(32) ); Events: <none>
This section creates the TimesTenClassic object. See "Defining and creating the TimesTenClassic object" and "The TimesTenClassic object type" for detailed information on the TimesTenClassic object.
Perform these steps:
Create an empty YAML file. You can choose any name, but you may want to use the same name you used for the name of the TimesTenClassic object. (In this example, sample
.) The YAML file contains the definitions for the TimesTenClassic object. See "TimesTenClassicSpecSpec" for information on the fields that you must specify in this YAML file as well as the fields that are optional.
In this example, replace the following. (The values you can replace are represented in bold.)
name
: Replace sample
with the name of your TimesTenClassic object.
storageClassName
: Replace oci
with the name of the storage class used to allocate PersistentVolumes to hold TimesTen.
storageSize
: Replace 250G
with the amount of storage that should be requested for each Pod to hold TimesTen. Note: This example assumes a production environment and uses a value of 250G
for storageSize
. For demonstration purposes, a value of 50G
is adequate. See the storageSize
and the logStorageSize
entries in the Table 11-3, "TimesTenClassicSpecSpec" for information.
image
: Replace phx.ocir.io/youraccount
/tt1814110:3
with the location of the image registry (phx.ocir.io
/
youraccount
) and the image containing TimesTen (tt1814110:3
).
imagePullSecret
: Replace sekret
with the image pull secret that Kubernetes should use to fetch the TimesTen image.
dbConfigMap
: This example uses one ConfigMap (called sample
) for the db.ini
, the adminUser
, and the schema.sql
metadata files. This ConfigMap will be included in the ProjectedVolume. This volume is mounted as /ttconfig
in the TimesTen containers. See "Using ConfigMaps and Secrets" and "Example using one ConfigMap" for information on ConfigMaps.
% vi sample.yaml apiVersion: timesten.oracle.com/v1 kind: TimesTenClassic metadata: name: sample spec: ttspec: storageClassName: oci storageSize: 250G image: phx.ocir.io/youraccount/tt1814110:3 imagePullSecret: sekret dbConfigMap: - sample
Use the kubectl
create
command to create the TimesTenClassic object from the contents of the YAML file (in this example, sample.yaml
). Doing so begins the process of deploying your active standby pair of TimesTen databases in the Kubernetes cluster.
% kubectl create -f sample.yaml configmap/sample created timestenclassic.timesten.oracle.com/sample created
You successfully created the TimesTenClassic object in the Kubernetes cluster. The process of deploying your TimesTen databases begins, but is not yet complete.
Use the kubectl
get
and the kubectl
describe
commands to monitor the progress of the active standby pair as it is provisioned.
Note:
For thekubectl
get
timestenclassic
and kubectl
describe
timestenclassic
commands, you can alternatively specify kubectl
get
ttc
and kubectl
describe
ttc
respectively. timestenclassic
and ttc
are synonymous when used in these commands, and return the same results. The first kubectl
get
and the first kubectl
describe
examples in this appendix use timestenclassic
. The remaining examples in this appendix use ttc
for simplicity.Use the kubectl
get
command and review the STATE
field. Observe the value is Initializing
. The active standby pair provisioning has begun, but is not yet complete.
% kubectl get timestenclassic sample NAME STATE ACTIVE AGE sample Initializing None 11s
Use the kubectl
describe
command to view the initial provisioning in detail.
% kubectl describe timestenclassic sample Name: sample Namespace: mynamespace Labels: <none> Annotations: <none> API Version: timesten.oracle.com/v1 Kind: TimesTenClassic Metadata: Creation Timestamp: 2020-05-31T15:35:12Z Generation: 1 Resource Version: 20231755 Self Link: /apis/timesten.oracle.com/v1/namespaces/mynamespace/timestenclassics/sample UID: 517a8646-a354-11ea-a9fb-0a580aed5e4a Spec: Ttspec: Db Config Map: sample Image: phx.ocir.io/youraccount/tt1814110:3 Image Pull Policy: Always Image Pull Secret: sekret Storage Class Name: oci Storage Size: 250G Status: Active Pods: None High Level State: Initializing Last Event: 3 Pod Status: Cache Status: Cache Agent: Down Cache UID Pwd Set: false N Cache Groups: 0 Db Status: Db: Unknown Db Id: 0 Db Updatable: Unknown Initialized: true Pod Status: Agent: Down Last Time Reachable: 0 Pod IP: Pod Phase: Pending Replication Status: Last Time Rep State Changed: 0 Rep Agent: Down Rep Peer P State: Unknown Rep Scheme: Unknown Rep State: Unknown Times Ten Status: Daemon: Down Instance: Unknown Release: Unknown Admin User File: false Cache User File: false Cg File: false High Level State: Down Intended State: Active Name: sample-0 Schema File: false Cache Status: Cache Agent: Down Cache UID Pwd Set: false N Cache Groups: 0 Db Status: Db: Unknown Db Id: 0 Db Updatable: Unknown Initialized: true Pod Status: Agent: Down Last Time Reachable: 0 Pod IP: Pod Phase: Pending Replication Status: Last Time Rep State Changed: 0 Rep Agent: Down Rep Peer P State: Unknown Rep Scheme: Unknown Rep State: Unknown Times Ten Status: Daemon: Down Instance: Unknown Release: Unknown Admin User File: false Cache User File: false Cg File: false High Level State: Unknown Intended State: Standby Name: sample-1 Schema File: false Rep Create Statement: create active standby pair "sample" on "sample-0.sample.mynamespace.svc.cluster.local", "sample" on "sample-1.sample.mynamespace.svc.cluster.local" NO RETURN store "sample" on "sample-0.sample.mynamespace.svc.cluster.local" PORT 4444 FAILTHRESHOLD 0 store "sample" on "sample-1.sample.mynamespace.svc.cluster.local" PORT 4444 FAILTHRESHOLD 0 Rep Port: 4444 Status Version: 1.0 Events: Type Reason Age From Message ---- ------ ---- ---- ------- - Create 50s ttclassic Secret tt517a8646-a354-11ea-a9fb-0a580aed5e4a created - Create 50s ttclassic Service sample created - Create 50s ttclassic StatefulSet sample created
Use the kubectl
get
command again to see if value of the STATE
field has changed. In this example, the value is Normal
, indicating the active standby pair of databases are now provisioned and the process is complete.
% kubectl get ttc sample NAME STATE ACTIVE AGE sample Normal sample-0 3m5s
Use the kubectl
describe
command again to view the active standby pair provisioning in detail.
Note: In this example, the now Normal
line displays on its own line. In the actual output, this line does not display as its own line, but at the end of the StateChange
previous line.
% kubectl describe ttc sample Name: sample Namespace: mynamespace Labels: <none> Annotations: <none> API Version: timesten.oracle.com/v1 Kind: TimesTenClassic Metadata: Creation Timestamp: 2020-05-31T15:35:12Z Generation: 1 Resource Version: 20232668 Self Link: /apis/timesten.oracle.com/v1/namespaces/mynamespace/timestenclassics/sample UID: 517a8646-a354-11ea-a9fb-0a580aed5e4a Spec: Ttspec: Db Config Map: sample Image: phx.ocir.io/youraccount/tt1814110:3 Image Pull Policy: Always Image Pull Secret: sekret Storage Class Name: oci Storage Size: 250G Status: Active Pods: sample-0 High Level State: Normal Last Event: 35 Pod Status: Cache Status: Cache Agent: Not Running Cache UID Pwd Set: true N Cache Groups: 0 Db Status: Db: Loaded Db Id: 26 Db Updatable: Yes Initialized: true Pod Status: Agent: Up Last Time Reachable: 1590939597 Pod IP: 192.0.2.1 Pod Phase: Running Replication Status: Last Time Rep State Changed: 0 Rep Agent: Running Rep Peer P State: start Rep Scheme: Exists Rep State: ACTIVE Times Ten Status: Daemon: Up Instance: Exists Release: 18.1.4.11.0 Admin User File: true Cache User File: false Cg File: false High Level State: Healthy Intended State: Active Name: sample-0 Schema File: true Cache Status: Cache Agent: Not Running Cache UID Pwd Set: true N Cache Groups: 0 Db Status: Db: Loaded Db Id: 26 Db Updatable: No Initialized: true Pod Status: Agent: Up Last Time Reachable: 1590939597 Pod IP: 192.0.2.2 Pod Phase: Running Replication Status: Last Time Rep State Changed: 1590939496 Rep Agent: Running Rep Peer P State: start Rep Scheme: Exists Rep State: STANDBY Times Ten Status: Daemon: Up Instance: Exists Release: 18.1.4.11.0 Admin User File: true Cache User File: false Cg File: false High Level State: Healthy Intended State: Standby Name: sample-1 Schema File: true Rep Create Statement: create active standby pair "sample" on "sample-0.sample.mynamespace.svc.cluster.local", "sample" on "sample-1.sample.mynamespace.svc.cluster.local" NO RETURN store "sample" on "sample-0.sample.mynamespace.svc.cluster.local" PORT 4444 FAILTHRESHOLD 0 store "sample" on "sample-1.sample.mynamespace.svc.cluster.local" PORT 4444 FAILTHRESHOLD 0 Rep Port: 4444 Status Version: 1.0 Events: Type Reason Age From Message ---- ------ ---- ---- ------- - Create 4m43s ttclassic Secret tt517a8646-a354-11ea-a9fb-0a580aed5e4a created - Create 4m43s ttclassic Service sample created - Create 4m43s ttclassic StatefulSet sample created - StateChange 3m47s ttclassic Pod sample-0 Daemon Unknown - StateChange 3m47s ttclassic Pod sample-0 CacheAgent Unknown - StateChange 3m47s ttclassic Pod sample-0 RepAgent Unknown - StateChange 3m47s ttclassic Pod sample-1 Daemon Unknown - StateChange 3m47s ttclassic Pod sample-1 CacheAgent Unknown - StateChange 3m47s ttclassic Pod sample-1 RepAgent Unknown - StateChange 3m26s ttclassic Pod sample-0 Agent Up - StateChange 3m26s ttclassic Pod sample-0 Release 18.1.4.11.0 - StateChange 3m26s ttclassic Pod sample-0 Daemon Down - StateChange 3m26s ttclassic Pod sample-1 Agent Up - StateChange 3m26s ttclassic Pod sample-1 Release 18.1.4.11.0 - StateChange 3m26s ttclassic Pod sample-1 Daemon Down - StateChange 3m26s ttclassic Pod sample-0 Daemon Up - StateChange 3m25s ttclassic Pod sample-1 Daemon Up - StateChange 2m13s ttclassic Pod sample-0 RepState IDLE - StateChange 2m13s ttclassic Pod sample-0 Database Updatable - StateChange 2m13s ttclassic Pod sample-0 CacheAgent Not Running - StateChange 2m13s ttclassic Pod sample-0 RepAgent Not Running - StateChange 2m13s ttclassic Pod sample-0 RepScheme None - StateChange 2m13s ttclassic Pod sample-0 Database Loaded - StateChange 2m11s ttclassic Pod sample-0 RepAgent Running - StateChange 2m10s ttclassic Pod sample-0 RepScheme Exists - StateChange 2m10s ttclassic Pod sample-0 RepState ACTIVE - StateChange 113s ttclassic Pod sample-1 Database Loaded - StateChange 113s ttclassic Pod sample-1 Database Not Updatable - StateChange 113s ttclassic Pod sample-1 CacheAgent Not Running - StateChange 113s ttclassic Pod sample-1 RepAgent Not Running - StateChange 113s ttclassic Pod sample-1 RepScheme Exists - StateChange 113s ttclassic Pod sample-1 RepState IDLE - StateChange 106s ttclassic Pod sample-1 RepAgent Running - StateChange 101s ttclassic Pod sample-1 RepState STANDBY - StateChange 101s ttclassic TimesTenClassic was Initializing, now Normal
Your active standby pair of TimesTen databases are successfully deployed (as indicated by Normal
.) There are two TimesTen databases, configured as an active standby pair. One database is active. (In this example, sample-0
is the active database, as indicated by Rep
State
ACTIVE
). The other database is standby. (In this example, sample-1
is the standby database as indicated by Rep
State
STANDBY
). The active database can be modified and queried. Changes made on the active database are replicated to the standby database. If the active database fails, the Operator automatically promotes the standby database to be the active. The formerly active database will be repaired or replaced, and will then become the standby.
Use the kubectl
describe
commands to verify the underlying objects.
StatefulSet:
% kubectl get statefulset sample NAME READY AGE sample 2/2 8m21s
Service:
% kubectl get service sample NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample ClusterIP None <none> 6625/TCP 9m28s
Pods:
% kubectl get pods NAME READY STATUS RESTARTS AGE sample-0 2/2 Running 0 10m sample-1 2/2 Running 0 10m timestenclassic-operator-5d7dcc7948-8mnz4 1/1 Running 0 11h
PersistentVolumeClaims (PVCs):
% kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE tt-persistent-sample-0 Bound ocid1.volume.oc1.phx.abyhqljrbxcgzyixa4pmmcwiqxgqclc7gxvdnoty367w2qn26tij6kfpx 6qq 250Gi RWO oci 10m tt-persistent-sample-1 Bound ocid1.volume.oc1.phx.abyhqljtt4qxxoj5jqiskriskh66hakaw326rbza4uigmuaezdnu53qhh oaa 250Gi RWO oci 10m
You can run the kubectl
exec
command to invoke shells in your Pods and control TimesTen, which is running in those Pods. TimesTen runs in the Pods as the oracle
user. Once you have established a shell in the Pod, use the su - oracle
command to switch to the oracle
user. After you switch to the oracle
user, verify you can connect to the sample
database, and that the information from the metadata files is correct. You can optionally run queries against the database or any other operations.
Establish a shell in the Pod and switch to the oracle
user
% kubectl exec -it sample-0 -c tt -- /usr/bin/su - oracle
Connect to the sample
database. Verify the information in the metadata files is in the database correctly. For example, attempt to connect to the database as the scott
user. Check that the PermSize
value of 200
is correct. Check that the scott.emp
table exists.
% ttIsql sample Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. Type ? or "help" for help, type "exit" to quit ttIsql. connect "DSN=sample"; Connection successful: DSN=sample;UID=oracle;DataStore=/tt/home/oracle/datastore/sample; DatabaseCharacterSet=AL32UTF8;ConnectionCharacterSet=US7ASCII;PermSize=200; DDLReplicationLevel=3; (Default setting AutoCommit=1) Command> connect adding "uid=scott;pwd=tiger" as scott; Connection successful: DSN=sample;UID=scott;DataStore=/tt/home/oracle/datastore/sample; DatabaseCharacterSet=AL32UTF8;ConnectionCharacterSet=US7ASCII;PermSize=200; DDLReplicationLevel=3; (Default setting AutoCommit=1) scott: Command> tables; SCOTT.EMP 1 table found.
This example simulates a failure of the active TimesTen database. This is for demonstration purposes only. Do not do this in a production environment.
Use the kubectl
delete
pod
command to delete the active database (sample-0
in this case)
% kubectl delete pod sample-0
Use the kubectl
describe
command to observe how the Operator recovers from the failure. The Operator promotes the standby database (sample-1
) to be active. Any applications that were connected to the sample-0
database are automatically reconnected to the sample-1
database by TimesTen. After a brief outage, the applications can continue to use the database. See "Monitoring the health of the active standby pair of databases" for information on the health and states of the active standby pair.
Note: In this example, the text for the Message
column displays on two lines for three state changes. However, the actual output displays on one line for each of these three state changes.
% kubectl describe ttc sample Name: sample ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- - StateChange 2m1s ttclassic TimesTenClassic sample: was Normal, now ActiveDown - StateChange 115s ttclassic Pod sample-1 Database Updatable: Yes - StateChange 115s ttclassic TimesTenClassic sample:was ActiveDown, now StandbyDown - StateChange 115s ttclassic Pod sample-1 RepState ACTIVE - StateChange 110s ttclassic Pod sample-0 High Level State Unknown - StateChange 63s ttclassic Pod sample-0 Pod Phase Running - StateChange 63s ttclassic Pod sample-0 Agent Up - StateChange 63s ttclassic Pod sample-0 Instance Exists - StateChange 63s ttclassic Pod sample-0 Daemon Up - StateChange 63s ttclassic Pod sample-0 Database None - StateChange 42s ttclassic Pod sample-0 Database Loaded - StateChange 42s ttclassic Pod sample-0 Database Updatable: No - StateChange 42s ttclassic Pod sample-0 RepAgent Running - StateChange 42s ttclassic Pod sample-0 CacheAgent Not Running - StateChange 42s ttclassic Pod sample-0 RepScheme Exists - StateChange 42s ttclassic Pod sample-0 RepState IDLE - StateChange 36s ttclassic Pod sample-0 High Level State Healthy - StateChange 36s ttclassic Pod sample-0 RepState STANDBY - StateChange 36s ttclassic TimesTenClassic sample:was StandbyDown, now Normal
Kubernetes has automatically respawned a new sample-0
Pod to replace the Pod you deleted. The Operator configured TimesTen inside of that Pod, bringing the database in the Pod up as the new standby database. The replicated pair of databases are once again functionally normally.
This example concludes with deleting the databases and all objects associated with TimesTenClassic. These steps are used for example purposes only. Doing these steps results in the termination of the Pods that are running the TimesTen databases as well as the deletion of the TimesTen databases themselves.
Delete the ConfigMap object. (sample
, in this example.)
% kubectl delete configmap sample configmap "sample" deleted
Delete the TimesTenClassic object and the underlying objects.
% kubectl delete -f sample.yaml timestenclassic.timesten.oracle.com "sample" deleted
Verify the Pods that were running the TimesTen databases no longer exist.
% kubectl get pods NAME READY STATUS RESTARTS AGE timestenclassic-operator-5d7dcc7948-8mnz4 1/1 Running 0 5d23h
Delete the persistent storage used to hold your databases. You have to do this manually.
% kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE tt-persistent-sample-0 Bound ... tt-persistent-sample-1 Bound ... % kubectl delete pvc tt-persistent-sample-0 persistentvolumeclaim "tt-persistent-sample-0" deleted % kubectl delete pvc tt-persistent-sample-1 persistentvolumeclaim "tt-persistent-sample-1" deleted
If you no longer want to run the Operator, you can stop it. Navigate to the /deplo
y directory (kube_files
/deploy
, in this example) and use the kubectl
delete
command to stop the operator.
% cd kube_files/deploy
% kubectl delete -f operator.yaml
deployment.apps "timestenclassic-operator" deleted