- Learn about Kubernetes concepts: connecting applications
- Learn to expose a service running on Kubernetes
- Deploy a single-instance Pet application in Kubernetes
- Create a
web.ymlfile in thekubernetesfolder to define the k8s objects required to deploy a single-instance Pet application and connect it to the MySQL service - Update the
deploy.shscript at the root of the project to deploy the application - Update the application to read database configuration from environment variables
- Application is exposed on the host and can be accessed on
http://<CLUSTER_IP>:8080
Kubernetes adds environment variables for every active service when launching
new pods, which allows us to perform service discovery. The relevant variables
for our MySQL database service are PET_DB_SERVICE_HOST and PET_DB_SERVICE_PORT,
so we can change our application's src/resources/application-mysql.properties
configuration to use that and other information that will be defined in the
Kubernetes definition file:
# database init, supports mysql too
database=mysql
spring.datasource.url=jdbc:mysql://${PET_DB_SERVICE_HOST}:${PET_DB_SERVICE_PORT}/${PET_DB_DATABASE}
spring.datasource.username=${PET_DB_USER}
spring.datasource.password=${PET_DB_PASSWORD}
spring.datasource.initialization-mode=alwaysCreate the kubernetes definition file kubernetes/web.yml, which will define the
other environment variables and access the MySQL password secret:
apiVersion: v1
kind: Service
metadata:
name: pet-web
labels:
app: pet
spec:
ports:
- port: 8080
selector:
app: pet
tier: frontend
type: LoadBalancer
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: pet-web
labels:
app: pet
spec:
selector:
matchLabels:
app: pet
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: pet
tier: frontend
spec:
containers:
- image: pet-app
imagePullPolicy: Never
name: pet-web
env:
- name: SPRING_PROFILES_ACTIVE
value: mysql
- name: PET_DB_DATABASE
value: petclinic
- name: PET_DB_USER
value: petclinic-user
- name: PET_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 8080
name: pet-webNow we can repackage our application with Maven:
$ ./mvnw package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building petclinic 2.0.0.BUILD-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
...
[INFO] --- spring-boot-maven-plugin:2.0.0.RELEASE:repackage (default) @ spring-petclinic ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:35 min
[INFO] Finished at: 2018-04-10T13:16:01+01:00
[INFO] Final Memory: 95M/591M
[INFO] ------------------------------------------------------------------------We need to rebuild our image using the Docker daemon inside of minikube:
$ eval $(minikube docker-env)
$ docker build --tag=pet-app --build-arg JAR_FILE=target/spring-petclinic-2.0.0.BUILD-SNAPSHOT.jar .
Sending build context to Docker daemon 270.6MB
Step 1/4 : FROM openjdk:8-jdk-alpine
8-jdk-alpine: Pulling from library/openjdk
ff3a5c916c92: Already exists
5de5f69f42d7: Pull complete
fd869c8b9b59: Pull complete
Digest: sha256:4cd17a64b67df1a929a9c6dedf513afcdc48f3ca0b7fddee6489d0246a14390b
Status: Downloaded newer image for openjdk:8-jdk-alpine
---> 224765a6bdbe
Step 2/4 : ARG JAR_FILE
---> Running in 99e39c8f3b87
---> d1f9cda3b36d
Removing intermediate container 99e39c8f3b87
Step 3/4 : ADD ${JAR_FILE} app.jar
---> a59d14a26319
Step 4/4 : ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -jar /app.jar
---> Running in 20374bf0517b
---> 2e68f5165a1e
Removing intermediate container 20374bf0517b
Successfully built 2e68f5165a1e
Successfully tagged pet-app:latestCheck that the image was published to Minikube's Docker:
$ docker image ls pet*
REPOSITORY TAG IMAGE ID CREATED SIZE
pet-app latest 2e68f5165a1e 3 minutes ago 140MBNow we can update the deploy.sh script to apply the web k8s objects:
#!/usr/bin/env bash
set -xe
kubectl apply -f kubernetes/mysql.yml
kubectl apply -f kubernetes/web.ymlAnd re-deploy:
$ ./deploy.sh
+ kubectl apply -f kubernetes/mysql.yml
service "pet-db" unchanged
persistentvolumeclaim "db-pv-claim" unchanged
deployment "pet-db" unchanged
+ kubectl apply -f kubernetes/web.yml
service "pet-web" created
deployment "pet-web" createdValidate that the objects are created successfully:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
pet-db-7997cf844-lsppt 1/1 Running 0 1h
pet-web-59cd5678b8-p7thk 1/1 Running 0 1h
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d
pet-db ClusterIP None <none> 3306/TCP 1h
pet-web LoadBalancer 10.104.27.46 <pending> 8080:30596/TCP 1hGet the external service URL to test the application is working and accessible:
$ minikube service pet-web --url
http://192.168.99.100:30596Visiting the URL in your browser (in this case http://192.168.99.100:30596) should open the PetClinic application.