사전 조건으로는


1. Ubuntu 16.04 Openstack(Pike) Default 컴포넌트 설치 


2. 단일 Controller Node에서 작업


3. 외부와 네트워크 통신이 가능


* 설치 단계


1)  네트워크 설정


Network Interfacecontroller host name을 등록한다


$ ifconfig




$ vi etc/network/interfaces

# The loopback network interface

auto lo

iface lo inet loopback

 

# The primary network interface

auto enpno03

iface eth0 inet static                      ## 상황에 따라 설정을 다르게 해준다.

address 192.168.0.67

netmask 255.255.255.0

gateway 192.168.0.1

dns-nameserver 8.8.8.8

 

$ vi /etc/hosts

#controller                                   ## 상황에 따라 설정을 다르게 해준다.

192.168.0.67       controller

 

$ reboot

 



2)  Openstack Package 설치


$ apt install software-properties-common

$ add-apt-repository cloud-archive:pike

$ apt-get update & apt-get disk-upgrade # 해당 작업을 안해주면 다른 버전의 Openstack Package가 설치 될 가능성이 있다.

$ apt install python-openstackclient


3) Mysql 설치


$ apt install mariadb-server python-pymysql


1.     mysql config 설정

$ /etc/mysql/mariadb.conf.d/99-openstack.cnf


[mysqld]

bind-address = #{server ip}

default-storage-engine = innodb

innodb_file_per_table = on

max_connections = 4096

collation-server = utf8_general_ci

character-set-server = utf8


$ service mysql restart

$ mysql_secure_installation

 

3) Message queue 설치


$ apt install rabbitmq-server

$ rabbitmqctl add_user openstack RABBIT_PASS

$ rabbitmqctl set_permissions openstack ".*" ".*" ".*"


4) Memcached 설치


$ apt install memcached python-memcache

# /etc/memcached.conf 변경

-l 127.0.0.1 또는 -l CONTROLLER_IP

$ service memcached restart


5) Openstack Keystone 설치


1.    keystone 데이터 베이스 생성

       $ mysql

$ CREATE DATABASE keystone;

       $ GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' \

IDENTIFIED BY 'KEYSTONE_DBPASS';

       $ GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' \

IDENTIFIED BY 'KEYSTONE_DBPASS';


2.     Keystone 설치

       $ apt install keystone apache2 libapache2-mod-wsgi


3.     Keystone config 파일 수정


# /etc/keystone/keystone.conf

[database]

# ...

connection = mysql+pymysql://keystone:KEYSTONE_DBPASS@controller/keystone

 

[token]

# ...

provider = fernet



1.     Keystone 데이터 베이스 동기화

$ su -s /bin/sh -c "keystone-manage db_sync" keystone

 

2.     Keystone 저장소 키 초기화

$ keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone

$ keystone-manage credential_setup --keystone-user keystone --keystone-group keystone

 

3.     Keystone Bootstrap

      $ keystone-manage bootstrap --bootstrap-password ADMIN_PASS \

         --bootstrap-admin-url http://controller:35357/v3/ \

         --bootstrap-internal-url http://controller:5000/v3/ \

         --bootstrap-public-url http://controller:5000/v3/ \

      --bootstrap-region-id RegionOne

 

4.     Apache config 수정


# /etc/apache2/apache2.conf

ServerName controller



이후는 다음에..

환경은


NIC1 외부망 IP 61.xx.xx.xx, 내부 망 10.8.0.1

NIC2 내부망 172.xx.xx.x을 사용 하여


Openstack(NIC2 172.xx.xx.x) 서버를 구축되었고 NIC1외부망에 Openvpn 서버를 설정하여 외부에서 클라이언트가 접근 가능하도록 VPN 망을 구성 하였다.


설치 및 환경이 완료 되었고 Openstack 서버에서 리소스 생성 및 VM 생성 테스트 까지 진행 하였다.


테스트가 끝나고 Jenkins 및 SCM 서버를 설치 중 Jenkins 서버에서 WEB Plugin이 다운로드 안되는 현상이 발견 되었다.


Jenkins 서버에 ssh 접속 하여 ping을 확인 한 결과 내부 끼리 통신은 되는데 외부 끼리 통신이 안된다는 문제점이 발견 되었다.


VPN 서버는 접속이 되었지만 내부 VM에서 외부로 ping이 나가려고 하면


10.8.0.1 아이피에 대하여 iptable 및 port forwarding이 필요한 것 같다.


설정 방법은


# tunneling

$ iptables -I FORWARD 1 --source 10.8.0.0/24 -j ACCEPT 

$ iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE 



# port forwarding

$ sudo iptables -t nat -A POSTROUTING -o em2 -j MASQUERADE

$ sudo iptables -A FORWARD -i em2 -o em3 -m state --state RELATED,ESTABLISHED -j ACCEPT

$ sudo iptables -A FORWARD -i em3 -o em2 -j ACCEPT


을 실행 시켜 VM 내부에서 ping이 외부로 나가 도록 구성 하였다.

Domain Name Server는 www.naver.com/www.google.com와 같은 웹 주소를 기계가 알 수 있는 IP로 변환 하는 작업 실행 한다.


ubuntu 14.04 기준으로 dns server setup 하는 방법


1. Bind9 설치


$ sudo apt-get install bind9 


2. DNS 환경 설정


1) named.conf.local 수정


$ sudo vi /etc/bind/named.conf.local



에서 leedh.com 으로 도메인을 가정하에 파일 수정



/etc/bind/db.leedh.com은 Dns DB 파일이다.


2) IP주소를 도메인 명으로 바꾸기 위해 해당 DB 파일을 수정 한다.

sudo vi db.leedh.com


;

; BIND data file for local loopback interface

;

$TTL    604800

@       IN      SOA     ns.leedh.com. root.leedh.com. (

                              2         ; Serial

                         604800         ; Refresh

                          86400         ; Retry

                        2419200         ; Expire

                         604800 )       ; Negative Cache TTL

;

@       IN      NS      ns.leedh.com.    #Dns Server

@       IN      A       115.68.151.169   #Dns Server IP

@       IN      AAAA    ::1

ns      IN      A       115.68.151.169    #Dns Server IP

openstack      IN      A       115.68.151.164    #Service Server IP List

xen1    IN      A       115.68.151.170 #Service Server IP List



3) 리버스 파일 생성이 완료 되면 bind9 service를 restart 한다.

$ sudo service bind9 restart



4) resolv.conf 수정

sudo vi /etc/resolv.conf 파일의 nameserver를 127.0.0.1 # localhost로 변경 한다.


5) 서비스 확인


$ nslookup naver.com # 네이버의 주소가 출력 되는지 확인


$ nslookup xen1.leedh.com #추가 한 Server IPrk 출력 되는지 확인한다.


추가 한 서버의 IP가 나타나면 bind9를 이용하여 DNS 서버가 구축 완료 된 것











Azure 환경에서 환경 구성을 한 뒤 Micro-BOSH를 배포 하였을 경우 스토리지 계정에서 스템셀 이미지가 오라가는 중 Time out이 발생하였다.


보통 스템셀이 올라가다 에러가 발생 한 경우 인프라 환경에서의 방화벽(보안 그룹) 및 네트워크 통신 문제가 대다수 여서 재차 확인 해본 결과 이상이 없었다.


다시 처음 부터 bosh doc를 확인하며 실행 해본 결과 deploy가 성공적으로 완료 되었다.


실패 한 이유는 Azure 스토리지 계정의 컨테이너 명칭이 사용자가 결정하는 것이 아니라 azure-cpi 내부에서 정해져 놓은것과 스토리지 계정 생성 시 변경 된 점이 있다는 것으로 추정 된다.


아래는 ruby로 구성 된 의심이 되는 Azure CPI의 소스 일부분을 발췌하였다.






Azure 스토리지 계정를 standard_LRS 타입으로 생성

컨테이너의 명칭을 bosh(private), stemcell(public)으로 생성

컨테이너 테이블 명칭을 stemcells로 생성하고 배포 하였더니 성공적으로 배포가 완료 되었다.

AWS 환경에서 CF & Diego 설치 후 


$ cf login 후에 Java Sample App을 push 중


Java 런타임 환경의 BuildPack을 업로드 하지 못하는 에러가 발생 했다. 에러 메세지의 로그는 아래와 같았다.


2018-02-22T17:18:49.86+0900 [STG/0]      ERR [DownloadCache]                  WARN  Unable to download https://java-buildpack.cloudfoundry.org/memory-calculator/trusty/x86_64/index.yml into cache /tmp: execution expired

2018-02-22T17:18:49.86+0900 [STG/0]      ERR [Buildpack]                      ERROR Compile failed with exception #<RuntimeError: Open JDK Like Memory Calculator error: Unable to find cached file for https://java-buildpack.cloudfoundry.org/memory-calculator/trusty/x86_64/index.yml>

2018-02-22T17:18:49.86+0900 [STG/0]      ERR Open JDK Like Memory Calculator error: Unable to find cached file for https://java-buildpack.cloudfoundry.org/memory-calculator/trusty/x86_64/index.yml

2018-02-22T17:18:49.86+0900 [STG/0]      ERR Failed to compile droplet: Failed to compile droplet: exit status 1

Show less




구글링 하던 중 해당 에러에 관련하여 offline java buildpack을 사용 가이드가 나와 있어 offline java buildpack을 다운로드 하여 재실행 하였는데 같은 에러 메세지가 발생 하였다.


CF_TRACE log를 확인하여 보니 443 HTTPS  통신 중 500 Staging error와 diego와 통신이 안된다는 에러를 발견 할 수 있었다.


성공적으로 CF & Diego는 설치 완료 했지만 CF에서 cf-cli 명령어를 받는 Cloud Controller에서 Diego로 통신을 할 수 없는 문제 인것 같았다.


에러를 해결 하며 알게 된 점이


다른 인프라 환경과는 다르게 AWS는 Public Subnet과 Private Subnet이 나누어져 있으며 

Pubilc Subnet은 Elastic IP를 할당 한 VM이 있고 Router Table이 Internetgateway와 연결이 되어 있어야 한다.

Private Subnet은 내부 아이피를 할당 한 VM이 있고 Router Table에 별도의 Natgateway를 연결 하여 내부적으로 Nat 통신이 가능하도록 구성을 하여야한다.


아래는 기존의 Cloud foundry 설치 방법이 였고 위에 문제 떄문에 아키텍쳐를 변경 하였다.

아키텍쳐를 변경하고서 다른 문제점이 발생 할 가능성이 있다.





아래는 변경 한 Cloud foundy의 아키텍처 참고 이미지다.





bosh, cf를 public subnet

diego를 private subnet 으로 구성하고 nat gateway를 생성하여 연결 했다.



해당 이슈가 발생하면서 발견 한 이슈는 AWS로 VM 생성 시 EBS로 volum이 Attach 되는 것 같은데 Root disk의 용량을 늘려주려면 어떻게 하는지 모르겠다..








Cloud foundry에서는 각 컴포넌트 별로 통신을 하기 위해 Open SSL 기반의 인증서를 사용 한다.


현재 나의 자바 소스에서는 Progresbuilder를 통해 certstrap이라는 자동 스크립트 파일을 바탕으로 Open SSL 기반의 인증서를 여러개 생성하고 키 값에 맞춰 필요한 컴포넌트에 인증서를 맵핑 시킨다.


로컬에서는 문제 없이 돌아가지만 클라우드 환경의 서버에서 자바 패키지를 빌드하고 자바 패키지에 필요한 소프트웨어를 설치 하기 위해 자동 스크립트를 만들어 사용 중이다.


certstrap이 돌아가기 위해서 gopath 지정이 반드시 필요 한대, 현재는 gopath를 지정한 파일을 생성하여 리눅스 파일 시스템 /etc/profile.d/ 에 옮겨 놓고 작업을 하였다.


서버가 재부팅 및 off/on 하였을 경우 해당 gopath가 날라가는 에러가 발생 하였다.


리눅스 환경에서 환경 변수를 읽는 시점 및 gopath의 특정한 문법 등을 찾아 보았지만 원인을 찾지 못하여 자바 톰켓 서버가 실행 되는 순간 gopath를 지정하여 읽고 들어가게 만드는 방법을 임시 방편으로 쓰던 중  /etc/profile.d/에 들어간 gopath 지정 파일이 실행 파일이 아닌것을 확인 하였고, 실행 파일 권한을 부여하고 재실행하였더니 문제가 사라졌다.


openstack 서버 pike 버전의 설치를 알아보던 중 devstack의 설치 스크립트에 관련하여 간단하게 설치 할 수 있다는 것을 알게 되었다.


하지만 devstack은 말 그대로 dev버전 임으로 서버가 꺼졌다 켜졌을 경우 이전 데이터의 안정성을 보장 할 수 없고 설치 한 가상머신에 대하여 서버가 작동이 중단 및 재실행이 안된다, 말 그대로 한번 설치 하고 테스트를 할 수 있는 서버 환경 인것 같다.


Devstack은 sudo를 사용하여 root가 아닌 사용자로 실행해야 한다. devstack 설치 방법은 아래와 같다.


$ sudo useradd -s /bin/bash -d /opt/stack -m stack


$ echo "stack ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/stack


$ sudo su - stack


아래 git 주소를 clone 한다.


git clone https://github.com/leedonghyean/devstack.git


Openstack은 오픈소스 환경임으로 별도의 stable 된 git version이 올라가는게 아니라 다양하게 올라가는 것 같다.


해당 git hub의 MD 파일을 확인 하여 보면 git checkout을 통해 안전한 버전의 pike로 checkout 할 수 있는 것 같다.


다운받은 github의 stack.sh 스크립트 파일에서 설치 할 프로세스 등을 확인 할 수 있고

stackrc에서 네트워크 타입과 각 각의 오픈스택 구성 컴포넌트 git을 정의 할 수 있는 것  같다.


local.conf라는 파일을 생성 한다.

해당 파일은 localrc의 속성 값으로 설치 스크립트가 실행 할 때 환경 변수로 들고 들어 가는 것 같다.

파일에 


[[local|localrc]]

# default

HOST_IP=192.168.0.6

 

# network

FLAT_INTERFACE=eth0

FIXED_RANGE=10.0.0.0/20

FIXED_NETWORK_SIZE=4096

FLOATING_RANGE=192.168.0.0/24

 

# vnc

VNCSERVER_LISTEN=0.0.0.0

VNCSERVER_PROXYCLIENT_ADDRESS=$HOST_IP


# system password

ADMIN_PASSWORD=admin

MYSQL_PASSWORD=admin

RABBIT_PASSWORD=admin

SERVICE_PASSWORD=admin

SERVICE_TOKEN=openstackservicetoken


서비스 패스워드, Floating IP 주소 내부 아이피 할당 주소 등 프로퍼티를 명세 할 수 있다.


프로퍼티 값을 명세 하고 ./stack.sh를 설치 하면 30~60분 사이에 devstack 서버가 완성 된다.


서버가 생성 되면 기본 대시보드 Horizon, 인증 Keystone 주소는 아래와 같다.


Horizon: http://myhost/


Keystone: http://myhost/identity/v2.0/





devstack은 1회용 서버 이기 때문에 회사 및 개인이 지속적으로 활용 하기엔 어려움이 있는 테스트 버전의 서버 인 것 같다.

일반 Openstack 설치를 하려면 스크립트 설치가 아닌 컴포넌트 하나 하나를 찾아가며 설치를 해야 한다.

cloud foundry 배포 중  is not running after update. Review logs for failed jobs: route_registrar  에러가 발생 하고 배포가 실패 할 경우


ssh 접속을 통해 해당 blob 컴포넌트가 컴파일 된 서버에 접속 한다.


1. ping 8.8.8.8을 하여 외부와 통신이 가능 한지


2. ping 내부 서브넷 아이피 및 dhcp와 통신하여 내부와 통신이 가능 한지 확인 하였을 때 이상이 없었다.


로그 파일의 문구는 아래와 같다.



위의 문제점은 cloud foundry 배포 시 설정 파일에서 domain 주소를 잘 못 입력하여 API 통신 시 할당 되는 API endpoint에 접근이 불가능 하여 발생 한 에러인 것 같다.

cloud foundry를 통해 Application 배포 시 Application의 기본적인 포트는 80으로 부여 받는다.


해당 Application 배포 시 사용 및 대기 하는 Port가 80이 아닌 TCP 통신이 필요 한 경우 Client에서 일반 도메인으로 접근 할 수 있도록 cloud foundry와 이와는 별개의 TCP만 사용 할 수 있는 TCP_Routing API 서비스가 필요 하다.


그림에서 나와 있는 부분은 사용자의 요청을 로드 벨런스로 받아 들여 해당 요청에 대한 포워딩을 해주는 방식이다.

하지만 아래에서는 로드 밸런스 없이 Elastic IP를 할당하여 TCP 요청을 사용 할 수 있는 서버를 구성 하였다.


설치에 사용 한 cloud foundry 서버 버전 구성은 AWS 환경에서

BOSH v261

Cloud foundry v273

Diego v1.25.3 을 사용 하였다.


해당 TCP_Router 서비스를 배포 하려면 전제 조건으로는 Cloud foundry와 diego(cell) 및 spiif 설치가 되어 있어야 한다.


1. cloud foundry 배포 시 설치 한 Postgresql 또는 mysql에 routing API 통신 데이터를 관리 하기 위한 데이터베이스 테이블과 권한이 존재 하여야 한다. cloud foundry 배포 시 사용 한 Manifest 파일에 데이터베이스 테이블과 권한을 명세 하여 배포 하거나 ssh를 통해 해당 데이터베이스 서버에 접속하여 테이블을 생성해야 한다.

cloud foundry의 컴포넌트에 데이터 베이스를 사용하지 않고 따로 서버로 구성 하였을 경우 통신이 가능하게 구성하여 테이블을 생성 한다.


2. https://github.com/cloudfoundry/routing-release git hub를 다운로드 받고 0.159.0 버전으로 checkout 한다.

Checkout 한 github에서 scripts 폴더의 generate-manifest 파일을 확인 한다.

generate-manifest 파일은 cf와 diego 배포 시 사용했던 Manifest와 해당 github의 template를 바탕으로 spiff라는 소프트 웨어를 사용하여 필요한 데이터를 Merge 시키고 Tcp_router 결과 파일을 생성 시킨다.

-c 에는 cf-deployment.yml

-d에는 diego-deployment.yml

-o에는 option.yml 파일이 들어 간다.


3. TCP_router 설치 Manifest 파일이 성공적으로 생성 되었다면 $ bosh deploy 명령어를 통해 TCP_router를 배포 한다.

배포 시 Cloud foundry 설치 서브넷과 동일 한 서브넷을 사용 하였고 Cloud foundry와 API 통신을 하기 위해 TCP_router job에 Elastic(Public IP) IP를 할당 하였다.



4. TCP Router가 성공적으로 배포 완려 되었으면 Cloud foundry Manifest 파일에서 Routing API를 허용 하고 Diego backend 사용을 허용 한다.

또한 cf 명령어를 통해 들어온 API를 routing_API로 포워딩 하기 위해 cloud controller job에 Elastic IP를 할당 한다.

Manifest 속성을 변경 완료 하였으면 bosh deploy 명령으로 Cloud foundry를 재 배포 한다.

아래는 완성 된 서버들의 형상이다.



5. Cloud foundry 재 배포가 완료 되면 cf를 다시 로그인 하여 $ cf router groups 명령어를 실행 한다. 명령어 실행 출력 결과가 나타나면 TCP Port를 사용 할 수있다.


6. 해당 Router_groups를 통해 TCP 전용의 TCP Domain을 생성 한다.

$ cf create-shared-domain {#사용 할 도메인 TCP 도메인 명} --router-groups=default_groups


7. TCP 도메인이 생성 되었으면 도메인을 통해 Application을 올리거나 별도의 tcp_route를 생성하여 실행 하고 있는 application에 Mapping 해주면 80 포트 뿐만 아니라 다양한 포트로 접근이 가능하다.









자바 multipart로 파일을 업로드 중 아래와 같은 이슈가 발생 하였음.


threw exception [Request processing failed; 

nested exception is org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. null] with root cause

java.net.SocketTimeoutException: null


해당 에러에 관련하여 아래의 방법으로 추측 하여 어떤 상황일떄 에러가 발생하는지 확인하여 보았다.


1. 서버에 용량의 꽉 찾을 경우

     No Space device 라는 에러 문구가 발생 한다.


2. 한번에 여러개의 파일을 올리거나 용량이 큰 파일을 올렸을 경우

     maxFileSize: 5000KB

     maxRequestSize: 5000KB 나의 환경은 설정 되었을 때 EOF 에러메세지를 나타낸다.


3. 네트워크가 중간에 끊어 졌을 경우

     jar 파일이 실행 되고 있는 서버에 대해 Inbound 및 Outbound 패킷이 흐르지 못하게 변경해놓고 실행하여 봤다.

    해당 Processing of multipart/form-data request failed. null] with root cause 에러가 발생 한다.



java maven build 시 cannot find symbol Error가 발생 하였다.


나의 환경은 spring boot module project로 구성 되어 있으며


parent 프로젝트를 maven build 시 각 각의 module 프로젝트들이 build가 된다.


나의 해당 컴파일 Error parent 프로젝트의 pom에 모듈 선언 부분에서 공통으로 사용하는 프로젝트에 관련하여 모듈이 삭제 되어 있었음.


해당 오류는 문자열의 오탈자나 bulid path, pom.xml의 dependency 확인이 필요 한 에러 같다.

centos 7.x 버전에서의 Mongo db 설치 가이드


$ echo "[mongodb-org-3.0]" > /etc/yum.repos.d/mongodb-org-3.0.repo


$ echo "name=MongoDB Repository" >> /etc/yum.repos.d/mongodb-org-3.0.repo


$ echo "baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.0/x86_64/">> /etc/yum.repos.d/mongodb-org-3.0.repo


$ echo "gpgcheck=0" >> /etc/yum.repos.d/mongodb-org-3.0.repo


$ echo "enabled=1" >> /etc/yum.repos.d/mongodb-org-3.0.repo


$ vi mongodb-org-3.0.repo



$ yum update


$ yum install -y mongodb-org





+ Recent posts