수 많은 우문은 현답을 만든다

Openshift(Application 배포 - Nodejs와 mysql 연동하기) 본문

개발지식/Openshift (k8s)

Openshift(Application 배포 - Nodejs와 mysql 연동하기)

aiden.jo 2020. 7. 28. 18:46

안녕하세요, 조영호입니다.

오늘은 이전에 살펴온 오픈시프트 컨테이너 플랫폼에서 Pod, Node 운영이 아닌 실제로 어떻게 애플리케이션을 이 컨테이너 오케스트레이션 플랫폼에 올리고 운영할 수 있는지 살펴보겠습니다. 간단하게 애플리케이션을 만드는 4가지 방법을 살펴본 후에 Nodejs와 Mysql을 각각 다른 파드로 구성하고 서로 통신하는 것 까지 해보도록 하겠습니다.

 

기존의 Monolithic 구조의 애플리케이션들은 하나의 서버에 여러 서비스(예를들어 Nodejs, Mysql 혹은 Spring, Apache, Tomcat 등)가 같이 공존했습니다. 요즘 화두가 되고있는 MSA (Micro Service Architecture) 개념은 이런 Monolithic 구조의 서비스를 작고 자원 효율적인 모듈로 따로 떼어내고 유기적으로 동작하게 하는데에 목표가 있습니다. 아주 기초적이지만 오늘 두개의 파드로 두개의 서비스를 구성하고 서로 통신시키는 것 까지 해보도록 하겠습니다.

 

 

Openshift 에서 애플리케이션을 만드는 4가지 방법

1. 소스코드로 만들기

 oc new-app github나 로컬 소스를 지정하면 language detection이 언어를 인식하고 OCP 이미지 스트림에서 해당 언어의 이미지를 불러옵니다. 이미지가 없다면 Docker Hub에서 이미지를 불러옵니다.

 

2. 이미지로부터 만들기

in a specific registry or Docker Hub registry, or images in the local Docker server. 에서 이미지를 가져옵니

이미지가 컨테이너 이미지 (--docker-image 인수 사용)인지 이미지 스트림 (-i | --image 인수 사용)인지 명시해야합니다.

 

3. 템플릿으로 만들기

JSON이나 YAML로 정의한 템플릿으로 애플리케이션을 배포할 수 있습니다.

예제 :  https://docs.openshift.com/container-platform/3.11/dev_guide/templates.html#writing-templates

 

4. UI 콘솔에 접속해서 만들기
클릭 클릭으로 쉽게 배포할 수 있습니다.

 

 

 

배포하기 이전에 살펴볼 내용

1. new-app의 Output ObjectsObjectDescription

이전 포스팅에서 그냥 apply/create -f 로 파드를 만들면 사실 파드만 만들어지고 파드의 상태나 포트포워딩을 관리할 deploymentConfig와 Service가 생성되지 않는 문제가 있었습니다. 그러나 new-app 명령으로 애플리케이션을 배포하면 deploymentConfig와 Service가 자동으로 생성됩니다. 

(참고 : https://docs.openshift.com/container-platform/3.11/dev_guide/application_lifecycle/new_app.html#new-app-output)

 


2. 앱 배포에 사용할 수 있는 옵션들


-e | --env
애플리케이션 실행에 필요한 환경변수를 입력한다

 

--build-en
컨테이너 빌드시 필요한 환경변수를 입력한다

 

-l|--label

레이블 설정

-o|--output
생성될 오브젝트의 미리보기를 출력한다

 

--name
오브젝트들이 중복 에러를 내지 않도록 이름을 지정한다

 

-n|--namespac
현재 접속중인 네임스페이스와 다른 네임스페이스에 배포하도록 설정할 수 있다

 

# oc new-app ruby+mysql

+ 기호를 써서 하나의 파드에 여러 이미지들 포함시킬 수 있다

 

# oc new-app --search php

레포지토리에서 이미지를 검색할 수 있다

 

 

Node.js와 MySQL 배포하기

이번에는 Openshift에 Node.js, MySQL의 파드를 각각 1개씩 띄우고 Node.js에서 MySQL의 데이터를 호출하는 방법까지 알아보겠습니다. 어렵지 않으니 스텝별로 잘 따라오시면 됩니다!

1. Project 생성

우선 deploy 라는 이름으로 Project를 생성해줍니다. Project는 kubernetes에서의 namespace와 같은 개념으로, 클러스터의 파티션을 나누어 접근 권한에 따른 프로젝트 제한이나 목적에 따른 프로젝트 구분 등에 사용할 수 있습니다.

# oc new-project deploy 
새로운 프로젝트를 생성합니다.
# oc project deploy
생성된 프로젝트로 접속합니다.

2. MySQL 설치

# oc new-app mysql
mysql 애플리케이션을 배포합니다.
# oc get pods

NAME             READY     STATUS             RESTARTS   AGE
mysql-1-742kt    0/1       CrashLoopBackOff   2          37s
mysql-1-deploy   1/1       Running            0          40s
생성된 pod의 상태를 확인해보니 에러가 발생했습니다.

# oc logs mysql-1-742kt

=> sourcing 20-validate-variables.sh ...
You must either specify the following environment variables:
  MYSQL_USER (regex: '^[a-zA-Z0-9_]+$')
  MYSQL_PASSWORD (regex: '^[a-zA-Z0-9_~!@#$%^&*()-=<>,.?;:|]+$')
  MYSQL_DATABASE (regex: '^[a-zA-Z0-9_]+$')
데이터베이스에 필요한 필수 환경변수들이 빠졌기 때문에 에러가 발생했네요. 파드의 로그 트래팅은 이렇게 하시면 됩니다. 사실 Openshift UI에서는 입력받도록 되어있는 항목들인데 Terminal에서 실행할때는 직접 입력을 해줘야합니다.  

# oc delete dc mysql && oc delete service mysql
Pod의 재 배포를 위해 Pod의 상태와 배포를 관리하는 Service와 DeploymentConfig를 삭제합니다.
# oc new-app mysql -e MYSQL_USER=admin MYSQL_PASSWORD=admin MYSQL_DATABASE=test
-e는 2번 : 앱 배포에 사용할 수 있는 옵션 에서 다룬 것 처럼 환경 변수를 의미합니다.
# oc get pods

NAME            READY     STATUS    RESTARTS   AGE
mysql-1-ts5sl   1/1       Running   0          4m

배포가 잘 된 것을 확인해볼 수 있습니다.

3. MySQL 접속하기

# oc exec -it mysql-1-ts5sl sh
MySQL이 설치 된 Pod에 접속합니다.
sh-4.2$ mysql -u admin -p
MySQL 접속 시도
mysql> show databases;
접속 성공 및 데이터베이스 조회
mysql> use test;
mysql> 
create table info (id int AUTO_INCREMENT PRIMARY KEY, name varchar(20));

mysql> insert into info values(1, 'youngho');
mysql> select * from info;
테이블 및 데이터 생성

4. Nodes 설치

# oc new-app --search nodejs
nodejs 이미지가 있는지 검색합니다. 오픈시프트의 new-app 커맨드의 장점은 DeploymentConfig와 Service가 자동으로 배포된다는 점 입니다. 
# oc new-app --image-stream=nodejs
nodejs 애플리케이션을 배포합니다.
# oc get route
No resources found.
# oc expose svc/nodejs
route.route.openshift.io/nodejs exposed
expose 커맨드를 사용해 nodejs 서비스를 외부로 노출해줍니다.
# oc get route

NAME      HOST/PORT                                                 PATH   SERVICES   PORT       TERMINATION   WILDCARD
nodejs    nodejs-deploy.apps.jo-master.fyre.ibm.com             nodejs     8080-tcp                             None
다시 route 커맨드를 사용해보면 nodejs에 포트가 할당 된 것을 볼 수 있습니다.

# oc get pods

NAME              READY     STATUS             RESTARTS   AGE
mysql-1-ts5sl     1/1       Running            0          1h
nodejs-1-cp92s    0/1       CrashLoopBackOff   4          3m
그런데 nodejs 파드에 에러가 발생했습니다.

# oc logs nodejs-1-cp92s

This is a S2I base image for Nodejs:
To use it, install S2I: https://github.com/openshift/source-to-image

이 이미지는 S2I용 이미지라고 하니 재 설치를 해야합니다.

# oc delete svc/nodejs && oc delete dc/nodejs && oc delete route/nodejs
우선 nodejs와 관련된 내용들을 삭제해줍니다.
# oc new-app https://github.com/sclorg/nodejs-ex -l name=myapp
특정 깃허브에서 nodejs 샘을을 끌어옵니다.
(참고 : https://github.com/sclorg/nodejs-ex
# oc get pods

NAME                        READY     STATUS    RESTARTS   AGE
mysql-1-ts5sl             1/1          Running   0          16h
nodejs-ex-1-dpqdh    1/1       Running   0          14s

5. Nodejs 설치 확인 접속하기

# oc exec -it nodejs-ex-1-dpqdh sh
sh-4.2$ node -v
v10.16.3
Node.js에 접속해서 잘 설치되어있는지 확인하기 위해 버전을 확인합니다.
# oc get svc | grep nodejs

NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE

nodejs-ex  ClusterIP   172.30.202.71    <none>        8080/TCP   9m

# oc edit svc nodejs-ex
여기서 ClusterIP를 NodePort로 변경해줍니다. ClusterIP는 클러스터 내부 통신용으로 사용되고 있다는 의미이며 NodePort는 외부에서 접속 가능한 상태를 나타냅니다.
# oc get svc | grep nodejs-ex

NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
nodejs-ex  NodePort    172.30.202.71    <none>        8080:30574/TCP   12m
보시는 바와 같이 TYPE이 NodePort로 변경되면서, 기존 포트인 8080/TCP에서 :30574 외부 포트가 새롭게 할당된 것을 알 수 있습니다. 

# http://jo-master.fyre.ibm.com:30574/

위의 링크로 접속하시면 Nodejs로 띄운 브라우저를 확인하실 수 있습니다.
(해당 클러스터는 자원때문에 삭제 예정이라서 접속되지 않으실거예요 ㅠㅠ)

6. Node.js와 MySQL 연동하기

# oc exec -it nodejs-ex-1-dpqdh sh
우선 Pod에 접속합니다.
sh-4.2$ npm install express mysql
sh-4.2$ npm audit fix
sh-4.2$ vi package.json
express mysql 모듈을 설치하고 package.json의 dependancy에 “mysql": "^2.18.1"을 추가합니다.
sh-4.2$ vi server.js
Node.js가 실행시킬 자바스크립트 파일에 데이터베이스 커넥션을 생성하는 아래의 코드를 작성합니다.

const mysql      = require('mysql');
const connection = mysql.createConnection({
  host     : 'mysql-1-ts5sl',
  user     : 'admin’,
  password : 'admin’,
  database : 'test'
});

connection.connect();
connection.query('SELECT * from info’, (error, rows, fields) => {

  if (error) throw error;

  console.log('User info is: ', rows);

});

connection.end();

sh-4.2$ npm start
host 정보는 있으나 mysql-1-ts5sl:3306에 접근할 수 없다는 에러 메세지를 확인하실 수 있습니다.
# oc get pods -o wide

nodejs-ex-1-dpqdh     1/1       Running     0          1h        10.130.1.20    jo-worker-3.fyre.ibm.com   <none>
이와 같은 에러를 만나신 분들은 server.js의 host를 10.130.1.20으로 변경해주세요!

sh-4.2$ npm start

User info is:  [ RowDataPacket { idx: 1, name: 'YounghoJo', gender: 'man' } ]
짠! 성공적으로 데이터베이스에 연결 되어 정보를 가져온 것을 확인할 수 있습니다. 이제 남은 것은 즐겁게 개발하는 일만 남았겠네요^^


 

어려운 내용이 아닐 수 있지만 막상 시작하시기 어려운 분들에게 작게나마 도움이 되셨기를 바랍니다.

저 또한 시작은 쉽지 않았으나 익숙해지니 정말 재미있습니다 !

갈 길이 멀지만 모두 화이팅 !

 

감사합니다.

 

 

참고
https://docs.openshift.com/container-platform/3.11/dev_guide/application_lifecycle/new_app.html#dev-guide-new-app

https://poiemaweb.com/nodejs-mysql

'개발지식 > Openshift (k8s)' 카테고리의 다른 글

Openshift Administration (POD)  (0) 2020.07.14
쿠버네티스 기본 개념과 실습  (0) 2020.07.10
컨테이너와 쿠버네티스 쉽게 이해하기  (0) 2020.07.10
Openshift Core Concept  (0) 2020.07.10
Openshift Overview  (0) 2020.07.10