반응형
반응형

Ansible같은 경우 기본적으로 ssh를 이용해서, 원격커맨드를 날리는 것이 컨셉이지만,

Windows는 기본이 ssh를 사용하지 않기 때문에, winrm을 사용해서 구성해야 한다.

 

다만, Ansible이 winrm을 이용해서 통신을 할 때 기본은 ssl을 지원하는 5986포트로 통신을 하고 있기 때문에,

Windows에 ssl 구성을 해둔적이 없다면, ssl을 이용하지 않는 5985 포트를 이용해서 구성해야 한다.

 

# inventory


[aaa:vars]
ansible_ssh_user=Administrator # 윈도우 계정 넣으면 됨
ansible_ssh_pass=admin123! # 윈도우 계정에 대한 패스워드
ansible_ssh_port=5985  # 이게 winrm 포트임, 변경했다면 변경한 포트에 맞게
ansible_connection=winrm # 제일 중요함

 

 

이렇게 구성하지 않고, 아이피 목록만 넣게 되면 ssh로 통신하게 되므로,

Windows환경을 가진 서버들을 관리하고 싶으면 저렇게 구성해서 사용이 필요함.

반응형
,
반응형

AWS에서 EC2를 생성할 때 CentOS 관련 이미지로 생성을 하면,

아마존 콘솔에서 아무리 높은 용량의 EBS를 마운트했다고해도, OS에 들어가보면 기본 Root볼륨이 8G로 잡혀있게 된다.

(Public AMI든 Private AMI든 상관없이 모두 발생)

 

Root볼륨외에 다른 디렉토리를 만들어서, 그 디렉토리에 남은 용량을 마운트하여 사용해도 되지만,

패키지 설치나 커널 등 신경쓰지 않으면 사용자가 의도하지 않는 시점에도 Root볼륨에 상주하여 용량을 꽤 잡아먹을 수 있기 때문에, 기존 Root볼륨에 합쳐서 사용하는 방법을 알아보았다.

 

혹시 Root볼륨에 붙은 디바이스명이 /dev/xvda가 아니라면, 아래 키워드는 주의해서 실행이 필요함.

아래 키워드들은 /dev/xvda의 첫번째 디바이스로 가정하고 작성된 키워드들임.

 

1. growpart 패키지 설치

$ yum install -y cloud-utils-growpart

 

2. EBS에 할당된 용량만큼 기존 용량에서 확장한다.

$ growpart /dev/xvda 1

 

 

3. 리부팅 (보통은 여기서 마무리 되지만, 마무리 안된 경우 4번으로 넘어감)

$ reboot

 

 

4. Resize 진행

$ resize2fs /dev/xvda1

 

 

반응형
,
반응형

새롭게 yaml 파일을 구성하다보면, 이것저것 테스트를 할 일이 있는데, 나중에야 의미가 있겠지만 의미 없어보이는 retry파일이 남게 되어 비활성화하는 방법을 찾아봄.


/etc/ansible/ansible.cfg 파일에 아래와 같은 내용을 추가해준다.

### /etc/ansbile/ansible.cfg ###
[defaults]
retry_files_enabled = False


반응형
,
반응형

설치 / 초기화 / flannel 까지 세팅을 했는데, kubectl get nodes에서 계속해서 NotReady라고 나온다.

$ kubectl get nodes
NAME     STATUS     ROLES    AGE   VERSION
u16-01   NotReady   master   62m   v1.13.3


시간이 지났는데도 Ready로 바뀌지 않는 경우, 뭐 때문에 NotReady라고 나오는 지 알고 싶다면, 아래와 같은 키워드를 이용하여, Condition 부분을 살펴보면 됨.

$ kubectl describe node 노드이름


(예시)

...
Conditions:
  Type             Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----             ------  -----------------                 ------------------                ------                       -------
  MemoryPressure   False   Wed, 20 Feb 2019 07:50:16 +0000   Wed, 20 Feb 2019 06:47:37 +0000   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure     False   Wed, 20 Feb 2019 07:50:16 +0000   Wed, 20 Feb 2019 06:47:37 +0000   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure      False   Wed, 20 Feb 2019 07:50:16 +0000   Wed, 20 Feb 2019 06:47:37 +0000   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready            False   Wed, 20 Feb 2019 07:50:16 +0000   Wed, 20 Feb 2019 06:47:37 +0000   KubeletNotReady              runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized
...


network plugin이 없다는 에러인데, 이런 경우 /etc/cni/net.d/10-flannel.conflist 파일을 찾아서, 복사 후 /etc/cni/net.d/10-flannel.conf로 만들어주면, 재시작 등 별도의 작업 없이 바로 해결 가능.



반응형
,
반응형

사내에 국내 / 해외 모니터링을 하는 중앙 서버가 하나 있고, 해당 중앙 서버를 Web 환경에서 컨트롤 할 수 있는 Spring Boot로 개발한 어플리케이션을 하나 운영중인데, 중앙 서버가 모니터링 하는 서버들의 상태를 특정 주기마다 불러와서 보여주는 역할을 하고 있다.


해당 역할을 하는 중앙 서버의 모니터링 시스템이 어플리케이션이 아니라, 그냥 데몬이기 때문에 어플리케이션 단에서는 ssh 통신을 해서 Input Stream을 통해 콘솔에 나타나는 정보를 가져와야 한다.


ssh 통신 간 사용한 라이브러리는 jsch (http://www.jcraft.com/jsch/)를 이용하였고, In / Output Stream을 편리하게 메소드 형태로 가져올 수 있게 구현이 되어 있다.


아무런 생각없이, 아래와 같이 구현하고 몇 개월동안 별 문제 없이 운영을 했었음. (ssh 연결 과정은 생략하며, Stream 처리 부분만 명시함.)

...
// stdout이 jsch에서 가져온 InputStream임..
BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
StringBuffer sb = new StringBuffer();
String line;
while((line = reader.readLine()) != null) {
    sb.append(line + "\n");
}
...


정상적인 상황에서는 문제가 없지만, 가끔 중앙 서버와 통신하는 서버의 IP가 잘못 입력된 경우나, 없어진 서버가 생기면 시스템에 과부하가 오는 현상이 발견되었다.


디버깅을 하던 과정 중 위 코드의 치명적인 문제를 발견함.


1. 일단, BufferedReader의 readLine method가 blocking method이기 때문에, 읽을 수 있을 때까지 무한정 대기하며, 서버내의 자원을 점유한다. (이런 류의 요청이 쌓이면, OOM 등 시스템에 문제가 전파됨.)


2. 무한정 대기하다가 결국 못읽는다고 판단하면, Exception을 발생시키는데, 이 시점을 코드 레벨에서 컨트롤할 수 없음.

----------------------------------------------------------------------------

최종적으로 아래와 같이 해결함.


1. BufferedReader에서 제공하는 ready method를 이용해, 읽을 수 있는 지 먼저 검사하는 방식으로 시스템이 blocking되지 않도록 변경


2. Guava(https://github.com/google/guava)에서 제공하는 SimpleTimeLimitter를 이용하여, 코더가 Timeout을 컨트롤 할 수 있도록 구조를 변경

BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
StringBuffer sb = new StringBuffer();
int timeoutSec = 3;
SimpleTimeLimiter limiter = new SimpleTimeLimiter();
    try {
	limiter.callWithTimeout(() -> {
            String line;
            boolean isReady = false;
            while(!isReady) {
                isReady = reader.ready();
            }
            while((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
	}, timeoutSec, TimeUnit.Seconds, false);
    }
...


이제 중앙 서버가 IP가 잘못 등록되었거나 존재하지 않는 원격 서버와의 통신을 시도해도, 3초 이상 기다리지 않고 요청을 끊어버리므로 위에서 발견된 문제는 모두 해결이 되었다.

반응형
,
반응형

daemonize 옵션을 지원하지 않는 foreground 프로세스의 경우 background 형태로 동작하는 것처럼 하려면 보통은 nohup 명령어를 사용하여 아래와 같이 실행을 하게 된다.

$ nohup program &


실행을 하고나면, 명령어를 실행한 경로에 nohup.out이라는 파일이 생기며, program 이라는 프로세스가 뿜어내는 로그들을 찍게 되는데, 이후에 해당 프로세스를 죽이거나 재실행 하기 위해서는, 프로세스를 일일히 뒤져서 pid를 알아내서 죽여야 한다.


이런 번거로움을 방지하기 위해서는, nohup 명령어로 프로세스를 띄울 때 pid를 파일로 저장해서 해당 파일이 존재하는 경우 kill을 하고 띄우는 방법을 이용하면 좋을 것 같아서, 아래와 같은 스크립트를 하나 만들어서 활용하기로 하였다.

#!/bin/bash

if [ -f program.pid ]; then
  kill -9 `cat program.pid`
fi

nohup program > nohup.out 2>&1 & echo $! > program.pid


nohup.out 파일조차 남는게 지저분해보이고 귀찮으면, nohup.out 부분을 /dev/null로 변경해주면 된다.

반응형
,
반응형

docker-compose.yml 파일을 구성할 때, 특별한 이유가 없는 한 도커 이미지 버전을 latest로 구성하게 된다.


latest로 해놨다고 지속적으로 업데이트 해주는게 아니라, 컨테이너를 구성할 당시의 지정된 image의 latest버전이기 때문에, 새롭게 latest버전이 release되면 수동으로 업데이트를 해주어야 하는데, 이 방법에 대해 알아보자.


1. 이미지 pull

$ docker-compose pull


2. 컨테이너 다시 만들기

$ docker-compose up --force-recreate --build -d


3. (선택) 기존 이미지 제거 (사용되지 않는 이미지를 한 번에 날리게 되니, 임시로 내려둔 컨테이너가 있다면 주의한다.)

$ docker image prune -f



반응형
,
반응형

python 관련한 모듈 설치 시에 easy_install이나 pip를 사용하는데, 아무 설정없이 그냥 설치하면, nodejs나 maven같이 각 프로젝트에 해당 하는 모듈을 설치하는 것이 아니라, 시스템에 global하게 설치가 되버려서, 잘 됬던 기능도 호환성 이슈에 따라 문제가 생기는 경우가 발생하게 된다.


위와 같은 문제가 발생하는 것을 막기 위해, virtualenv 라는 모듈을 설치하여, 시스템에 global하게 설치되는 방식이 아닌, 해당 프로젝트에서만 종속되는 모듈을 설치할 수 있도록 가상 개발환경 구축이 가능하다.


[설치]

일단 아래와 같은 키워드로 virtualenv를 설치해보자. (사전에 pip가 설치되어 있어야 함.)

$ pip install virtualenv


가상 환경을 구축할 폴더를 하나 만들고, virtualenv를 이용하여 가상 환경을 구축해보자.

$ mkdir virtualenv_test
$ virtualenv venv

virtualenv 명령어 실행 시 첫번째 argument는 만들어질 가상환경의 이름(alias)이다. 보통 venv, .venv 등으로 만들며 이름만 다르다면 여러개도 만들 수 있다.


가상 환경 구축이 완료되면, 해당 디렉토리에 venv (alias) 디렉토리가 생기며, 가상 환경 컨트롤을 위한 몇 가지 폴더와 스크립트가 생긴다.


이제 기본 세팅은 끝났고, 가상 환경 활성화 / 비활성화에 대해 알아보겠다.


[활성화 / 비활성화]

만들어진 폴더들을 보면, Windows 환경인 경우에 Scripts 폴더가 있고, Linux 환경의 경우 bin 폴더가 있을 것이다.

* Windows

$ ls venv/
Include/  Lib/  pip-selfcheck.json  Scripts/  tcl/


* Linux

$ ls venv/
bin  lib  local


활성화는 아래와 같은 키워드로 한다.

* Windows

$ . venv/Scripts/activate


* Linux

$ . venv/bin/activate


활성화가 완료되면, git에서 브랜치를 변경했을 때처럼 쉘 앞에 (venv) 라는 문자열이 생기며, 앞으로 pip를 통해 설치하는 모듈은 해당 가상환경에만 종속되게 설치가 된다.


주의할 점은, 비활성화를 시키지 않은 채 다른 프로젝트로 이동해 작업을 하다가 필요한 모듈을 설치하면, 활성화 당시의 가상환경에 설치가 되기 때문에 혼선이 있을 수 있어, 하나의 프로젝트에서 필요한 작업을 완료하고 나면, 비활성화를 꼭 시켜주도록 한다.


비활성화는 아무 디렉토리에서나 아래 명령어를 통해 가능하다.

(venv)$ deactivate


이렇게 가상환경 구축을 이용해서 작업을 하다가, 최종적으로 원격 서버에 배포를 진행하기 위해서는 가상환경에서 설치했던 모듈들을 파일로 만들어줄 필요가 있다.


그럴땐 아래와 같은 키워드로 설치된 패키지 목록을 파일로 만들어준다.

(venv)$ pip freeze > requirements.txt


이렇게 해두면, 원격 서버에서 소스를 올린 후에 아래와 같은 커맨드로 한 번에 모듈을 설치할 수 있게 된다.

$ pip install -r requirements.txt


반응형
,
반응형

Oracle Jdk 1.8버전을 받아서 내부 시스템에서 활용을 하고 있었는데, SNS나 여기저기 커뮤니티에서 Oracle이 야금야금 라이센스를 걸고 넘어지기 시작했다는 소문을 접수하고, OpenJdk로 전부 다 갈아버리기도 마음을 먹었다.


Oracle Jdk 1.8은 Binary 형태로 압축을 풀어서 환경변수만 맞춰서 사용했었는데, OpenJdk 1.8 버전은 아직 Binary로 제공하진 않는 것처럼 보여서, 패키지 설치로 진행하기로 했다.


일반적으로 다 잘 동작했는데, 서버 간 Https 통신하는 부분에서 아래와 같은 에러가 발생함.

...
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
...

구글링을 좀 해보니, java 인증서가 설치되어 있지 않은 이슈였다.

실제로 /etc/ssl/certs/java/ 경로에 가보니 아무것도 없어서, SSL 통신이 안됐던 거였음.


아래와 같은 명령어로 기존에 있던 인증서를 정리한 후, 다시 설치 해주면 해결 된다. (Ubuntu 14.04 기준)

$ sudo dpkg --purge --force-depends ca-certificates-java
$ sudo apt-get install ca-certificates-java


어플리케이션 종류에 따라, 어플리케이션 재실행을 해야 될 수도 있음.

반응형
,
반응형

Windows환경에서 git bash를 이용해서, Linux 서버에 배포를 하는 작업을 주로 하는데, add 하는 과정에서 CRLF가 붙어버려서, 일반적으로는 문제가 없지만, 쉘 스크립트 등은 치명적일 수 있기 때문에, 이를 방지하는 설정이 있다는 걸 알게 되었다.


사실 문제가 생겨서는 아니고, add 할때마다 아래와 같은 Warning 메시지가 나오는게 거슬려서 찾아보게 됨.

warning: LF will be replaced by CRLF in test.txt.
The file will have its original line endings in your working directory.


git bash를 띄워서, 아래와 같은 명령어를 입력하면 자동으로 CRLF가 생성되는 것을 방지한다.

$ git config --global core.autocrlf false


반응형
,
반응형