Category: Linux

systemctl tomcat no bind 8005 port

Tomcat 을 설치하고 난후에 systemd 에 유닛으로 등록하고 나고 서비스를 시작하고 shutdown 을 하려고 할때에 다음과 같은 오류를 만날 수 있다.

8005 포트로 접속을 할 수 없어서 셧다운시에 오류를 발생시키는 것이다. 왜 이런문제가 발생할까? systemd tomcat 유닛의 내용은 다음과 같다.

그리고 이 상태로 다음과 같이 tomcat 을 서비스로 시작 한다.

이렇게 하고 난후에 netstat 명령어로 포트 리스닝 상태를 살펴보면 8005 포트가 보이지 않는다. 더 큰 문제는 shutdown 포트가 올라오지 않으면 Tomcat 이 작동하지 않는데 있다.

해결 방법은 의외로 간단하다. 다음과 같이 systemd tomcat 유닛 파일에 WorkingDirectory 를 CATALINA_BASE 로 해주면 된다.

이렇게 하게되면 tomcat 이 shutdown 포트까지 올라오면서 정상적으로 다 구동되게 된다.

ps, 이걸 몰라 3시간을 해멧다.

Ubuntu APT Could not get lock /var/lib/dpkg/lock 문제

우분투(Ubuntu) 를 부팅하고 난 후에 로그인을 하면 몇개의 새로운 업데이트가 있는지를 알려준다. 그래서 새로운 패키지 설치를 위해서 ‘apt upgrade’ 명령을 하게 되면 다음과 같은 오류 메시지를 만나곤 한다.

패키지를 설치하는 명령어인 dpkg 명령어가 이미 실행중인 것으로 인해서 실행이 안된다는 것이다. 실행을 할때에 lock 파일을 생성하게 되는데, 이를 근거로 혹시 다른 것이 이미 실행되고 있는건 아닌지 추측하고 있다.

도대체 무슨 일이 벌어지고 있는 걸까? 다른 것이 이미 실행중일지도 모르니까 다음과 같이 프로세스를 체크해 본다.

보아하니 apt.systemd.daily 이것이 apt 명령어를 실행하고 그래서 dpkg 가 이미 실행되고 있는 것으로 보인다.

이것은 아마도 부팅과 동시에 패키지를 업데이트 해주는일을 하는 녀석인 것으로 보이는데, 자동으로 패키지를 업데이트를 해준다니 얼마나 고맙겠냐만은 때로는 어떤 것이 설치되는지를 직접 선택하거나 해야하는 경우에는 자동으로 알아서 해주는것이 큰 위험이 될 수도 있다.

이것을 멈추게 하는 방법이 있다.

이렇게하면 부팅하면서 자동으로 apt 업데이트를 하는 건 막을 수 있다.

참고,

만일 부팅과장에서 각 서비스별 소비된 시간을 알고 싶다면 다음과 같이 확인해 볼 수 있다.

이렇게 보면 userspace 로 인한 시간이 1분이 넘어간다. 좀 더 자세하게 보기 위해서는 다음과 같이 확인해 볼수 있다.

Ubuntu18.04 호스트네임 영구 변경 설정

Ubuntu18.04 에서 호스트네임을 변경하기 위해서는 다음과 같이 해준다.

이렇게 한 후에 리부팅을 하면 원래 변경전 호스트네임이 나온다. 이럴때 /etc/cloud/cloud.cfg 파일에서 다음과 같이 변경을 해주면 된다.

이렇게 바꾼후에 다음과 같이 로그인 서비스를 재시작 해준다.

UBUNTU 18.04 KVM 게스트에 콘솔 접속하기

KVM 가상화를 사용하고 있고 게스트로 Ubuntu18.04 를 사용하고 있다면 콘솔 접속을 위해서는 다음과 같이 해주어야 한다.

/etc/default/grub 편집

grub 에서 ttyS0 에 콘솔 접속이 되도록 다음과 같이 편집해 준다.

위와같이 편집을 한 후에 grub 을 다시 작성해준다.

위와같이 설정을 하고 재부팅을 한 후에 KVM 콘솔 접속을 하면 아주 잘 된다.

Python – easy_install, pip 설치하는 방법

Python 에서는 easy_install, pip 를 설치하는 방법중에 하나가 ‘get-pip.py’ 스크립트를 이용하는 것인데, 다음과 같다.

wget, curl 과 같은 프로그램을 이용할 수 없을 경우에 python 프로그램을 이용할 수도 있다.

python3 의 경우에는 다음과 같다.

python2 의 경우에는 다음과 같다.

 

한줄짜리 python 프로그램으로 get-pip.py 를 다운받고 설치를 해준다. ‘–user’ 는 사용자 홈 디렉토리를 설치 디렉토리로 삼게 한다.

 

systemd –user 사용하기

Systemd 는 기존 리눅스 시스템에서 사용해왔던 init script 를 대체한다. 배포판마다 적용된 버전이 다른데, CentOS에 경우에는 7 버전부터 Ubuntu 의 경우에는 16.04 부터 적용되기 시작했다.

Systemd 는 부팅과정에서 최초로 실행되는 프로세스이며 리눅스 시스템 전체를 움직하게 하는 프로세스이다. 이 프로세스는 또 다른 프로세스들을 제어하는데 이를 위해서 systemd 프로그램을 제공한다.

부팅과정에서 자동으로 데몬들을 실행시키는 것도 systemd 가 하는데 이 프로그램은 데몬에 대한 명세서인 unit 파일을 기반으로 실행을 시켜준다. 이러한 파일들은 전역 시스템 영역에 속한다.

전역 systemd 영역

전역 systemd 영역의 파일들은 다음에 디렉토리를 가진다.

  • CentOS: /usr/lib/systemd
  • Ubuntu: /lib/systemd

한가지 특징이 있는데, CentOS 경우에는 전역 systemd 디렉토리가 한가지이지만 Ubuntu 의 경우에는 /lib/systemd외에 /usr/lib/systemd 도 존재하는데 /usr/lib/systemd 는 user 영역을 위한 것이다.

커스터마이징 전역 systemd 영역

앞서 살펴본 디렉토리는 배포판의 패키지를 설치할 경우에 사용되어진다. 하지만 이것외에 별도에 설치한 데몬 프로그램을 전역 systemd 에 등록하고 싶다면 다음의 디렉토리를 사용한다.

  • /etc/systemd

예를들어 컴파일 설치한 프로그램, 자바 프로그램의 경우에 systemd 에 등록해서 사용하자 한다면 위 디렉토리에 unit 파일을 작성하면 된다.

사용자 systemd 영역

systemd 는 자동으로 데몬으로 실행시켜 준다. 그런데, 이러한 실행은 systemd 라는 전역적인 권한을 가진 상태에서 이루어진다. 그렇다면 사용자가 자신만의 systemd 를 운영할 수 없지않을까 하는 아이디어로 나온것이 사용자 systemd 영역이다.

동작방법은 두가지로 나뉜다.

  • 사용자가 시스템에 로그인을 할때 실행
  • 시스템이 부팅할때에 사용자 systemd 영역도 함께 실행

그리고 사용자 systemd 영역은 사용자 홈디렉토리에 unit 파일을 작성해야 한다. 이 디렉토리는 다음의 위치에 존재한다.

  • ~/.config/systemd/user

사용자 systemd 영역 실행은 다음의 명령어를 사용한다.

  • systemctl –user

사용자 systemd 영역 동작 방법

잠깐 어떻게 이게 가능한지를 설명해 본다. 이 기본적인 동작을 위해서는 PAM 이 실행되어야 하는데 /etc/pam.d/systemd-user 파일이 이 일을 하게 해준다. 이 파일은 대략 다음과 같다.

이 PAM 모듈은 사용자가 로그인을 하게 되면 자동으로 systemd –user 명령을 실행해준다. 그리고 로그아웃을 하게되면 systemd –user 로 실행된 프로세스는 종료된다.

기본 설정

모든 사용자 systemd 영역 파일들은 ~/.config/systemd/user 에 존재하게 된다. 처음 로그인을 할때에 서비스가 실행되길 원한다면 다음과 같이 서비스를 활성화 할 수 있다.

한가지 팁(Tip) 으로, 만일 root 사용자라면 모든 시스템 사용자의 사용자 systemd 영역 서비스를 다음과 같이 할 수 있다.

환경 변수

서비스 데몬들이 실행될때에도 환경 변수들이 필요하다. 예를들어, PATH 같은 것이 대표적이다. 문제는 사용자 systemd 영역 서비스 데몬들은 .bashrc 파일에 정의된 환경변수들을 계승하지 않는다.  이것은 environment.d 디렉토리에 정의하는데 위치는 ~/.config/environment.d/ 이며 여기에 .conf 확장자를 가지는 파일을 작성하는데 INI 형식인 NAME=VAL 식으로 작성한다.

전역적인 환경변수 파일은 다음에 위치한다. 이 파일들은 모든 사용자 unit 파일에 영향을 준다.

  • /etc/environment.d/*.conf
  • /usr/lib/environment.d/*.conf
  • /etc/environment

모든 사용자 unit 에 영향을 주는 기본 환경변수인 DefaultEnvironment 는 /etc/systemd/user.conf 도 있다.

기존의 환경 변수들을 추가할 수도 있다. 예를들어, PATH 라는 환경변수는 사용자마다 가장 많이 커스터마이징되는 변수다. 이러한 변수를 systemd 에서 환경변수로 등록하고자 한다면 다음과 같이 해준다.

사용자 systemd 영역에 설정된 변수들을 보고 싶다면 다음과 같이 하면 된다.

사용자 systemd 자동 실행

systemctl –user 사용은 사용자가 로그인을 해야만 실행이되며 사용자 세션이 닫히면, 사용자가 로그아웃을 하면 자동으로 종료 된다. 하지만 사용자의 로그인/로그아웃에 상관없이 서버가 부팅되면 자동으로 실행되고 서버가 종료되어야만 중지되게 하고 싶다면 어떻게 할가?

이것은 로그인 관련된 내용으로 링거링(Lingering) 설정에 영향을 받는다.

multi-user.target 문제

systemd unit 파일 작성할때에 어떤 환경에서 실행될 것인지를 명시하기 위해서 다음과 같이 작성한다.

그런데, ‘systemctl –user’ 를 사용할때에는 multi-user.target 사용해서는 안된다. 이는 –user 에서 사용할 수 있는 타켓이 제한되어 있기 때문인데, 다음과 같이 확인이 가능하다.

위에 리스트를 보면 multi-user.target 은 존재하지 않는다. 따라서 ‘systemd –user’ 사용을 위한 systemd 유닛 파일을 작성할때에는 default.target 을 사용하는 것이 적절하다.

ElasticSearch 에 대한 systemd unit 파일 예제.

이제 간단하게 예제하나를 작성해 보자.

전문 검색 엔진인 ElasticSearch 는 자바를 기반으로 작동한다. 그러다보니 반드시 root 로 실행할 필요가 없다. 실제로 대부분 자바기반의 서비스들은 일반 계정으로 실행하는게 대부분이다.

unit 파일에 대해서 먼저 알아둘 필요가 있다. 이 파일들은 대체로 다음에 위치한다.

  • /usr/lib/systemd/systemd: 설치된 패키지에 의해서 제공된 units
  • /etc/systemd/systemd: 시스템 관리자에 의해서 제공된 units

하지만 사용자 systemd 영역을 사용할 것임으로 앞에서 언급한 대로 사용자 홈디렉토리에 관련 디렉토리를 생성해 준다.

자바 프로그램은 자바를 필요로하는데, 설치가 되어 있다고 하더라도 PATH, JAVA_HOME 등의 환경변수를 설정해 줘야 한다. systemd 가 알아차릴 환경변수는 environment.d 에서 작성해야 함으로 java.conf 파일을 다음과 같이 작성해 준다.

이제 elasticsearch.service 를 다음과 같이 작성한다. 이 파일은 ElasticSearch 의 소스가 공개된 GitHub 에서 찾을 수 있다.

Ubuntu 1.604 에서 문제

한가지 문제가 있다. elasticsearch.service 파일을 보면 중간에 리소스를 조정해주는 내용이 나온다.

  • LimitNOFILE=65536
  • LimitNPROC=4096

그런데, 이 설정은 적용되지 않는다. Systemd 에서 시스템 자원 조정을 위한 파일들이 여럿 존재한다.

  1. /etc/systemd/system.conf
  2. /etc/systemd/system/user@1000.service.d/limit.conf – 1000 은 userid 값이다.
  3. .config/systemd/user/elasticsearch.service.d/limits.conf

여기서 3번째는 작동되지 않는다. 1번의 경우에는 전역적으로 모든 사용자에게 적용이 된다.    2번째 경우에는 사용자에게만 적용이 된다.

보통 시스템 리소스는 /etc/security/limits.conf 파일에서 조정하는게 보편적이지만 systemd 는 이처럼 자체적으로 리소스를 제어할 수 있도록 해준다.

systemctl –user 사용법

이제 elasticsearch.service 를 활성화하고 사용법을 익혀보자.

먼저 elasticsearch.service 를 다음과 같이 활성화 해준다.

그리고 서비스 시작/중지는 사용자 계정으로 로그인을 하면 자동으로 시작되며 로그아웃을 하면 중지된다. 하지만 수동으로 시작,중지를 하고 싶다면 다음과 같이 하면 된다.

Virtual Image 만들기

dd 명령어를 사용해서 다음과 같이 Virtual Image 만들기가 가능하다.

10GiB 의 용량을 가진 가상 이미지를 만들어 줍니다.

Ubuntu 18.04 도메인을 찾을 수 없을때

Ubuntu 18.04 를 사용중인데, 보안 업데이트를 하기 위해서 apt 명령을 입력했더니 다음과 같이 도메인을 찾을 수 없는 이유로 오류가 생긴다.

“Temporary failure resolving” 이게 뭘까 싶어서 알아본 내용을 정리한다.

resolve.conf 파일을 열어보면 다음과 같이 되어 있을 것이다.

resolv.conf 파일은 다들 알다시피 도메인 네임 서버를 지정해주는 설정 파일로 이 파일이 잘못되면 도메인을 ip로 변환할 수가 없게되어 결국에는 인터넷 연결을 할 수가 없게 된다.

그런데, 위 내용을 보면 도메인 서버 ip는 로컬 호스트로 보이고 코멘트에 이것을 수동으로 바꾸지 말것을 경고하고 있다. 거기다 resolve 상태를 “systemd-resolve –status”로 확인하라고 친절히 안내하고 있다. 이 명령어는 uplink DNS 서버에 대한 상태를 알려준다.

그러면 이 uplink DNS 를 바꿀 수는 없을까?

systemd-resolve 데몬이 이를 수행하는데, 이는 다음과 같은 위치의 파일들을 읽어서 동작한다.

Ubuntu18.04 에서는 /etc/systemd/resolved.conf 파일이 존재하며 여기에 DNS= 부분에 DNS 서버를 space 로 구분해 리스트로 적어놓을 수 있다.

실제로 ‘DNS=8.8.8.8’ 을 입력하고 ‘systemctl restart systemd-resolved’ 하면 적용되어 apt update 가 잘 동작했다.

Bash 파일 존재 유무 체크하기

Bash 쉘 스크립트를 작성할때 자주 사용하는 로직인 바로 파일 존재 유무를 체크하는 것이다. 파일 하나만 체크할 수도 있고 여러파일을 체크할 수도 있다. 여러 파일을 체크할때는 다음과 같이 할 것이다.

이것을 Bash 쉘 스크립트에서는 어떻게 리턴을 받아야 하나하는 고민이 생긴다. 가장 쉬운 방법은 stdout, stderror 를 체크하는 방법이다.

Bash 에서 이를 exit code 라고 하고 $? 에 세팅이되어 다음과 같은 로직이 가능해진다.

명령어가 성공(stdout)하면 $?에 0, stderr 면 1 이다. 위를 실행하면 다음과 같다.

위 방법외에도 한줄로 다음과 같이 할 수도 있다.

AND 와 OR 연산자를 이용해서 메시지를 출력하도록 한다.

하지만 위 방법도 오류 메시지, 혹은 결과가 출력이 되는데 이를 방지하고 결과만 받고 싶다면 다음과 같이 할 수 있다.

이렇게 하면 결과 출력 없이 yes, no 만 출력이 된다.

출처: How to check if a file exists in a shell script