Nesta página, você vê como criar imagens mais enxutas do Docker.
Como criar contêineres mais enxutos
Quando você coloca um aplicativo em contêineres, os arquivos que não são necessários no ambiente de execução, como dependências de tempo de compilação e arquivos intermediários, são incluídos inadvertidamente na imagem do contêiner. Esses arquivos desnecessários aumentam o tamanho da imagem e geram mais tempo e custo à medida que ela é transferida entre o registro do Docker e o ambiente de execução do contêiner.
Para reduzir o tamanho da imagem do contêiner, separe a compilação do aplicativo, além das ferramentas usadas para criá-lo, a partir da montagem do contêiner do ambiente de execução.
O Cloud Build oferece uma série de objetos de contêineres com cargas de trabalho ferramentas para desenvolvedores, como Git, Docker e a Google Cloud CLI. Use essas ferramentas para definir um arquivo de configuração de versão com uma etapa para criar o aplicativo e outra para montar o ambiente de tempo de execução final.
Por exemplo, se você estiver criando um aplicativo Java, que requer arquivos como do código-fonte, bibliotecas de aplicativos, sistemas de build, dependências e o JDK, é possível ter um Dockerfile parecido com o seguintes:
FROM java:8
COPY . workdir/
WORKDIR workdir
RUN GRADLE_USER_HOME=cache ./gradlew buildDeb -x test
RUN dpkg -i ./gate-web/build/distributions/*.deb
CMD ["/opt/gate/bin/gate"]
No exemplo acima, o Gradle, que é usado para criar o pacote, faz o download de um grande número de bibliotecas para fins de funcionamento. Essas bibliotecas são essenciais para a criação do pacote, mas não são necessárias no momento da execução. Todas as dependências de tempo de execução são agrupadas no pacote.
Cada comando no Dockerfile
cria uma nova camada no contêiner. Se os dados forem gerados nessa camada e não forem excluídos no mesmo comando, esse espaço não poderá ser recuperado. Nesse caso, o Gradle está fazendo download de centenas de megabytes de bibliotecas para o diretório cache
para executar o build, mas as bibliotecas não são excluídas.
Uma maneira mais eficiente de executar a versão é usar o Cloud Build para separar a criação do aplicativo da criação da camada de tempo de execução dele.
No exemplo a seguir, separamos a etapa de criação do aplicativo Java da etapa de montagem do contêiner de tempo de execução:
YAML
-
Criar o aplicativo: em
cloudbuild.yaml
, adicione uma etapa para criar o aplicativo.O código a seguir adiciona uma etapa que cria a imagem
java:8
, que contém o código Java.steps: - name: 'java:8' env: ['GRADLE_USER_HOME=cache'] entrypoint: 'bash' args: ['-c', './gradlew gate-web:installDist -x test']
- Montar o contêiner do ambiente de execução: em
cloudbuild.yaml
, adicione uma etapa para montar o contêiner do ambiente de execução.O código a seguir adiciona uma etapa chamada
gcr.io/cloud-builders/docker
, que monta o contêiner do ambiente de execução. Ele define o contêiner do ambiente de execução em um arquivo separado chamadoDockerfile.slim
.O exemplo usa a camada de base do Alpine Linux
openjdk:8u111-jre-alpine
, que é incrivelmente leve. Além disso, ele inclui o JRE em vez do JDK mais volumoso, que foi necessário para criar o aplicativo.cloudbuild.yaml steps: - name: 'java:8' env: ['GRADLE_USER_HOME=cache'] entrypoint: 'bash' args: ['-c', './gradlew gate-web:installDist -x test'] - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA', '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:latest', '-f', 'Dockerfile.slim', '.' ] Dockerfile.slim FROM openjdk:8-jre-alpine COPY ./gate-web/build/install/gate /opt/gate CMD ["/opt/gate/bin/gate"]
- Criar as imagens do Docker: em
cloudbuild.yaml
, adicione uma etapa para criar as imagens.steps: - name: 'java:8' env: ['GRADLE_USER_HOME=cache'] entrypoint: 'bash' args: ['-c', './gradlew gate-web:installDist -x test'] - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA', '-t', 'gcr.io/$PROJECT_ID/$REPO_NAME:latest', '-f', 'Dockerfile.slim', '.'] images: - 'gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA' - 'gcr.io/$PROJECT_ID/$REPO_NAME:latest'
JSON
-
Criar o aplicativo: em
cloudbuild.json
, adicione uma etapa para criar o aplicativo.O código a seguir adiciona uma etapa chamada
java:8
para criar o código Java.{ "steps": [ { "name": "java:8", "env": [ "GRADLE_USER_HOME=cache" ], "entrypoint": "bash", "args": [ "-c", "./gradlew gate-web:installDist -x test" ] }, }
-
Montar o contêiner do ambiente de execução: em
cloudbuild.json
, adicione uma etapa para montar o contêiner do ambiente de execução.O código a seguir adiciona uma etapa chamada
gcr.io/cloud-builders/docker
, que monta o contêiner do ambiente de execução. Ele define o contêiner do ambiente de execução em um arquivo separado chamadoDockerfile.slim
.O exemplo usa a camada de base do Alpine Linux
openjdk:8u111-jre-alpine
, que é incrivelmente leve. Além disso, ele inclui o JRE em vez do JDK mais volumoso, que foi necessário para criar o aplicativo.cloudbuild.json: { "steps": [ { "name": "java:8", "env": [ "GRADLE_USER_HOME=cache" ], "entrypoint": "bash", "args": [ "-c", "./gradlew gate-web:installDist -x test" ] }, { "name": "gcr.io/cloud-builders/docker", "args": [ "build", "-t", "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA", "-t", "gcr.io/$PROJECT_ID/$REPO_NAME:latest", "-f", "Dockerfile.slim", "." ] } ], } Dockerfile.slim: FROM openjdk:8u111-jre-alpine COPY ./gate-web/build/install/gate /opt/gate CMD ["/opt/gate/bin/gate"]
- Criar as imagens do Docker: em
cloudbuild.json
, adicione uma etapa para criar as imagens.{ "steps": [ { "name": "java:8", "env": [ "GRADLE_USER_HOME=cache" ], "entrypoint": "bash", "args": [ "-c", "./gradlew gate-web:installDist -x test" ] }, { "name": "gcr.io/cloud-builders/docker", "args": [ "build", "-t", "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA", "-t", "gcr.io/$PROJECT_ID/$REPO_NAME:latest", "-f", "Dockerfile.slim", "." ] } ], "images": [ "gcr.io/$PROJECT_ID/$REPO_NAME:$COMMIT_SHA", "gcr.io/$PROJECT_ID/$REPO_NAME:latest" ] }