본문 바로가기

클라우드/도커(Docker)

도커 Docker gcc 컴파일러를 사용하여 이미지 만들기

더보기

# 바이너리만 있는 이미지
# ldd 공유 라이브러리를 출력해주는 명령어
# 참조하는 라이브러리
# libc 표준 라이브러리
# gcc 컴파일러로 실행파일을 만들어 준다 
vagrant@docker:~$ sudo apt install gcc
vagrant@docker:~$ mkdir hello
vagrant@docker:~$ cd hello/
vagrant@docker:~/hello$ cat hello.c
#include <stdio.h>

int main() {
printf("Hello ldh World\n");
return 0;
}

vagrant@docker:~/hello$ gcc hello.c -o hello  # gcc 소스코드 -o output
vagrant@docker:~/hello$ ls hello 
hello
vagrant@docker:~/hello$ file hello
hello: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked,
interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=a20cc4ecf1c0a171d0e360c0bb5bfd77f622422f,
for GNU/Linux 3.2.0, not stripped


# 실행
vagrant@docker:~/hello$ ./hello
Hello ldh World


더보기

# 동적 링크 


# Dockerfile 작성  
# scratch라는 빈 이미지 사용
# FROM 없이는 이미지 빌드가 안된다 (베이스 이미지가 있어야한다)
# HELLO 하나 실행하려고 수백메가짜리 운영체제 올리는건 비효율적
vagrant@docker:~/hello$ cat Dockerfile
FROM scratch
COPY hello /hello
CMD ["/hello"]

# 이미지 생성
vagrant@docker:~/hello$ docker build -t hello .

# 확인
vagrant@docker:~/hello$ docker images
REPOSITORY        TAG        IMAGE ID       CREATED          SIZE
hello             latest     4e38b022fd9a   37 seconds ago   16.7kB

# 컨테이너 생성
vagrant@docker:~/hello$ docker run --rm hello
standard_init_linux.go:228: exec user process caused: no such file or directory

-> 생성되지 않는다

# 생성되지 않는 이유
vagrant@docker:~/hello$ file hello
hello: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=a20cc4ecf1c0a171d0e360c0bb5bfd77f622422f, for GNU/Linux 3.2.0, not stripped

-> dynamically linked 동적링크 실행파일 내에 라이브러리가 없기 때문 
   실행시켜 주려면 이미지 내에 hello, lib, lib64를 추가해 주어야한다 
   ( 실습시간엔 hello-world 이미지를 save하여 copy 하였다 /생략)
   
   
# Dockerfile 수정 
vagrant@docker:~/hello$ cat Dockerfile
FROM scratch
COPY hello /hello
COPY lib /lib
COPY lib64 /lib64
CMD ["/hello"]

# 이미지 생성
vagrant@docker:~/hello$ docker build -t hello .

# 컨테이너 생성
vagrant@docker:~/hello$ docker run --rm hello
Hello ldh World


--> 
헬로우 파일에 라이브러리가 몇개 없기 때문에, 수동으로 추가 할 수 있지만 복잡한 이미지엔 적용하기 쉽지 않다


더보기

# 정적 링크

# --static 컴파일
# 필요한 라이브러리를 실행파일에 다 넣어, 추가로 라이브러리가 필요없다
# 하지만 사이즈가 커진다
vagrant@docker:~/hello$ gcc hello.c --static -o hello-static
vagrant@docker:~/hello$ file hello-static 
hello-static: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, 
BuildID[sha1]=50e948f04cf8619014d8e64eedfc8811068399fa, for GNU/Linux 3.2.0, not stripped


# Dockerfile 작성  
vagrant@docker:~/hello$ cat Dockerfile 
FROM scratch
COPY hello-static /hello
CMD ["/hello"]

# 이미지 생성
vagrant@docker:~/hello$ docker build -t hello-static .

# 컨테이너 생성  
vagrant@docker:~/hello$ docker run --rm hello-static
Hello ldh World


더보기

# 멀티 스테이지 빌드
# c컴파일러가 포함되어있는 이미지를 사용하여  빌드
# 첫번째에 있는 이미지로부터 파일을 가져오세요 (--from 0  )
vagrant@docker:~/hello$ cat Dockerfile 
FROM gcc
COPY hello.c /
WORKDIR /
RUN gcc hello.c --static -o hello

FROM scratch
COPY --from=0 /hello /hello
CMD ["/hello"]

# 이미지 생성 
vagrant@docker:~/hello$ docker build -t hello-multi .

# 컨테이너 생성, 실행 
vagrant@docker:~/hello$ docker run --rm hello-multi
Hello ldh World


# as 별명
#--from=별명
vagrant@docker:~/hello$ cat Dockerfile 
FROM gcc as builder 
COPY hello.c /
WORKDIR /
RUN gcc hello.c --static -o hello

FROM scratch
COPY --from=builder /hello /hello
CMD ["/hello"]