본문 바로가기

Dockerfile 로 apache Deployment 배포하기

인포꿀팁 발행일 : 2022-02-07 최종 업데이트 : 2022-02-07
시작하기전 ...

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
       

      댓글