ERP 서버 이전

하루면 되지 않을까 생각하고 시작했던 서버 이전이 여러가지 난관에 부딛히며 일주일간 개 고생을 하였다. 다시는 개 고생하지 말자며 그간의 경험을 기록한다.

서버는 apache-php-mysql 환경과 apache-tomcat-oracle-xe 환경 두대가 있다.

5년간 운영된 나의 서버는 그동안 많은 고생을 해주었고 작은(짭짤한) 수입을 내게 안겨주었다. 하드의 보증 기간도 3년인데 5년이나 사용한 나의 서버가 이제 언제 죽을지 몰라서 걱정하는 사태에 이르렀기에 클라우드 서버로의 서버 이전을 결심하게 되었다.

클라우드 서버 이용의 장점은, 무지 많으나 그중에 자동스크립트로 서버운영이 가능하고 서버 생성 삭제 증설이 간편하며 블록저장소의 고가용성 등이 있다.

아래는 일주일 간의 고생 내용이다.

1. 클라우드 서버 선택
iwinv.kr : 오픈스택 기반의 클라우드 서비스
아마존 대비 120배 저렴.
다양한 웹 GUI 서비스 기능. (모니터링, 방화벽, 서버 업/다운 그레이드, 오토스케일, 로드밸런스, 블록스토리지, DNS관리, 서버 운영 가이드 등)

2. DOCKER 환경 설치
base 운영체제 : 우분투16.04_64bit
sudo 사용 유저 생성
ssh root 로그인 제한 설정
최신 버전의 docker-ce, docker-compose 설치
docker-compose 사용 네트워크 생성 mtu-1450
(networks-outside-external-name)
block-storage 파티션생성 및 자동 마운트 설정

3. 서버 이미지 저장
현재까지 설정된 서버를 이미지로 저장하여 추가 서버 생성시 이미지를 통해 현재 시점의 이미지로 서버를 추가 할 수 있다.

4. 저장된 이미지를 통한 추가 서버 생성.
로그인 시 /dev/null 오류 발생. (처리 : 파일 삭제 rm -f /dev/null 후 재시작)
명령프롬프트가 동일하여 서버 구분이 어려움. (/etc/hostname 이름 변경 )
sudo 명령 사용시 hostname 오류 발생. (/etc/hosts에 127…. hostname추가)

5.사용할 docker 이미지 서치 (php서버)
apache-php-ssl 설정이 된 서버 이미지 검색 및 검증 후 설치 테스트
(적당한 이미지 검색 및 검증 테스트에 6시간이상 소요됨 ssl 설정이 큰 이유)
php: short코드 문제 발생 및 로그인시 세션 data 파일 생성 오류 발생.
mysql: mariadb로 설치시 db파일이 생성되지 않는 문제 발생하여 mysql생성.
#php 도커 이미지 : ubuntu-16-apache-php-5.6
#컨테이너 이미지 모두 삭제 방법(docker rm `docker ps -a -q`)
#PHP 짧은 태그 허용

6.docker-compose.yml 파일 생성(version 2)
docker 컨테이너 이미지 설정(volume, port)
mtu-1450 network 사용설정
자동 재시작 설정 restart

7.mysql dump 복원
db 사용계정은 mysql evn설정을 통해 자동으로 생성.
#Mysql 백업 및 복구

8.php 소스 반영 및 db연결
db연결 설정 :  도메인 ‘db'(컨테이너이름) 로 연결 설정함.
DB연결 함수 없음 오류 발생 : php7.1에서 5.6으로 docker 이미지 변경
apache redirect 설정 .htaccess 기입방법 사용.

9. letsencript 인증서 설정
소스 다운로드 : git clone letsencript …
인증서 생성 : 초기 이메일등 입력 후 차후 crontab을 이용한 자동생성 가능

10. 테스트 및 확인
안전함 사이트 접속 가능 및 성능 기존 사이트에 비해 30~40% 상향됨.
(예상 원인 ssd 블록스토리지의 성능향상으로 인한 DB 성능 개선 및 ddr4의 최신 서버환경.)

11. 사용할 docker 이미지 서치 (tomcat서버)
이미지 서치 및 검증에 2일 소요 :  tomcat-ssl cert파일 바로 사용문제.
java openjre문제. 결국 openjre 및 jks 사용해서 톰캣구성함. (메모리튜닝등 남음)
#사용된 oracle 도커 이미지 :  sath89/oracle-xe-11g
( manager폴더가 삭제가 안되어서 webapps를 볼륨링크로 연결하여 생성안되게 막음)
#아래는 스터디용 링크
axiom-data-science : 서버 생성 스크립트 작성시 참조(메모리 설정등)
(보안상 tomcat 계정으로 기동되는 이미지들은 work폴더에 jsp_classs파일이 생성되지 않는 문제가 있다.)

12. docker-compose.yml 파일 생성(version2)
docker 컨테이너 이미지 설정(volume, port)
mtu-1450 network 사용설정
자동 재시작 설정 restart
command명령 letsencrip 인증서를 jks로 변환해야하는데 스터디 필요.ㅠ

13. 오라클 DB dump파일 복원
charactorset 문제 발생. WINMS949에서 UTF8로 넘어가면서 컬럼 자릿수 오류 다수 발생. 해결방법: 스키마 생성 후 올류나는 컬럼 자릿수 수정 후 임폴트하는 방법과 문자셋을 변경하는 방법.
문자셋 변경함: 오류 발생.  varchar에 대한 문자셋이 중복됨. 해결방법 database 문자셋 변경.
# 오라클 DB 이전 (exp/imp)
# 오라클 리스너 확인 : lsnrctl status
#ORA-06553 알수없는 문자셋 오류 처리
(update props$를 KO16MSWIN949를 실행 후 DB데이터 복구에는 성공했으나 ORA-06553오류가 발생했다. DATABASE CHARACTER 부분을 추가 실행하여 문제를 해결함.)

14. java 소스반영.
db연결 설정 변경 IP주소를 컨테이너 이름 (oracle)으로 변경.
tomcat redirect 설정: web.xml파일 <web-app>에 <security-constraint>추가
톰캣 재시작시 로딩이 오래걸리는 문제 확인 안됨.ㅠ.(2분가까이..)
#tomcat https설정 : server.xml <Connector port=”443″ … 추가

15. letsencript 인증서 생성.
jks 파일 변환 : openssl 사용 및 keytool 사용
jks 파일 volume연결.(파일이 없을 시 폴더로 인식해서 빈폴더 생성됨)

16. 작동 확인 및 테스트
문제없음. 성능 기존서버 대비 30~40%정도 빨라짐….. 일단 튜닝을 안해도 되겠다…ㅎㅎㅎ

17. docker 컨테이너 표준시 변경
서버를 재시작 시 지속적으로 변경해주는 스크립트를 작성해서 변경하는 방법도 있으나 , /etc/localtime 파일을 volume으로 연결해 주는 방법이 더 간편하다. (스크립트 작성시 참조 : 리눅스 한국 시간으로 변경)

18. letsencript crontab 설정

 

 

 

클라우드 서버에 docker 기반 서비스 셋팅 ( 서버이전 )

3년 넘게 사용해온 물리 서버가 있다.

IDC에 입주해있기 때문에 비교적 안전하게 장기간 사용할 수 있겠지만

이것이 언제 뻗을지 모른다는 불안감에 항상 시달리고 있다.

 

고객으로 부터 연락이 왔다. 윈도우 10 설치를 하였는데 https 인증서 접속 오류가 난다.

이전에 ssl을 5년짜리 사설 인증서를 만들어서 설정을 해두었기 때문에

브라우저에 별도로 신뢰할 수 있는 인증서로 등록을 하지 않으면 해당 오류가 발생한다.

 

전에도 메뉴얼을 만들어서 안내를 해주었는데도 사용자들이 잊어버리고 컴퓨터를 새로깔고서는 안된다고 문의가 들어온다.

때마침 let’s encript 무료 공인 인증서를 알게되어서 시간이 좀 걸린다고 안내를 하고 ssl을 변경하기로 마음 먹었다. 시간이 더 걸리더라도 나는 한번만 일하면 되는 더 가치있는 일을 하고 싶었다.

 

오래된 리눅스 서버(centos6.x)에 접속을해서 뭔가를 하려고 하니 아차.. 난 이제 ubuntu에 익숙해져 있었다.

구글링을 하지 않을 수 없는 상황에서 letsencript 설치도 python2.x 버전을 지원하지 않아 서버의 python을 업그레이드 해야하고 아. 점점 짜증이 밀려왔다.

그래서 그냥 서버를 이관하기로 결심했다.  점점 일이 산으로 가는 느낌이지만 난 보다 가치있는 일을 하기를 좋아한다… —

 

우선 클라우드 서버가 물리 서버보다 비용이 약간 더 저렴하고 더 안정적이고

서버 한대에 vhost를 나누지 않아도 공인 ip를 기반으로 독립된 서버를 각각 운영할 수 있다.

게다가 block storage를 사용하면 데이터가 4개의 서버에 분산 저장이되어 안정적이며 거기에 더해 1주에 한번씩 데이터를 별도의 장치에 백업을 해주어서 천만에 하나 데이터가 날라가는 상황이 발생하더라도 1주일 전 시점으로는 복구가 가능하다.

 

자, 이런 클라우드 가상서버 환경에 더에서 docker 기반으로 서비스를 구축하면

언제든지 docker 폴더를 다운로드 받아서 운영과 같은 환경으로 로컬에서 테스트가 가능하다. 반대로 로컬을 그대로 운영으로 옮기는 것도 가능하며 별도의 서버 이동으로 인한 오류는 발생하지 않는다.

게다가 서버 재시작은 1~2초 밖에 걸리지 않으며 스케일링 기능이나 오케스트레이션 기능으로 자동으로 서버 관리 및 확장 모니터링이 가능하다.;…

 

장점을 나열하자면 수도없이 많다. 어찌되었든 난 2개의 서버중에 한대를 성공적으로 이관을 하였으며 물리 서버보다 오히려 서버 성능이 더 좋아졌다. 왜나하면 물리서버는 저장장치가 hdd인 반면 가상서버는 ssd 이기 때문이다.

고객 만족 서비스 제공으로 나름 뿌듯함에 이글을 적고있다.

 

이제 서론은 그만하고 어떻게 작업이 진행되었고 어떤 문제들이 발생해서 어떻게 해결하였는지 후기를 남긴다.

현재 먼저 진행된 건은 docker 기반의 apache php mysql 환경으로 letsencript-auto를 이용하여 ssl인증서까지 자동으로 생성 적용된다.

그리고 오늘 더 해야할 건은 docker 기반의 tomcat oracle-xe 환경으로 역시 letsencript-auto를 이용하여 ssl 인증서까지 자동으로 생성한다.

 

 

 

 

 

 

Bash 스크립트 명령어 치환

echo `uname -s’ 를 출력해보면

Linux라는 문자열이 출력되는 것을 볼 수 있다.

uname -s라는 문자열이 명령어로 치환되어 반환된 결과 값인 Linux 문자로 변경 되는데 이런 것들을 명령어 치환이라고 부른다.

지금까지는 항상 복붙을 통해 위와같은 명령어들을 사용해 오다가 복붙이 안되는 환경에서 직접 타이핑을 해야될 일이 생겼는데 그만 실수를 하고 말았다.

역따옴표(` `)가 명령어치환 선언문자인데 나는 작음다옴표(‘ ‘)를 사용하여 제대로 치환이 안되는 문제가 발생했다.

솔직히 몰랐다 여태 작은따옴표인줄 알고있었는데 역따옴표있다.

뭐라고 구글링 해야되는지도 몰랐는데 간신히 echo 명령어 치환으로 검색해서 찾다보니 아래의 링크의 두번째 줄에서 역따옴표임을 알게되었다.;–

ㅋㅋㅋ

14장. 명령어 치환(Command Substitution)

클라우드 서버 리눅스 초기 설정

iwinv.kr 을 이용하여 서버를 구축한다.

절차는 다음과 같다.
가상서버선택 -> 운영체제 선택 -> 디스크 볼륨 추가 -> 방화벽설정 -> 설치

몇분후 가상서버 생성이 완료되는데 계정과 비밀번호는 등록된 관리자 email로 발송된다.

서버 생성 후 다음과 같은 초기 설정이 필요하다

1.  root 계정 비밀번호 변경
2. 앞으로 사용할 sudo 권한 유저 생성.(visudo사용편집)
3. ssh root 로그인 방지(/etc/ssh/sshd_config 파일수정 PermitRootLogin no)
4. apt-get update && apt-get dist-upgrade
5. (한국 서버로 패키지 저장소 변경..등 궂이 안해도 됨)

초기 설정 후 이미지를 저장해 놓고 가상 서버 추가 생성시 저장된 이미지를 이용하여 서버를 생성할 수 있다.
# 추가로 저장된 이미지로 서버를 생성하면 /dev/null 퍼미션 오류가 발생한다.  이때는 /dev/null 파일을 삭제 후 서버를 재시작 해주면된다.
(재시작시 생성되는데 시간이 좀 걸리므로 재시작 말로 아래 명령으로 생성해 주어도 된다.
mknod -m 0666 /dev/null c 1 3)
#또 /etc/hosts  및 /etc/hostname 도 수정

 

이제 docker를 설치한다.

openstack에서는 오버레이 네트워크 사용으로 오버해드가 발생하는 것을 방지하기 위해서 가상 네트워크의 mtu 값을 기본 1500에서 1450으로 낮추는 어서 설정하게 되어있다.

반면 docker 네트워크는 기본 설정인 1500으로 되어있기 때문에 패킷손실로 네트워크 오류가 발생한다. 때문에 docker 설치 후 반드시 mtu 기본값을 변경해 주어야 하며, docker-compose는 기본네트워크를 사용하지 않고 임의 네트워크를 생성하여 작동하는데 이때 기본 mtu값 1500이 변경이 불가능하여 수동으로 네트워크를 생성하여 mtu 값을 1450으로 지정하고 사용할 네트워크를 명시하여 지정하여야 한다.

 

docker 설치

1. 설치된 docker 제거

sudo apt-get remove docker docker-engine docker.io

2. apt https를 통한 저장소 사용을 하도록 추가 패키지 설치

sudo apt-get install apt-transport-https ca-certificates curl software-properties-common

3. Docker의 공식 GPG 키 추가

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

4. 안정적인 저장소 추가

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

5. apt 색인 업데이트

sudo apt-get update

6. docker-ce 설치

$ sudo apt-get install docker-ce

 

docker 설정

1. docker 그룹 생성

sudo groupadd docker

2. 사용자 추가

sudo usermod -aG docker $USER

3. sudo 명령 없이 docker 사용가능한지 확인( 재로그인 또는 재시작 필요)

docker run hello-world

4. 부팅할때 docker 시작 구성

sudo systemctl enable docker

5. 기타 다른 저장소, 커널호환성, DNS서버지정, 원격 API 접근허용 등 설정은 docker홈페이지 참조.

 

docker 네트워커 기본 mtu 변경(네트워크 문제해걸)

1. docker.service 파일 복사

sudo cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service

2. docker.service 설정 수정( –mut 1450 옵션추가)

sudo vi /etc/systemd/system/docker.service

ExecStart=/usr/bin/dockerd -H fd:// ExecStart=/usr/bin/dockerd -H fd:// --mtu 1450 # 옵션 추가

3. docker 재시작

sudo systemctl daemon-reload
sudo service docker restart

4. docker 네트워크를 생성할때 mtu변경 옵션 #참고 (mtu-1450은 네트워크이름)

docker network create -o "com.docker.network.driver.mtu"="1450" mtu-1450

 

docker-compose 설치

1. docker compose 다운로드 ( 최신 버전확인 후 아래 명령어의 버전정보 변경)

sudo curl -L https://github.com/docker/compose/releases/download/1.16.0-rc1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

2.  docker-compose 파일 실행권한 추가

sudo chmod +x /usr/local/bin/docker-compose

3. 설치 테스트

docker-compose --version

 

docker-compose 네트워크 생성 (mtu=1450)

docker network create -o "com.docker.network.driver.mtu"="1450"

# mtu-1450은 네트워크이름임

 

 

block storage 추가시 설정 및 확인

1. 추가된 block storage 확인

sudo parted -l

# 신규 디스크 추가시 Error: /dev/vdb: unrecognised disk label 오류 발생함.
/dev/vdb가 디스크 장치명임.( 이용중 장치 추가시 reboot 또는 /etc/init.d/networking restart 해줘야함)

2. 파티션 생성

# sudo parted /dev/vdb
parted) mklabel msdos
parted) mkpart primary 4 100%
parted) q

3. 파티션 포맷

/sbin/mkfs.xfs -f /dev/vdb

4. 파티션 마운트

mkdir /home/jinho/docker
mount /dev/vdb /home/jinho/docker
df -Th

5. 마운트 설정파일에 등록

디스크 상세정보 ID 값 및 이름 확인 
(ID: 39727e60-fff2-4d6c-8419-9dad2704aa4d )

vi /etc/mpoint 파일에 다음행 추가
39727e60-fff2-4d6c-8419-9dad2704aa4d /home/jinho/docker

# 오루발생 iwinv에서 가이드하고있는 mpoint로는 자동마운트가 되지 않음
vi /etc/fstab 파일에 다음행 추가
/dev/vdb /home/jinho/docker  xfs  defaults  0  0
#설정내용 바로 적용
sudo mount -a

6. 기타 디스크 삭제 분리 이동에 관련해서는 아래 링크 참조

iwinv 리얼서버 추가 디스크 관리

 

 

오픈스택 네트워크의 mtu값이 1450인 이유

오픈스택 MTU 값이 1450이 된 이유 설명 링크
VXLAN과 같은 오버레이 네트워크는 오버헤드를 증가시키고 페이로드 또는 사용자 데이터를 위해 사용 가능한 용량을 감소시키는 추가적인 패킷 헤더를 포함합니다. 가상 네트워크 인프라에 대한 지식이 없더라도 인스턴스들은 기본 이더넷에 대한 1500 바이트의 maximum transmission unit (MTU) 를 사용하여 패킷 전송을 시도합니다. Internet protocol (IP) 네트워크는 end-to-end MTU를 발견하고 패킷 크기를 정확히 조정하기 위한 path MTU discovery (PMTUD) 메커니즘을 포함합니다. 그러나 몇몇 운영체제와 네트워크에서는 차단하거나 또는 PMTUD를 지원하지 않아 성능 저하 또는 연결 실패를 야기합니다.

이상적으로, tenant 가상 네트워크를 포함하는 물리 네트워크 상에서 jumbo frames 를 활성화하여 해당 문제를 방지할 수 있습니다. 점보 프레임은 가상 네트워크에서 VXLAN 오버헤드에 대한 영향력을 무효화하도록 MTU를 약 9000 바이트까지 지원합니다. 그러나 많은 네트워크 장치들은 점보 프레임을 지원하지 않으며 OpenStack 관리자들은 종종 네트워크 인프라에 대한 제어를 담당하지 않습니다. 후인 경우, VXLAN 오버헤드를 고려하여 인스턴스 MTU를 줄임으로써 MTU 문제를 방지할 수 있습니다. 적합한 MTU 값을 결정하는데는 실험을 필요로 하지만 1450 바이트가 대부분의 환경에서 잘 동작할 것입니다. IP 주소를 인스턴스에 할당 및 MTU 값 또한 조정하는 DHCP 서버를 구성할 수 있습니다.

즉 오버레이 네트워크를 사용시 발생하는 오버헤드를 줄이기 위해서 점보프레임을 활성화할 수 있는데 많은 네트워크 장치에서 점보프레임을 지원하지 않기 때문에 MTU 값을 줄이는 것으로 이문제를 해결할 수 있다. 1450이 대부분의 환경에서 잘 동작한다.

하지만 docker 사용시 mtu값이 1500으로 설정되기 때문에 오픈스택 네트워크에서 50의 패킷 손실이 발생하고 이로인한 오버헤드가 엄청나다…

docker의 mtu 기본 값이 서버의 설치된 서버의 기본 mtu값을 사용하도록 하는 기능이 추가되야 될 것 같은데 버전업이 되면서 이문제는 해결될 것 같다.

ERP 서버이전

3~4년 정도 사용한 ERP 서버를 가지고 있는데

서버 노후화로 인해 문제 발생시 빠르게 장애처리를 할 수 없는 불안감에 서버를 이전하기로 생각만 해오다가 오늘 드디어 서버를 이전 하기로 결심 했다.

사실은 그동안 사용해오던 사설 인증서를 letsencrlypt로 교체하기 위한 작업을 하려다 보니까. 서버 운영체제가 centos 6.1이다.

처음에 리눅스를 접하게 되어 사용하던 것이 centos이지만 지금은 우분투를 사용하고 있어서 centos의 모든 설정이 매우 낯설게 느껴져서 힘들었는데 거기에 더해 인증서를 자동 갱신하기 위한 certbot 설치에서 난관이 있어 서버 이전을 결심하게 되었다. (거의 에라 모르겠다. 아 짜증나 이런 심정에 결심을 하였다.)

서버는 iwinv.kr에서 제공하는 가상 클라우드 서버를 사용하고 docker 기반으로 서버 구성을 잡으려고 한다.  4개의 물리 컴퓨터 하드에 복제 저장되는 스토리지에 volume을 위치해두면 차후에 서버 장애시 저장된 이미지의 OS를 서버를 재생성하고 docker를 up하는데 10분이 걸리지 않을 것으로 예상한다.

서버 장애감지와 복구도 자동으로 해야겠지만 위에서 말하는 장애는 물리 컴퓨터의 고장으로 서버가 죽어버리를 상황에 대한 복구 처리이다. 보통은 장애 발생시 반나절 이상이 걸리를 것을 예상해보면 10분이란 시간이 얼마나 짧은 시간인지 알 수 있다.

 

작업 절차는 아래와 같다.

  1. 클라우드 서버를 생성한다.
  2. docker와 docker-compose를 설치한다.
  3. MTU 문제를 해결한다.
    (docker의 기본 네트워크 설정의 mut값은 1500(일반적인 값)인데 반해서 iwinv에서 사용하는 openstack으로 생성된 가상머신은 mtu가 1450으로 셋팅이 되어있다.  때문에 50의 최대 전송패킷의 차이로  들어오는 모든 패킷마다 50의 손실이 발생하고 이때문에 엄창난 네트워크 트래픽 처리 지연이 발생해 버린다..ㅠ 거의 통신불능에 가깝다.
    docker의 네트워크를 생성하여 mtu값을 지장하고 docker-compose를 시작할때 생성된 네트워크를 사용하도록 지정한다. 복잡한 이야기지만 docker의 기본 네트워크를 변경시킬 수도 있으나 docker-compose를 사용해서 컨테이너를 시작할 경우 임이의 네트워크를 생성하여 컨테이너 그룹을 시작하는데 이때는 docker의 기본 설정을 따르지 않기 때문에 네트워크를 미리 생성하여 docker-compose의 시작히 해당 네트워크를 사용하도록 지정을 해야한다. 전에 이것때문에 서버 반영하는날 새벽까지 개고생을 한 기억이 있다. )
  4. ERP 서버를 컨테이너 환경을 docker-compose를 이용하여 구축한다.
    apache, php, mysql 환경과, tomcat, oracle-xe 환경이다.
  5. DB 데이터 이전과 소스 반영 후 성능 테스트를 진행한다.
  6. crontab과 certbot 에이전트를 이용하여 letsencrypt SSL생성을 적용한다.
  7. 문제가 없는 것을 확인하여 최종 사용자에게 서버 이전을 공지한다.
  8. 서버 이전작업 당일 새벽 1시 생성된 최종 DB 데이터를 사용하여 데이터 이관 후 도메인 연결을 신규 서버로 변경한다.

생각해보니 공지를 미리 안해서 오늘 서버 이전은 불가능 할 것 같다… 아아아아.!

공지사유

1.  물리서버 노후화 문제 : 장애발생시 복구시간 및 하드 장애시 데이터 손실 문제.

2.  1이 가장 큰 이유이다. 사실 가상머신으로 서버를 이전하면 성능이 60%가량으로 떨어지기 때문에 하하하 1의 문제가 없다면 사용자 입장에서는 서버이전을 할 필요가 없다.ㅡㅡㅋ

이상 서버이전 준비 끝.