-->

솔직히 도커는 고래이미지가 더 귀엽지 않나...쩝

[Docker] Dockerfile생성, 그리고 build 하기 (ssh컨테이너용)

 

앞선 포스팅을 따라왔다면 우리는 docker hub에서 centos나 ubuntu의 이미지를 pull 하여 container를 생성했고,

해당 container를 run 하여 open-ssh를 설치하여 접속이 가능한지 테스트까지 해봤다.

그러나 매번 환경설정을 해주는 것은 너무나 비효율적이다.

이번에는 우리가 수동으로 작업한 일련의 과정들을 "자동화" 하는 방법에 대해 알아보려고 한다.

나만의 docker image를 만드는 것이 바로 Dockerfile의 build이다.

 

commit과 개념적으로 차이가 있다.

commit : docker container로부터 나의 docker image를 새로 생성 (backup)

build : 내가 설정해놓은 순서대로 명령을 실행하여 docker image를 새로 생성 (automation)

둘 다 docker image를 생성해내는 과정이고 해당 image를 바탕으로 container를 실행하게 된다.

 

여타 샘플들은 appach 서버나 nginx를 이용해 샘플 웹서버를 띄우는 것을 보여주는데 일단 우리는 저번에 작업한

open-ssh를 dockerfile로 만들어보자.

https://minggu92.tistory.com/71

 

[Docker] docker container ssh 설치 및 접속

[Docker] docker container ssh 접속 docker로 컨테이너 관리를 하기 위한 ssh 접속 환경설정을 해보자. 먼저 centos 이미지를 통해 컨테이너를 만들어준다. 난 1002 포트를 이용해보도록 하겠다. #centos7 이미..

minggu92.tistory.com

 

 

1. DockerFile 폴더 생성

Dockerfile을 관리할 폴더를 먼저 생성한다. 해당 경로에 Dockerfile을 만들 것이다.

#root 경로에 dockerfile 폴더 생성
[minggu92@cloud ~]$ cd /
[minggu92@cloud /]$ mkdir dockerfiles
[minggu92@cloud /]$ cd dockerfiles
[minggu92@cloud dockerfiles]$

 

2. DockerFile 파일 생성

기본적으로 Dockerfile은 확장자 이름이며 명령문으로 구성되어있다.

어떤 이미지를 pull 하여 작업을 시작할 건지, 내가 어떤 경로에서 작업을 진행할 건지 등에 대해서 define 한다.

또한 Dockerfile은 확장자가 따로 존재하지 않기 때문에 리눅스 환경에서는 touch나 vim편집기로 바로 생성을 하면 된다.

#dockerfile 생성
[minggu92@cloud dockerfiles]$ touch Dockerfile
[minggu92@cloud dockerfiles]$ ls
Dockerfile
[minggu92@cloud dockerfiles]$ vi Dockerfile
~
~
~
~
"Dockerfile" 0L, 0C

 

3. Dockerfile 명령어

FROM base 이미지 설정
WORKDIR 작업 디렉터리 설정
RUN 이미지 빌드 시 커맨드 실행
ENTRYPOINT 이미지 실행 시 항상 실행되야 하는 커맨드 설정
CMD 이미지 실행 시 디폴트 커맨드 또는 파라미터 설정
EXPOSE 컨테이너가 리스닝할 포트 및 프로토콜 설정
COPY/ADD 이미지의 파일 시스템으로 파일 또는 디렉터리 복사
ENV 환경 변수 설정
ARG 빌드 시 넘어올 수 있는 인자 설정

 

4. Dockerfile 생성 예제 (실패)

# 1. pull OS image (centos or ubuntu)
# format : FROM [image]:[tag]
FROM centos:7
# FROM ubuntu:18.04

# 2. 메타데이터 표시
LABEL "purpose"="ssh_test"
LABEL "author"="minggu"
ENV USER minggu1

# 3. 업데이트 및 네트워크 환경설정
#RUN ["[command]", "[parameter1]", "[parameter2]" ...]
# -y 명령어를 빼먹으면 도커 실행이 안된다. 반드시 yes 하자.
RUN yum -y update
RUN yum -y install ntsysv initscripts net-tools sudo openssh-server openssh-clients openssh-askpass
RUN mkdir /var/run/sshd

# 4. minggu1유저에게 sudo 권한 생성
RUN sed -ri '20a'$USER'    ALL=(ALL) NOPASSWD:ALL' /etc/sudoers

# 5. .ssh 생성 및 권한주기
RUN useradd -m $USER
RUN mkdir /home/$USER/.ssh
RUN chown $USER.$USER /home/$USER/.ssh
RUN chmod 700 /home/$USER/.ssh

#6. 패스워드 설정
RUN echo 'root:root' | chpasswd
RUN echo $USER':test' | chpasswd

# 7. 포트 22번 노출 지정
EXPOSE 22

# 8. CMD : 컨테이너 생성시 시작명령어
#CMD ["[command]", "[parameter1]", "[parameter2]" ...]
#CMD ["[parameter1]", "[parameter2" ...]
#CMD <전체커맨드>
CMD ["/usr/sbin/sshd", "-D"]

실패한 빌드이다 스크롤을 더 내려보자

 

5. Dockerfile build

docker build -t [name]:[tag] [경로] -f [*.Dockerfile] 

docker build -t [name]:[tag] ./ (현재 경로에 Dockerfile 실행)

#docker build
#현재 경로에서 도커파일 실행 
# -t : 생성할 docker image의 이름 (tagging)
[minggu92@cloud dockerfiles]$ docker build -t dockerfile_test:1.0 ./
Sending build context to Docker daemon  3.072kB
Step 1/16 : FROM centos:7
 ---> eeb6ee3f44bd
Step 2/16 : LABEL "purpose"="ssh_test"
 ---> Running in 17d6fce5505f
Removing intermediate container 17d6fce5505f
 ---> b35959dbb71f
Step 3/16 : LABEL "author"="minggu"
 ---> Running in e1fe6b8a511d
Removing intermediate container e1fe6b8a511d
 ---> f6544610e2d1
Step 4/16 : ENV USER minggu1
 ---> Running in 86922e78b989
Removing intermediate container 86922e78b989
 ---> bbd2336cfde0
Step 5/16 : RUN yum -y update
 ---> Running in 57acdb08bce3
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
 * base: mirror.kakao.com
....
...
Step 7/16 : RUN mkdir /var/run/sshd
 ---> Running in bdb92aa6b47f
Removing intermediate container bdb92aa6b47f
 ---> 8fbab73936a3
Step 8/16 : RUN sed -ri '20a'$USER'    ALL=(ALL) NOPASSWD:ALL' /etc/sudoers
 ---> Running in 776d610cad63
Removing intermediate container 776d610cad63
 ---> cc5793aeae93
Step 9/16 : RUN useradd -m $USER
 ---> Running in e126cc75fab1
Removing intermediate container e126cc75fab1
 ---> 2880fd7432e7
Step 10/16 : RUN mkdir /home/$USER/.ssh
 ---> Running in 8d4fb62a9c1a
Removing intermediate container 8d4fb62a9c1a
 ---> dd18dd6c418a
Step 11/16 : RUN chown $USER.$USER /home/$USER/.ssh
 ---> Running in ae85ea8cc25a
Removing intermediate container ae85ea8cc25a
 ---> 85a217c9a5e7
Step 12/16 : RUN chmod 700 /home/$USER/.ssh
 ---> Running in 4e52674f51c9
Removing intermediate container 4e52674f51c9
 ---> 065e746af97f
Step 13/16 : RUN echo 'root:root' | chpasswd
 ---> Running in 26c454a3e869
Removing intermediate container 26c454a3e869
 ---> ca30365e6fa4
Step 14/16 : RUN echo $USER':test' | chpasswd
 ---> Running in 12be00106c8c
Removing intermediate container 12be00106c8c
 ---> f298007089b9
Step 15/16 : EXPOSE 22
 ---> Running in a3b36ef19f51
Removing intermediate container a3b36ef19f51
 ---> b2e424784afb
Step 16/16 : CMD ["/usr/sbin/sshd", "-D"]
 ---> Running in 7db68b21901d
Removing intermediate container 7db68b21901d
 ---> 770fa9a45b87
Successfully built 770fa9a45b87
Successfully tagged dockerfile_test:1.0

엥 왜 됐지?

잘됐다.

 

 

 

6. build 된 이미지 확인 및 실행

# 도커 이미지 출력
[minggu92@cloud dockerfiles]$ docker images
REPOSITORY        TAG       IMAGE ID       CREATED        SIZE
dockerfile_test   1.0       770fa9a45b87   2 hours ago    725MB
...

#에러발생
[minggu92@cloud dockerfiles]$ docker container run -it dockerfile_test:1.0
Could not load host key: /etc/ssh/ssh_host_rsa_key
Could not load host key: /etc/ssh/ssh_host_ecdsa_key
Could not load host key: /etc/ssh/ssh_host_ed25519_key
sshd: no hostkeys available -- exiting.

음 역시 실행 시 에러가 발생.

일단 도커 이미지 삭제해주자.

#도커 이미지 삭제
[minggu92@cloud dockerfiles]$ docker rmi dockerfile_test:1.0
Error response from daemon: conflict: unable to remove repository reference "dockerfile_test:1.0" (must force) - container 6afa2ec66174 is using its referenced image 770fa9a45b87

#도커 컨테이너 전체 삭제
[minggu92@cloud dockerfiles]$ docker rm -f $(docker ps -qa)
[minggu92@cloud dockerfiles]$ docker rmi dockerfile_test:1.0
Untagged: dockerfile_test:1.0
Deleted: sha256:.....
....

 

7. Dockerfile 수정

# 1. pull OS image (centos or ubuntu)
# format : FROM [image]:[tag]
FROM centos:7
# FROM ubuntu:18.04

# 2. 메타데이터 표시
LABEL "purpose"="ssh_test"
LABEL "author"="minggu"
ENV USER minggu1

# 3. 업데이트 및 네트워크 환경설정
#RUN ["[command]", "[parameter1]", "[parameter2]" ...]
# -y 명령어를 빼먹으면 도커 실행이 안된다. 반드시 yes 하자.
RUN yum -y update && yum -y install ntsysv initscripts net-tools sudo openssh-server openssh-clients openssh-askpass
RUN mkdir /var/run/sshd

# 4. minggu1유저에게 sudo 권한 생성
RUN sed -ri '20a'$USER'    ALL=(ALL) NOPASSWD:ALL' /etc/sudoers

# 5. .ssh 생성 및 권한주기
RUN useradd -m $USER
RUN mkdir /home/$USER/.ssh
RUN chown $USER.$USER /home/$USER/.ssh
RUN chmod 700 /home/$USER/.ssh

#6. 패스워드 설정
RUN echo 'root:root' | chpasswd
RUN echo $USER':test' | chpasswd

# 7. Generate Keys & 포트 22번 노출 지정 
RUN ssh-keygen -q -N "" -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -q -N "" -t rsa -f /root/.ssh/id_rsa
RUN cp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys
EXPOSE 22

#ENTRYPOINT로 미리 명령어 실행할 수 있지만 도커 실행할 때 설정하는걸로
#ENTRYPOINT["/sbin/init", "systemctl start sshd", "systemctl enable sshd"]

# 8. CMD : 컨테이너 생성시 시작명령어
#CMD ["[command]", "[parameter1]", "[parameter2]" ...]
#CMD ["[parameter1]", "[parameter2" ...]
#CMD <전체커맨드>
CMD ["/usr/sbin/sshd", "-D"]

RUN 뒤에 && 을 붙이는 건 앞 명령어가 정상 실행이 되면 뒤 명령어를 실행하겠다는 뜻이다.

step을 줄이기 위해 && 표현을 쓰도록 하자.

 

8. 최종

#도커파일 빌드
[minggu92@cloud dockerfiles]$ docker build -t dockerfile_test:1.0 ./

#도커 실행
[minggu92@cloud dockerfiles]$ docker run --privileged -d -p 1002:22 --name minggu1_ssh dockerfile_test:1.0  /sbin/init
d45e8fc8ba2c821eccea71d0ca00316f7f9fa621e8d4f10b433cab8def6b413c
[minggu92@cloud dockerfiles]# docker exec -it minggu1_ssh /bin/bash
[root@a81f33368378 /]#

#계정 변경
[root@a81f33368378 /]# su - minggu1
[minggu1@d45e8fc8ba2c ~]$ systemctl status sshd
● sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2022-03-22 04:16:54 UTC; 13s ago
     Docs: man:sshd(8)
           man:sshd_config(5)
 Main PID: 92 (sshd)
   CGroup: /docker/d45e8fc8ba2c821eccea71d0ca00316f7f9fa621e8d4f10b433cab8def6b413c/system.slice/sshd.service
           └─92 /usr/sbin/sshd -D
           ‣ 92 /usr/sbin/sshd -D
[minggu1@d45e8fc8ba2c ~]$

 

혹시 systemctl명령어 사용 중 에러가 발생했다면 아래를 참고

https://minggu92.tistory.com/74

 

[Docker] Failed to get D-Bus connection: Operation not permitted (systemctl 명령어 사용실패)

[Docker] Failed to get D-Bus connection: Operation not permitted dockerfile을 실행해 container를 run 하고 서비스를 실행하려고 하면 에러가 난다. #dockerfile 실행 [minggu92@cloud dockerfiles]..

minggu92.tistory.com

 

 

 

 

 

 

 

 

<참고>

https://www.daleseo.com/dockerfile/

 

Dockerfile에서 자주 쓰이는 명령어

Engineering Blog by Dale Seo

www.daleseo.com

https://blog.d0 ngd0 nge.xyz/docker-dockerfile-write/

 

Docker - Dockerfile 작성 / Build (이미지 제작)

[Docker - Dockerfile Write] 인프라 구성을 관리 및 효율적으로 운영하기 위해 "Dockerfile"를 이용할 수 있으며, Dockerfile를 작성하여 사용자가 원하는 설계 방향이나 설정된 내용으로 도커 이미지를 제작

blog.d0ngd0nge.xyz

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=forioso&logNo=220508084650 

 

Docker 빌더해보기

Docker 는 특정 이미지로 부터 명령어를 추가한 새로운 이미지를 생성할 수 있다. Docker 를 빌더해 보자...

blog.naver.com

 

반응형

+ Recent posts