Outcomes
You should be able to deploy a database server, and access it indirectly through a Kubernetes service, and also directly pod-to-pod for troubleshooting.
As the student user on the workstation machine, use the lab command to prepare your system for this exercise.
This command ensures that all resources are available for this exercise.
It also creates the deploy-services project and the /home/student/DO180/labs/deploy-services/resources.txt file.
The resources.txt file contains some commands that you use during the exercise.
You can use the file to copy and paste these commands.
[student@workstation ~]$ lab start deploy-services
Note
It is safe to ignore pod security warnings for exercises in this course. OpenShift uses the Security Context Constraints controller to provide safe defaults for pod security.
Instructions
Log in to the OpenShift cluster as the
developeruser with thedeveloperpassword. Use thedeploy-servicesproject.Log in to the OpenShift cluster.
[student@workstation ~]$
oc login -u developer -p developer\https://api.ocp4.example.com:6443Login successful. ...output omitted...Set the
deploy-servicesproject as the active project.[student@workstation ~]$
oc project deploy-services...output omitted...
Use the
registry.ocp4.example.com:8443/rhel8/mysql-80container image to create a MySQL deployment nameddb-pod. Add the missing environment variables for the pod to run.Create the
db-poddeployment.[student@workstation ~]$
oc create deployment db-pod --port 3306 \ --image registry.ocp4.example.com:8443/rhel8/mysql-80deployment.apps/db-pod createdAdd the environment variables.
[student@workstation ~]$
oc set env deployment/db-pod \ MYSQL_USER=user1 \ MYSQL_PASSWORD=mypa55w0rd \ MYSQL_DATABASE=itemsdeployment.apps/db-pod updatedConfirm that the pod is running.
[student@workstation ~]$
oc get podsNAME READY STATUS RESTARTS AGE db-pod-6ccc485cfc-vrc4r 1/1 Running 0 2m30sYour pod name might differ from the previous output.
Expose the
db-poddeployment to create a ClusterIP service.View the deployment for the pod.
[student@workstation ~]$
oc get deploymentNAME READY UP-TO-DATE AVAILABLE AGE db-pod 1/1 1 1 3m36sExpose the
db-poddeployment to create a service.[student@workstation ~]$
oc expose deployment/db-podservice/db-pod exposed
Validate the service. Confirm that the service selector matches the label on the pod. Then, confirm that the
db-podservice endpoint matches the IP of the pod.Identify the selector for the
db-podservice. Use theoc get service commandwith the-o wideoption to retrieve the selector that the service uses.[student@workstation ~]$
oc get service db-pod -o wideNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR db-pod ClusterIP 172.30.108.92 <none> 3306/TCP 108sapp=db-podThe selector shows an
app=db-podkey:value pair.Capture the name of the pod in a variable.
[student@workstation ~]$
PODNAME=$(oc get pods\-o jsonpath='{.items[0].metadata.name}')Query the label on the pod.
[student@workstation ~]$
oc get pod $PODNAME --show-labelsNAME READY STATUS RESTARTS AGE LABELS db-pod-6ccc485cfc-vrc4r 1/1 Running 0 6m50sapp=db-pod...Notice that the label list includes the
app=db-podkey-value pair, which is the selector for thedb-podservice.Retrieve the endpoints for the
db-podservice.[student@workstation ~]$
oc get endpointsNAME ENDPOINTS AGE db-pod10.8.0.85:33064m38sYour endpoints values might differ from the previous output.
Verify that the service endpoint matches the
db-podIP address. Use theoc get podscommand with the-o wideoption to view the pod IP address.[student@workstation ~]$
oc get pods -o wideNAME READY STATUS RESTARTS AGE IP ... db-pod-6ccc485cfc-vrc4r 1/1 Running 0 54m10.8.0.85...The service endpoint resolves to the IP address that is assigned to the pod.
Delete and then re-create the
db-poddeployment. Confirm that thedb-podservice endpoint automatically resolves to the IP address of the new pod.Delete the
db-poddeployment.[student@workstation ~]$
oc delete deployment.apps/db-poddeployment.apps "db-pod" deletedVerify that the service still exists without the deployment.
[student@workstation ~]$
oc get serviceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE db-pod ClusterIP 172.30.108.92 <none> 3306/TCP 9m53sThe list of endpoints for the service is now empty.
[student@workstation ~]$
oc get endpointsNAME ENDPOINTS AGE db-pod <none> 12mRe-create the
db-poddeployment.[student@workstation ~]$
oc create deployment db-pod --port 3306 \ --image registry.ocp4.example.com:8443/rhel8/mysql-80deployment.apps/db-pod createdAdd the environment variables.
[student@workstation ~]$
oc set env deployment/db-pod \ MYSQL_USER=user1 \ MYSQL_PASSWORD=mypa55w0rd \ MYSQL_DATABASE=itemsdeployment.apps/db-pod updatedConfirm that the newly created pod has the
app=db-podselector.[student@workstation ~]$
oc get pods --selector app=db-pod -o wideNAME READY STATUS RESTARTS AGE IP ...db-pod-6ccc485cfc-l2x1/1 Running 0 32s 10.8.0.85 ...Notice the change in the pod name. The pod IP address might also change. Your pod name and IP address might differ from the previous output.
Confirm that the endpoints for the
db-podservice include the newly created pod.[student@workstation ~]$
oc get endpointsNAME ENDPOINTS AGE db-pod10.8.0.85:3306 16m
Create a pod to identify the available DNS name assignments for the service.
Create a pod named
shellto use for troubleshooting. Use theoc runcommand and theregistry.ocp4.example.com:8443/openshift4/network-tools-rhel8container image.[student@workstation ~]$
oc run shell -it \ --image registry.ocp4.example.com:8443/openshift4/network-tools-rhel8If you don't see a command prompt, try pressing enter. bash-4.4$From the prompt inside the
shellpod, view the/etc/resolv.conffile to identify the cluster-domain name.bash-4.4$
cat /etc/resolv.confsearch deploy-services.svc.cluster.localsvc.cluster.local... nameserver 172.30.0.10 options ndots:5The container uses the values from the
searchdirective as suffix values on DNS searches. The container appends these values to a DNS query, in the written order, to resolve the search. The cluster-domain name is the last few components of these values that start aftersvc.Use the
ncandechocommands to test the available DNS names for the service.nc -z
<service>_<server>_<port>The long version of the DNS name is required when accessing the service from a different project. When the pod is in the same project, you can use a shorter version of the DNS name.
bash-4.4$
nc -z db-pod.deploy-services 3306 && \ echo "Connection success to db-pod.deploy-services:3306" || \ echo "Connection failed"Connection success to db-pod.deploy-services:3306Exit the interactive session.
bash-4.4$
exitSession ended, resume using 'oc attach shell -c shell -i -t' command when the pod is runningDelete the pod for the shell.
[student@workstation ~]$
oc delete pod shellpod "shell" deleted
Use a new project to test pod communications across namespaces.
Create a second namespace with the
oc new-projectcommand.[student@workstation ~]$
oc new-project deploy-services-2Now using project "deploy-services-2" on server "https://api.ocp4.example.com:6443". ...output omitted...Execute the
ncandechocommands from a pod to test the DNS name access to another namespace.[student@workstation ~]$
oc run shell -it --rm \ --image registry.ocp4.example.com:8443/openshift4/network-tools-rhel8 \ --restart Never -- nc -z db-pod.deploy-services.svc.cluster.local 3306 && \ echo "Connection success to db-pod.deploy-services.svc.cluster.local:3306" \ || echo "Connection failed"pod "shell" deleted Connection success to db-pod.deploy-services.svc.cluster.local:3306Return to the
deploy-servicesproject.[student@workstation ~]$
oc project deploy-servicesNow using project "deploy-services" on server "https://api.ocp4.example.com:6443".
Use a Kubernetes job to add initialization data to the database.
Create a job named
mysql-initthat uses theregistry.ocp4.example.com:8443/redhattraining/do180-dbinit:v1container image. This image uses themysql-80container image as a base image, and it includes a script that adds a few initial records to the database.[student@workstation ~]$
oc create job mysql-init \ --image registry.ocp4.example.com:8443/redhattraining/do180-dbinit:v1 \ -- /bin/bash -c "mysql -uuser1 -pmypa55w0rd --protocol tcp \ -h db-pod -P3306 items </tmp/db-init.sql"job.batch/mysql-init createdThe
-hoption of themysqlcommand directs the command to communicate with the DNS short name of thedb-podservice. Thedb-podshort name can be used here, because the pod for the job is created in the same namespace as the service.The double dash
--before/bin/bashseparates theoccommand arguments from the command in the pod. The-coption of/bin/bashdirects the command interpreter in the container to execute the command string. The/tmp/db-init.sqlfile is redirected as input for the command. Thedb-init.sqlfile is included in the image, and contains the following script.DROP TABLE IF EXISTS `Item`; CREATE TABLE `Item` (`id` BIGINT not null auto_increment primary key, `description` VARCHAR(100), `done` BIT); INSERT INTO `Item` (`id`,`description`,`done`) VALUES (1,'Pick up newspaper', 0); INSERT INTO `Item` (`id`,`description`,`done`) VALUES (2,'Buy groceries', 1);
Confirm the status of the
mysql-initjob. Wait for the job to complete.[student@workstation ~]$
oc get jobNAME COMPLETIONS DURATION AGE mysql-init1/122mRetrieve the status of the
mysql-initjob pod, to confirm that the pod has aCompletedstatus.[student@workstation ~]$
oc get podsNAME READY STATUS RESTARTS AGE db-pod-6ccc485cfc-2lklx 1/1 Running 0 4h24m mysql-init-ln9cg 0/1Completed0 23mDelete the
mysql-initjob, because it is no longer needed.[student@workstation ~]$
oc delete job mysql-initjob.batch "mysql-init" deletedVerify that the corresponding
mysql-initpod is also deleted.[student@workstation ~]$
oc get podsNAME READY STATUS RESTARTS AGE db-pod-6ccc485cfc-2lklx 1/1 Running 0 4h2
Create a
query-dbpod by using theoc runcommand and theregistry.ocp4.example.com:8443/redhattraining/do180-dbinit:v1container image. Use the pod to execute a query against the database service.Create the
query-dbpod. Configure the pod to use the MySQL client to execute a query against thedb-podservice. You can use thedb-podservice short name, which provides a stable reference.[student@workstation ~]$
oc run query-db -it --rm \ --image registry.ocp4.example.com:8443/redhattraining/do180-dbinit:v1 \ --restart Never \ -- mysql -uuser1 -pmypa55w0rd --protocol tcp \ -h db-pod -P3306 items -e 'select * from Item;'mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------------------+------------+ | id | description | done | +----+-------------------+------------+ | 1 | Pick up newspaper | 0x00 | | 2 | Buy groceries | 0x01 | +----+-------------------+------------+ pod "query-db" deleted
It might be necessary to use pod-to-pod communications for troubleshooting. Use the
oc runcommand to create a pod that executes a network test against the IP address of the database pod.Confirm the IP address of the MySQL database pod. Your pod IP address might differ from the output.
[student@workstation ~]$
oc get pods -o wideNAME READY STATUS RESTARTS AGE IP ... db-pod-6ccc485cfc-2lklx 1/1 Running 0 4h5 10.8.0.69 ...Capture the IP address in an environment variable.
[student@workstation ~]$
POD_IP=$(oc get pod -l app=db-pod \ -o jsonpath='{.items[0].status.podIP}')Create a test pod named
shellwith theoc runcommand. Execute thenccommand to test against the$POD_IPenvironment variable and the3306port for the database.[student@workstation ~]$
oc run shell --env POD_IP=$POD_IP -it --rm \ --image registry.ocp4.example.com:8443/openshift4/network-tools-rhel8 \ --restart Never \ -- nc -z $POD_IP 3306 && echo "Connection success to $POD_IP:3306" \ || echo "Connection failed"pod "shell" deleted Connection success to 10.8.0.69:3306