Ansible로 Docker 컨테이너 관리

개요


이곳의 내용은 이전에 노트가 쓴 문장다시 만들었어이다.
지금 다시 살펴보면 거친 부분이 많아 인프라를 구현한 코드를 살짝 수정했습니다.

구현


Ansible의 Playbook 구현 사항은 다음과 같습니다.
  • Docker 이미지 가져오기
  • JS 프레임, Nuxt.js 용기 구축
  • Docker Hub 이미지push
  • 사용된 도구 및 Ansible 모듈

  • Ansible 2.9.10
  • Docker 19.03.11
  • Docker API 1.40
  • Python 3.8.2
  • Docker SDK Python 1.80
  • docker_image
  • docker_container
  • docker_imagedocker_container를 사용하려면 Docker API 버전이 1.20 이상, Docker SDK Python 버전이 1.80 이상이어야 하기 때문에 사전에 버전을 높여야 한다.

    사전 준비


    우선 노드 이미지를 얻고 심플한 Nuxt.js 프로젝트를 만들 수 있는 도구create-nuxt-app는 미리 사용할 수 있으며, 응용 디렉터리를 메인 디렉터리로 하는 Docker file을 만들 수 있습니다.
    Dockerfile
    FROM node:latest
    WORKDIR /app
    
    이 Docker file을 구성하여 노드 이미지를 만든 후 컨테이너에 Nuxt를 연결합니다.js 프로젝트의 초기 형태를 구축합니다.
    컨테이너 내 명령
    docker run  -it <コンテナID> bash
    yarn create nuxt-app
    
    nuxt-app 명령을 실행한 후 대화 형식에서 Nuxt를 설정하여 간단하게 Nuxt 프로젝트를 만들 수 있습니다.질문의 상세한 내용은 참고사이트 축소판 그림로 각자의 취향에 따라 프로젝트의 초기 형태를 만든다.
    모형 제작을 마친 후 용기에서 꺼내 현지 기계로 복제한 모형.docker cp <コンテナID>:/app .이렇게 되면 준비됐으니 지금부터 Docker file과 Playbook을 만들어 보겠습니다.

    디렉토리 구조


    디렉토리는 다음과 같이 구성됩니다.]
    $ tree
    ├── dockerFile
    │   ├── Dockerfile
    │   └── app/(Nuxt.jsのひな型)
    └── build_image.yml
    └── create_container.yml
    

    Docker File 만들기


    Node 컨테이너에서 가져온 로컬 Nuxtjs의 초기 형태를 용기에Nuxt를 설정합니다.js 이미지를 만드는 Docker file을 만듭니다.
    Dockerfile
    FROM node:latest
    ENV NUXT_HOST=0.0.0.0
    ENV NUXT_TELEMETRY_DISABLED=1
    WORKDIR /app
    
    COPY ./app/package.json ./app/yarn.lock ./
    RUN yarn install
    
    COPY ./app .
    
    CMD ["yarn", "run", "dev"]
    

    Playbook 생성


    다음 Docker file을 만드는 데 사용할 Playbook을 만듭니다.
    build_image.yml
    - name: Build Nuxt.js image
      hosts: localhost
      tasks:
      - name: build nuxt.js
        docker_image:
          build:
            path: ./dockerFile
          name: yuta28/ansible-test
          tag: Nuxtimage
          push: yes #イメージビルド後自動的にDockerHubへpushする
          source: build
        register: build_result
    
      - debug: var=build_result
    
    docker_이미지의 build 옵션에서 Docker file의 현재 디렉토리를 지정합니다.
    name 옵션은 완성된 Docker 이미지의 이름을 지정합니다.
    source 옵션에서build을 지정하여 Docker File에서 이미지를 구성할 수 있습니다.
    마지막으로 이미지 기반 컨테이너의 Playbook,create-container.yml을 생성합니다.
    create_container.yml
    - name: Create and run container
      hosts: localhost
      tasks:
      - name: Nuxt container
        docker_container:
          name: NuxtContaier
          image: yuta28/ansible-test:Nuxtimage
          state: started
          ports:
            - "127.0.0.1:8080:3000" #コンテナ内のポート3000にNuxt.jsが構築されるのでローカルのポート8080から参照できるようにマッピング
          tty: true
          detach: true
        register: contaier_result
    
      - debug: var=contaier_result
    

    Ansible 실행


    준비되었습니다. Ansible을 실행합니다.
    $ ansible-playbook build_image.yml 
    [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
    
    PLAY [Build Nuxt.js image] ***************************************************************************************************************************************************************************
    
    TASK [Gathering Facts] *******************************************************************************************************************************************************************************
    ok: [localhost]
    
    TASK [build nuxt.js] *********************************************************************************************************************************************************************************
    [WARNING]: The default for build.pull is currently 'yes', but will be changed to 'no' in Ansible 2.12. Please set build.pull explicitly to the value you need.
    changed: [localhost]
    
    TASK [debug] *****************************************************************************************************************************************************************************************
    ok: [localhost] => {
        "build_result": {
            "actions": [
                "Built image yuta28/ansible-test:Nuxtimage from ./dockerFile",
                "Pushed image yuta28/ansible-test to docker.io/yuta28/ansible-test:Nuxtimage"
            ],
            "changed": true,
            "failed": false,
            "image": {
                "Architecture": "amd64",
                "Author": "",
                "Comment": "",
                "Config": {
                    "AttachStderr": false,
                    "AttachStdin": false,
                    "AttachStdout": false,
                    "Cmd": [
                        "yarn",
                        "run",
                        "dev"
                    ],
                    "Domainname": "",
                    "Entrypoint": [
                        "docker-entrypoint.sh"
                    ],
                    "Env": [
                        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                        "NODE_VERSION=14.8.0",
                        "YARN_VERSION=1.22.4",
                        "NUXT_HOST=0.0.0.0",
                        "NUXT_TELEMETRY_DISABLED=1"
                    ],
                    "Hostname": "",
                    "Image": "sha256:fe9a213a2bb59321425eb62ddcb54c9388e673b3f588ed4108b0b0c0c8ba78bb",
                    "Labels": null,
                    "OnBuild": null,
                    "OpenStdin": false,
                    "StdinOnce": false,
                    "Tty": false,
                    "User": "",
                    "Volumes": null,
                    "WorkingDir": "/app"
                },
                "Container": "50e3089197639ba613f1ae439d90142668cc5f0c360967fe8099c0093987695e",
                "ContainerConfig": {
                    "AttachStderr": false,
                    "AttachStdin": false,
                    "AttachStdout": false,
                    "Cmd": [
                        "/bin/sh",
                        "-c",
                        "#(nop) ",
                        "CMD [\"yarn\" \"run\" \"dev\"]"
                    ],
                    "Domainname": "",
                    "Entrypoint": [
                        "docker-entrypoint.sh"
                    ],
    〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜中略〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
                },
                "Size": 1430378578,
                "VirtualSize": 1430378578,
                "push_status": null
            },
            "warnings": [
                "The default for build.pull is currently 'yes', but will be changed to 'no' in Ansible 2.12. Please set build.pull explicitly to the value you need."
            ]
        }
    }
    
    PLAY RECAP *******************************************************************************************************************************************************************************************
    localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0      
    
    $ ansible-playbook create_container.yml
    [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
    
    PLAY [Create and run container] *********************************************************************************************************************************************************************
    
    TASK [Gathering Facts] *******************************************************************************************************************************************************************************
    ok: [localhost]
    
    TASK [Nuxt container] ********************************************************************************************************************************************************************************
    changed: [localhost]
    
    TASK [debug] *****************************************************************************************************************************************************************************************
    ok: [localhost] => {
        "contaier_result": {
            "ansible_facts": {
                "docker_container": {
                    "AppArmorProfile": "docker-default",
                    "Args": [
                        "yarn",
                        "run",
                        "dev"
                    ],
                    "Config": {
                        "AttachStderr": false,
                        "AttachStdin": false,
                        "AttachStdout": false,
                        "Cmd": [
                            "yarn",
                            "run",
                            "dev"
                        ],
                        "Domainname": "",
                        "Entrypoint": [
                            "docker-entrypoint.sh"
                        ],
                        "Env": [
                            "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                            "NODE_VERSION=14.8.0",
                            "YARN_VERSION=1.22.4",
                            "NUXT_HOST=0.0.0.0",
                            "NUXT_TELEMETRY_DISABLED=1"
                        ],
                        "ExposedPorts": {
                            "3000/tcp": {}
                        },
                        "Hostname": "f5597614f5d5",
                        "Image": "yuta28/ansible-test:Nuxtimage",
                        "Labels": {},
                        "OnBuild": null,
                        "OpenStdin": false,
                        "StdinOnce": false,
                        "Tty": true,
                        "User": "",
                        "Volumes": null,
                        "WorkingDir": "/app"
                    },
                    "Created": "2020-08-16T07:05:36.169002938Z",
                    "Driver": "overlay2",
                    "ExecIDs": null,
    〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜中略〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜        },
            "failed": false
        }
    }
    
    PLAY RECAP *******************************************************************************************************************************************************************************************
    localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    
    Ansible가failed 없이 끝까지 실행했기 때문에 컨테이너가 가동되었는지 확인http://127.0.01:8080부터Nuxt까지.js의 샘플 페이지에 접근할 수 있는지 시험해 보겠습니다.
    $ docker ps
    CONTAINER ID        IMAGE                           COMMAND                  CREATED             STATUS              PORTS                      NAMES
    f5597614f5d5        yuta28/ansible-test:Nuxtimage   "docker-entrypoint.s…"   37 minutes ago      Up 37 minutes       127.0.0.1:8080->3000/tcp   NuxtContaier
    

    샘플 페이지를 잘 방문할 수 있는지 확인했습니다.

    Docker Hub에 대한 push

    build_image.yml 자동push로 설정되어 있기 때문에 보시다시피 제 Docker Hub에 대한 인상이push로 바뀌었습니다.

    반성점


    Docker 이미지부터 컨테이너 부팅까지 Ansible을 통해 수행됩니다.
    다만, nuxt-app의 규격상 지령을 집행한 후 대화 형식으로 설정해야 하며, 도저히 용기에 들어가 수동으로 이 부분을 입력할 수 밖에 없다는 점은 유감스럽다.expect와 같은 명령을 사용하면 비밀번호를 변경하는 등 직접 입력 형식의 대화 형식을 설정할 수 있다.그러나 선택 형식이 예를 들어 좋아하는 프레임을 선택하라는 대화 형식이라면 선택한 항목을 반영할 수 없고 맨 위의 옵션이 대답으로 반영된다.
    그리고 기본 노드 이미지에 expect 명령이 없으며,yum 명령도 설치할 수 없으며, 필요한 원본 파일을 준비하여make 명령으로 입력해야 한다.Docker file에서 처음부터 이 일대의 설정을 설정하는 것은 매우 번거롭기 때문에 자동화인지 대화 형식의 유지인지는 사람에 따라 다르다고 생각합니다.(더 쉬운 방법이 있다면 꼭 알려주세요)

    추기


    평론에서 건의를 받다.
    node 컨테이너가 Debian OS이기 때문에 APT 패키지로 설치하는 것 같습니다.
    그러나 선택식expect 명령도 선택할 수 없다.
    상호 작용이 아닌 프로파일을 복사할 수 있는 방법을 조사해 봅시다.

    다음 회 예고


    다음에는 모듈이 아닌 안시블-벤더를 활용한 컨테이너 관리에 도전해 본다.

    LT 자료


    LT 슬라이드 자료입니다.

    좋은 웹페이지 즐겨찾기