레이블이 Jenkins인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Jenkins인 게시물을 표시합니다. 모든 게시물 표시

openjdk for latest jenkins

# jenkins 2.422 버전을 다운로드
wget https://updates.jenkins.io/download/war/2.422/jenkins.war

# jenkins 2.422 버전을 실행해 보면 다음과 같이 java 11 버전 이상이어야 한다
# Jenkins 2.357 버전 부터는 java11(openJDK11) 이상이 필요하다.
java -jar ./jenkins.war --httpPort=8888

Runninet_cluster_level with Java 8 from /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.144-0.b01.el7_4.x86_64/jre, which is older than the minimum required version (Java 11).
Supported Java versions are: [11, 17, 21]

# 설치할 수 있는 openjdk 를 확인해보자
yum list java*openjdk-devel

# 다행히 11 버전이 보인다. 설치~
sudo yum install java-11-openjdk-devel.x86_64

# 설치 경로 확인
rpm -ql java-11-openjdk-devel.x86_64

# openjdk11 로 jenkins 실행해보자
/usr/lib/jvm/java-11-openjdk-11.0.20.0.8-1.el7_9.x86_64/bin/java -jar ./jenkins.war.bill --httpPort=8888

# jenkins 다음과 같은 에러가 발생한다.
/usr/lib/jvm/java-11-openjdk-11.0.20.0.8-1.el7_9.x86_64/lib/libfontmanager.so: undefined symbol: hb_buffer_set_cluster_level

# openjdk21버전으로 다운로드해서 사용해보자.
wget https://download.java.net/java/GA/jdk21/fd2272bbf8e04c3dbaee13770090416c/35/GPL/openjdk-21_linux-x64_bin.tar.gz
tar zxvf openjdk-21_linux-x64_bin.tar.gz

# 21버전으로 실행하면 에러가 없이 된다~
jdk-21/bin/java -jar ./jenkins.war --httpPort=8888

jenkins systemctl failed

# jenkins systemctl 상태를 확인하면 Failed 로 나온다.
sudo systemctl status jenkins -n 30 -l

# jenkins 서비스(데몬) 시작시 문제가 되는 부분을 찾기 위해 디버깅
sudo vi /etc/init.d/jenkins
...
case "$1" in
    start)
        echo -n "Starting Jenkins "
        daemon --user "$JENKINS_USER" --pidfile "$JENKINS_PID_FILE" $JAVA_CMD $PARAMS > /dev/null
        RETVAL=$?
        echo "java version: $(/usr/bin/java -version 2>&1 | grep -i version)"
        echo "JENKINS_USER: $JENKINS_USER"
        echo "JENKINS_PID_FILE: $JENKINS_PID_FILE"
        echo "JAVA_CMD: $JAVA_CMD"
        echo "PARAMS: $PARAMS"
        echo "RETVAL: $RETVAL"
        if [ $RETVAL = 0 ]; then
...

# 실제 다음과 같은 명령이 실행된다.
# 참고로 daemon 은 . /etc/init.d/functions 로 로딩한 함수다.
daemon --user ysoftman --pidfile /var/run/jenkins.pid /usr/bin/java -Djava.awt.headless=true -Dcom.sun.jndi.ldap.connect.pool.maxsize=20 -Dcom.sun.jndi.ldap.connect.pool.prefsize=10 -Dcom.sun.jndi.ldap.connect.pool.timeout=5000 -DJENKINS_HOME=/var/lib/jenkins -jar /usr/lib/jenkins/jenkins.war --logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war --daemon --httpPort=8080 --debug=5 --handlerCountMax=100 --handlerCountMaxIdle=20

# /etc/init.d/jenkins 변경 사항 반영을 위해 다시 로딩
sudo systemctl daemon-reload

# jenkins 서비스 재시작
sudo systemctl restart jenkins

# daemon 함수 실행시 root 가 아니라고 메시지로 실패(RETVAL=1)된다.
Starting Jenkins runuser: may not be used by non-root users

# 해결방법
# /etc/sysconfig/jenkins 에서 다음과 같이 root 로 변경한다.
JENKINS_USER="root"

# 그리고 /etc/init.d/jenkins 의 daemon 실행시 --user 옵션없이 다음과 같이 실행한다.
daemon --pidfile "$JENKINS_PID_FILE" $JAVA_CMD $PARAMS > /dev/null

# 이제 다시 시작하면 아름 스샷과 같이 데몬서비스로 동작한다.
sudo systemctl daemon-reload
sudo systemctl restart jenkins

jenkins artifact 생성시 symbolic link 상태 문제

# jenkins 에서 빌드 결과물을 archive 해서 artifact 를 만들때
# 빌드 결과물에 symbolic link 가 있고 그 대상 링크가 경로가 실제 있다면
# symbolic link 속성 대신 일반 디렉토리로 아카이빙된다.

# 예시
# aaa 잡 완료 후 workspace 결과물(ysoftman-result)이 생긴다.
# aaa/workspace/ysoftman-result
# ysoftman-result 안에는 다음과 같이 심볼릭 링크가 있고
apple -> /data/apple
lemon -> /data/lemon

# 젠키스 장비에 심볼릭 링크의 대상 경로가 실제 존재 할때
/data/apple
/data/lemon

# workspace/ysoftman-result 를 artifact 로 생성하게 되면
# aaa/builds/100/archive/artifact/ysoftman-result 의 내용은
apple
lemon
# 으로 심볼릭 링크가 사라지고 링크 대상을 복사한 일반 디렉토리로 변경된다.

# 이 상태의 artifact 를 배포했는데 배포된 서버의 /data/appe, /data/lemon 로
# 심볼릭 링크로 연결되지 않아 데이터 접근에 문제가 있었다.

# 결국 젠킨스의 /data/apple 와 /data/lemon 를 삭제해
# 빌드 결과물의 심볼릭 링크 상태가 유지된 artifact 가 생성되도록 했다.

Jenkins github REAMD.md 수정시 빌드 제한

# git 저장소에 README.md 같은 파일 커밋발생시 원치않은 jenkins 빌드가 발생한다.
# 이를 막기 위해선 해당 jenkins 잡에서 아래화면처럼 exclude 영역을 추가하면 된다.
소스 코드 관리 -> git -> additional behaviours -> polling ignores commits in certain
paths -> excluded regions

# 특정 디렉토리의 모든 파일 제외
docs/.*


# 참고로 아직 pipeline 잡에서는 exclude regions 기능에 문제가 있어 보인다.

jenkinsfile sh 명령 실행하기

# jenkinsfile 중 쉘 스크립트를 실행해 결과 변수로 저장하기
# returnStdout = true 로 설정해야 stdout 결과를 string 으로 받아 올 수 있다.
# 스크립트 결과 끝에 newline 제거를 위해 trim() 처리 한다.
script {
   env.BUILD_TIME = sh (
   script : 'date "+%Y-%m-%d_%H:%M:%S_%Z"',
   returnStdout: true,
  ).trim()

# jenkinsfile 에서 sh 로 실행하면
# SHELL=/bin/bash 로 되어 있다.
# 현재 환경 변수 출력해보기
sh ('printenv | sort')

# bashrc 등의 환경변수들이 로딩되어 있지 않아
# sh 사용전 environment 로 설정해야 한다.
# environment 사용 주의 사항
# - 변수에 export 는 사용하지 못한다.
# - 변수 선언을 중복 할 수없다.
pipeline {
  environment {
    GOPATH="$HOME/gopath"
    PATH="/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/usr/local/go/bin/:$GOPATH/bin:$PATH"
  }

... 생략

sh '''
echo "ysoftman"
go --help
'''


# sh ''' ''' 내에서 . ~/.bashrc 등은 제대로 동작하지 않는다.
# triple single quote ''' ''' 내에서는 멀티 라인을 사용할 수 있지만 변수 치환을 안된다.
# triple double quote """ """ 내에서는 멀티 라인과 변수 치환을 사용할 수 있다.
# jenkinfile 은 groovy 스크립트 문법을 참고하면 좋다.

jenkins 동시 수행되는 job들 중 ssh 연결 실패

jenkins 동시 수행되는 job들 중 ssh 연결 실패(UNREACHABLE 에러)가 발생하는 경우가 있다.
jenkins 에 5개의 잡이 다음과 같은 주기로 실행되고 있다.
a job : 1분 주기
b job : 2분 주기
c job : 2분 주기
d job : 5분 주기
e job : 5분 주기
각 잡들은 ansible 로 모두 같은 파일 서버로 부터 각 잡에 맞는 파일을 다운로드 한다.
간헐적으로 잡들의 ansible 연결 실패 발생한다.
다음과 같은 증상들이 있다.
- 간헐적으로 ssh 연결 실패가 발생한다.
- 연결 실패가 발생하면 최소 2개의 잡이 동시에 발생한다.
- ansible -vvv 옵션으로 자세한 verbose 를 찍어보면, 다음 처럼 특정 controlpath(cp, 소켓파일)을 사용한다.
 예) 8a8131ca11
 ssh -o ControlPath=/home/ysoftman/.ansible/cp/8a8131ca11
- 간헐적 에러가 발생하는 시간은 8a8131ca11 가 생성되는 시간이다.
- 최초 8a8131ca11 생성 후 ansible ssh 연결이 잘 되다가 갑자기 끊어지는 현상이 있다.
- ssh -o ControlPersist=60s (ansible ssh 디폴트, https://docs.ansible.com/ansible/latest/plugins/connection/ssh.html) 옵션을 사용해 8a8131ca11 가 60초만 유지후 삭제 될거라고 생각했지만 60초 후에도 계속 유지되는것처럼 보였다.
우선 모든 잡들이 8a8131ca11 이름을 사용하고 있다.
ansible.cfg 에 ssh 관련 별다른 옵션은 설정하지 않았다.
따라서 ansible 의 기본 controlpath 생성 로직을 사용하게 된다.
https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/ssh.py -> _create_control_path()
create_control_path() 는
remote host, remote port, remote user, connection, pid 로
sha1() -> hdex -> digest로 앞 10바이트만 잘라서 cp 이름을 정한다.
하지만 아래 소스를 보면 control_path 없으면, host, port, user만 사용된다.
결국 같은 host, port, user 를 사용하는 5개의 잡은 모두 같은 cp 이름을 생성한다.
https://github.com/ansible/ansible/blob/47aea84924e8149e153107564c8b029dc4f52c27/lib/ansible/plugins/connection/ssh.py#L663
if not self.control_path:
    self.control_path = self._create_control_path(
        self.host,
        self.port,
        self.user
    )
8a8131ca11(cp 파일) 60초 후 삭제될거라 생각했지만
1분 간격으로 실행되는 a잡이 실행시 ssh -o ControlPersist=60s 로
cp 60s 늘리거나 새로 생성 한다.
이런식으로 cp 파일은 의도하지 않게 몇일 동안 삭제 되지 않다가 잡(ansible) 수행시
어떤 이유에서인지 간헐적으로 cp 파일 삭제 후 생성되는 순간이 발생하고
이때 삭제된 cp 를 사용하려는 ansible 잡이 연결 실패 에러가 나는것으로 보인다.

# 해결
# ansible 파일 서버 inventory 파일에
# ansible_ssh_common_args 옵션을 사용하면
ysoftman.fileserver  ansible_ssh_common_args="-o ControlPersist=10s"

# 다음과 같이 명령 뒤에 설정값을 중복으로 붙게 되는데
# ssh 는 먼저 선언한 값으로 처리해 10s 값이 적용되지 않는다.
ssh -o ControlPersist=60s -o ControlPersist=10s

# 그래서 별도의 ansible_ysoftman.cfg 파일을 만들어 설정했다.
[defaults]
host_key_checking = False
remote_user = ysoftman
transport = ssh
stdout_callback = debug

[ssh_connection]
# UNREACHABLE 에러 발생시 발생시 2번은 재시도
retries = 2

# ssh -tt(tty 강제 할당) 옵션 비활성화
usetty = no

# ssh 옵션 자세한 설명은 man ssh_config 참고
# ControlMaster=auto 사용할 수 있는 cp 파일이 있으면 사용하고 없으면 새로 만든다.
# ControlPersist=yes(또는 0) cp 파일이 백그라운드로 계속 남아 있도록 한다.
# ssh_args = -o ControlMaster=auto -o ControlPersist=yes

# ansible 실행시 ANSIBLE_CONFIG 환경변수로 적용
ANSIBLE_CONFIG=ansible_ysoftman.cfg ansible-playbook -i ./inventory/aaa do_something.yml

# 참고
# ssh cp 관련 control command
# 8a8131ca11 종료
ssh -o ControlPath=/home/ysoftman/.ansible/cp/8a8131ca11 -O exit ysoftman@10.10.10.10

# 8a8131ca11 상태 확인
ssh -o ControlPath=/home/ysoftman/.ansible/cp/8a8131ca11 -O check ysoftman@10.10.10.10

jenkins github credential 실패시 확인사항

[문제]
github.aaa.com 에서 github.bbb.com 으로 마이그레이션
github.bbb.com 계정으로 developer settings -> personal access token 을 생성
jenkins -> credentials -> ysoftman bbb secrect key (personal access token 를 사용한다.) 생성
jenkins -> 환경설정 -> github 에 다음과 같이 설정하고
API URL : https://github.bbb.com/api/v3
Credentials : ysoftman bbb secrect key
Test connection 실행하면 다음과 같이 실패한다.
Failed to validate the account

[원인 및 해결]
/var/jenkins/jenkins.log 로그를 보면 403(bad request)로 실패한다.
그런데 jenkins 서버 터미널로 테스트 하면 github.bbb.com 에 잘 접속된다.
curl http://ysoftman:토큰@github.bbb.com/api/v3

원인은 jenkins 에 설정된 프록시 서버 문제로
jenkins -> plugin manager -> 고급 -> http 프록시 설정에 no proxy host 에 github.bbb.com 추가하면 접속 된다.
jenkins job 까지 프록시 설정을 반영하기 위해선 http://젠킨스주소/restart 로 재시작해야 한다.

[추가로]
tomcat 상으로 jenkins 가 구동되는 경우, jenkins 만 재시작하면 안된다.
tomcat 데몬이 올라갈때의 no_proxy 설정이 유지되기 때문에
bash 상에서 다음과 같이 no_proxy 설정 후 tomcat 을 재시작해야 한다.
export no_proxy=github.aaa.com,github.bbb.com

jenkins - waiting for next available executor 해결하기

# Jekins executors 는 아래처럼 10개로 설정되어 있는 상태다.
Jenkins 관리 -> node 관리 -> 설정


# executor idle 상태로 충분한데도 다음과 같은 pending 이 발생하는 경우가 있다.
"waiting for next available executor"


# 원인
# "Authorize Project" 라는 플러그인이 설치돼 있었고


# 다음과 같이 빌드를 트리거하는 사용자로 설정한 경우 발생한다.
Jenkins -> Configure Global Security -> Access Control for Builds


# 해결 방법
# "Authorize Project" 플러그인을 삭제하거나
# "project default build authorization" 항목을 삭제하거나
# 다음과 같이 "프로젝트 디폴트 빌드 권한"을 시스템으로 설정하면 된다.


jenkins 테마 변경

# jenkins 기본 테마는 영 별로인데, 플러그인으로 변경할 수 있다.
# 플러그인 설치
jenkins 환경설정 -> plugin manager -> Simple Theme Plugin

# 이제 테마 css url 을 추가하면 된다.
jenkins 환경설정 -> theme -> add -> css url

# neo2 테마 (https://jenkins-contrib-themes.github.io/jenkins-neo-theme/)
https://tobix.github.io/jenkins-neo2-theme/dist/neo-light.css

# material 테마 (http://afonsof.com/jenkins-material-theme/)
# red
https://cdn.rawgit.com/afonsof/jenkins-material-theme/gh-pages/dist/material-red.css

# blue
https://cdn.rawgit.com/afonsof/jenkins-material-theme/gh-pages/dist/material-blue.css

# purple, orange, indigo, cyan... 등 컬러에 맞는 URL을 사용하면 된다.

#####

# jenkins 환경설정 -> ansi color 설정
Name : onedark.vim
Default Background : jenkins Default
Default Foreground : jenkins Default
Black : #282C34
Red : #e06c75
Green : #98c379
Yellow : #e5c07b
Blue : #61afef
Magenta : #c678dd
Cyan : #56b6c2
White : #abb2bf

github jenkins webhook 사용

# github repository(저장소)에서 commit, push 등 이벤트가 발생할 경우 jenkins 로 알리는 webhook(웹훅)을 사용할 수 있다.

# 우선 jenkins 에서 github plugin 이 설치되어 있어야 한다.
https://wiki.jenkins.io/display/JENKINS/GitHub+Plugin

# 방법1
# jenkins job(잡) -> 구성 -> 빌드유발 -> Poll SCM 체크
# 이 방법은 주기적 폴링(체크)해야 하기 때문에 추천하지 않는다.

# 방법2
# github 저장소 설정에 jenkins hook url 을 설정한다.
github 저장소 -> setings -> integration&services -> add services -> jenkins(github plugin) -> jenkins hook url

# 그리고 jenkins job(잡) -> 구성 -> 빌드유발 에서 다음 항목을 체크한다.
GitHub hook trigger for GITScm polling

# 참고로 jenkins(github plugin) deprecated 되서 사용하지 않는것이 좋다.
Note: GitHub Services are being deprecated. Please contact your integrator for more information on how to migrate or replace a service with webhooks or GitHub Apps.

# 방법3
# 위 방법2은 github 저장소 설정에 jenkins(github plugin)를 다수 등록 수 없다.
# 그래서 2개 이상의 jenkins 서버를 사용하기 위해 웹훅으로 설정해야 한다.
# github 설정에서 web hook 추가
github 저장소 -> settings -> hooks -> webhooks -> add webhook
# 마지막은 /으로 끝나야 동작한다.
Payload URL : https://젠키스도메인/github-webhook/
Content type : application/x-www-form-urlencoded
Secret: 빈값
Let me select individual events.
Pull requests, Pushes ... 등 웹훅이 필요한 상황 체크
Recent Deliveries 에서 체크할 ping 결과를 테스트 할 수 있다.

# 그리고 jenkins job(잡) -> 구성 -> 빌드유발 에서 다음 항목을 체크한다.
GitHub hook trigger for GITScm polling

# pipeline 으로 구성한 잡의 경우 별도의 설정 없이 /github-webhook 으로 요청이 들오면 파이프라인이 시작된다.

# 이제 github(jenkins 잡에서 설정한 브랜치)에 푸시(github 에서 설정한 이벤트들) 이벤트가 발생하면 잡을 트리거할 수 있다.

jenkins ldap 로그인 에러

# jenkins ldap 로그인이 안되거나 몇번씩 로그인을 시도해야 하는 경우가 발생한다.
# /var/log/jenkins/jenkins.log 또는
# http://ysoftman-jenkins/log/all 에서 로그인을 보면 ldap 인증에러가 발생했다.
org.acegisecurity.AuthenticationServiceException: LdapCallback;
ldap.ysoftman.com:389; socket closed; nested exception is javax.naming.ServiceUnavailableException: ldap.ysoftman.com:389; socket closed; remaining name '';

# 클라이언트(젠킨스)가 ldap 서버의 타임아웃에 비해 너무 길어서 생긴 이슈로 보이며,
# 젠킨스의 ldap 커넥션 풀 크기와 타임아웃을 작게 주도록 한다.
https://docs.oracle.com/javase/jndi/tutorial/ldap/connect/config.html

# 위 설명을 자세히 보면 java system properties 로 설정해야 된다고 나온다.
# 젠킨스 설정 파일에 다음과 같이 설정한다.

# ubuntu
sudo vi /etc/default/jenkins
# 또는
# centos
sudo vi /etc/sysconfig/jenkins
JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Dcom.sun.jndi.ldap.connect.pool.maxsize=20 -Dcom.sun.jndi.ldap.connect.pool.prefsize=10 -Dcom.sun.jndi.ldap.connect.pool.timeout=5000"

# jenkins 관리 -> "끄기전 준비" 를 켜서 잡이 실행되는 것을 막는다.
# 이제 jenkins 서버에 접속해 jenkins 서비스를 재시작하면 옵션이 적용된다.
sudo systemctl restart jenkins

# 옵션이 적용 확인
ps -ef | grep jenkins

jenkins multibranch pipeline 환경 설정

# 우선 github 계정에 personal access token 을 생성한다.
settings -> developer settings -> personal access token 에서
scopes 선택시, repo 권한 admin:repo_hook 권한을 체크한다.

# jenkins multibranch pipeline 사용하기
# 다음 플러그인들을 설치 한다.
Blue Ocean : 파이프라인 작성을 UI 적으로 사용(관련 플러그인들이 함께 설치된다.)
Pipeline: Stage View Plugin
GitHub API Plugin
GitHub Authentication plugin
GitHub Branch Source Plugin
GitHub Pipeline for Blue Ocean
GitHub plugin

# API endpoint : jenkins 관리 -> 시스템설정 에서 다음 항목을 설정해야 한다.
# github github servers -> api urls
api urls : https://developer.github.com/v3/

# github github servers -> credentials
# github 저장소 접근 id, pw(personal access token) 으로 추가.
# 추가 후 해당 credential 의 ID(123-456-789) 값을 jenkinsfile 에 명시한다.
environment {
   ysoftman = credentials('123-456-789')
}

# github enterprise servers -> api endpoint
api endpoint : https://developer.github.com/v3/
name : ysoftman github

# multibranch pipeline 생성
jenkins -> new item -> multibranch pipeline : ysoftman_multibranch_pipeline

# github 브랜치 설정
# ysoftman_multibranch_pipeline -> configure -> branch sources
# API endpoint : 위 시스템 설정에한 넣은 값 선택
# Credentials : 위 시스템 설정에한 넣은 값 선택
# Owner : https://github.com/ysoftman/test_code 의 경우 ysoftman
# Repository : owner 의 저장소 리스트를 볼 수 있고 이중 하나를 선택할 수 있다.
# Behaviours : 선택한 저장소의 All branches 를 스캔할 수 있다.


# orphaned item strategy -> discard old item 을 선택하면 삭제된 브랜치나 태그들은 모두 파이프라인에서 바로 제거 된다.
# 아래 처럼 유지 기간을 입력하면 삭제 되더라도 7일까지만 유지하고 지나면 삭제한다.
# 참고로 0 값은 설정할 수 없고 빈값으로 설정해야 바로 제거 된다.
# Days to keep old items: 빈값
# Max # of old items to keep: 빈값


# 파이프라인 스크립트(jenkinsfile) 작성
# jenkinsfile 는 groovy(자바동작타입스크립트언어)사용 스크립트 사용한다.
# jenkinsfile 파일 작성방법
https://jenkins.io/doc/book/pipeline/

# 스크립트에 문제가 있다면 다음과 같은 에러가 발생한다.
GitHub has been notified of this commit’s build result
java.lang.NoSuchMethodError: No such DSL method 'cleanWs' found among steps

# 위 에러 예시는 cleanWs() 함수를 사용할수 없는 경우로
# Workspace Cleanup Plugin 플러그인을 설치해야 한다.

# 참고로 jenkinsfile 은 에러가 있을 경우
# build history -> replay 에서 스크립트를 수정해 테스트할 수 있다.
# 테스트 후 문제가 없다면 github 저장소로 커밋/push 하자.

ansible "Shared connection to xxx closed"

2개의 jenkins(젠키스) job(잡) 이 스케줄링에 의해 동시 실행될때
"Shared connection to 아이피 closed"

에러를 발생하며 ssh 접속이 되지 않는다.
각각의 젠킨스 잡은 ansible-playbook 을 수행하는데 2개 모두 같은 호스트를 대상으로 하고 있다.
ansible version : 2.2.1.0
user : ysoftman (가정)
jenkins host os : centos 7.2
target host name : ysoftman-file-server (10.10.10.10) (가정)
target host os : centos 7.2

다음과 같은 에러 메시지와 함께 접속 실패가 발생한다.
(ansible-playbook 실행시 -vvvv 옵션)
<10.10.10.10> SSH: EXEC ssh -vvv -o ControlMaster=auto -o ControlPersist=30m -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=ysoftman -o ConnectTimeout=10 -o ControlPath=/ysoftman/.ansible/cp/ansible-ssh-%h-%p-%r -tt 10.10.10.10 '/bin/sh -c '"'"'/usr/bin/python /ysoftman/.ansible/tmp/ansible-tmp-1488621902.23-156878567418929/command.py; rm -rf "/ysoftman/.ansible/tmp/ansible-tmp-1488621902.23-156878567418929/" > /dev/null 2>&1 && sleep 0'"'"''
fatal: [ysoftman-file-server]: UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 56: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug2: mux_client_hello_exchange: master version 4\r\ndebug3: mux_client_forwards: request forwardings: 0 local, 0 remote\r\ndebug3: mux_client_request_session: entering\r\ndebug3: mux_client_request_alive: entering\r\ndebug3: mux_client_request_alive: done pid = 27663\r\ndebug3: mux_client_request_session: session request sent\r\ndebug1: mux_client_request_session: master session id: 4\r\ndebug3: mux_client_read_packet: read header failed: Broken pipe\r\ndebug2: Control master terminated unexpectedly\r\nShared connection to 10.10.10.10 closed.\r\n", 
    "unreachable": true
}

관련해서 구글링을 열심해 해봤는데

에서는 ControlPath 에 명시된 소켓 경로가 너무 길어서 발생한것으로 2.3 에서는 수정되었다고 한다. 그런데 위 트레이스 로그를 보면 경로명이 긴것도 아니고 동시실행될때만 접속실패가 발생하고 각각의 ansible 잡이 독립적으로 수행될때는 접속이 문제가 없어 이 원인은 아닌것으로 생각된다.


에 나와 같은 문제를 제기하고 있었고 다음과 같이 ansible-playbook 실행시 paramiko(파이썬으로 구현한 openssh) connection 를 사용하라고 한다.
ansible-playbook -i ./ysoftman ysoftman.yml -c paramiko -vvvv

또는


와 같이 playbook(.yml) 에 명시할 수 도 있다.
connection: paramiko

또는

http://docs.ansible.com/ansible/intro_configuration.html#transport
와 같이 ansible.cfg 에 명시한다.
(디폴트 smart 로 설정하면 play에  명시된 connection 을 따른다.)
transport = paramiko

문제가 되었던 서버에서는 paramiko 사용으로 해결되었다.
그런데 다른 서버의 콘솔에서 ansible-playbook 명령을 실행하면 접속 인증 실패가 발생한다. -c ssh 나 -c smart 를 옵션을 주어 실행하면 잘된다.

A 장비(젠킨스)에서 ansible 실행시 -c ssh | smart | paramiko 모두 동작
B 장비(로컬)에서 ansible 실행시 -c paramiko 인증 실패

원인은 B 장비의에서 -c paramiko 를 사용할 경우 .ssh/config 설정파일을 사용하지 않고 .ssh/id_rsa (기본 개인키)파일만 바라보고 있어 인증을 할 수 없는 것이다.
id_rsa 파일이 존재하지 않는다면 : No authentication methods available
id_rsa 파일이 존재하지만 대상 호스트에 공개키가 등록되지 않았다면 : Authentication failed
에러가 발생한다.
.ssh/config 에 명시된 private_key 파일을 id_rsa 로 복사하였더니, -c paramiko 로도 실행이 잘 된다.

[참고1]

에 보면 레드햇계열의 버전 6 이하에서는 openssh 버전이 오래된 ControlPersist 같은 ssh 성능 향상 옵션을 사용할 수 없어 ansible 이 ssh 접속에 paramiko 를 강제로 사용했다고 한다.

[참고2]
controlpersist 로 유지되는 커넥션 종료하기
ssh -o ControlPath=/Users/ysoftman/.ansible/cp/ansible-ssh-10.10.10.10-ysoftman -O exit ysoftman@10.10.10.10
또는 소켓 파일을 모두 삭제
rm -rf ~/.ansible/cp/

slack api 사용하기

# slack(슬랙)에서 제공하는 web api 를 통해 다양한 기능을 사용할수 있다.
# 우선 api 를 사용하기 우해선 내 토큰 생성(파악)해야 한다.

# 특정 채널에 메시지 보내기
https://api.slack.com/methods/chat.postMessage
# curl 로 슬랙 api 사용하도록 하자.
curl -X POST -d "token=abc123&channel=mychannel&text=테스트 메시지&username=ysoftman's bot" https://slack.com/api/chat.postMessage

# 이모지 사용자 설정 내용 파악
curl -X POST -d "token=abc123" https://slack.com/api/emoji.list

그밖의 슬랙 api


#####

# jenkins -> slack 알림

# slack 설정
# 내슬랙.slack.com -> apps -> jenkins ci 앱검색 -> 추가 또는 기존 settings
# 토큰값을 파악하고


# jenkins slack 플러그인 설치
# jenkins -> credentials -> secret text 타입으로 slack 토큰 등록
# jenkins -> 시스템 설정 -> slack -> workspace, credential, channel 설정


Jenkins Fatal error C1090 문제

Jenkins 에서 Visual Stdudio C++ 프로젝트들을 병렬로 처리할때 다음과 같은 에러 발생으로 빌드 실패가 되는 경우가 있다.

fatal error C1090: PDB API를 호출하지 못했습니다. 오류 코드 '23'
Fatal error C1090: PDB API call failed, error code '23'

해당 문제는 jenkins 이슈에 등록되어 있는 상태이다.
https://issues.jenkins-ci.org/browse/JENKINS-9104

msbuild 플러그인 최신 버전에 이슈를 해결했다고 하니 설치하도록 한다.
참고 https://github.com/jenkinsci/msbuild-plugin/pull/19

install jenkins

# Debian/Ubuntu 에서 패키지 저장소 추가해서 설치하는 경우
# jenkins 접속 키 추가
wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -

# jenkins 저장소 위치 추가
sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list'

# apt-get 갱신
sudo apt-get update

# jenkins 설치
sudo apt-get install jenkins

# jenkins.war 위치 파악
dpkg -L jenkins


#####


# Redhat/Centos 에서 rpm 패키지 다운받아 설치하는 경우
wget https://pkg.jenkins.io/redhat/jenkins-2.112-1.1.noarch.rpm
sudo rpm -ivh jenkins-2.112-1.1.noarch.rpm

# jenkins rpm 버전 업데이트시 다음과 같이 설치하면 현재 설치된 jenkins(서비스가 중지된 상태라도)와 충돌 에러가 발생한다.
sudo rpm -ivh jenkins-2.112-1.1.noarch.rpm
jenkins-2.112-1.1.noarch에서 설치되는 /etc/init.d/jenkins 파일은 jenkins-2.40-1.1.noarch 패키지의 파일과 충돌합니다
jenkins-2.112-1.1.noarch에서 설치되는 /etc/sysconfig/jenkins 파일은 jenkins-2.40-1.1.noarch 패키지의 파일과 충돌합니다
jenkins-2.112-1.1.noarch에서 설치되는 /usr/lib/jenkins/jenkins.war 파일은 jenkins-2.40-1.1.noarch 패키지의 파일과 충돌합니다

# jenkins rpm 버전 업데이트시 rpm 옵션으로 -U(업그레이드)하면 된다.
sudo rpm -Uvh jenkins-2.112-1.1.noarch.rpm

# jenkins home 디렉토리 변경
sudo vi /etc/sysconfig/jenkins
JENKINS_HOME="/home/ysoftman/jenkinsdata"

# 기본 포트 변경시
sudo vi /etc/default/jenkins
HTTP_PORT=8080

# 서비스로 jenkins 구동
# 정지할때는 stop 옵션 사용
sudo service jenkins start

# 최신 OS 라면 systemctl 사용
sudo systemctl start jenkins


#####


# mac 에서 패키지로 설치하는 경우
# 설치
brew install jenkins

# 실행
/usr/local/opt/jenkins/bin/jenkins 스크립트 파일에서 아래 명령을 실행한다.
java -jar /usr/local/opt/jenkins/bin/libexec/jenkins.war

# 디폴트 JENKINS_HOME 디렉토리
cd $HOME/.jenkins


#####


# .war 로 구동하는 경우
java -jar /usr/share/jenkins/jenkins.war

# 8080 포트를 이미 다른 프로세스가 사용하고 있다면 다음과 같은 에러 발생
Caused by: java.io.IOException: Failed to listen on port 8080

# 다른 포트를 사용하여 구동
java -jar /usr/share/jenkins/jenkins.war --httpPort=8888


#####


# 구동시 참고 사항
# 로그 위치
vi /var/log/jenkins/jenkins.log

# 또는
https://127.0.0.1:8080/log/all

# 접속해 보기
http://127.0.0.1:8080

# admin 패스워드는 다음 로그 파일에 기록되어있다.
# 로그 파일로 이 파일을 수정후 재시작해도 admin 패스워드는 변경되지 않았다.
cat /var/lib/jenkins/secrets/initialAdminPassword

# 암호 분실시 /var/lib/jenkins/config.xml 에서 다음과 같이 수정하여 재시작
<useSecurity>false</useSecurity>

# jenkins home, jenkins 서버 이전시 홈 디렉토리를 복사(백업/복구)하면 된다.
/var/lib/jenkins

# job 설정은 다음 위치에 config.xml 파일로 저장된다.
/var/lib/jenkins/jobs/job이름/config.xml

# 재시작시 '곧 Jenkins가 종료될 예정입니다.' 메시지 후 재시작 되지 않을때
# /restart 페이지에서 바로 종료 할 수 있다. (rest api 참고)
http://127.0.0.1/restart