본문 바로가기
프로그램 활용/클라우드 가상화 도커

Docker에 Aapche Tomcat 설치하고 Oracle 12c 연결

by 3604 2023. 7. 25.
728x90

CentOS에 Docker 설치 - Apache 이미지 설치 - 파일 복사하기

출처: https://blogger.pe.kr/849

IT 인프라에서 가상화의 꽃은 뭐니 뭐니해도 지금까지는 응용프로그램 가상화다. 하드웨어의 성능의 발전하면서 하나의 서버 하드웨어에 여러개의 운영체제를 구동하는 "Server Virtualization (서버 가상화)"가 대세인 듯 했으나 하나의 머신에서 실행되는 가상화 된 서버의 개수가 늘어날 수록 운영체제(OS)가 중복 실행되어 리소스가 낭비되는 현상이 심해진다.

이런 문제를 해결함과 동시에 서버에서 실행되는 응용프로그램 개발 및 응용프로그램의 버전관리와 배포 등 관리 편의성을 높이기 위해 등장한 것이 바로 "Application Virtualization(응용프로그램 가상화)"다. 이 응용프로그램 가상화는 서버에서 실행되는 응용프로그램(Apache, Tomcat, MySQL 등)과 응용프로그램이 필요로하는 여러 파일들을 하나로 캡슐화(Encapsulation)한 것으로서 서버 운영체제와는 격리된 형태로 배포 및 실행되어 보안성 및 관리 편의성을 높였다.

가장 대표적인 Application Virtualzion 솔루션이 바로 컨테이너 기반의 오픈소스 가상화 플랫폼인 Docker(도커)다.

도커를 짧은 말로 설명하기엔 너무 어렵다. 구구절절 설명하지 않고 CentOS 7에 Docker 플랫폼을 설치하고 Apache 웹서버를 어떻게 가상화하는지 그 과정을 설명하면서 필요할 때 마다 개념을 설명하도록 하겠다.

먼저 CentOS 7.8 에서 바로 yum 명령을 이용해 Docker 설치를 시도해 본다.

CentOS의 기본 리포지토리에는 Docker가 없다.

yum 명령으로  무료버전인 커뮤니티 에디션 즉 Docker-CE를 설치하려 하면 위 화면과 같이 에러가 발생한다. CentOS의 기본 리포지토리에서는 Docker 패키지가 배포되지 않는다.

다음과 같이 Docker 설치를 위한 몇몇 드라이버와 Docker를 배포하는 리포지토리를 yum에 추가하기 위한 Util 패키지를 설치한다.

Device Mapper 드라이버와 yum utils 패키지 설치

CentOS 7.8에는 device-mapper-persistent 드라이버가 이미 설치되어 있는 것 같다.

정상적으로 설치가 완료 되었다.

yum config manager를 통해 docker 무료버전을 배포하고 있는 리포지토리를 추가해 준다.

Docker 설치를 위한 yum 리포지토리 추가 등록

추가된 리포지토리는 docker-ce.repo 라는 리포지토리 파일로 저장되었다.

다시 docker ce 버전 설치를 시도한다. 앞에서 추가한 Docker 리포지토리에서 패키지를 다운받아 

yum install docker-ce 로 docker 설치하기

두번 쯤 뭔가를 물어보는데... 그냥 Y를 입력했던 것으로 기억된다.

설치가 완료되었으면 리부팅을 해도 좋겠다.

리부팅 했으면 로그인하여 docker 를 실행한다. 

service 명령을 통해 docker 실행하기

 

CentOS 또는 Ubuntu 등 리눅스 서버에서 service 명령 혹은 systemctl 명령을 통해 docker를 실행한 것은 PC에서 VMWare나 Virtual PC 등 가상화 프로그램을 실행한 것과 같다. 

가상화 프로그램을 실행했다면 운영체제 이미지 파일이 필요하듯 Docker에서도 이미지 파일을 통해 가상화 된 응용프로그램이 실행된다.

다음의 docker images 명령으로 설치되어 있는 가상 운영체제 또는 가상 응용프로그램을 확인할 수 있다.

이 포스트에서는 root 권한으로 docker 이미지를 설치하고 관리하기 때문에 sudo를 통해 root 계정 권한으로 docker 명령을 실행하고 있지만 /etc/group 파일의 docker 그룹에 사용자 계정을 추가해주면 sudo 입력 없이 실행할 수 있다.

Docker에 설치된 이미지 목록 확인

현재 설치되어 있는 가상 운영체제 또는 가상 응용프로그램이 하나도 없다.

그렇다면 가상 운영체제 및 가상 응용프로그램 이미지는 어디서 구해야 할까? Docker의 경우 Docker 이미지 배포 사이트에서 표준 가상 이미지를 Pull 하거나 Docker Hub와 같은 공유사이트에서 다른 사람이 만들어 올려둔 이미지를 Pull할 수 있다.

아래는 Docker 공식사이트에서 아파치 웹서버 최신 버전 이미지를 Pull 하는 화면이다.

Docker 공식사이이트에서 Apache 웹서버 이미지 가져오기

다운로드 된 도커 이미지 목록을 확인해본다. 

Docker Image 목록 확인

2일 전에 만들어진 166MB 용량의 최신 httpd 이미지가 보인다.

하지만 이 상태는 이미지만 다운로드 받았을 뿐 실행된 상태는 아니다. 아래의 docker ps -a 명령으로 실행중인 도커 컨테이너가 있는지 확인해본다.

docker container 목록 보기

도커는 다운로드 받은 이미지를 그냥 실행하는 것이 아니라 Container(컨테이너)를 만들어야 실행이 가능하다. 컨테이너는 이미지의 실행 버전이라고 이해하면 되며 설정이나 파일을 변경할 경우 실행을 위해 만든 컨테이너 내의 파일이 변경된다.

아직은 컨테이너를 만들지 않았기 때문에 컨테이너가 하나도 보이지 않는다. 

컨테이너는 이미지가 최초 실행될 때 만들어지거나 별도로 생성하면 만들어진다. 아래에서는 다운로드 받은 Apache Web서버 이미지를 최초 실행하면서 컨테이너를 만든다.

docker container 최초 실행하기

-p 옵션은 docker가 실행중인 호스트, 즉 위의 화면에서는 centos7-docker 라는 centos 7 서버의 TCP/80번 포트로 들어오는 HTTP 요청을 컨테이너 내부의 80번 포트로 연결하라는 의미다. Docker도 일종의 가상머신이기에 통신포트를 사용한다. 

-d 옵션의 경우 컨테이너를 백그라운드로 실행하라는 의미다. 만약 -d 옵션을 부여하지 않고 docker run 명령을 실행하면 컨테이너를 실행한 뒤 쉘 프롬프트로 되돌아 오지 않는다.

뒤의 httpd는 이미지의 이름이다. 최초 실행이므로 이미지 이름을 주면 된다.

만약 컨테이너의 이름을 미리 정하고 싶다면 다음과 같이 --name 옵션을 주어 컨테이너 이름을 부여할 수도 있다.

$ sudo docker run -d -p 80:80 --name apache-taeho httpd

다시 한번 docker ps -a 명령으로 컨테이너 목록을 살펴본다.

docker container 보기

컨테이너가 생성되면서 CONTAINER ID가 부여되었고 infallible_gould 라는 컨테이너 이름이 자동으로 부여되었다. 뒤에서 이 컨테이너 이름을 변경하는 방법도 알아본다.

PORTS는 호스트의 0.0.0.0:80 이 컨테이너의 80/tcp로 연결됨을 보여준다. 

이제 외부에서 이 컨테이너에서 실행중인 Apache 웹서버에 접속해본다. 컨테이너가 실행중인 호스트의 IP를 브라우저에 입력해본다.

It works! 라는 웹페이지가 표시된다.

컨테이너가 실행되는 것을 확인했으므로 컨테이너를 중지시켜 본다.

docker stop CONTAINER_ID

컨테이너를 중지할 때는 CONTAINER ID 또는 CONTAINER NAME을 입력하면 된다.

컨테이너가 중지되었는지 확인하기 위해 다시 한번 docker ps -a 명령을 실행한다.

container 중지 상태 확인하기

컨테이너 목록이 표시되고 오른쪽 끝에 STATUS 항목을 보면 Exited 로 표시되어 컨테이너가 중지 상태임을 알 수 있다.

이제 컨테이너 내부에 웹 소스를 올리는 방법을 살펴본다. 

Apache 컨테이너에 웹 소스를 올리기 위해서는 먼저 Apache 컨테이너의 DocumentRoot가 어디인지를 알아야 한다. 실제로 Apache 컨테이너에 접속해 DocumentRoot 경로를 들어가 보자.

다시 컨테이너를 실행시킨다. 

Docker 컨테이너 실행

한번 실행된 컨테이너는 docker run이 아닌 docker start 명령으로 실행할 수 있다.

그 다음은 docker exe 명령을 통해 Docker 컨테이너에 /bin/bash를 실행시켜 접속한다.

docker exe 명령으로 쉘을 통해 컨테이너 접속하기

반드시 -it 옵션을 주어야 /bin/bash 로 접속해 컨테이너 내 파일에 접근할 수 있다.

Docker Apache Container 접속

컨테이너에 접속하면 쉘 프롬프트의 호스트네임이 Container ID로 바뀐다. 그리고 Apache2 디렉토리로 접근하게 된다. DocumentRoot는 apache2 디렉토리 아래의 htdocs 디렉토리다. 그 안에 들어가면 index.html 파일이 있고 내용을 확인하면 It works!를 출력하는 초간단 HTML 페이지가 있는 것을 확인할 수 있다.

컨테이너 내의 이 경로 즉 /usr/local/apache2/htdocs 로 새로 만든 HTML 파일 하나를 넣어 웹브라우저를 통해 접근해 보는 것으로 하고 일단 컨테이너와의 접속을 끊는다. 

Apche2 Container 접속 끊기

호스트인 centos7-docker 에서 아래 화면처럼 전혀 다른 html 파일을 하나 만든다. 이 포스트에서는 blogger.html 이라는 html 파일을 만들었다.

이 파일을 Apache2 컨테이너 내로 복사해 넣는다.

docker cp 명령으로 컨테이너 내부로 파일 복사하기

docker cp 명령으로 파일을 Apache 컨테이너 내부의 DocumentRoot로 복사해 넣는다. sudo 를 통해 docker 명령을 실행하므로 이따금씩 비밀번호를 묻는다.

웹브라우저에서 새로 컨테이너에 복사해 넣은 웹페이지에 접근해본다.

이렇게 새로운 파일이 저장된 컨테이너는 도커 이미지로 존재하는 것이 아니라 실행중이거나 실행 가능한 컨테이너에만 존재한다. 만약 이 컨테이너를 백업하거나 개발 서버의 컨테이너를 운영서버로 배포하고자 한다면 컨테이너를 Commit해 이미지로 저장하도록 한다.

아래 화면처럼 docker commit 명령으로 변경내용을 반영한 새로운 배포 가능한 이미지를 생성한다.

docker commit 으로 이미지 새로 만들기

-m 옵션은 새로 만들 이미지의 설명이라고 보면되고 Commit 할 컨테이너 ID와 리포지토리 이름(httpd-0808)을 입력한다. 리포지토리 이름은 변경하지 않아도 무방하다. 

다시 도커 이미지 목록을 보면 생성된 새로운 도커이미지(이름 : httpd-8080)가 보이는 것을 알 수 있다. 

만약 컨테이너의 이름이 맘에 들지 않는다면 아래 명령을 통해 컨테이너의 이름도 변경할 수 있다.

#CentOS_Docker_Install

Docker에 Tomcat 설치하고 Oracle 12c 연결하기

 

Docker에 Tomcat 설치하고 Oracle 12c 연결하기

앞의 포스트에서 CentOS 7에 Docker를 설치하고 Apache Image를 Pull 하여 설치했다. 그리고 테스트 용 HTML 파일을 Apache Image 안으로 복사한 뒤 다른 PC에서 웹브라우저를 이용해 테스트 용 HTML 파일이 잘

blogger.pe.kr

 

앞의 포스트에서 CentOS 7에 Docker를 설치하고 Apache Image를 Pull 하여 설치했다. 그리고 테스트 용 HTML 파일을 Apache Image 안으로 복사한 뒤 다른 PC에서 웹브라우저를 이용해 테스트 용 HTML 파일이 잘 호출되는 것을 확인했다.

이번엔 Apache와 연동할 WAS인 Tomcat을 설치하고 역시..이전에 다른 서버에 설치해 둔 Oracle 12c와 연동하는 테스트까지를 포스팅 한다.

Tomcat 역시 Docker 이미지가 제공된다. 그리고 이 톰캣 내부에는 Java Runtime까지 포함되어 있어 별도로 Java를 설치할 필요가 없다.

docker pull 명령으로 tomcat 가장 최근버전(배포되는)을 가져와 설치한다.

docker pull 명령으로 tomcat 이미지 설치하기

이미지만 가져와 설치한 것이지 컨테이너가 생성된 것은 아니다. docker run 명령으로 tomcat 이미지를 최초 실행시켜 컨테이너를 만든다.

docker run 명령으로 최초 실행시켜 컨테이너 만들기

옵션으로 백그라운드 실행 ( -d ), 호스트의 8080 포트와 컨테이너의 8080 포트를 연결시켜주고 ( -p 8080:8080 ) 컨테이너의 이름을 tomcat-taeho ( --name tomcat-taeho )로 지정한다. 마지막의 tomcat 은 다운로드 받아 설치한 이미지의 이름이다.

이제 생성된 Docker Container인 tomcat-taeho에 docker exe 명령을 이용해 Shell로 접속해 본다. 

실행중인 도커 컨테이너에 쉘로 접속하기

기본적으로 Tomcat에서 Apache의 DocumentRoot에 해당되는 경로는 는 톰캣이 설치된 경로의 webapps 아래의 ROOT 라는 폴더다. 이 설정은 conf 디렉토리에 있는 server.xml 에 설정되어 있다.

Tomcat의 기본 DocumentRoot 경로

없으니...만들어 준다. ( 왜 없지??? )

테스트 용으로 접속 시간을 알려주는 JSP 소스를 기본페이지 파일명인 index.jsp에 넣어 호스트 컴퓨터에서 만들어준다. 

Tomcat 접속 테스트 용 index.jsp

호스트에 생성한 index.jsp를 docker cp 명령을 이용해 Tomcat 도커 컨테이너 내부의 DocumentRoot에 해당하는 appBase 또는 docBase에 복사해 넣는다.

관련 server.xml의 설정은 아래표를 보고 공부해야 한다.

그리고 웹 브라우저를 통해 index.jsp가 잘 호출되고 실행되는지 확인해 본다.

접속 시간이 잘 표시되는 것을 알 수 있다.

Tomcat Container에 접속한 쉘에서 env 명령을 실행해보면 Tomcat Version과 Java Version을 확인할 수 있다.

그리고 java -version 명령을 실행하면 자세한 Java 환경 정보를 알 수 있다.

 

다음은 이전에 다른 서버에 설치해 둔 Oracle 12c와의 JDBC 접속을 테스트할 차례다. 

일단 Oracle12c의 JDBC 드라이버를 아래의 경로에 복사해 넣어야 한다. 이 경로는 env 명령을 실행하면 변수 중 CATALINA_HOME 이라는 변수가 갖고 있는 경로 아래의 lib 다.

tomcat의 jdbc 드라이버 파일이 위치해야 하는 경로(CATALINA_HOME/lib)

Oracle 12c 버전의 JDBC Driver를 다운로드 받아 아래화면처럼 Tomcat Container 내 CATALINA_HOME/lib에 복사해 넣는다. (다운로드는 Oracle 12c JDBC Driver 공식 다운로드 페이지인 여기에서)

Oracle 12c JDBC Driver 복사해 넣기

oracle 18c  

ㅁ 오라클 설치된 곳의 lib 폴더
$su - root
$cd /opt/oracle/product/18c/dbhomeXE/jdbc/lib
$ls
ojdbc8.jar  ojdbc8_g.jar  ojdbc8dms.jar  ojdbc8dms_g.jar  simplefan.jar

ㅁ 웹서버 컨테이너에 oracle jar 파일 복사
usr/local/tomcat/lib/

[root@localhost lib]# ls
ojdbc8.jar  ojdbc8_g.jar  ojdbc8dms.jar  ojdbc8dms_g.jar  simplefan.jar
[root@localhost lib]# docker cp ojdbc8.jar 7c18b12e8d21:/usr/local/tomcat/lib/
Successfully copied 4.16MB to 7c18b12e8d21:/usr/local/tomcat/lib/
[root@localhost lib]# docker cp ojdbc8_g.jar 7c18b12e8d21:/usr/local/tomcat/lib/
Successfully copied 6.94MB to 7c18b12e8d21:/usr/local/tomcat/lib/
[root@localhost lib]# docker cp ojdbc8dms.jar 7c18b12e8d21:/usr/local/tomcat/lib/
Successfully copied 5.8MB to 7c18b12e8d21:/usr/local/tomcat/lib/
[root@localhost lib]# docker cp ojdbc8dms_g.jar 7c18b12e8d21:/usr/local/tomcat/lib/
Successfully copied 6.97MB to 7c18b12e8d21:/usr/local/tomcat/lib/
[root@localhost lib]# docker cp simplefan.jar 7c18b12e8d21:/usr/local/tomcat/lib/
Successfully copied 30.7kB to 7c18b12e8d21:/usr/local/tomcat/lib/

 

그리고 Tomcat과 Oracle이 잘 연결되는지를 테스트할 JSP 소스페이지도 Tomcat Container의 ROOT 폴더에 복사해 넣는다.

이 소스는 다음과 같다. 이 소스는 인터넷에서 쉽게 검색을 통해 얻을 수 있다. (출처 : https://infotake.tistory.com/71)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"

%><%@ page import="java.sql.*, java.util.*"

%><html>

<head>

<title>JSP Oracle, JDBC 예제</title>

<meta http-equiv="Cache-Control" content="no-cache"/>

<meta http-equiv="Expires" content="0"/>

<meta http-equiv="Pragma" content="no-cache"/>

</head>

<body>

<%

    Connection conn = null;

 

    try {

        String DB_HOST = "jdbc:oracle:thin:@192.168.219.53:1521:mypdb";

        // 아이피, 포트, 서비스(SID) 정보를 수정, PDB인 경우 PDB명

        String DB_USER = "mypuser01"; // 아이디(유저) - 11g 이상시 대소문자 구분 확인

        String DB_PASS = "oracle123"; // 패스워 - 11g 이상시 대소문자 구분 확인

 

        Class.forName("oracle.jdbc.driver.OracleDriver");

        conn = DriverManager.getConnection(DB_HOST, DB_USER, DB_PASS);

 

        out.println("연결성공!");

    } catch (ClassNotFoundException e) {

        out.println("연결 드라이버 없음");

    } catch (SQLException e) {

        out.print("연결실패 : ");

        if(e.getMessage().indexOf("ORA-28009") > -1)

            out.println("허용되지 않는 접속 권한 없음");

        else if(e.getMessage().indexOf("ORA-01017") > -1)

            out.println("유저/패스워드 확인");

        else if(e.getMessage().indexOf("IO") > -1)

            out.println("IO - 연결확인!");

        else

            out.println("기본 연결확인!");

 

    } finally {

        if(conn != null)

            conn.close();

    }

%>

</body>

</html>

그리고 웹브라우저에서 oracle 접속 테스트 용 JSP 페이지를 호출한다.

접속에 실패하면 소스 상에서 볼 수 있듯 각 단계별로 원인을 찾기 쉽도록 다른 에러메시지를 출력하도록 하고 있다.

만약 에러가 발생한다면 oracle 12c의 listener.ora 파일에서 아래의 노란색 점선 상자의 내용을 추가하고 리스너를 재구동한 뒤 접속해봐야 한다.

 

 

728x90