This chapter discusses the process for deploying active standby pairs of TimesTen databases. It describes the process for creating TimesTenClassic objects in your environment. It also provides examples that demonstrate how to monitor the provisioning of the active standby pair of TimesTen databases. The chapter concludes with examples that show you how to connect to the database and run operations in it.
Topics:
The TimesTen Operator extends the Kubernetes API to provide the TimesTenClassic object type. This type provides the definitions you need to successfully deploy your TimesTen databases to the Kubernetes cluster. You customize these definitions for your particular environment. Specifically, you create a YAML file and, in it, you specify the required TimesTenClassic definitions for the TimesTenClassic object. By assigning values to the fields of these definitions, you customize and define your deployment environment. For example, when you supply the oci
value for the storageClassName
field, you are telling the Operator the name of the storage class you want to use. See Chapter 11, "The TimesTenClassic Object Type" for the object definitions, and the fields that you define in your YAML file.
Examples of the YAML file were introduced previously when discussing ConfigMaps and Secrets, an init container, and other configuration options. (See "Using ConfigMaps and Secrets" for information on ConfigMaps and Secrets. Also see "Using an init container" and "Additional configuration options" for other configuration options.) However, "Defining and creating the TimesTenClassic object" shows you how to define the TimesTenClassic object in detail.
After specifying your configuration in the YAML file, you use the kubectl
create
command from your Linux development host to create the corresponding TimesTenClassic object in your cluster. After you issue this command, the process for deploying your active standby pair of TimesTen databases begins. You can view this process by issuing kubectl
get
and kubectl
describe
commands, such as, kubectl
get
pods
and kubectl
describe
timestenclassic
. Once your databases are deployed, you can then connect to your active database, issue queries, and perform other operations to verify your database is working as it should.
Defining your environment involves creating TimesTenClassic objects with attributes customized for your environment. The fields include the name of the image pull secret, the name of your TimesTen image, and the other definitions required to successfully deploy your TimesTen databases. See "The TimesTenClassic object type" for information on defining objects of type TimesTenClassic.
Perform these steps to define and create the TimesTenClassic object:
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. (This example assumes a production environment and uses 250G for storage. For demonstration purposes, you can use 50G of storage. 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 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.
You can use various kubectl
commands to monitor the progress of the active standby pair deployment. After the deployment is complete and successful, you can connect to the database and run operations in it to verify it is working as it should.
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 chapter use timestenclassic
. The remaining examples in this book 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.
The Operator creates other underlying objects automatically. Verify that these objects are created.
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.