간단한 Web 프로젝트를 Spring Boot로 만들었는데

이상하게 Tomcat에 War로 올리면 404 에러로 경로를 못찾는 현상이 발생했다.

 

덕분에 몇시간을 날렸는데 이유는 간단했다..

 

 

Spring Boot의 Main 클래스에 SpringBootServletInitializer를 상속받지 않아서였다.

 

일반적인 Spring Framework에서는 Web.xml에 DispatcherServlet을 등록하는 작업이 필요했다.

Servlet 3.0에서는 web.xml이 없이도 배포가 가능 해졌는데 Apache Tomcat 7부터 지원을 한다.

 

web.xml의 역할을 WebApplicationinitializer 인터페이스를 구현하여 프로그래밍으로 ServletContext를 구현할 수 있도록 바뀐것이다.

SpringBootServletInitializer는 WebApplicationinitializer의 구현체이다. 

SpringBootServletInitializer를 이용하여 WebApplicationContext를 생성하여 Servlet Context에 추가할 수 있다.

 

나 같은 경우에는 프로젝트에 web.xml도 없었고, WebApplicationinitializer를 구현한 SpringBootServletInitializer도 없었기 때문에 Tomcat에서 URL의 요청을 받아드릴수가 없었던 것이다..

 

SpringBootServletInitializer를 상속 한다는건 결국 Tomcat과 같은 Servlet Container 환경에서 Spring Boot Application을 동작 가능 하도록 Web Application Context를 구성한다는 의미이다.!

 

나와 같은 삽질은 다른 사람들은 하지 않았으면....

RHEL 기반인 CentOS7에 postgreSQL을 설치하는 포스팅이다.

 

이전에 포스팅한 LXD에 올린 Centos7 컨테이너로 진행할 예정인데 일반적인 환경과 크게 다를건 없을것 같다.

 

 

1. http://yum.postgresql.org/ 에 접속해보면 설치가능한 버전과 지원하는 OS를 확인할 수 있다.

 

2. 저장소를 설치

-> sudo yum install https://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-7-x86_64/pgdg-centos96-9.6-3.noarch.rpm 

 

3. 설치가능한 패키지 검색

-> sudo yum list postgres*

 

3. PostgreSQL 9.6 버전 패키지 설치

-> sudo yum install postgresql96-server postgresql96-contrib

 

4. DB 생성

-> sudo /usr/pgsql-9.6/bin/postgresql96-setup initdb

 

5. PostgreSQL 시작

-> sudo systemctl restart postgresql-9.6

or

-> sudo service postgresql-9.6 start

 

6. 부팅시 자동 시작되게 설정

-> sudo systemctl enable postgresql-9.6 

 

 

이렇게 하면 PostgreSQL 서버를 설치하고 구동하는게 끝났다.

netstat -tnlp 명령어를 쳐서 아래와 같이 5432 포트로 서버가 구동되어있는걸 확인하면 끝.


[root@vm1 data]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      309/sshd
tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      427/postmaster
tcp6       0      0 :::22                   :::*                    LISTEN      309/sshd
tcp6       0      0 :::5432                 :::*                    LISTEN      427/postmaster

 

접속 해보고 싶다면 psql 명령어를 이용해서 접속할 수 있다.

-> sudo -u postgres psql

참고로 psql 접속 종료 명령어는 \q

 

이제 생성한 DB를 외부에서도 접속 가능하게 설정을 수정해줘야 하는데 vi에디터로 몇 줄 고쳐주면 된다.

 

6. 외부접속 허용하기 

-> cd /var/lib/pgsql/9.6/data/

-> vi pg_hba.conf

 

스크린샷처럼 맨 하단 라인에 아래의 내용을 추가한다

 host    all     all     0.0.0.0/0       password

 

그리고서 저장 후 vi를 종료 (:wq)

 

이제 마지막으로 postgresql.conf 파일을 수정

-> vi postgresql.conf

? 명령어를 사용해서 listen 검색 후 listen_addresses = '*' 로 수정한다. (주석 제거)

 

마찬가지로 저장 후 vi 종료

 

 

Orange Ade로 리눅스에 올린 PostgreSQL을 접속해보니 잘된다. 

 

혹시 위의 설정까지 했는데 안된다면 리눅스의 방화벽을 해제하길..!!

LXC와 LXD 둘중 뭐로할까 고민을 했는데

회사에서 쓰고있는 LXD를 이용하기로 결정했다.

 

검색해보면 LXD보다는 LXC 문서가 많아서 걱정이 됬는데 잘 정리된 글을 보고 따라하니 한방에 성공.

나중에 까먹지 않기 위해서 블로그에 정리하는 글이다.

 

참조한 문서는 

https://www.cyberciti.biz/faq/how-to-set-up-and-use-lxd-on-centos-linux-7-x-server/

 

How to Set Up and Use LXD on CentOS Linux 7.x Server - nixCraft

Explains how to set up and use LXD on CentOS Linux 7.x server and create or configure your first operating system level virtualization.

www.cyberciti.biz

 

Step 1 – CentOS 7 업데이트

sudo yum update
sudo reboot // 난 리붓안함

 

Step 2 –  on CentOS 7에 EPEL 저장소 설정

sudo yum install epel-release
sudo yum update

 

Step 3 – CentOS 리눅스에서 COPR 저장소를 활성화 및 구성하는 방법

sudo yum install yum-plugin-copr

sudo yum copr enable ngompa/snapcore-el7

 

Step 4 – LXD 설치

sudo yum install snapd
sudo systemctl enable --now snapd.socket

 

Step 5 – LXD용 CentOS Linux 커널 구성


grubby --args="user_namespace.enable=1" --update-kernel="$(grubby --default-kernel)"
grubby --args="namespace.unpriv_enable=1" --update-kernel="$(grubby --default-kernel)"
sudo sh -c 'echo "user.max_user_namespaces=3883" > /etc/sysctl.d/99-userns.conf'
sudo reboot

Step 6 – LXD를 CentOS에 설치


sudo snap search lxd

sudo snap install lxd
sudo ln -s /var/lib/snapd/snap /snap

 

설치 확인하는법:
snap list
snap services // 이거할때 데몬에러뜸 하지만 무시

// 여기까지 진행 후 Reboot으로 시스템 재부팅

Step 7 – LXD 설정


sudo usermod -a -G lxd vivek
newgrp lxd
id

 

// LXC 서버 확인 (생성된 컨테이너를 확인할 수 있다. 하지만 지금은 초기라 List에 뜨는게 없을꺼임)
lxc list

 

[root@localhost 아무개]# lxc image list images:
+--------------------------------------+--------------+--------+----------------------------------------------+---------+-----------+-------------------------------+
|                ALIAS                 | FINGERPRINT  | PUBLIC |                 DESCRIPTION                  |  ARCH   |   SIZE    |          UPLOAD DATE          |
+--------------------------------------+--------------+--------+----------------------------------------------+---------+-----------+-------------------------------+
| alpine/3.6 (3 more)                  | d3416fd3f3e3 | yes    | Alpine 3.6 amd64 (20190528_13:00)            | x86_64  | 3.17MB    | May 28, 2019 at 12:00am (UTC) |
+--------------------------------------+--------------+--------+----------------------------------------------+---------+-----------+-------------------------------+
| alpine/3.6/arm64 (1 more)            | cc9107640c99 | yes    | Alpine 3.6 arm64 (20190528_13:02)            | aarch64 | 3.07MB    | May 28, 2019 at 12:00am (UTC) |
+--------------------------------------+--------------+--------+----------------------------------------------+---------+-----------+-------------------------------+

 

// LXC Storage 생성 (컨테이너를 생성하기위한 스토리지 생성단계)
lxd init

[root@localhost 아무개]# lxd init
Would you like to use LXD clustering? (yes/no) [default=no]: 
Do you want to configure a new storage pool? (yes/no) [default=yes]: 
Name of the new storage pool [default=default]: 
Name of the storage backend to use (btrfs, ceph, dir, lvm) [default=btrfs]: lvm
Create a new LVM pool? (yes/no) [default=yes]: 
Would you like to use an existing block device? (yes/no) [default=no]: 
Size in GB of the new loop device (1GB minimum) [default=15GB]: 
Would you like to connect to a MAAS server? (yes/no) [default=no]: 
Would you like to create a new local network bridge? (yes/no) [default=yes]: 
What should the new bridge be called? [default=lxdbr0]: 
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: 
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: 
Would you like LXD to be available over the network? (yes/no) [default=no]: 
Would you like stale cached images to be updated automatically? (yes/no) [default=yes] 
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: 

 

[root@localhost 아무개]# lxc storage list        // 생성된 스토리지 확인
+---------+-------------+--------+--------------------------------------------+---------+
|  NAME   | DESCRIPTION | DRIVER |                   SOURCE                   | USED BY |
+---------+-------------+--------+--------------------------------------------+---------+
| default |             | lvm    | /var/snap/lxd/common/lxd/disks/default.img | 1       |
+---------+-------------+--------+--------------------------------------------+---------+

 

Step 8 – 첫번째 컨테이너 생성하기

// 아래의 명령어를 사용하면 설치할수 있는 컨테이너의 List가 출력됨(무수히 많음)

lxc image list images:  // 전체 리스트
$ lxc image list images: | grep -i centos  // Centos 리스트
$ lxc image list images: | grep -u ubuntu // Ubuntu 리스트

 

첫번째 컨테이너 생성하는 방법

 


lxc launch images:{distro}/{version}/{arch} {container-name-here}

lxc launch images:{운영체제}/{버전}/{비트?} {컨테이너 이름}
Let us see some examples to create and start containers from various Linux distro images as per your needs.

 

[root@localhost 아무개]# lxc launch images:centos/7/amd64 test
Creating test
Starting test   

CentOS7 리눅스 생성 방법

lxc launch images:centos/7/amd64 cenots-db  

Ubuntu 리눅스 생성 방법

lxc launch images:ubuntu/xenial/amd64 ubuntu-nginx

Fedora 리눅스 생성 방법

lxc launch images:fedora/28/amd64 fedora27-c1

 

LXD의 명령어들


lxc list // 생성된 컨테이너 목록


[root@localhost 아무개]# lxc list

+------+---------+-----------------------+----------------------------------------------+------------+-----------+
| NAME |  STATE  |         IPV4          |                     IPV6                     |    TYPE    | SNAPSHOTS |
+------+---------+-----------------------+----------------------------------------------+------------+-----------+
| test | RUNNING | 10.14.12.13 (eth0) | fd42:e47e:ef8a:90b:216:3eff:fee0:867b (eth0) | PERSISTENT |           |

+------+---------+-----------------------+----------------------------------------------+------------+-----------+

 


시작 종료 재부팅 방법
lxc start 컨테이너명     // 시작
lxc stop 컨테이너명     // 종료
lxc restart 컨테이너명  // 재시작

 

제거 or 삭제

lxc delete 컨테이너명   // 삭제


컨테이너 정보 가져오기
lxc info 컨테이너명      // 정보

 

컨테이너에 접속하기
lxc exec 컨테이너명 bash

[root@localhost 아무개]# lxc exec test bash
[root@test ~]#

 

혼자 집에서 심심풀이로 만드는게 있는데 프론트에서 서버로 보내는 요청이 실패가 되는 현상이 발생했다.

 

크롬 콘솔을 보니 cross 어쩌고 저쩌고..

 

왜그런지 찾아보니 보안상의 이유로 스크랩트 내에서 HTTP요청을 SOP(Same-Origin Policy)로 막는 현상이 있었다.

 

SOP는 두 Origin간에 프로토콜, 포트, 호스트가 같아야 동일 Origin으로 간주하는데

 

예를 들어서 서버가 https://luji.tistory.com/ 주소를 사용중이고 Client에서 보내는 요청이 

1) https://luji.tistory.com/post  일 경우에는 성공

2) http://luji.tistory.com/post  일 경우에는 실패 (프로토콜이 다름 https / http)

3https://luji.tistory.com:8080/post  일 경우에는 실패(포트가 다름)

4https://www.luji.tistory.com/post  일 경우에는 실패(호스트가 다름)

 

이런 경우에 SOP정책에 의해 실패된다

 

그렇담 해결방법은 클라이언트에서 JSONP를 사용하거나 서버에서 CORS를 이용하여 해결 가능하다.

 

Spring Boot에서 CORS를 이용한 방법

1) Controller 개별 지정

@CrossOrigin
@GetMapping("/q")
String getTest(int test) throws Exception {
return testService.test(test);
}

 

2) 전역으로 지정

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}

 

티스토리에 플러그인을 적용하지 않아서 코드가 더러운데 나는 WebConfig.java를 생성하여 addCorsMappings를 오버라이드하는 방식으로 전역파일로 따로 빼서 addMapping에 경로를 지정해서 사용중이다.

+ Recent posts