🍳머리말
K8s cluster에서 Provisioned WAS(tomcat)와 DB(mysql)를 연결하는 예제 {}로 감싸진 부분은 직접 입력해야하는 부분입니다.
📕 Prerequisite
📔 Docker
📔 CNI가 설치된 k8s cluster.
📔 Docker Hub 계정
📕 DB(mysql) 준비
📔 namespace 생성
논리적 격리를 위해 namespace를 생성해줍니다.
kubectl create namespace [이름]
제 경우는 제 이름을 따서 mskim이라는 namespace를 생성해줬습니다.
kubectl create namespace mskim
📔 replicaset 생성
제 namespace로 replicaset을 생성해줍니다. mysql latest image를 사용했습니다. label은 mysql로 사용할 것입니다.
mysql-deployment.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myweb-mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: docker.io/mysql
imagePullPolicy: Never #Do not use remote mirror
name: mysql
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
mysql의 password는 password로 설정했습니다.
📔 service 생성
cluster 내에서만 통신할 수 있도록 service객체를 ClusterIP type으로 만들어 deployment를 여기로 노출시킵니다.
mysql-service.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- name: mysql-svc
port: 3306
targetPort: 3306
selector:
app: mysql
type: ClusterIP
확인
kubectl -n [namespace명] get svc
teminal 출력
📔 예제 database, table, data생성
📑 pod 이름 확인
kubectl -n [namespace명] get pods
다음과 같이 myweb-mysql-랜덤5글자 형태로 running 중이라면 성공입니다.
📑 해당 pod에 접속
형식은 아래와 같습니다.
kubectl -n [namespace명] exec -it [pod명] bash
제 경우는 이런 명령어를 입력했습니다.
kubectl -n mskim exec -it myweb-mysql-fg9rw bash
입력후에는 이런식으로 접속됩니다.
📑 MySQL 접속
형식은 다음과 같습니다.
mysql -u[user명] -p[password]
제 경우 user는 root, password는 password로 설정했으므로 다음과 같은 명령어로 접속합니다.
mysql -uroot -ppassword
접속 후 해당화면입니다.
📑 MySQL server에 data생성
다음과 같은 sql문들을 실행해줍니다. database, table, row들을 추가하는 sql문입니다.
create database testDB;
use testDB;
create table testTable(
id int(11) not null auto_increment,
name varchar(20) not null,
constraint testTable_pk primary key(id)
);
insert into testTable(name) values("hi");
insert into testTable(name) values("mskim");
insert into testTable(name) values("hello");
insert into testTable(name) values("James");
insert into testTable(name) values("JIN");
아래와 같이 Query Ok message가 출력된다면 된 것입니다.
📕 WAS(tomcat) 준비
📔 JDBC driver 설치
Tomcat official image에는 JDBC driver가 없습니다. 따라서 필요한 sql에 따른 driver를 jar형태로 image의 file system에 포함시켜야 합니다.
아래 url에서 jar를 설치해주도록 합니다. mysql version에 따른 connector는 고려하지 않았습니다. 필요한 경우 호환되는 version을 알고있다는 가정하에 진행하겠습니다.
https://dev.mysql.com/downloads/connector/j/
받은 jar file은 jvm상에서 실행할 수 있는 압축 file입니다.
📔 Sample.war 설치
apache tomcat 공식으로 제공하는 Sample Application인 Sample.war를 받아줍니다. tomcat image의 filesystem으로 넣어주면 자동으로 압축을 해제해 실행해줍니다.
https://tomcat.apache.org/tomcat-8.5-doc/appdev/sample/
📔 Docker hub 접속
1. docker hub에 login해줍니다.
2. 하기와 같이 새로운 repository를 생성해줍니다. 이름을 was로 설정한 후 create button을 click하면 됩니다.
생성된 결과는 다음과 같습니다.
📔 Tomcat Image Build
docker daemon을 실행해주시고 다음 명령어로 작성한 Dockerfile을 이용, jdbc.jar, sample.war과 함께 tomcat을 docker hub에서 받아와 image를 build해줍니다. 이를 위해서 작업한 dir경로의 terminal에서 하기와 같은 명령어를 실행합니다.
Dockerfile 예시
제 경우는 base continer를 openjdk 10을 사용했고 tomcat 10 mysql-connedtor-java는 mysql 8에 맞춰 download받아 image build했습니다.
FROM openjdk:10-jdk
MAINTAINER jyson
# 환경 변수 및 작업 경로
ENV CATALINA_HOME /usr/local/tomcat
ENV PATH $CATALINA_HOME/bin:$PATH
RUN mkdir -p "$CATALINA_HOME"
WORKDIR ${CATALINA_HOME}
# 톰캣 설치 파일 다운로드 실행 및 압축해제
RUN wget http://apache.mirror.cdnetworks.com/tomcat/tomcat-10/v10.0.20/bin/apache-tomcat-10.0.20.tar.gz;
RUN tar -xf apache-tomcat-10.0.20.tar.gz --strip-components=1;
# war 파일 복사
COPY ./sample.war $CATALINA_HOME/webapps
# jdbc driver jar 복사
COPY ./mysql-connector-java.jar ../openjdk-10/lib
COPY ./mysql-connector-java.jar /usr/local/tomcat/lib/
# 컨테이너에서 사용할 포트
EXPOSE 8080
# 설정 완료 후 실행
CMD ["catalina.sh", "run"]
작성 후에는 다음과 같은 명령어로 image build 해줍니다.
docker build -t [dockerhub ID]/[repo명]:[tag명] .
제 경우 docker ID는 xhdxhl, repo명은 was, tag명은 0.1이므로 다음과 같이 작성했습니다.
docker build -t xhdxhl/was:0.1 .
명령어 입력시 아래와 같이 나옵니다.
📔 Tomcat Image Push
local환경에서 build 명령어로 image를 말았으니 원격 repo에 push를 해야합니다.
아까 build했을 때 설정한 값들로 push 명령어를 입력해줍니다.
docker push [docker ID]/[repo명]:[tag명]
제 경우 입력한 명령어는 다음과 같습니다.
docker push [docker ID]/[repo명]:[tag명]
명령어를 입력하면 다음과 같이 뜹니다.
push 후에는 docker hub에 다음과 같이 tag 0.1의 image가 목록으로 browser에 출력됩니다.
📔 Tomcat Secret 생성
db의 credential정보는 secret으로 관리하는 것이 좋습니다. 비록 예제이나 서비스를 운영하는 것처럼 보이기 위해 secret을 생성해 deployment로 주입할 예정입니다.
tomcat-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: tomcat-secret
stringData:
DB_URL: "jdbc:mysql://mysql/testDB"
DB_USER: "root"
DB_PASSWORD: "password"
📔 Tomcat Deployment 생성
이제 dockerhub의 원격 repo로 push된 image를 pull해서 deployment를 생성해줍니다.
tomcat-deployment.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myweb-tomcat
spec:
replicas: 1
selector:
matchLabels:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- image: docker.io/xhdxhl/was:0.1
imagePullPolicy: Always
name: myweb
resources:
limits:
cpu: "0.5"
memory: 1Gi
ports:
- containerPort: 8080
env:
- name: db_url
valueFrom:
secretKeyRef:
name: tomcat-secret
key: DB_URL
- name: db_user
valueFrom:
secretKeyRef:
name: tomcat-secret
key: DB_USER
- name: db_password
valueFrom:
secretKeyRef:
name: tomcat-secret
key: DB_PASSWORD
📔 Tomcat Service 생성
tomcat-service.yaml
apiVersion: v1
kind: Service
metadata:
name: myweb
spec:
ports:
- name: myweb-svc
port: 8080 #Port number of the Service
targetPort: 8080 #Port number of container exposed
nodePort: 30001 #The real port number of the node
selector:
app: myweb #Service selected pod with tag app: myweb
type: NodePort
확인
kubectl -n [namespace명] get svc
출력결과
pod 확인 명령어
kubectl -n [namespace명] get pods
출력결과
📔 Tomcat 외부노출 확인
크롬창에서 http://[cluster가 구성된 node의 ip]:[nodeport로 노출된 tomcat service의 port번호]로 접속합니다.nodeport 번호는 30001번으로 지정했으니 url은 예시로 http://192.168.9.199:30001 가 됩니다.
다음처럼 tomcat이 원활히 배포되었고 sample.war의 압축을 자동으로 해제해 다음 html을 출력하는 화면을 볼 수 있습니다.
📕 WAS-DB사이 connection 확인
📔 jsp file 작성
db와의 연결이 제대로 이루어졌을 확인하기 위해 작성합니다. db와 연결 후에 간단한 query문을 실행하는 sql문 입니다.
📑 dbtest.jsp
<%@ page import="java.sql.*" contentType="text/html; charset=UTF-8" %>
<%@ page import="javax.naming.*" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String DB_URL = System.getenv("db_url");
String DB_USER = System.getenv("db_user");
String DB_PASSWORD= System.getenv("db_password");
Connection conn;
Statement stmt;
ResultSet rs;
try
{
out.println("START TRY!!");
out.println("<br/>");
conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
out.println("getConnection success");
out.println("<br/>");
stmt = conn.createStatement();
out.println("createStatement success");
out.println("<br/>");
out.println("MySQL Connection Success!");
out.println("<br/>");
String sql = "select * from testTable";
rs = stmt.executeQuery(sql);
while(rs.next()) {
out.println("id - " +rs.getString("id")+ " |");
out.println("NAME - " +rs.getString("name")+ " |");
out.println("<hr>");
}
stmt.close();
conn.close();
}
catch(Exception e)
{
e.printStackTrace();
}
%>
</body>
</html>
📔 .jsp를 tomcat container안으로 옮기기
kubectl은 기본적으로 cp명령어를 지원합니다.
kubectl -n [namespace명] cp [옮길 file 경로] [pod명]:[pod내부 container의 목적지 경로]
제 경우 다음과 같은 명령어를 입력했습니다.
kubectl -n [namespace명] cp ./dbtest.jsp myweb-tomcat-cm6g6:./webapps/ROOT
📔 web에서 연결 확인
자 이제 접속이 되었으니 .jsp가 적용됐는지 확인해 봅시다.
/[jsp file명]로 구분해 접속해볼 수 있습니다. dbtest.jsp를 넣어놓았으니 url은 다음과 같습니다.
http://192.168.9.199:30001/dbtest.jsp
연결이 잘 되었고 testTable의 row들을 성공적으로 출력하고 있습니다.
'Cloud' 카테고리의 다른 글
(Kubernetes) - 명령어 모음 (0) | 2022.01.06 |
---|---|
(Operator-sdk) - Ubuntu에서 operator project 만들기 (0) | 2021.12.23 |
(Kubernetes) - container와 local간 file 이동 (0) | 2021.12.16 |
(Kubernetes) - application에 data 주입 4 (0) | 2021.12.06 |
(Kubernetes) - application에 data 주입 3 (0) | 2021.12.06 |