[Container] Docker 이미지와 컨테이너

도커 컨테이너 이미지는 여러개의 층(layer)으로 구성된다.

  • Q. 왜 여러개의 층(layer)으로 구성하는가?
    Dockerfile 로 만들어질 때, Dockerfile 내 명령어 한 줄 마다 하나의 층이 생기기 때문이다.

  • Q.왜 층을 나누는가?
    Dockerfile 에서 변경된 부분만 저장하기 위해서다. 만약 변경되지 않은 부분이 OS 관련된 부분이나 Driver 관련된 부분이라면 나머지 층에 대한 용량을 훨씬 덜 수 있다.
    또한,

  • Q. 층은 어떻게 구분하는가?
    내용을 기반으로 해시값을 뽑아낸다. 정확하게는 Digest 값으로 'sha256' 해시 알고리즘을 사용한다. 마치 파일 하나처럼 보는 것이다.

  • Q. 가장 기본이 되는 층은 무엇인가?
    Dockerfile 작성시 최상단에 작성하는 FROM {IMAGE_NAME} 이다.
    아래 예시에서는 'FROM ubuntu:18.04' 가 된다.

FROM ubuntu:18.04
COPY . /app
RUN make /app
CMD python /app/app.py
  • Q. 이미지는 무엇인가?
    '컨테이너를 만들 수 있는 읽기 전용 템플릿' 이라고 소개하고 있다. 추가적인 커스터마이징이 가능하나, 커스터마이징을 한 이미지 또한 읽기 전용이다.
    도커 이미지 사용 시 가장 기본이 되는 OS 이미지는 대부분 해당 OS 개발 회사에서 지원하여 만들어지며, 공식 기본 이미지는 오픈소스로 공개되어 관리되고 있다.
    도커 공식 이미지 빌드: https://github.com/docker-library/official-images

도커 컨테이너는 도커 이미지를 실행(run)하면 프로세스로써 동작하며, 동작중인 컨테이너는 마치 VM에 올라간 OS처럼 Root 시스템을 독자적으로 가지고 있다.

  • Q. 왜 프로세스로 동작하는가?
    빠르다. 자원 손실이 아주 적다. 독립적이다. 권한을 제어하기 쉽다. 격리하기 쉽다.
    컨테이너는 이미 리눅스에서 구현된 격리 프로세스 기술이며 잘 만들어져있다.
    아, 죽이기도 쉽고 나름 안전하다.

  • Q. VM과 차이점은 무엇인가?
    각각 VM 마다 무거운 OS를 모두 띄워야 하는 게 VM (근데 요즘은 좀 가벼워짐),
    컨테이너는 Docker 엔진이 대신 해석해서 OS가 통쨰로 올라가진 않는다.

  • Q. Root 시스템은 진짜인가?
    실제 컨테이너의 프로세스 ID를 살펴보면 Host OS의 Root가 아님을 알 수 있다. PID 1번은 OS 최상위.
    Host OS 에서는 그저 프로세스지만, 컨테이너 내부에서는 컨테이너 자신이 PID 1번이라고 믿는 꼴. (그사세)
    컨테이너 내부에서 volume 을 생성하고 사용하면 내부에서 사용하는 UID 를 사용하고, 해당 UID는 Container 혹은 직접 지정한 UID로 편집된 것으로 나온다.

  • Q. 도커 엔진이 죽으면 어떻게 되는가?
    기본 설정상으론 컨테이너로 올라간 모든 프로세스가 종료된다. 동작을 안한다는 얘기다.
    하지만 live-restore 모드를 켜면 동작은 하도록 설정할 수 있다. https://docs.docker.com/config/containers/live-restore/
    프로세스이며 메모리에 올라가기 때문에 가능한 일이긴 한데, 안정적이지 못하다는 공식 문서의 얘기가 있다.

'인프라' 카테고리의 다른 글

Kubernetes 사용시 편리한 명령어 모음 - 기초  (0) 2019.08.20

Gitlab-runner 환경에서 Fabric8로 Docker 빌드시 /var/run/docker.sock 을 찾지 못하는 에러
2019.09.05. 

명령어 : mvn $MAVEN_CLI_OPTS install -f ${SERVICE_IMAGE} -Pdocker -DskipTests
에러 :
24195 [INFO] ------------------------------------------------------------------------
24195 [INFO] BUILD FAILURE
24195 [INFO] ------------------------------------------------------------------------
24196 [INFO] Total time: 23.174 s
24196 [INFO] Finished at: 2019-09-05T09:09:35+09:00
24196 [INFO] ------------------------------------------------------------------------
24197 [ERROR] Failed to execute goal io.fabric8:docker-maven-plugin:0.26.0:build (push) on project site-service: Execution push of goal io.fabric8:docker-maven-plugin:0.26.0:build failed: No <dockerHost> given, no DOCKER_HOST environment variable, no read/writable '/var/run/docker.sock' or '//./pipe/docker_engine' and no external provider like Docker machine configured -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal io.fabric8:docker-maven-plugin:0.26.0:build (push) on project site-service: Execution push of goal io.fabric8:docker-maven-plugin:0.26.0:build failed: No <dockerHost> given, no DOCKER_HOST environment variable, no read/writable '/var/run/docker.sock' or '//./pipe/docker_engine' and no external provider like Docker machine configured
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:956)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:192)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)
Caused by: org.apache.maven.plugin.PluginExecutionException: Execution push of goal io.fabric8:docker-maven-plugin:0.26.0:build failed: No <dockerHost> given, no DOCKER_HOST environment variable, no read/writable '/var/run/docker.sock' or '//./pipe/docker_engine' and no external provider like Docker machine configured
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:148)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:956)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:192)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)
Caused by: java.lang.IllegalArgumentException: No <dockerHost> given, no DOCKER_HOST environment variable, no read/writable '/var/run/docker.sock' or '//./pipe/docker_engine' and no external provider like Docker machine configured
at io.fabric8.maven.docker.access.DockerConnectionDetector.detectConnectionParameter (DockerConnectionDetector.java:83)
at io.fabric8.maven.docker.service.DockerAccessFactory.createDockerAccess (DockerAccessFactory.java:37)
at io.fabric8.maven.docker.AbstractDockerMojo.execute (AbstractDockerMojo.java:220)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:956)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:192)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)
24213 [ERROR]
24213 [ERROR] Re-run Maven using the -X switch to enable full debug logging.
24213 [ERROR]
24213 [ERROR] For more information about the errors and possible solutions, please read the following articles:
24213 [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException




기본적인 부분부터 살펴보는게 맞다.
Gitlab-runner 는 gitlab-runner 라는 계정에서 작동한다. 당연하게도 아무런 설정도 없는 계정.

시스템에서 Docker 는 docker 라는 계정에서 작동하거나 root 에서 작동한다.
이 구조라면 리눅스에서 gitlab-runner는 docker socket 에 손도 못댄다. 
하지만 fabric8 이라는 라이브러리가 자꾸 손을 댈려고 한다. 

Gitlab-runner의 권한 문제 같아서 그룹 권한을 줬더니 된다. 끝.

목차 (UPDATE: 2019.08.20)

  • kube 설치 후 pemission 문제 해결
  • kubectl 자동완성
  • 특정 포드 찾아서 한번에 지우는 명령어
  • 네트워크 생성 및 접속 툴
  • Dashboard 접속 Token 확인 명령어
  • CoreDNS 오작동 에러

[ kube 설치 후 pemission 문제 해결 ]

> sudo chown -R $USER $HOME/.kube
혹은
> sudo chown -R $USER $HOME/.minikube

[ kubectl 자동완성 ]

1 > source <(kubectl completion bash)
2> alias kc=kubectl
3 > complete -F __start_kubectl kc
4> source ~/.bashrc

[ 서비스 중 인 주소 ]

kubectl cluster-info

[ 특정 포드 찾아서 한번에 지우는 명령어 ]

kubectl get pods -n kube-system -oname |grep coredns |xargs kubectl delete -n kube-system
kubectl get pods -n istio-system -oname |grep istio |xargs kubectl delete -n kube-system

xargs : 파이프로 건너온 인자를 뒤에 추가해주는 기능 
grep : 특정 검색어에 해당하는 줄만 추출

[ 네트워크 생성 및 접속 툴 ]

> kubectl run nettool -it --image=praqma/network-multitool --generator=run-pod/v1 --rm=true bash

[ Dashboard 접속 Token 확인 명령어 ]

> kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep eks-admin | awk '{print $1}')
+ 접속 시 deployments.apps is forbidden: 이라고 나오면.. 권한문제
>kubectl create clusterrolebinding serviceaccounts-cluster-admin --clusterrole=cluster-admin --group=system:serviceaccounts
(!!This allows any user with read access to secrets or the ability to create a pod to access super-user credentials)

[ CoreDNS 오작동 에러 ]

$ echo -e '[Service]\nEnvironment="KUBELET_EXTRA_ARGS=--resolv-conf=/run/systemd/resolve/resolv.conf"\n' | sudo tee /etc/systemd/system/kubelet.service.d/99-local.conf
$ sudo systemctl daemon-reload
$ sudo systemctl restart kubelet

$ kubectl -n kube-system get deployment coredns -o yaml | 
sed 's/allowPrivilegeEscalation: false/allowPrivilegeEscalation: true/g' | kubectl apply -f -

$ echo -e '[Service]\nEnvironment="KUBELET_EXTRA_ARGS=--resolv-conf=/run/systemd/resolve/resolv.conf"\n' | sudo tee /etc/systemd/system/kubelet.service.d/99-local.conf
$ sudo systemctl daemon-reload
$ sudo systemctl restart kubelet
$ kubectl get pods -n kube-system -oname |grep coredns |xargs kubectl delete -n kube-system

$ iptables -P FORWARD ACCEPT
$ iptables -P INPUT ACCEPT
$ iptables -P OUTPUT ACCEPT


'인프라' 카테고리의 다른 글

[Container] Docker 이미지와 컨테이너  (0) 2021.03.16

Gitlab-ce Server 이전시 발생 문제와 해결 (backup and restore, pg_dump, version upgrade, 500 에러

2019.08.20. 기준 문서


(1) Docker Container 로 올라가있는 기존 Gitlab-ce (v.11.7) 서버를 새로운 서버로 이전을 시도

중에..이를 위해 백업 데이터를 생성해야 하는데 여기서 첫번째 문제 발생한다.

souce build (이미지 빌드) 버전이기 때문에 아래와 같은 명령어로 백업 수행 시도
$ gitlab-rake gitlab:backup:create RAILS_ENV=production

에러 메시지는 아래와 같았다.
pg_dump: aborting because of server version mismatch
[FAILED]
rake aborted!

딱 봐도 버전이 안맞는다는 에러이지만, 아무리 명령어를 쳐봐도 동일한 버전이였다.
서버 버전이 문제가 아닐까? 했지만, 그 문제는 아니였다.

알고보니 DB 서버 버전과 gitlab 내부에서 사용하는 "pg_dump"의 client 버전이 달라서 발생한 문제
/# postgres --version
postgres (PostgreSQL) 9.6.11
root@8256e59e3eae:/# /opt/gitlab/embedded/bin/pg_dump --version
pg_dump (PostgreSQL) 9.6.11

아래와 같은 순서로 수행하여 해결했다.
1. 서버에 가서 $find / -name pg_dump 명령어로 pg_dump 실행파일을 찾음
2. 해당 파일을 gitlab 서버에 복사, 위치는 대략 /opt/gitlab/embedded/postgresql/{version}/bin
3. 복사한 실행파일을 심볼릭 링크로 /opt/gitlab/embedded/bin 안에 넣어줌

그런데, 아래와 같이 다시 새로운 에러가 떴다.
Dumping PostgreSQL database gitlab
...
pg_dump: error while loading shared libraries: libpq.so.5: cannot open shared object file: No such file or directory

딱 봐도 라이브러리가 없다는 얘기로 보였다, 
그래서 다시 DB 서버에 해당 라이브러리를 찾아봤다.

위와 동일하게 심볼릭 링크를 아~무리 지정해서 넣어도 찾지를 못했다 (동일 에러 발생). 많은 검색 끝에, "LD_LIBRARY_PATH" 이 경로 지정이 문제라는걸 알게 되었다...(칼퇴를 위한 몸부림)

아래와 같이 라이브러리를 넣은 위치를 지정해주면, 정상적으로 진행이 된다.
LD_LIBRARY_PATH={libpq.so.5 라이브러리가 위치한 디렉토리}

.so 로 끝나는 라이브러리의 위치를 알려줘야하는 문제였다. 이렇게 백업을 완료하고...


(2) 11.7 버전에서 12.1 버전으로 업그레이드

이전 Gitlab 서버 버전은 11.7.x, 이전하려는 서버에 백업 데이터를 넣어야하기 때문에 우선 동일한 버전으로 docker image를 지정하여 올렸다.

테스트 시 너무나도 잘 작동해서 기쁜 마음에 바로 버전을 latest 로 올려보았다. (절대 이러면 안된다. 테스트 서버이기 때문에 가능한 일이다,)

역시! Container가 2분마다 한번씩 사망선고를 받고 다시 태어나기를 반복하고 있었다. Stack Overflow 검색했더니 충격적인 내용을 보고야 말았다.

대략, Gitlab 서버 버전 업그레이드는 major 버전 한단계씩 하는게 좋다는 이야기.
"We recommend that you first upgrade to the latest available minor version within your major version. By doing this, you can address any deprecation messages that could change behavior in the next major release."

"It is considered safe to jump between patch versions and minor versions within one major version."

* You can only upgrade 1 minor release at a time. So from 9.1 to 9.2, not to 9.3.

from:https://stackoverflow.com/questions/54993966/do-i-have-to-update-gitlab-through-each-minor-version

현재 안정 버전이 12.1.0-ce.0 이니깐....
11.7.0-ce.0 > 11.8.0-ce.0 > 11.9.0-ce.0 > 11.10.0-ce.0 > 11.11.0-ce.0 > 12.0.0-ce.0 > 12.1.0-ce.0

이정도 쯤이야......



(3) Gitlab server 백업 데이터 이전 및 버전 업그레이드 후... Settings - CI/CD 항목 진입시 500 에러

모든게 잘 작동하는 것 같았고, 모든 데이터가 너무나도 잘 살아있던 그 때. CI/CD 항목을 들어가는 순간, 야생의 500 에러 페이지가 나타났다. 모든 프로젝트의 Settings 메뉴에 CI/CD 항목만 들어가면 500 에러 페이지가 나왔다.

웹 서버의 경우 500 번대 에러가 나는 경우, 아무리 콘솔을 봐도 답을 찾긴 어렵다. 서버 에러는 서버 로그를 봐야한다.

gitlab-ctl tail 명령어는 gitlab 서버의 로그를 실시간으로 보여준다. 
너무나도 잘 만들었다.

명확하게 보이는 에러였지만, 해결 방법이 좀 길었다.
==> /var/log/gitlab/gitlab-rails/production.log <==
Started GET "/hslee/test-k8s-cicd/-/settings/ci_cd" for 172.18.0.1 at 2019-08-20 02:18:16 +0000
Processing by Projects::Settings::CiCdController#show as HTML
Parameters: {"namespace_id"=>"hslee", "project_id"=>"test-k8s-cicd"}
Completed 500 Internal Server Error in 315ms (ActiveRecord: 58.6ms)


ActionView::Template::Error ():
25: project_clusters_path(@project),
26: class: 'btn btn-info'
27: %hr
28: = render partial: 'ci/runner/how_to_setup_runner',
29: locals: { registration_token: @project.runners_token,
30: type: 'specific',
31: reset_token_url: reset_registration_token_namespace_project_settings_ci_cd_ path }

lib/gitlab/crypto_helper.rb:27:in `aes256_gcm_decrypt'
app/models/concerns/token_authenticatable_strategies/encrypted.rb:45:in `get_token'
app/models/concerns/token_authenticatable_strategies/base.rb:33:in `ensure_token!'
app/models/concerns/token_authenticatable.rb:45:in `block in add_authentication_token_field'
app/models/project.rb:1590:in `runners_token'
app/views/projects/runners/_specific_runners.html.haml:28:in `_app_views_projects_runners__specific_runn ers_html_haml___4200129141666358982_69883394124780'
....(중략)....

==> /var/log/gitlab/gitlab-rails/production_json.log <==
{"method":"GET","path":"blarblar","format":"html","controller":"Projects::S ettings::CiCdController","action":"show","status":500,"error":"ActionView::Template::Error: ","duration" :315.46,"view":0.0,"db":58.61,"time":"2019-08-20T02:18:17.333Z","params":[{"key":"namespace_id","value": "hslee"},{"key":"project_id","value":"blarblar"}],"remote_ip":"172.18.0.1","user_id":17,"username": "blarblar","ua":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75 .0.3770.142 Safari/537.36","queue_duration":15.8,"gitaly_calls":1,"gitaly_duration":20.4,"correlation_id ":"blarblar"}


문제 해결 방법이 두가지가 있었는데, 첫번째 방법은 통하지 않았다. (해당 문제가 아니였다.)
  • 첫번째. db migrate 상태를 보고, on 되어있지 않으면 수동으로 켜주는 방법.
docker exec -it gitlab gitlab-rake db:migrate:status
#... 결과가 on 이 아니라면, ---
docker exec -it gitlab gitlab-rake db:migrate

-- db server 접속
su - postgres
psql -d postgres -U postgres

-- db 리스트 확인
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+---------+-------+-----------------------
gitlab | postgres | UTF8 | C | C | =Tc/postgres +
| | | | | postgres=CTc/postgres+
| | | | | gitlab=CTc/postgres

-- db 사용 선택
postgres=# \c gitlab
You are now connected to database "gitlab" as user "postgres".

-- db 내 프로젝트 테이블 정보 확인
gitlab=# \dti projects
List of relations
Schema | Name | Type | Owner | Table
--------+----------+-------+--------+-------
public | projects | table | gitlab |
(1 row)

-- 프로젝트 테이블 조회
gitlab=# select * from projects;
.... (테이블 결과, 너무 많아서 생략)....

-- 주요 부분 --
-- Clear project tokens
UPDATE projects SET runners_token = null, runners_token_encrypted = null;
-- Clear group tokens
UPDATE namespaces SET runners_token = null, runners_token_encrypted = null;
-- Clear instance tokens
UPDATE application_settings SET runners_registration_token_encrypted = null;
-- Clear runner tokens
UPDATE ci_runners SET token = null, token_encrypted = null;
  • 이러고 나면 Runner 토큰이 변경되므로 Runner 에 해당하는 서버에서 모두 토큰을 변경해주는 작업이 필요하다....ㅠㅠ


http://www.scala-sbt.org/


sbt 로 빌드된 Github 프로젝트를 사용해야 하는 상황
처음 SBT를 사용하는 나로선 이게 뭔가 싶었지만, 
maven 과 gradle 등의 빌드 도구에 구타를 당해봐서 당황하지 않고 설치를 시작했다
sbt는 홈페이지도 아주 simple 했다. (?homepage?)이름값 하는구나

버전 선택부터 문제였다. 컴퓨터를 만지다 보면 사람이 보수적으로 변한다
최신이 좋다는 머글들을 한심하게 바라보는 개발자의 마음이랄까
하지만 sbt 를 모르기 때문에 최신으로 받았다 1.0.2.

설치는 매우 순조롭게 진행되었다
자바로 개발되었는지 jar 파일로 설치파일을 실행 가능하다

리눅스의 경우 홈페이지에서 apt-get 으로 설치하라고 소개가 되어있다.
echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2EE0EA64E40A89B84B2DF73499E82A75642AC823
sudo apt-get update
sudo apt-get install sbt

빨간모자 계열은 아래와 같이
curl https://bintray.com/sbt/rpm/rpm | sudo tee /etc/yum.repos.d/bintray-sbt-rpm.repo
sudo yum install sbt

물론 MacOS 에서는 brew brew Homebrew
brew install sbt@1


하지만 문제는 설치를 다 마치고, 바로 sbt 프로젝트를 빌드를 시도하면서 시작되었다.

프로젝트 README 에는 간단하게 "sbt assembly" 를 하면 자동으로 빌드가 될 거고, 
target 폴더에 뿅 하고 jar 가 생길거라고.. 

맞다. 간단하게 찾아보니 sbt 는
플러그인을 통해 자동으로 복잡한 의존성을 해결해주고 빌드를 도와주는 도구라고 한다

하지만 그 많은 라이브러리와 플러그인이 꾸깃꾸깃 들어있어서 버전이나 서버 문제가 조금이라도 생기면....

그렇게 삽질이 시작되었다. 물론 해결을 했으니 공유해서 누군가는 구원받길 바라며 써본다.


문제발생 :: sbt ~~~~ not found, unresolved dependencies

에러의 첫 모습을 보면 다음과 같이 생겨먹었다

Warning 을 통해 의존성을 못찾겠다고 내뱉는다. (텍스트버전)
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] ::          UNRESOLVED DEPENDENCIES         ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: com.eed3si9n#sbt-assembly;0.14.0: not found
[warn] :: org.scoverage#sbt-scoverage;1.5.0: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::

그리곤 바로 이어서 에러를 뱉어준다. 둘 중 먼저 참조하는 녀석을 못찾겠다고.
[error] sbt.librarymanagement.ResolveException: unresolved dependency: com.eed3si9n#sbt-assembly;0.14.0: not found
[error] unresolved dependency: org.scoverage#sbt-scoverage;1.5.0: not found

두 에러를 잡기 위해선 아주 간단한 편집이 필요하다. 사실 어려운 문제는 아니었다.. 에러가 그렇지 뭐


문제해결 :: sbt-assembly not found

먼저 sbt-assembly 의 경우, sbt 프로젝트를 만든 root 의 project 디렉토리를 들어가보면 아무것도 없거나 assembly.sbt 가 있다. 없으면 만들고 있으면 편집 (vim assembly.sbt)

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5")

위 줄을 추가하거나 수정한다. (버전은 꼭 홈페이지에서 확인하고 수정해야한다)
사실 이 내용이 sbt-assembly github 페이지에 나온다..
github link : https://github.com/sbt/sbt-assembly 내용은 아래와 같다.

Setup :: Using Published Plugin

For sbt 0.13.6+ and sbt 1.0.0-M6, add sbt-assembly as a dependency in project/assembly.sbt:
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5")
For older sbt 0.13.x, see sbt-assembly 0.11.2.
For sbt 0.12, see sbt-assembly 0.9.2.
(You may need to check this project's tags to see what the most recent release is.)


문제해결 :: sbt-scoverage not found

위 sbt-assembly 문제를 해결하고 나서, 바로 같은 방법으로 github 페이지를 찾아봤다.
그렇게 길고 긴 4시간 삽질이 끝을 보였다.


가장 쉬운 방법은 project 디렉토리 내 plugin.sbt 를 만들거나 수정한다

addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.5.1")

위 줄을 추가하거나 수정한다. (버전은 꼭 홈페이지에서 확인하고 수정해야한다)
하지만 안되는 경우도 있는데, sbt project 버전이 플러그인이나 라이브러리와 맞지 않아서 발생할 수 있다.
발생하는 에러를 따라가서 플러그인이나 라이브러리의 홈페이지에서 명시된 sbt 버전이나 scala 버전을 확인하고 수정하면 된다.


결론

에러를 보면 습관적으로 구글에 복붙하게 되는데, 가끔 기본적인 부분에서 문제가 되는 경우가 있다.
공식 홈페이지나 API Documents 를 먼저 살펴보고, 버전이나 코드 문제가 아닌지 잘 살펴보자.

+ stackoverflow 를 맹신하지 말자...
++ 버전은 항상 변한다는걸 잊지말고...



+ Recent posts