본문 바로가기

Dockerfile 로 apache Deployment 배포하기

인포꿀팁 발행일 : 2022-02-07
시작하기전 ...

Dockerfile 이란?

Dockerfile 은 컨테이너 이미지를 빌드하는 방법에 대한 명령이 포함되고 이름이 Containerfile 또는 Dockerfile인 텍스트 파일입니다. Dockerfile의 기본 구문은 다음과 같습니다.

FROM ubi8/ubi:8.3
LABEL description="This is a custom httpd container image"
MAINTAINER John Doe <jdoe@xyz.com>
RUN yum install -y httpd
EXPOSE 80
ENV LogLevel "info"
ADD http://someserver.com/filename.pdf /var/www/html
COPY ./src/ /var/www/html/
USER apache
ENTRYPOINT ["/usr/sbin/httpd"]
CMD ["-D", "FOREGROUND"]

1. 해시 또는 파운드 기호(#)로 시작하는 줄은 주석입니다.

2. FROM 명령은 새 컨테이너 이미지가 ubi8/ubi:8.3 컨테이너 기본 이미지를 확장함을 선언합니다.
Dockerfile은 운영 체제 배포판에 있는 이미지뿐만 아니라 다른 컨테이너 이미지를 기본 이미지로
사용할 수 있습니다. 

3. LABEL은 이미지에 일반 메타데이터를 추가합니다. LABEL은 단순한 키-값 쌍입니다.

4. MAINTAINER는 생성된 컨테이너 이미지 메타데이터의 Author 필드를 나타냅니다. docker inspect 명령을 사용하여 이미지 메타데이터를 볼 수 있습니다.

5. RUN은 현재 이미지 맨 위의 새 계층에 있는 명령을 실행합니다. 명령을 실행하는 데 사용되는 쉘은 /bin/sh입니다.

6. EXPOSE는 컨테이너가 런타임에 지정된 네트워크 포트에서 수신함을 나타냅니다. EXPOSE 명령은 메타데이터만 정의합니다. 호스트에서 포트에 액세스하도록 설정할 수 없습니다. docker run 명령의 -p 옵션은 호스트의 컨테이너 포트를 공개합니다.

7. ENV는 컨테이너에서 사용할 수 있는 환경 변수를 정의합니다. Dockerfile 내에 다양한 ENV 명령을
선언할 수 있습니다. 컨테이너 내에 env 명령을 사용하여 각 환경 변수를 볼 수 있습니다.

8. ADD 명령은 로컬 또는 원격 소스에서 파일이나 폴더를 복사하여 컨테이너의 파일 시스템에 추가합니다. 이 명령이 로컬 파일을 복사하는 데 사용되는 경우 작업 디렉터리에 있어야 합니다. ADD 명령은 대상 이미지 디렉터리에 로컬 .tar 파일의 압축을 풉니다.

9. COPY는 작업 디렉터리에서 파일을 복사하여 컨테이너의 파일 시스템에 추가합니다. 이 Dockerfile 명령으로 URL을 사용하여 원격 파일을 복사할 수 없습니다.

10. USER는 RUN, CMD, ENTRYPOINT 명령에 대해 컨테이너 이미지를 실행할 때 사용할 사용자 이름 또는 UID를 지정합니다. 보안상의 이유로 root가 아닌 다른 사용자를 정의하는 것이 좋습니다.

11. ENTRYPOINT는 컨테이너에서 이미지가 실행될 때 실행할 기본 명령을 지정합니다. 생략할 경우 기본
ENTRYPOINT는 /bin/sh -c입니다. CMD는 ENTRYPOINT 명령의 기본 인수를 제공합니다. 기본 ENTRYPOINT가 (/bin/sh -c)를 적용하는 경우 CMD는 컨테이너를 시작할 때 실행되는 실행 가능한 명령과 매개 변수를 형성합니다.

Dockerfile 빌드 후 레포지토리에 push

사용할 이미지 pull로 현재 사용중인 Local Repository로 저장하기

docker에 로그인을 먼저한 후 가져올 이미지를 pull 을 해줍니다. 이때 가져올 이미지가 있는 레포지토리에 로그인을 합니다. 저는 redhat registry에 등록된 이미지를 사용했기때문에 registry.access.redhat.com에 로그인 했습니다.

[root@m-k8s ~]# docker login registry.access.redhat.com
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

[root@m-k8s Dockerfiles]# docker pull registry.access.redhat.com/ubi8/ubi:8.3
8.3: Pulling from ubi8/ubi
4b21dcdd136d: Pull complete
55eda7743468: Pull complete
Digest: sha256:37e09c34bcf8dd28d2eb7ace19d3cf634f8a073058ed63ec6e199e3e2ad33c33
Status: Downloaded newer image for registry.access.redhat.com/ubi8/ubi:8.3
registry.access.redhat.com/ubi8/ubi:8.3

[root@m-k8s Dockerfiles]# docker images
REPOSITORY                            TAG       IMAGE ID       CREATED         SIZE
quay.io/lyh/nexus                     latest    0becb22a136b   3 weeks ago     537MB
k8s.gcr.io/kube-apiserver             v1.22.1   f30469a2491a   4 months ago    128MB
k8s.gcr.io/kube-proxy                 v1.22.1   36c4ebbc9d97   4 months ago    104MB
k8s.gcr.io/kube-scheduler             v1.22.1   aca5ededae9c   4 months ago    52.7MB
k8s.gcr.io/kube-controller-manager    v1.22.1   6e002eb89a88   4 months ago    122MB
k8s.gcr.io/etcd                       3.5.0-0   004811815584   6 months ago    295MB
k8s.gcr.io/coredns/coredns            v1.8.4    8d147537fb7d   7 months ago    47.6MB

registry.access.redhat.com/ubi8/ubi   8.3       613e5da7a934   8 months ago    205MB

metallb/speaker                       v0.9.6    e9f480f8f070   9 months ago    99.4MB
k8s.gcr.io/pause                      3.5       ed210e3e4a5b   9 months ago    683kB
calico/pod2daemon-flexvol             v3.17.1   819d15844f0c   12 months ago   21.7MB
calico/cni                            v3.17.1   64e5dfd8d597   12 months ago   128MB
calico/node                           v3.17.1   183b53858d7d   13 months ago   165MB
calico/kube-controllers               v3.17.1   278f40d9f3b8   13 months ago   52.1MB

pull 받은 이미지의 tag 변경 (hub.docker.com에 올라갈 이미지)

Docker 도커 허브에서 내 레포지토리 명과 일치시킨후 저장합니다. tag도 설정하여 저장합니다.

[root@m-k8s Dockerfiles]# docker tag registry.access.redhat.com/ubi8/ubi:8.3 sample/apache:test
 

Dockerfile 작성 후 이미지 build

위에서 태그를 변경한 이미지 명을 FROM에 넣고 아래와 같이 변수값을 입력합니다.

입력이 완료되었다면 Dockerfile 이 있는 디렉터리에서 아래와 같은 명령어를 통해 build 해줍니다.

Dockerfile

FROM sample/apache:test
MAINTAINER young <_dldudgjs31@naver.com_>
LABEL description="A custom Apache container based on UBI 8"
RUN yum install -y httpd && \
yum clean all
RUN echo "Hello from Containerfile" > /var/www/html/index.html
EXPOSE 80
CMD ["httpd", "-D", "FOREGROUND"]
 
docker build -t pentalink/apache:test .
 

build 된 이미지를 dockerhub에 push

정상적으로 build가 완료 되었다면 이미지를 dockerhub에 push합니다.  이때 push 하기전에 docker가 docker.io에 로그인 되어 있어야 합니다. 또한 변경된 이미지 명과 동일하게 docker hub에 레포지토리를 먼저 생성해야합니다.

docker push pentalink/apache:test
 

Kubernetes 에 만든 이미지로 배포하기

Deployment yaml 생성

deployment를 생성하기 위해 yaml 파일을 만듭니다. 만든 이미지 태그를 아래와 같이 작성합니다. 배포후 아래와 같이 정상적으로 deployment와 replicaset이 생성된걸 볼 수 있습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: sample-apache
  name: sample-apache
spec:
  replicas: 2
  selector:
    matchLabels:
      app: sample-apache
  strategy: {}
  template:
    metadata:
      labels:
        app: sample-apache
    spec:
      containers:
      - image: pentalink/apache:test
        name: apache
 

Deployment 노출 시키기

생성한 deployment를 외부에 노출시키기위해 서비스를 생성합니다. 내부망에서만 접근 가능하게 테스트하기 위해 ClusterIP 타입의 서비스를 사용합니다. 이때 내부 ip가 생성이 된걸 확인할 수 있습니다.

[root@m-k8s ~]# k expose deployment sample-apache --port=80 --target-port=80 --type=ClusterIP --name apache

[root@m-k8s ~]# k get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
apache       ClusterIP   10.103.25.52   <none>        80/TCP    126m
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   119d
 
[root@m-k8s ~]# k get all
NAME                                 READY   STATUS    RESTARTS   AGE
pod/sample-apache-565f687f5c-hmpm4   1/1     Running   0          124m
pod/sample-apache-565f687f5c-hwxbz   1/1     Running   0          124m

NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/apache       ClusterIP   10.103.25.52   <none>        80/TCP    122m
service/kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   119d

NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/sample-apache   2/2     2            2           124m

NAME                                       DESIRED   CURRENT   READY   AGE
replicaset.apps/sample-apache-565f687f5c   2         2         2       124m
 

curl로 연결 확인

생성한 서비스의 IP와 PORT로 DEPLOYMENT 에 접근해봅니다. 아래와 같이 정상적으로 연결이 가능한걸 볼수 있습니다.

[root@m-k8s ~]# curl -i 10.103.25.52:80
HTTP/1.1 200 OK
Date: Fri, 07 Jan 2022 07:37:15 GMT
Server: Apache/2.4.37 (Red Hat Enterprise Linux)
Last-Modified: Fri, 07 Jan 2022 04:51:47 GMT
ETag: "19-5d4f6be853ec0"
Accept-Ranges: bytes
Content-Length: 25
Content-Type: text/html; charset=UTF-8

Hello from Containerfile
 

댓글