[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

+ Recent posts