mirror of
https://github.com/wsargent/docker-cheat-sheet.git
synced 2025-12-16 15:10:12 +01:00
remove-langs
This commit is contained in:
parent
ea7edbf534
commit
9a15ac1748
10 changed files with 0 additions and 3464 deletions
|
|
@ -1,4 +0,0 @@
|
|||
language: ruby
|
||||
rvm: 2.2
|
||||
before_script: gem install awesome_bot
|
||||
script: awesome_bot README.md --allow-redirect --allow-dupe -w vagrantup.com
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
# Docker Cheat Sheet
|
||||
|
||||
**Want to improve this cheat sheet? See the [Contributing](#contributing) section!**
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Why Docker](#why-docker)
|
||||
|
|
|
|||
910
es-es/README.md
910
es-es/README.md
|
|
@ -1,910 +0,0 @@
|
|||
# Docker Cheat Sheet
|
||||
|
||||
**¿Quieres colaborar en este *cheat sheet*? ¡Revisa la sección de [Contribución](#contributing)!**
|
||||
|
||||
## Tabla de Contenidos
|
||||
|
||||
* [Por qué Docker](#por-qué-Docker)
|
||||
* [Prerrequisitos](#prerrequisitos)
|
||||
* [Instalación](#instalación)
|
||||
* [Contenedores](#contenedores)
|
||||
* [Imágenes](#imágenes)
|
||||
* [Redes](#redes)
|
||||
* [Registry y Repositorios](#Registry-y-Repositorios)
|
||||
* [Dockerfile](#dockerfile)
|
||||
* [Capas](#capas)
|
||||
* [Enlaces](#enlaces)
|
||||
* [Volúmenes](#volúmenes)
|
||||
* [Exponiendo Puertos](#Exponiendo-Puertos)
|
||||
* [Buenas prácticas](#buenas-prácticas)
|
||||
* [Docker-Compose](#docker-compose)
|
||||
* [Seguridad](#seguridad)
|
||||
* [Consejos](#consejos)
|
||||
* [Contribución](#contribución)
|
||||
|
||||
## Por qué Docker
|
||||
|
||||
"Con Docker, los desarrolladores (y desarrolladoras) pueden construir cualquier aplicación en cualquier lenguaje usando cualquier herramienta. Las aplicaciones "Dockerizadas" son totalmente portables y pueden funcionar en cualquier lugar: En portátiles con OS X y Windows de compañeros; servidores de QA con Ubuntu en el cloud; y VMs de los datacenters de producción que funcionan con Red Hat.
|
||||
|
||||
Los desarrolladores pueden empezar a trabajar rápidamente a partir de cualquiera de las más de 13.000 aplicaciones disponibles en Docker Hub. Docker gestiona y guarda los cambios y dependencias, facilitando el trabajo a los Administradores de Sistemas a la hora de entender cómo funcionan las aplicaciones hechas por los desarrolladores. Y, con Docker Hub, los desarrolladores puedes automatizar el despliegue y compartir el trabajo con colaboradores a través de repositorios públicos o privados.
|
||||
|
||||
Docker ayuda a los desarrolladores a trabajar y conseguir aplicaciones de mejor calidad de forma más rápida." -- [Qué es docker](https://www.docker.com/what-docker#copy1)
|
||||
|
||||
## Prerrequisitos
|
||||
|
||||
De forma opcional, se puede hacer utilizar [Oh My Zsh](https://github.com/ohmyzsh/oh-my-zsh) con el [plugin de Docker](https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins#docker) para autocompletar los comandos de Docker.
|
||||
|
||||
### Linux
|
||||
|
||||
[El requisito mínimo](https://docs.docker.com/engine/installation/binaries/#check-kernel-dependencies) para Docker es utilizar una versión de Kernel (núcleo) posterior a la 3.10.x.
|
||||
|
||||
### MacOS
|
||||
|
||||
Se requiere de la versión 10.8 “Mountain Lion” o posterior.
|
||||
|
||||
### Windows 10
|
||||
|
||||
Se debe activar Hyper-V en la BIOS.
|
||||
|
||||
En caso de estar disponible, también se debe activar VT-D (Procesadores Intel).
|
||||
|
||||
### Windows Server
|
||||
|
||||
Como mínimo se requiere la versiín de Windows Server 2016 para instalar Docker y Docker Compose. No obstante, existen limitaciones en esta versión, como a la hora de utilizar redes virtualizadas y contenedores Linux.
|
||||
|
||||
Se recomienda utilizar Windows Server 2019 o posteriores.
|
||||
|
||||
## Instalación
|
||||
|
||||
### Linux
|
||||
|
||||
Ejecuta este comando rápido y sencillo proporcionado por Docker:
|
||||
|
||||
```sh
|
||||
curl -sSL https://get.docker.com/ | sh
|
||||
```
|
||||
|
||||
Si no estás dispuesto a ejecutar un shell script que no sabes lo que trae, por favor: revisa las instrucciones de [instalación](https://docs.docker.com/engine/installation/linux/) de tu distribución.
|
||||
|
||||
Si eres totalmente nuevo en Docker, te recomendamos seguir esta [serie de tutoriales](https://docs.docker.com/engine/getstarted/).
|
||||
|
||||
### macOS
|
||||
|
||||
Descarga e instala [Docker Community Edition](https://www.docker.com/community-edition). Si tienes Homebrew-Cask, simplemente escribe `brew install --cask docker`. O descarga e instala [Docker Toolbox](https://docs.docker.com/toolbox/overview/). [Docker For Mac](https://docs.docker.com/docker-for-mac/) está bien, pero no está tan pulido como como la instalación de VirtualBox. [Revisa la comparación aquí](https://docs.docker.com/docker-for-mac/docker-toolbox/).
|
||||
|
||||
> **NOTA:** Docker Toolbox está deprecado. Deberías utilizar Docker Community Edition, revisa [Docker Toolbox](https://docs.docker.com/toolbox/overview/).
|
||||
|
||||
Una vez hayas instalado Docker Community Edition, haz click en el icono de docker en el Launchpad. Entonces inicia un contenedor:
|
||||
|
||||
```sh
|
||||
docker run hello-world
|
||||
```
|
||||
|
||||
¡Y ya estaría! Ya tienes un contenedor de docker funcionando.
|
||||
|
||||
Si eres totalmente nuevo en Docker, te recomendamos seguir esta [serie de tutoriales](https://docs.docker.com/engine/getstarted/).
|
||||
|
||||
### Windows 10
|
||||
|
||||
Las instrucciones para instalar Docker Desktop para Windows se encuentran [aquí](https://docs.docker.com/desktop/windows/install/)
|
||||
|
||||
Una vez instalado, abre Powershell como administrador y ejecuta:
|
||||
|
||||
```powershell
|
||||
# Muestra la versión de docker instalada:
|
||||
docker version
|
||||
|
||||
# Descarga, crea, y ejecuta 'hello-world':
|
||||
docker run hello-world
|
||||
```
|
||||
|
||||
Para continuar con esta chuleta, haz click derecho sobre el icono de Docker en la sección de notificaciones (abajo a la derecha), y ves a ajustes. Para montar volúmenes, el disco C:/ debe ser habilitado en ajustes para poder pasar la información a los contenedores (se detalla más adelante en este artículo).
|
||||
|
||||
Para alternar entre contenedores Windows y Linux, haz botón derecho en el icono de Docker en la sección de notificaciones y haz click en el botón de cambiar el sistema operativo del contenedor. Hacer esto parará los contenedores que estén funcionando y serán inaccesibles hasta que el SO del contenedor vuelva a cambiar.
|
||||
|
||||
Adicionalmente, si tienes WSL (Subsitema de Windows para Linux) o WSL2 instalado en tu equipo, quizás también quieras instalar el Kernel de Linux para Windows. Las instrucciones para ello pueden encontrarse [aquí](https://techcommunity.microsoft.com/t5/windows-dev-appconsult/using-wsl2-in-a-docker-linux-container-on-windows-to-run-a/ba-p/1482133). Esto requiere la característica de Subsistema de Windows para Linux. Esto permitirá que los contenedores sean accesibles desde los sistemas operativos WSL, así como mejorar la eficiencia ejecutando sistemas operaviso WSL en docker. También es preferible utilizar la [terminal de Windows](https://docs.microsoft.com/en-us/windows/terminal/get-started) para esto.
|
||||
|
||||
### Windows Server 2016 / 2019
|
||||
|
||||
Sigue las instrucciones de Microsoft que puedes encontrar [aquí](https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/deploy-containers-on-server#install-docker)
|
||||
|
||||
Si haces uso de la última versión de 2019, prepárate para trabajar solo con powershell, dado que es solo una imágen del núcleo del servidor (sin interfaz de escritorio). Cuando inicies esta máquina, se logueará y mostrará una ventana de powerhell. Se recomienda instalar editores de texto y otras herramientas utilizando [Chocolatey](https://chocolatey.org/install)
|
||||
|
||||
Tras instalarlo, funcionarán los siguientes comandos:
|
||||
|
||||
```powershell
|
||||
# Muestra la versión de docker instalada:
|
||||
docker version
|
||||
|
||||
# Descarga, crea, y ejecuta 'hello-world':
|
||||
docker run hello-world
|
||||
```
|
||||
|
||||
Windows Server 2016 no puede ejecutar imágenes de Linux.
|
||||
|
||||
Windows Server Build 2004 es capaz de ejecutar contenedores de Linux y Windows simultáneamente a través del aislamiento de Hyper-V. Cuando se ejecuten los contenedores, utiliza el comando ```isolation=hyperv```, el cual lo aislará utilizando distintas instancias de kernel para cada contenedor.
|
||||
|
||||
### Revisar la versión
|
||||
|
||||
Es muy importante que siempre conozcas la versión de Docker que estás utilizando en cualquier momento. Es muy útil dado que permite saber las características compatibles con lo que estés ejecutando. Esto también es importante para conocer que contenedores puedes ejecutar de la docker store cuando estés intentando utilizar un contenedor como plantilla. Dicho esto, veamos como recuperar la versión de Docker que está ejecutándose actualmente.
|
||||
|
||||
* [`docker version`](https://docs.docker.com/engine/reference/commandline/version/) muestra que versión de docker está ejecutándose.
|
||||
|
||||
Recuperar la versión del servidor:
|
||||
|
||||
```console
|
||||
$ docker version --format '{{.Server.Version}}'
|
||||
1.8.0
|
||||
```
|
||||
|
||||
Puedes volcar la información en un JSON:
|
||||
|
||||
```console
|
||||
$ docker version --format '{{json .}}'
|
||||
{"Client":{"Version":"1.8.0","ApiVersion":"1.20","GitCommit":"f5bae0a","GoVersion":"go1.4.2","Os":"linux","Arch":"am"}
|
||||
```
|
||||
|
||||
## Contenedores
|
||||
|
||||
[Proceso básico del aislamiento en Docker](http://etherealmind.com/basics-docker-containers-hypervisors-coreos/). Los contenedores son a las máquinas virtuales lo que los threads son a los procesos. O puedes verlo como un *chroot* dopado.
|
||||
|
||||
### Ciclo de vida
|
||||
|
||||
* [`docker create`](https://docs.docker.com/engine/reference/commandline/create) crea un contenedor pero no lo inicia.
|
||||
* [`docker rename`](https://docs.docker.com/engine/reference/commandline/rename/) permite renombrar el nombre de un contenedor.
|
||||
* [`docker run`](https://docs.docker.com/engine/reference/commandline/run) crea e inicia un contenedor.
|
||||
* [`docker rm`](https://docs.docker.com/engine/reference/commandline/rm) elimina un contenedor.
|
||||
* [`docker update`](https://docs.docker.com/engine/reference/commandline/update/) actualiza los recursos máximos de un contenedor.
|
||||
|
||||
Si ejecutas un contenedor sin opciones este se iniciará y detendrá automáticamente, si quieres mantenerlo funcionando puedes utilizar el comando `docker run -td container_id`, esto utilizará la opción `-t`, que habilitará una pseudo-sesión de TTY, y `-d`, que separará el contenedor automáticamente (lo ejecutará en segundo plano y mostrará la ID del contenedor)
|
||||
|
||||
Si quieres un contenedor efímero, `docker run --rm` eliminará el contenedor en cuanto se detenga.
|
||||
|
||||
Si quieres mapear un directorio del host al contenedor de docker, `docker run -v $HOSTDIR:$DOCKERDIR`. Revisa [Volúmenes](https://github.com/wsargent/docker-cheat-sheet/#volumes).
|
||||
|
||||
Si al eliminar el contenedor también quieres borrar los volúmenes asociados, el borrado deberá contener `-v`, por ejemplo: `docker rm -v`.
|
||||
|
||||
También existe un [driver de logs](https://docs.docker.com/engine/admin/logging/overview/) disponible para contenedores individuales en Docker 1.10. Para ejecutar docker con un driver de logs personalizado, ejecuta `docker run --log-driver=syslog`.
|
||||
|
||||
Otra opciónútil es `docker run --name yourname docker_image` donde especificando la opción `--name` dentro del comando *run*, esto te permitirá iniciar y detener el contenedor utilizando el nombre especificado al crearlo.
|
||||
|
||||
### Ejecutando y deteniendo
|
||||
|
||||
* [`docker start`](https://docs.docker.com/engine/reference/commandline/start) inicia un contenedor.
|
||||
* [`docker stop`](https://docs.docker.com/engine/reference/commandline/stop) detiene un contenedor que esté iniciado.
|
||||
* [`docker restart`](https://docs.docker.com/engine/reference/commandline/restart) detiene y ejecuta un contenedor.
|
||||
* [`docker pause`](https://docs.docker.com/engine/reference/commandline/pause/) pausa un contenedor que se está ejecutando, congelándolo.
|
||||
* [`docker unpause`](https://docs.docker.com/engine/reference/commandline/unpause/) reactiva un contenedor.
|
||||
* [`docker wait`](https://docs.docker.com/engine/reference/commandline/wait) se bloquea hasta que el contenedor se detiene.
|
||||
* [`docker kill`](https://docs.docker.com/engine/reference/commandline/kill) envía una SIGKILL a un contenedor.
|
||||
* [`docker attach`](https://docs.docker.com/engine/reference/commandline/attach) se conecta a un contenedor.
|
||||
|
||||
Si quieres despegarte de un contenedor, utiliza `Ctrl + p, Ctrl + q`.
|
||||
|
||||
Si quieres integrar un contenedor con un [gestor de procesos](https://docs.docker.com/engine/admin/host_integration/), inicia el daemon con `-r=false`, después utiliza `docker start -a`.
|
||||
|
||||
Si quieres exponer un puerto del contenedor a través del host, revisa la sección [exponiendo puertos](#exposing-ports).
|
||||
|
||||
Las políticas de reinicio en una instancia bloqueada se [explica aquí](http://container42.com/2014/09/30/docker-restart-policies/).
|
||||
|
||||
#### Restricciones de CPU
|
||||
|
||||
Puedes limitar la CPU, ya sea especificando el porcentáge global de las CPU o definiendo el número de núcleos.
|
||||
|
||||
Por ejemplo, puedes especificar la configuración de [`cpu-shares`](https://docs.docker.com/engine/reference/run/#/cpu-share-constraint). Este parámetro es un poco raro -- 1024 significa el 100% de la CPU, por lo que si quieres que el contenedor utilice el 50% de todas las CPU, deberás especificar 512. Revisa <https://docs.docker.com/engine/reference/run/#/cpu-share-constraint> para más información.
|
||||
|
||||
```sh
|
||||
docker run -it -c 512 agileek/cpuset-test
|
||||
```
|
||||
|
||||
Tambiés puedes utilizar únicamente algunos núcleos de la CPU utilizando [`cpuset-cpus`](https://docs.docker.com/engine/reference/run/#/cpuset-constraint). Revisa <https://agileek.github.io/docker/2014/08/06/docker-cpuset/> para más detalles y algunos vídeos guays:
|
||||
|
||||
```sh
|
||||
docker run -it --cpuset-cpus=0,4,6 agileek/cpuset-test
|
||||
```
|
||||
|
||||
Fíjate que Docker puede seguir **viendo** todas las CPU dentro del contenedor -- simplemente no la utiliza entera. Revisa <https://github.com/docker/docker/issues/20770> para más información.
|
||||
|
||||
#### Restricciones de memoria
|
||||
|
||||
También puedes especificar [restricciones de memoria](https://docs.docker.com/engine/reference/run/#/user-memory-constraints) en Docker
|
||||
|
||||
```sh
|
||||
docker run -it -m 300M ubuntu:14.04 /bin/bash
|
||||
```
|
||||
|
||||
#### Capacidades
|
||||
|
||||
Las capacidades de linux se pueden establecer utilizando `cap-add` y `cap-drop`. Revisa <https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities> para más detalles. Debe usarse para una mejor seguridad.
|
||||
|
||||
Para montar un sistema de ficheros basado en FUSE, debes combinar --cap-add con --device:
|
||||
|
||||
```sh
|
||||
docker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs
|
||||
```
|
||||
|
||||
Para dar acceso a un único dispositivo:
|
||||
|
||||
```sh
|
||||
docker run -it --device=/dev/ttyUSB0 debian bash
|
||||
```
|
||||
|
||||
Para dar acceso a todos los dispositivos:
|
||||
|
||||
```sh
|
||||
docker run -it --privileged -v /dev/bus/usb:/dev/bus/usb debian bash
|
||||
```
|
||||
|
||||
Más información sobre contenedores con privilegios [aquí](
|
||||
https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities)
|
||||
|
||||
### Información
|
||||
|
||||
* [`docker ps`](https://docs.docker.com/engine/reference/commandline/ps) muestra los contenedores funcionando.
|
||||
* [`docker logs`](https://docs.docker.com/engine/reference/commandline/logs) recupera los logs del contenedor. (Puedes utilizar un driver personalizado para los logs, pero los logs solo están disponibles para `json-file` y `journald` en la versión 1.10).
|
||||
* [`docker inspect`](https://docs.docker.com/engine/reference/commandline/inspect) revisa toda la información del contenedor (incluyendo la dirección IP).
|
||||
* [`docker events`](https://docs.docker.com/engine/reference/commandline/events) recupera los eventos del contenedor.
|
||||
* [`docker port`](https://docs.docker.com/engine/reference/commandline/port) muestra los puertos abiertos al exterior del contenedor.
|
||||
* [`docker top`](https://docs.docker.com/engine/reference/commandline/top) muestra los procesos que se están ejecutando en el contenedor,
|
||||
* [`docker stats`](https://docs.docker.com/engine/reference/commandline/stats) Muestra las estadísticas del uso de recursos del contenedor.
|
||||
* [`docker diff`](https://docs.docker.com/engine/reference/commandline/diff) Muestra los archivos que han cambiado en el sistema de ficheros del contenedor.
|
||||
|
||||
`docker ps -a` muestra todos los contenedores: que están funcionados o parados.
|
||||
|
||||
`docker stats --all` lista todos los contenedores, por defecto solo los que están funcionando.
|
||||
|
||||
### Import / Export
|
||||
|
||||
* [`docker cp`](https://docs.docker.com/engine/reference/commandline/cp) copia los ficheros y carpetas de un contenedor al sistema de ficheros local.
|
||||
* [`docker export`](https://docs.docker.com/engine/reference/commandline/export) vuelca el sistema de ficheros de un contenedor como fichero .tar en el STDOUT.
|
||||
|
||||
### Ejecuntando comandos
|
||||
|
||||
* [`docker exec`](https://docs.docker.com/engine/reference/commandline/exec) ejecuta un comando en el contenedor.
|
||||
|
||||
Para entrar a un contenedor que está funcionando, acopla un nuevo proceso de terminal al contenedor usando: `docker exec -it <ID/Nombre del contenedor> /bin/bash`.
|
||||
|
||||
## Imágenes
|
||||
|
||||
|
||||
Las imágenes simplemente son [plantillas para contenedores de docker](https://docs.docker.com/engine/understanding-docker/#how-does-a-docker-image-work).
|
||||
|
||||
### Ciclo de vida
|
||||
|
||||
* [`docker images`](https://docs.docker.com/engine/reference/commandline/images) muestra todas las imágenes.
|
||||
* [`docker import`](https://docs.docker.com/engine/reference/commandline/import) crea una imágen a partir de un fichero .tar.
|
||||
* [`docker build`](https://docs.docker.com/engine/reference/commandline/build) crea una imágen a partir de un Dockerfile.
|
||||
* [`docker commit`](https://docs.docker.com/engine/reference/commandline/commit) crea una imágen a partir de un contenedor, deteniéndolo temporalmente si está funcionando.
|
||||
* [`docker rmi`](https://docs.docker.com/engine/reference/commandline/rmi) elimina una imágen.
|
||||
* [`docker load`](https://docs.docker.com/engine/reference/commandline/load) carga una imágen a partir de un fichero .tar pasado como STDIN, incluyendo imágenes y etiquetas.
|
||||
* [`docker save`](https://docs.docker.com/engine/reference/commandline/save) guarda una imágen en un fichero .tar pasado como STDOUT con todas las capas superiores, etiquetas y versiones.
|
||||
|
||||
### Información
|
||||
|
||||
* [`docker history`](https://docs.docker.com/engine/reference/commandline/history) muestra el historial de una imágen.
|
||||
* [`docker tag`](https://docs.docker.com/engine/reference/commandline/tag) etiqueta una imágen (local o *registry*).
|
||||
|
||||
### Limpiar
|
||||
|
||||
Puedes utilizar el comando `docker rmi` para eliminar una imágen específica, pero también existe una herramienta alternativa llamada [docker-gc](https://github.com/spotify/docker-gc) que elimina de forma segura las imágenes que ya no están siendo utilizadas por ningún contenedor. En la versión 1.13 de docker, también existe el comando `docker image prine`, el cual elimina las imágenes que no están siendo utilizadas. Revisa [Prune](#prune)
|
||||
|
||||
### Cargar/Guardar una imágen
|
||||
|
||||
Carga una imágen a partir de un fichero:
|
||||
|
||||
```sh
|
||||
docker load < my_image.tar.gz
|
||||
```
|
||||
|
||||
Guarda una imágen existente:
|
||||
|
||||
```sh
|
||||
docker save my_image:my_tag | gzip > my_image.tar.gz
|
||||
```
|
||||
|
||||
### Importar/Exportar un contenedor
|
||||
|
||||
Importa un contenedor como imágen a partir de un fichero:
|
||||
|
||||
```sh
|
||||
cat my_container.tar.gz | docker import - my_image:my_tag
|
||||
```
|
||||
|
||||
Exporta un contenedor existente:
|
||||
|
||||
```sh
|
||||
docker export my_container | gzip > my_container.tar.gz
|
||||
```
|
||||
|
||||
### Diferencia entre cargar y guardar una imágen e importar y exportar un contenedor como imágen
|
||||
|
||||
Cargar una imágen utilizando el comando `load` crea una nueva imágen incluyeno su historial.
|
||||
Importar un contenedor como imágen utilizando el comando `import` crea una nueva imágen excluyendo el historial, lo que se traduce en una imágen más ligera comparada con cargarla.
|
||||
|
||||
## Redes
|
||||
|
||||
Docker tiene la característica de [Redes](https://docs.docker.com/engine/userguide/networking/). Docker automáticamente crea tres interficies de red al instalarlo (puente, host, nula). Por defecto, cuando se lanza un nuevo contenedor es añadido la red puente. Para habilitar la comunicación entre varios contenedores puedes crear una nueva red y lanzar los contenedores en ella. Esto permite a los contenedores comunicarse entre ellos y aislarese de los contenedores que no están conectados a su misma red. Además, esto permite mapear nombres de contenedores a sus direcciones IP. Revisa *[working with networks](https://docs.docker.com/engine/userguide/networking/work-with-networks/)* para más información.
|
||||
|
||||
### Ciclo de vida
|
||||
|
||||
* [`docker network create`](https://docs.docker.com/engine/reference/commandline/network_create/) NAME Crea una nueva red (por defecto de tipo puente).
|
||||
* [`docker network rm`](https://docs.docker.com/engine/reference/commandline/network_rm/) NAME Elimina una o más redes indicando el nombre o el identificador. No pueden haber contenedores conectados a la red al eliminarla.
|
||||
|
||||
### Info
|
||||
|
||||
* [`docker network ls`](https://docs.docker.com/engine/reference/commandline/network_ls/) Lista las redes creadas.
|
||||
* [`docker network inspect`](https://docs.docker.com/engine/reference/commandline/network_inspect/) NAME Muestra información detallada de una o más redes.
|
||||
|
||||
### Connection
|
||||
|
||||
* [`docker network connect`](https://docs.docker.com/engine/reference/commandline/network_connect/) NETWORK CONTAINER Conecta un contenedor a una red.
|
||||
* [`docker network disconnect`](https://docs.docker.com/engine/reference/commandline/network_disconnect/) NETWORK CONTAINER Desconecta un contenedor de una red.
|
||||
|
||||
Puedes especificar una [ip específica a un contenedor](https://blog.jessfraz.com/post/ips-for-all-the-things/):
|
||||
|
||||
```sh
|
||||
# crea una nueva red puente con la subnet y puerta de enlace específicada
|
||||
docker network create --subnet 203.0.113.0/24 --gateway 203.0.113.254 iptastic
|
||||
|
||||
# ejecuta un contenedor de nginx con al ip especificada en la red iptastic
|
||||
$ docker run --rm -it --net iptastic --ip 203.0.113.2 nginx
|
||||
|
||||
# curl hacia la ip desde cualquier otro lugar (dando por hecho que es una ip pública hehe)
|
||||
$ curl 203.0.113.2
|
||||
```
|
||||
|
||||
## Registry y Repositorios
|
||||
|
||||
(Nota de traducción: Registry sería traducido como Regitro, pero nadie le llama así en el mundo real, así que...)
|
||||
|
||||
Un repositorio es una colección *alojada* de imágenes enlazadas que unidas crean el sistema de ficheros para un contenedor.
|
||||
|
||||
Un Registry es un *alojamiento* -- un servidor que almacena repositorios y provee de una API HTTP para [gestionar la actualización y descarga de repositorios](https://docs.docker.com/engine/tutorials/dockerrepos/).
|
||||
|
||||
Docker.com posee su propio [índice](https://hub.docker.com) como un Registry centralizado que contiene un gran número de repositorios. Dicho esto, aclarar que el docker Registry [no hace un buen trabajo verificando imágenes](https://titanous.com/posts/docker-insecurity), por lo que quizás deberías evitarlo si te preocupa la seguridad.
|
||||
|
||||
* [`docker login`](https://docs.docker.com/engine/reference/commandline/login) para loguear en un registry.
|
||||
* [`docker logout`](https://docs.docker.com/engine/reference/commandline/logout) para desloguear de un registry.
|
||||
* [`docker search`](https://docs.docker.com/engine/reference/commandline/search) busca en el registry por una imágen.
|
||||
* [`docker pull`](https://docs.docker.com/engine/reference/commandline/pull) recupera una imágen del registry a local.
|
||||
* [`docker push`](https://docs.docker.com/engine/reference/commandline/push) sube una imágen local al registry.
|
||||
|
||||
### Ejecutar un registry local
|
||||
|
||||
Puedes ejecutar un registry local utilizando el proyecto [distribución de docker](https://github.com/docker/distribution) y revisando las instrucciones de como realizar el [deploy local](https://github.com/docker/docker.github.io/blob/master/registry/deploying.md)
|
||||
|
||||
Adicionalmente revisa la [mailing list](https://groups.google.com/a/dockerproject.org/forum/#!forum/distribution)
|
||||
|
||||
## Dockerfile
|
||||
|
||||
[El archivo de configuración](https://docs.docker.com/engine/reference/builder/). Configura un contenedor de docker al ejecutar `docker build` en el. Mucho más preferible a `docker commit`.
|
||||
|
||||
Aquí tienes varios editores de textos comunes y módulos de resaltado de sintaxis que puedes usar para crear Dockerfiles:
|
||||
|
||||
* Si utilizas [jEdit](http://jedit.org), puedes hacer uso del módulo de resaltado de sintaxis para [Dockerfile](https://github.com/wsargent/jedit-docker-mode).
|
||||
* [Sublime Text 2](https://packagecontrol.io/packages/Dockerfile%20Syntax%20Highlighting)
|
||||
* [Atom](https://atom.io/packages/language-docker)
|
||||
* [Vim](https://github.com/ekalinin/Dockerfile.vim)
|
||||
* [Emacs](https://github.com/spotify/dockerfile-mode)
|
||||
* [TextMate](https://github.com/docker/docker/tree/master/contrib/syntax/textmate)
|
||||
* [VS Code](https://github.com/Microsoft/vscode-docker)
|
||||
* Revisa [Docker meets the IDE](https://domeide.github.io/)
|
||||
|
||||
### Instructions
|
||||
|
||||
* [.dockerignore](https://docs.docker.com/engine/reference/builder/#dockerignore-file)
|
||||
* [FROM](https://docs.docker.com/engine/reference/builder/#from) utiliza una imágen de base para las siguientes instrucciones.
|
||||
* [MAINTAINER (deprecated - use LABEL instead)](https://docs.docker.com/engine/reference/builder/#maintainer-deprecated) especifica el autor que ha generado las imágenes.
|
||||
* [RUN](https://docs.docker.com/engine/reference/builder/#run) ejecuta cualquier comando en una nueva capa de la imágen y guarda el estado resultante.
|
||||
* [CMD](https://docs.docker.com/engine/reference/builder/#cmd) proporcionar valores predeterminados para un contenedor en ejecución.
|
||||
* [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose) informa a Docker que el contenedor estará escuchando los puertos especificados mientras se ejecute. NOTA: no hace que los puertos sean accesibles.
|
||||
* [ENV](https://docs.docker.com/engine/reference/builder/#env) define una variable de entorno.
|
||||
* [ADD](https://docs.docker.com/engine/reference/builder/#add) copia nuevos ficheros, directorios o archivos remotos al contenedor. Invalida cachés. Procura evitar usar `ADD` e intenta utilizar `COPY` en su lugar.
|
||||
* [COPY](https://docs.docker.com/engine/reference/builder/#copy) copia nuevos ficheros o directorios al contenedor. Por defecto los copia como *root* independientemente de la configuración de USER/WORKDIR. Utiliza `--chown=<user>:<group>` para cambiar el dueño. (Lo mismo aplica a `ADD`).
|
||||
* [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint) configura un contenedor que funcionará como ejecutable.
|
||||
* [VOLUME](https://docs.docker.com/engine/reference/builder/#volume) crea un punto de montaje para volúmenes externos u otros contenedores.
|
||||
* [USER](https://docs.docker.com/engine/reference/builder/#user) especifica el usuario que ejecutará los próximos comandos de tipo RUN / CMD / ENTRYPOINTS.
|
||||
* [WORKDIR](https://docs.docker.com/engine/reference/builder/#workdir) especifica el directorio de trabajo.
|
||||
* [ARG](https://docs.docker.com/engine/reference/builder/#arg) define una variable que estará disponible durante el build.
|
||||
* [ONBUILD](https://docs.docker.com/engine/reference/builder/#onbuild) añade una instrucción que será lanzada cuando la imágen sea utilizada como base de otro build.
|
||||
* [STOPSIGNAL](https://docs.docker.com/engine/reference/builder/#stopsignal) define la señal que será enviada al contenedor para detenerse.
|
||||
* [LABEL](https://docs.docker.com/config/labels-custom-metadata/) aplica metadatos de clave/valor para las imágenes, contenedores o daemons (servicios).
|
||||
* [SHELL](https://docs.docker.com/engine/reference/builder/#shell) reemplaza la shell por defecto que es utilizada por Docker para ejecutar los comandos.
|
||||
* [HEALTHCHECK](https://docs.docker.com/engine/reference/builder/#healthcheck) indica a docker como probar el contenedor para revisar que sigue funcionando.
|
||||
|
||||
### Tutorial
|
||||
|
||||
* [Flux7's Dockerfile Tutorial](https://www.flux7.com/tutorial/docker-tutorial-series-part-3-automation-is-the-word-using-dockerfile/)
|
||||
|
||||
### Examples
|
||||
|
||||
* [Ejemplos](https://docs.docker.com/engine/reference/builder/#dockerfile-examples)
|
||||
* [Buenas prácticas para escribir Dockerfiles](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/)
|
||||
* [Michael Crosby](http://crosbymichael.com/) tiene más consejos de [buenas prácticas para Dockerfile](http://crosbymichael.com/dockerfile-best-practices.html) / [toma 2](http://crosbymichael.com/dockerfile-best-practices-take-2.html).
|
||||
* [Construyendo buenas imágenes de Docker](http://jonathan.bergknoff.com/journal/building-good-docker-images) / [Construyendo mejores imágenes de Docker](http://jonathan.bergknoff.com/journal/building-better-docker-images)
|
||||
* [Gestionando la configuración de un contenedor utilizando metadatos](https://speakerdeck.com/garethr/managing-container-configuration-with-metadata)
|
||||
* [Cómo escribir excelentes Dockerfiles](https://rock-it.pl/how-to-write-excellent-dockerfiles/)
|
||||
|
||||
## Capas
|
||||
|
||||
Las veriones de los sitemas de ficheros en docker se basan en capas. Son similares a los [git commits o conjuntos de cambios para sistemas de ficheros](https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/).
|
||||
|
||||
## Enlaces
|
||||
|
||||
Los enlaces definen como los contenedores de Docker se comunican entre ellos [mediante puertos TCP/IP](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/). [Atlassian](https://blogs.atlassian.com/2013/11/docker-all-the-things-at-atlassian-automation-and-wiring/) lo explica con ejemplos. También puedes resolver [enlaces con nombres de equipo](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#/updating-the-etchosts-file).
|
||||
|
||||
Esto ha sido parcialmente deprecado por [redes definidas por los usuarios](https://docs.docker.com/network/).
|
||||
|
||||
NOTA: Si ÚNICAMENTE quieres que los contenedores se comuniquen mediante enlaces, inicia el servicio de Docker con `-icc=false` para desactivar la comunicación entre procesos.
|
||||
|
||||
Si tienes un contenedor con el nombre CONTAINER (especificado vía `docker run --name CONTAINER`) y, en el Dockerfile, explones un puerto:
|
||||
|
||||
```
|
||||
EXPOSE 1337
|
||||
```
|
||||
|
||||
Y entonces creas otro contenedor llamado LINKED de la forma:
|
||||
|
||||
```sh
|
||||
docker run -d --link CONTAINER:ALIAS --name LINKED user/wordpress
|
||||
```
|
||||
|
||||
Entonces los puertos expuertos y alias de CONTAINER se mostrarán en LINKED con las siguientes variables de entorno:
|
||||
Then the exposed ports and aliases of CONTAINER will show up in LINKED with the following environment variables:
|
||||
|
||||
```sh
|
||||
$ALIAS_PORT_1337_TCP_PORT
|
||||
$ALIAS_PORT_1337_TCP_ADDR
|
||||
```
|
||||
|
||||
Y te puedes conectar a él de esta forma.
|
||||
|
||||
Para eliminar los enlaces, utiliza `docker rm --link'.
|
||||
|
||||
Generalmente, enlazar mediante servicios de docker es un subgrupo de "descrubrimiento de servicios", un gran problema si tienes pensado utilizar Docker para escalar en producción. Por favor, lee [The Docker Ecosystem: Service Discovery and Distributed Configuration Stores](https://www.digitalocean.com/community/tutorials/the-docker-ecosystem-service-discovery-and-distributed-configuration-stores) para más información.
|
||||
|
||||
## Volúmenes
|
||||
|
||||
Los volúmenes de Docker son [sitemas de archivos flotantes](https://docs.docker.com/engine/tutorials/dockervolumes/). Estos no se conectan a un contenedor en particular. Puedes utilizar los volúmenes montados de [contenedores de únicamente datos](https://medium.com/@ramangupta/). A partir de Docker 1.9.0, Docker ha nombrado volúmenes que reemplazan los contenedores de solo datos. Considere usar volúmenes con nombre para implementarlo en lugar de contenedores de datos.
|
||||
|
||||
|
||||
### Ciclo de vida
|
||||
|
||||
* [`docker volume create`](https://docs.docker.com/engine/reference/commandline/volume_create/)
|
||||
* [`docker volume rm`](https://docs.docker.com/engine/reference/commandline/volume_rm/)
|
||||
|
||||
### Información
|
||||
|
||||
* [`docker volume ls`](https://docs.docker.com/engine/reference/commandline/volume_ls/)
|
||||
* [`docker volume inspect`](https://docs.docker.com/engine/reference/commandline/volume_inspect/)
|
||||
|
||||
Los volúmenes son útiles en situaciones donde no puedes utilizar enlaces (los cuales son sólo TCP/IP). Por ejemplo, si necesitases tener dos instancias de docker comunicándose dejando datos en el sistema de ficheros.
|
||||
|
||||
Puedes montarlos en distintos contenedores de docker a la vez, utilizando `docker run --volumes-from`.
|
||||
|
||||
Dadp que los volúmenes están aislados del sistema de ficheros, estos también son utilizados para almacenar el estado a partir de cálculos de contenedores temporales. Exacto, puedes tener un contenedor sin estado y temporal ejecutándose a partir de una receta, destruírlo, y entonecs tener otra instancia temporal que pueda recuperar lo que ha dejado atrás el primer contenedor.
|
||||
|
||||
Revisa [volúmenes avanzados](http://crosbymichael.com/advanced-docker-volumes.html) para más información. [Container42](http://container42.com/2014/11/03/docker-indepth-volumes/) también es de utilidad.
|
||||
|
||||
Puedes [mapear directorios de MacOS como volúmenes de Docker](https://docs.docker.com/engine/tutorials/dockervolumes/#mount-a-host-directory-as-a-data-volume):
|
||||
|
||||
```sh
|
||||
docker run -v /Users/wsargent/myapp/src:/src
|
||||
```
|
||||
|
||||
Puedes utilizar un volúmen NFS remoto si [eres valiente](https://docs.docker.com/engine/tutorials/dockervolumes/#/mount-a-shared-storage-volume-as-a-data-volume)
|
||||
|
||||
También puedes plantearme utilizar contenedores de solo datos como se describen [aquí](http://container42.com/2013/12/16/persistent-volumes-with-docker-container-as-volume-pattern/) para tener portabilidad de datos.
|
||||
|
||||
Ten en cuenta que puedes montar [archivos como volúmenes](#volumes-can-be-files).
|
||||
|
||||
## Exponiendo puertos
|
||||
|
||||
Exponer puertos de entrada a través de un contenedor es [complejo pero factible](https://docs.docker.com/engine/reference/run/#expose-incoming-ports).
|
||||
|
||||
Puede hacerse a través del mapeo de puertos del contenedor hacia el host (utilizando únicamente la interficie de localhost) mediante el uso de `p`:
|
||||
|
||||
```sh
|
||||
docker run -p 127.0.0.1:$HOSTPORT:$CONTAINERPORT \
|
||||
--name CONTAINER \
|
||||
-t algunaimágen
|
||||
```
|
||||
Puedes decirle a docker que el contenedor escucha en el puerto especificado utilizando [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose):
|
||||
|
||||
```Dockerfile
|
||||
EXPOSE <CONTAINERPORT>
|
||||
```
|
||||
|
||||
Nótese que `EXPOSE` no expone el puerto por si mismo - solo `-p` lo hace.
|
||||
|
||||
Para exponer el puerto de un contenedor en localhost, ejecuta:
|
||||
|
||||
```sh
|
||||
iptables -t nat -A DOCKER -p tcp --dport <LOCALHOSTPORT> -j DNAT --to-destination <CONTAINERIP>:<PORT>
|
||||
```
|
||||
|
||||
Si estás ejecutando Docker en Virtualbox, también necesitarás hacer forward del puerto, utilizando [forwarded_port] (https://docs.vagrantup.com/v2/networking/forwarded_ports.html). Define un rango de puertos en tu Vagrantfile de la siguiente manera para mapearlos dinámicamente:
|
||||
|
||||
```
|
||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
...
|
||||
|
||||
(49000..49900).each do |port|
|
||||
config.vm.network :forwarded_port, :host => port, :guest => port
|
||||
end
|
||||
|
||||
...
|
||||
end
|
||||
```
|
||||
|
||||
Si te olvidas de los puertos que has mapeado, utiliza `docker port` para mostrarlo:
|
||||
|
||||
```sh
|
||||
docker port CONTAINER $CONTAINERPORT
|
||||
```
|
||||
|
||||
## Buenas prácticas
|
||||
|
||||
Aquí tienes algunas buenas prácticas de Docker y algunas batallitas:
|
||||
|
||||
* [The Rabbit Hole of Using Docker in Automated Tests](http://gregoryszorc.com/blog/2014/10/16/the-rabbit-hole-of-using-docker-in-automated-tests/)
|
||||
* [Bridget Kromhout](https://twitter.com/bridgetkromhout) has a useful blog post on [running Docker in production](http://sysadvent.blogspot.co.uk/2014/12/day-1-docker-in-production-reality-not.html) at Dramafever.
|
||||
* También tienes buenas prácticas en este [post](http://developers.lyst.com/devops/2014/12/08/docker/) de Lyst.
|
||||
* [Building a Development Environment With Docker](https://tersesystems.com/2013/11/20/building-a-development-environment-with-docker/)
|
||||
* [Discourse in a Docker Container](https://samsaffron.com/archive/2013/11/07/discourse-in-a-docker-container)
|
||||
|
||||
## Docker-Compose
|
||||
|
||||
Compose es una herramienta para definir y ejecutar varias aplicaciones en contenedores de Docker. Con Compose, utilizas un archivo YAML para configurar tus servicios. Entonces, con un único comando, creas e inicias todos los servicios desde tus configuraciones. Para aprender más sobre las características de Compose, revisa la [lista de características](https://docs.docker.com/compose/overview/#features).
|
||||
|
||||
Utilizando el siguiente comando puedes iniciar tu aplicación:
|
||||
|
||||
```sh
|
||||
docker-compose -f <docker-compose-file> up
|
||||
```
|
||||
|
||||
También puedes ejecutar docker-compose en segundo plano utilizando el parámentro -d, entonces podrás detenerlo cuando lo necesitas con el comando:
|
||||
|
||||
```sh
|
||||
docker-compose stop
|
||||
```
|
||||
|
||||
Puedes tirarlo todo, eliminando los contenedores completamente, con el comando down. Utiliza el parámetro `--volumes` para también eliminar los volúmenes de datos.
|
||||
|
||||
## Seguridad
|
||||
|
||||
Aquí te dejamos algunso consejos de seguridad sobre como funciona Docker. La página de Docker de [seguridad]](https://docs.docker.com/engine/security/security/) lo explica en más detalle.
|
||||
|
||||
Lo primero: Docker se ejecuta como root. Si estás en el grupo `docker`, [tienes acceso root](https://web.archive.org/web/20161226211755/http://reventlov.com/advisories/using-the-docker-command-to-root-the-host). Si expones el socket de unix de docker a un contenedor, le estás dando al contenedor acceso [root a la máquina host](https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container/).
|
||||
|
||||
|
||||
Docker no debería ser tu única defensa. Deberías asegurarlo y protejerlo.
|
||||
|
||||
Para entender como se exponen los contenedores, deberías leer [Entendiendo y endureciendo Contenedores Linux](https://www.nccgroup.trust/globalassets/our-research/us/whitepapers/2016/april/ncc_group_understanding_hardening_linux_containers-1-1.pdf) de [Aaron Grattafiori](https://twitter.com/dyn___). Esta es una guía completa y entendible sobre los riesgos relacionados con los contenedores, con una gran cantidad de enlaces y notas a pié de página. Los siguientes consejos de seguridad son útiles si ya has protejido tus contenedores en el pasado, pero no son substitutos a entenderlo.
|
||||
|
||||
### Consejos de seguridad
|
||||
|
||||
Para mayor seguridad, puedes ejecutar Docker dentro de una máquina virtual. Esto es un consejo del Jefe del Equipo de Seguridad de Docker -- [diapositivas](http://www.slideshare.net/jpetazzo/linux-containers-lxc-docker-and-security) / [notas](http://www.projectatomic.io/blog/2014/08/is-it-safe-a-look-at-docker-and-security-from-linuxcon/). Entonces, ejecutalo con AppArmor / seccomp / SELinux /grsec etc. para [limitar los permisos del contenedor](http://linux-audit.com/docker-security-best-practices-for-your-vessel-and-containers/). Revisa [las características de seguridad de Docker 1.10](https://blog.docker.com/2016/02/docker-engine-1-10-security/) para más detalles.
|
||||
|
||||
Los identificadores de las imágenes de Docker son [información sensible](https://medium.com/@quayio/your-docker-image-ids-are-secrets-and-its-time-you-treated-them-that-way-f55e9f14c1a4) y no deberían exponerse al mundo exterior. Trátalos como contraseñas.
|
||||
|
||||
Revisa la [Chuleta de Seguridad de Docker](https://github.com/konstruktoid/Docker/blob/master/Security/CheatSheet.adoc) de [Thomas Sjögren](https://github.com/konstruktoid): ahí podrás encontrar buenos consejos sobre como protejerse.
|
||||
|
||||
Revisa el [script de seguridad de Docker Bench](https://github.com/docker/docker-bench-security).
|
||||
|
||||
|
||||
[Las 10 Mejores Prácticas de Seguridad para Imágenes de Docker](https://snyk.io/blog/10-docker-image-security-best-practices/) de Snyk
|
||||
|
||||
Puedes empezar utilizando un Kernel con parches inestables de *grsecurity* / *pax* compilados, como [Alpine Linux](https://en.wikipedia.org/wiki/Alpine_Linux). Si haces uso de *grsecurity* en producción, deberías buscar [soporte comercial](https://grsecurity.net/business_support.php) para los [parches estables](https://grsecurity.net/announce.php), de la misma forma que deberías hacer para RedHat. Son unos 200$ al mes, lo cual es insignificante para el presupuesto de devops.
|
||||
|
||||
A partir de Docker 1.11, puedes limitar fácilmente el número de procesos que se ejecutan en un contenedor para evitar *fork bombs*. Esto requiere utilizar un Kernel de Linux >= 4.3 con CGROUP_PIDS=y en la configuración del kernel.
|
||||
|
||||
```sb
|
||||
docker run --pids-limit=64
|
||||
```
|
||||
|
||||
A partir de Docker 1.11 también está disponible la posibilidad de evitar que los procesos ganen nuevos privilegios. Esta característica está en el Kernel de Linux desde la versión 3.5. Puedes leer más al respecto en [este](http://www.projectatomic.io/blog/2016/03/no-new-privs-docker/) blog.
|
||||
|
||||
```sh
|
||||
docker run --security-opt=no-new-privileges
|
||||
```
|
||||
|
||||
De la [Chuleta de Seguridad de Docker](http://container-solutions.com/content/uploads/2015/06/15.06.15_DockerCheatSheet_A2.pdf) (es un PDF y es un poco complejo de usar, así que mejor copia de abajo) de [Container Solutions](http://container-solutions.com/is-docker-safe-for-production/):
|
||||
|
||||
Desactiva la comunicación interproceso con:
|
||||
|
||||
```sh
|
||||
docker -d --icc=false --iptables
|
||||
```
|
||||
|
||||
Establece que el contenedor sea solo lectura:
|
||||
|
||||
```sh
|
||||
docker run --read-only
|
||||
```
|
||||
|
||||
Verifica las imágenes con un *hashsum*:
|
||||
|
||||
```sh
|
||||
docker pull debian@sha256:a25306f3850e1bd44541976aa7b5fd0a29be
|
||||
```
|
||||
|
||||
Establece el volúmen como solo lectura:
|
||||
|
||||
```sh
|
||||
docker run -v $(pwd)/secrets:/secrets:ro debian
|
||||
```
|
||||
|
||||
Crea y utiliza un usiario en el Dockerfile para evitar ejecutar como root dentro del contenedor:
|
||||
|
||||
```Dockerfile
|
||||
RUN groupadd -r user && useradd -r -g user user
|
||||
USER user
|
||||
```
|
||||
|
||||
### Espacio de Nombres del Usuario (*User Namespaces*)
|
||||
|
||||
También hay que trabajar con los [espacios de nombres de usuario](https://s3hh.wordpress.com/2013/07/19/creating-and-using-containers-without-privilege/) -- disponibles en la 1.10, pero no activados por defecto.
|
||||
|
||||
Para activar esta característica ("reasignar los usuarios") en ubuntu 15.10, [sigue este ejemplo](https://raesene.github.io/blog/2016/02/04/Docker-User-Namespaces/).
|
||||
|
||||
### Videos de Seguridad
|
||||
|
||||
* [Using Docker Safely](https://youtu.be/04LOuMgNj9U)
|
||||
* [Securing your applications using Docker](https://youtu.be/KmxOXmPhZbk)
|
||||
* [Container security: Do containers actually contain?](https://youtu.be/a9lE9Urr6AQ)
|
||||
* [Linux Containers: Future or Fantasy?](https://www.youtube.com/watch?v=iN6QbszB1R8)
|
||||
|
||||
### Ruta de Seguridad
|
||||
|
||||
La ruta de Docker habla sobre [el soporte de *seccomp*](https://github.com/docker/docker/blob/master/ROADMAP.md#11-security).
|
||||
|
||||
También hay una política de AppArmor llamada [base](https://github.com/jfrazelle/bane), y están trabajando en [perfiles de seguridad](https://github.com/docker/docker/issues/17142)
|
||||
|
||||
## Consejos
|
||||
|
||||
Fuentes:
|
||||
|
||||
* [15 Docker Tips in 5 minutes](http://sssslide.com/speakerdeck.com/bmorearty/15-docker-tips-in-5-minutes)
|
||||
* [CodeFresh Everyday Hacks Docker](https://codefresh.io/blog/everyday-hacks-docker/)
|
||||
|
||||
### Prune
|
||||
|
||||
Los nuevos [Comandos de manejo de datos](https://github.com/docker/docker/pull/26108) llegaron a Docker en la versión 1.13
|
||||
|
||||
* `docker system prune`
|
||||
* `docker volume prune`
|
||||
* `docker network prune`
|
||||
* `docker container prune`
|
||||
* `docker image prune`
|
||||
|
||||
### df
|
||||
|
||||
`docker system df` muestra un resumen del espacio actualmente utilizado por los distintos elementos de Docker.
|
||||
|
||||
### Heredoc Docker Container
|
||||
|
||||
```sh
|
||||
docker build -t htop - << EOF
|
||||
FROM alpine
|
||||
RUN apk --no-cache add htop
|
||||
EOF
|
||||
```
|
||||
|
||||
### Últimas IDs
|
||||
|
||||
```sh
|
||||
alias dl='docker ps -l -q'
|
||||
docker run ubuntu echo hello world
|
||||
docker commit $(dl) helloworld
|
||||
```
|
||||
|
||||
### Commit con comando (necesita de Dockerfile)
|
||||
|
||||
```sh
|
||||
docker commit -run='{"Cmd":["postgres", "-too -many -opts"]}' $(dl) postgres
|
||||
```
|
||||
|
||||
### Recuperar la dirección IP
|
||||
|
||||
```sh
|
||||
docker inspect $(dl) | grep -wm1 IPAddress | cut -d '"' -f 4
|
||||
```
|
||||
|
||||
O, con [jq](https://stedolan.github.io/jq/) instalado:
|
||||
|
||||
```sh
|
||||
docker inspect $(dl) | jq -r '.[0].NetworkSettings.IPAddress'
|
||||
```
|
||||
|
||||
O, utilizando una [plantilla](https://docs.docker.com/engine/reference/commandline/inspect):
|
||||
|
||||
```sh
|
||||
docker inspect -f '{{ .NetworkSettings.IPAddress }}' <container_name>
|
||||
```
|
||||
|
||||
O, al construir la imágen desde un Dockerfile, cuando quieres pasar argumentos de compilación:
|
||||
|
||||
```sh
|
||||
DOCKER_HOST_IP=`ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1`
|
||||
echo DOCKER_HOST_IP = $DOCKER_HOST_IP
|
||||
docker build \
|
||||
--build-arg ARTIFACTORY_ADDRESS=$DOCKER_HOST_IP
|
||||
-t sometag \
|
||||
some-directory/
|
||||
```
|
||||
|
||||
### Recuperar el mapping de puertos
|
||||
|
||||
```sh
|
||||
docker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' <nombredecontenedor>
|
||||
```
|
||||
|
||||
### Encontrar contenedores mediante expresiones regulares
|
||||
|
||||
```sh
|
||||
for i in $(docker ps -a | grep "REGEXP_PATTERN" | cut -f1 -d" "); do echo $i; done
|
||||
```
|
||||
|
||||
### Recuperar la configuraciín del entorno
|
||||
|
||||
```sh
|
||||
docker run --rm ubuntu env
|
||||
```
|
||||
|
||||
### Detener los contenedores en funcionamiento
|
||||
|
||||
```sh
|
||||
docker kill $(docker ps -q)
|
||||
```
|
||||
|
||||
### Eliminar todos los contenedores (¡FORZANDO! Los borrará estén funcionando o parados)
|
||||
|
||||
```sh
|
||||
docker rm -f $(docker ps -qa)
|
||||
```
|
||||
|
||||
### Eliminar los viejos contenedores
|
||||
|
||||
```sh
|
||||
docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm
|
||||
```
|
||||
|
||||
### Eliminar los contenedores detenidos
|
||||
|
||||
```sh
|
||||
docker rm -v $(docker ps -a -q -f status=exited)
|
||||
```
|
||||
|
||||
### Eliminar los contenedores después de pararlos
|
||||
|
||||
```sh
|
||||
docker stop $(docker ps -aq) && docker rm -v $(docker ps -aq)
|
||||
```
|
||||
|
||||
### Eliminar las imágenes colgadas
|
||||
|
||||
```sh
|
||||
docker rmi $(docker images -q -f dangling=true)
|
||||
```
|
||||
|
||||
### Eliminar todas las imágenes
|
||||
|
||||
```sh
|
||||
docker rmi $(docker images -q)
|
||||
```
|
||||
|
||||
### Eliminar los volúmenes colgados
|
||||
|
||||
Como en Docker 1.9:
|
||||
|
||||
```sh
|
||||
docker volume rm $(docker volume ls -q -f dangling=true)
|
||||
```
|
||||
|
||||
En 1.90, el filtro `dangling=false` _no_ funciona - es ignorado y mostrará todos los volúmenes
|
||||
|
||||
### Mostrar las dependencias de las imágenes
|
||||
|
||||
```sh
|
||||
docker images -viz | dot -Tpng -o docker.png
|
||||
```
|
||||
|
||||
### Reducir el tamaño de los contenedores Docker
|
||||
|
||||
- Limpiar el APT en una capa `RUN` - Esto debería hacerse en la misma capa que los otros comandos `apt`. Sino, las capas previas seguirán teniendo la información original y la imágen seguirá siendo pesada.
|
||||
```Dockerfile
|
||||
RUN {apt commands} \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
```
|
||||
- Aplanar una imágen
|
||||
```sh
|
||||
ID=$(docker run -d image-name /bin/bash)
|
||||
docker export $ID | docker import – flat-image-name
|
||||
```
|
||||
- Para las copias de seguridad
|
||||
```sh
|
||||
ID=$(docker run -d image-name /bin/bash)
|
||||
(docker export $ID | gzip -c > image.tgz)
|
||||
gzip -dc image.tgz | docker import - flat-image-name
|
||||
```
|
||||
|
||||
### Monitorizar los recursos del sistema utilizados por los contenedores en funcionamiento
|
||||
|
||||
Para revisar el uso de CPU, memoria y E/S de red para un solo contenedor, puedes utilizar:
|
||||
|
||||
```sh
|
||||
docker stats <container>
|
||||
```
|
||||
|
||||
Para todos los contenedores listados por ID:
|
||||
|
||||
```sh
|
||||
docker stats $(docker ps -q)
|
||||
```
|
||||
|
||||
Para todos los contenedores listados por nombre:
|
||||
|
||||
```sh
|
||||
docker stats $(docker ps --format '{{.Names}}')
|
||||
```
|
||||
|
||||
Para todos los contenedores listados por imágen:
|
||||
|
||||
```sh
|
||||
docker ps -a -f ancestor=ubuntu
|
||||
```
|
||||
|
||||
Eliminar todas las imágenes sin etiquetas:
|
||||
|
||||
```sh
|
||||
docker rmi $(docker images | grep “^” | awk '{split($0,a," "); print a[3]}')
|
||||
```
|
||||
|
||||
Eliminar contenedores mediante una expresión regular:
|
||||
|
||||
```sh
|
||||
docker ps -a | grep wildfly | awk '{print $1}' | xargs docker rm -f
|
||||
```
|
||||
|
||||
Elimina todos los contenedores en estado "Exit":
|
||||
|
||||
```sh
|
||||
docker rm -f $(docker ps -a | grep Exit | awk '{ print $1 }')
|
||||
```
|
||||
|
||||
### Los volúmenes pueden ser ficheros
|
||||
|
||||
Ten encuenta que puedes montar ficheros como volúmenes. Por ejemplo, pueden inyectar un archivo de configuración así:
|
||||
|
||||
```sh
|
||||
# copia el archivo del contenedor
|
||||
docker run --rm httpd cat /usr/local/apache2/conf/httpd.conf > httpd.conf
|
||||
|
||||
# edita el archivo
|
||||
vim httpd.conf
|
||||
|
||||
# inicia el contenedor con la configuracion modificada
|
||||
docker run --rm -it -v "$PWD/httpd.conf:/usr/local/apache2/conf/httpd.conf:ro" -p "80:80" httpd
|
||||
```
|
||||
|
||||
## Contribución
|
||||
|
||||
Aquí tienes como contribuír a esta chuleta.
|
||||
|
||||
### Open README.md
|
||||
|
||||
hack click en el [README.md](https://github.com/wsargent/docker-cheat-sheet/blob/master/README.md) <-- este link
|
||||
|
||||

|
||||
|
||||
### Edit Page
|
||||
|
||||

|
||||
|
||||
### Make Changes and Commit
|
||||
|
||||

|
||||
|
||||

|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 109 KiB |
BIN
images/click.png
BIN
images/click.png
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 77 KiB |
BIN
images/edit.png
BIN
images/edit.png
Binary file not shown.
|
Before Width: | Height: | Size: 8.6 KiB |
905
pt-br/README.md
905
pt-br/README.md
|
|
@ -1,905 +0,0 @@
|
|||
# Docker Cheat Sheet
|
||||
|
||||
**Deseja melhorar este *cheat sheet*? Veja a seção de [Contribuição](#contribution)**
|
||||
|
||||
## Conteúdo
|
||||
|
||||
* [Porque usar docker](#why-docker)
|
||||
* [Pré-requisitos](#prerequisites)
|
||||
* [Instalação](#installation)
|
||||
* [Containers](#containers)
|
||||
* [Imagens](#images)
|
||||
* [Redes](#networks)
|
||||
* [Registro e Repositório](#registry--repository)
|
||||
* [Dockerfile](#dockerfile)
|
||||
* [Camadas](#layers)
|
||||
* [Links](#links)
|
||||
* [Volumes](#volumes)
|
||||
* [Expondo portas](#exposing-ports)
|
||||
* [Boas práticas](#best-practices)
|
||||
* [Docker-Compose](#docker-compose)
|
||||
* [Segurança](#security)
|
||||
* [Dicas](#tips)
|
||||
* [Contribuição](#contributing)
|
||||
|
||||
## Porque usar Docker
|
||||
|
||||
"Com Docker, desenvolvedores podem construir qualquer app em qualquer linguagem usando qualquer conjunto de ferramentas. Apps *Dockerizados* são completamente portáveis e podem rodar em qualquer lugar -- OS X e Windows laptops, servidores QA rodando Ubuntu na nuvem e *data centers* em produção rodando Red Hat em Máquinas Virtuais.
|
||||
|
||||
Desenvolverodes podem iniciar a utilizá-lo rapidamente com um dos mais de 13.000 apps disponíveis no Docker hub. Docker gerencia e rastreia alterações e dependências, tornando mais fácil para *sysadmins* o entendimento do funcionamento de apps construido pelos desenvolvedores. Além disso, com Docker Hub, desenvolvedores podem automatizar o pipeline de *build* e compartilhar *artifacts* com colaboradores através de repositórios públicos ou privados.
|
||||
|
||||
Docker auxilia desenvolvedores a construir e entregar aplicações de alta qualidade de maneira mais rápida." -- [O que é Docker (*What is Docker*)](https://www.docker.com/what-docker#copy1)
|
||||
|
||||
## Pré-requisitos
|
||||
|
||||
Eu utilizo [Oh My Zsh](https://github.com/ohmyzsh/oh-my-zsh) com [Docker plugin](https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins#docker) para autocompletar os comandos do docker.
|
||||
|
||||
### Linux
|
||||
|
||||
O kernel 3.10.x é [o requisito mínimo](https://docs.docker.com/engine/installation/binaries/#check-kernel-dependencies) para o uso do Docker.
|
||||
|
||||
### MacOS
|
||||
|
||||
É necessário *“Mountain Lion”* 10.8 ou mais recente.
|
||||
|
||||
### Windows 10
|
||||
|
||||
É necessário que o *Hyper-V* esteja habilitado na BIOS. Além disso, para precessadores intel, o VT-D também precisa estar habilidado caso esteja disponível.
|
||||
|
||||
### Windows Server
|
||||
|
||||
Windows Server 2016 é a versão mínima necessária para instalar o docker e o docker-compose. Existem limitações nessa versão, como por exemplo múltiplas redes virtuais e containers Linux. Windows Server 2019 ou posterior é recomendado.
|
||||
|
||||
## Instalação
|
||||
|
||||
### Linux
|
||||
|
||||
Um simples, fácil e rápido *script* é disponibilizado pelo Docker:
|
||||
|
||||
```
|
||||
curl -sSL https://get.docker.com/ | sh
|
||||
```
|
||||
|
||||
Se você não deseja rodar um *shell script* aleatório de internet, basta acessar as [instruções de instalação](https://docs.docker.com/engine/installation/linux/) para a sua distribuição.
|
||||
|
||||
Se você não sabe nada sobre Docker, provavelmente você deveria seguir essa [série de tutoriais](https://docs.docker.com/engine/getstarted/) antes de continuar.
|
||||
|
||||
### macOS
|
||||
|
||||
Baixe e instale o [*Docker Community Edition*](https://www.docker.com/community-edition). Se você possui o Homebrew-Cask, apenas utilize o comando `brew install --cask docker`. Ou baixe e instale o [*Docker Toolbox*](https://docs.docker.com/toolbox/overview/). [Docker para Mac](https://docs.docker.com/docker-for-mac/) é ok, mas ele ainda não é tão pronto quanto a instalação da VirtualBox. [Veja a comparação](https://docs.docker.com/docker-for-mac/docker-toolbox/).
|
||||
|
||||
> **NOTA** *Docker Toolbox* está no estado *legacy*. Você deveria usar o *Docker Community Edition*. Veja o [*Docker Toolbox*](https://docs.docker.com/toolbox/overview/).
|
||||
|
||||
Assim que você instalar o *Docker Community Edition*, clique no ícone do Docker no *Launchpad*. Em seguida inicie um container:
|
||||
|
||||
```
|
||||
docker run hello-world
|
||||
```
|
||||
|
||||
É isso! Agora você tem um Docker container rodando.
|
||||
|
||||
Se você não sabe nada sobre Docker, provavelmente você deveria seguir essa [série de tutoriais](https://docs.docker.com/engine/getstarted/) antes de continuar.
|
||||
|
||||
### Windows 10
|
||||
|
||||
Você encontra instruções para instalar o Docker Desktop para Windows [neste link](https://docs.docker.com/desktop/windows/install/).
|
||||
|
||||
Uma vez instalado, abra o *powershell* como administrador
|
||||
|
||||
```powershell
|
||||
#Exibe a versão do docker instalado
|
||||
docker version
|
||||
|
||||
#Todos comandos pull, create, e run 'hello-world' em apenas um:
|
||||
docker run hello-world
|
||||
|
||||
```
|
||||
|
||||
Para continuar as instruções neste *cheat sheet*, clique com botão direito do mouse no ícone do Docker -- no menu iniciar ou onde quer que seja -- e vá em configurações. Para montar volumes, você precisa habilitar o disco C:/ para que as informaçõe sejam transmitidas para os containers (que ainda será explicado neste artigo).
|
||||
|
||||
Para trocar entre containers Windows e Linux, clique com o botão direito no icone do Docker e, na sequência, clique no botão para trocar sistema operacional dos containers. Após fazer isso, todos os containers ques estiveram rodando serão desligados e ficaram inacessíveis até que o SO do container ser trocado novamente.
|
||||
|
||||
|
||||
Além disso, se você possui WSL ou WSL2 instalado no seu desktop, você pode instalar o Kernel do Linux para Windows. Instruções para executar tal tarefa podem ser encontradas [aqui] [here](https://techcommunity.microsoft.com/t5/windows-dev-appconsult/using-wsl2-in-a-docker-linux-container-on-windows-to-run-a/ba-p/1482133). Atente-se ao fato de que para isso, é necessário o recurso do Subsistema Windows para Linux. Isso permitirá que os containers sejam acessados pelos sistemas operacionais WSL, bem como o ganho de eficiêcia da execução dos sistemas operacionais WSL no Docker. Por fim, tamém é preferível o uso do [terminal Windows](https://docs.microsoft.com/en-us/windows/terminal/get-started) para tal tarefa.
|
||||
|
||||
### Windows Server 2016 / 2019
|
||||
|
||||
Siga as instruções da Microsoft disponíveis [aqui](https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/deploy-containers-on-server#install-docker)
|
||||
|
||||
|
||||
Se estiver usando a última versão de 2019, esteja preparado para trabalhar com o *powershell*, uma vez que esta versão não possui interface desktop. Quando inciar a máquina, ela vai logar e ir direto para um janela *powershell*. É recomendado instalar um editor de texto dentre outras ferramentas utilizando [Chocolatey](https://chocolatey.org/install).
|
||||
|
||||
Após a instalação, esses comandos devem funcionar:
|
||||
|
||||
```powershell
|
||||
#Exibe a versão do docker instalado
|
||||
docker version
|
||||
|
||||
#Todos comandos pull, create, e run 'hello-world' em apenas um:
|
||||
docker run hello-world
|
||||
|
||||
```
|
||||
|
||||
O Windows Server 2016 não é capar de rodar images Linux.
|
||||
|
||||
O Windows Server Build 2004 é capar de rodar containers Linux e Windows simultâneamente através do isolamento *Hyper-V*. Quando rodar os containers, utilize o comando ```--isolation=hyperv``` que vai isolar o container utilizando uma instância de kernel separada.
|
||||
|
||||
|
||||
### Checando a versão
|
||||
|
||||
É muito importante que você sempre saiba a versão do Docker que você está utilizando. Isso é muito útil porque você vai saber quais *features* são compatíveis com aquilo que você está rodado. Além disso, isso também é importante pois você saberá quais containers você deve rodar a partir da *Docker store* quando você estiver tentando usar *containers templates*. Sendo assim, vamos dar um olhar em como saber a versão do Docker que você está rodando no momento.
|
||||
|
||||
|
||||
* [`docker version`](https://docs.docker.com/engine/reference/commandline/version/): mostra a versão do Docker que você está rodando
|
||||
|
||||
Obtendo a versão do servidor:
|
||||
|
||||
```
|
||||
$ docker version --format '{{.Server.Version}}'
|
||||
|
||||
1.8.0
|
||||
```
|
||||
|
||||
Você também pode fazer um *dump* dos dados em JSON:
|
||||
|
||||
```
|
||||
$ docker version --format '{{json .}}'
|
||||
|
||||
{"Client":{"Version":"1.8.0","ApiVersion":"1.20","GitCommit":"f5bae0a","GoVersion":"go1.4.2","Os":"linux","Arch":"am"}
|
||||
```
|
||||
|
||||
## Containers
|
||||
|
||||
[O processo básico isolado do Docker](http://etherealmind.com/basics-docker-containers-hypervisors-coreos/). Containers são para máquinas virtuais o que *threads* são para processos. Ou você pode imaginá-los como *chroots* com esteróides.
|
||||
|
||||
### Ciclo de vida
|
||||
|
||||
* [`docker create`](https://docs.docker.com/engine/reference/commandline/create) cria um container mas não o inicia.
|
||||
* [`docker rename`](https://docs.docker.com/engine/reference/commandline/rename/) permite renomear um container.
|
||||
* [`docker run`](https://docs.docker.com/engine/reference/commandline/run) cria e inicia um container em uma única operação
|
||||
* [`docker rm`](https://docs.docker.com/engine/reference/commandline/rm) deleta um container
|
||||
* [`docker update`](https://docs.docker.com/engine/reference/commandline/update/) atualiza os limites de recurso de um container.
|
||||
|
||||
Normalmente, se você rodar um container sem utilizar nenhuma opção ele vai iniciar e parar imediatamente. Se você deseja que ele continue rodando você pode usar o comando `docker run -td <container_id>`. A opção `-t` vai alocar uma sessão pseudo-TTY e o `-d` vai desacomplar o container automaticamente (ou seja, vai rodar o container em background e imprimir o ID do container).
|
||||
|
||||
Se você deseja um container transiente, `docker run --rm` vai remover o container assim que ele parar.
|
||||
|
||||
Se você deseja mapear um diretório da máquina *host* para o container do Docker, `docker run -v $HOSTDIR:$DOCKERDIR`. Saiba mais em [Volumes](https://github.com/wsargent/docker-cheat-sheet/#volumes).
|
||||
|
||||
Se você também deseja remover o volume associado ao container, ao deletar o container você deve incluir a opção `-v`, por exemplo, `docker rm -v`.
|
||||
|
||||
Também existe o [*logging driver*](https://docs.docker.com/engine/admin/logging/overview/), disponível para containers individuais no docker 1.10. Para rodar o docker com um *log driver* customizado (ou seja, para syslog), use `docker run --log-driver=syslog`.
|
||||
|
||||
Outra opção muito útil é o `docker run --name <yourname> <docker_image>` porque você pode especificar o `--name` dentro do comando `run` que vai lhe permite iniciar e parar o container através do nome que você especificou quando o criou.
|
||||
|
||||
|
||||
### Iniciando e parando
|
||||
|
||||
* [`docker start`](https://docs.docker.com/engine/reference/commandline/start) inicia um container, então ele passa a rodar.
|
||||
* [`docker stop`](https://docs.docker.com/engine/reference/commandline/stop) para um container que esteja rodando.
|
||||
* [`docker restart`](https://docs.docker.com/engine/reference/commandline/restart) para e inicia um container.
|
||||
* [`docker pause`](https://docs.docker.com/engine/reference/commandline/pause/) pausa um container que esteja rodando, "congelando" ele da maneira que está.
|
||||
* [`docker unpause`](https://docs.docker.com/engine/reference/commandline/unpause/) vai despausar um container que estava rodando.
|
||||
* [`docker wait`](https://docs.docker.com/engine/reference/commandline/wait) bloqueia o container até que ele seja parado.
|
||||
* [`docker kill`](https://docs.docker.com/engine/reference/commandline/kill) envia um SIGKILL para um container que esteja rodando.
|
||||
* [`docker attach`](https://docs.docker.com/engine/reference/commandline/attach) vai se conectar a um container que esteja rodando.
|
||||
|
||||
Se você deseja desacoplar um container que esteja rodando, utilize `Ctrl + p, Ctrl + q`. Se você deseja integrar um container com o [gerenciador de processos do host](https://docs.docker.com/engine/admin/host_integration/), inicialize o daemon com `-r=false` e depois use `docker start -a`.
|
||||
|
||||
Se você deseja expor portas do container través do *host*, veja a seção [expondo portas](#exposing-ports).
|
||||
|
||||
Políticas de reinicialização para instâncias "crashadas" do docker são [cobridas aqui](http://container42.com/2014/09/30/docker-restart-policies/).
|
||||
|
||||
#### Restrições de CPU
|
||||
|
||||
Você pode limitar o uso da CPU, seja usando uma porcentagem de todas as CPUs ou usando *cores* específicos.
|
||||
|
||||
Por exemplo, você pode usar a configuração [`cpu-shares`](https://docs.docker.com/engine/reference/run/#/cpu-share-constraint). A configuração é um pouco estranha -- 1024 significa 100% da CPU, então se você quer um container que toma 50% de todos os *cores*, você deve utilizar 512. Veja <https://goldmann.pl/blog/2014/09/11/resource-management-in-docker/#_cpu> para mais:
|
||||
|
||||
```
|
||||
docker run -it -c 512 agileek/cpuset-test
|
||||
```
|
||||
|
||||
Você também pode usar alguns *cores* de uma CPU com o comando [`cpuset-cpus`](https://docs.docker.com/engine/reference/run/#/cpuset-constraint). Veja <https://agileek.github.io/docker/2014/08/06/docker-cpuset/> para mais detalhes e alguns vídeos bem legais:
|
||||
|
||||
```
|
||||
docker run -it --cpuset-cpus=0,4,6 agileek/cpuset-test
|
||||
```
|
||||
|
||||
Observe que o Docker ainda pode **enxergar** todas as CPUs de dentro do container -- ele apenas não está usando todas elas. Veja <https://github.com/docker/docker/issues/20770> para mais detalhes.
|
||||
|
||||
|
||||
#### Restrições de memória
|
||||
|
||||
Você também pode setar [restrições de memória](https://docs.docker.com/engine/reference/run/#/user-memory-constraints) no Docker:
|
||||
|
||||
```
|
||||
docker run -it -m 300M ubuntu:14.04 /bin/bash
|
||||
```
|
||||
|
||||
#### *Capabilities*
|
||||
|
||||
Linux *capabilities* podem ser setadas utilizand as opções `cap-add` e `cap-drop`. Veja See <https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities> para mais detalhes. Elas devem ser utilizadas para aumentar a seguraça do sistema.
|
||||
|
||||
Para montar um *filesystem* baseado no FUSE, você precisa combinar tanto `--cap-add` quanto `--device`:
|
||||
|
||||
```
|
||||
docker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs
|
||||
```
|
||||
|
||||
Para dar acesso a um único *device*:
|
||||
|
||||
```
|
||||
docker run -it --device=/dev/ttyUSB0 debian bash
|
||||
```
|
||||
|
||||
Para dar acesso a todos os *devices*:
|
||||
|
||||
```
|
||||
docker run -it --privileged -v /dev/bus/usb:/dev/bus/usb debian bash
|
||||
```
|
||||
|
||||
Para mais informações sobre privilégios em containers [clique aqui](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities).
|
||||
|
||||
### Info
|
||||
|
||||
* [`docker ps`](https://docs.docker.com/engine/reference/commandline/ps) motra os containers que estão rodando.
|
||||
* [`docker logs`](https://docs.docker.com/engine/reference/commandline/logs) obtém um log dos containers. (Você pode usar um log customizado, mas eles estão disponíveis apenas para `json-file` e `journald` na versão 1.10).
|
||||
* [`docker inspect`](https://docs.docker.com/engine/reference/commandline/inspect) olha para todas as informações de um container (incluindo o endereço IP).
|
||||
* [`docker events`](https://docs.docker.com/engine/reference/commandline/events) obtém os eventos de um container.
|
||||
* [`docker port`](https://docs.docker.com/engine/reference/commandline/port) mostra a porta pública de um container.
|
||||
* [`docker top`](https://docs.docker.com/engine/reference/commandline/top) mostra os processos rodando dentro de um container.
|
||||
* [`docker stats`](https://docs.docker.com/engine/reference/commandline/stats) mostra uma estatística dos recursos que o container está utilizando.
|
||||
* [`docker diff`](https://docs.docker.com/engine/reference/commandline/diff) mostra os arquivos alterados pelo FS de um container.
|
||||
|
||||
`docker ps -a` mostra os containers que estão rodando e os que foram parados.
|
||||
|
||||
`docker stats --all` mostra uma lista de todos os containers. O padrão é mostrar apenas os que estão rodando.
|
||||
|
||||
### Importar / Exportar
|
||||
|
||||
* [`docker cp`](https://docs.docker.com/engine/reference/commandline/cp) copia arquivos ou pastas entre o container e o *filesystem* local.
|
||||
* [`docker export`](https://docs.docker.com/engine/reference/commandline/export) transforma o *filesystem* do container em um fluxo de arquivo *tarball* para STDOUT.
|
||||
|
||||
|
||||
### Executando comandos
|
||||
|
||||
* [`docker exec`](https://docs.docker.com/engine/reference/commandline/exec) executa um comando dentro do container.
|
||||
|
||||
Por exemplo, para entrar em um container fictício, que esteja rodando, chamado foo, inclua um shell a ele da seguinte maneira: `docker exec -it foo /bin/bash`.
|
||||
|
||||
## Imagens
|
||||
|
||||
Imagens são apenas [templates de um container docker](https://docs.docker.com/engine/understanding-docker/#how-does-a-docker-image-work).
|
||||
|
||||
### Ciclo de vida
|
||||
|
||||
* [`docker images`](https://docs.docker.com/engine/reference/commandline/images) mostra todas as imagens.
|
||||
* [`docker import`](https://docs.docker.com/engine/reference/commandline/import) cria uma imagem a partir de um *tarball*.
|
||||
* [`docker build`](https://docs.docker.com/engine/reference/commandline/build) cria uma imagem a partir de um Dockerfile.
|
||||
* [`docker commit`](https://docs.docker.com/engine/reference/commandline/commit) cria uma imagem a partir de um container, pausando ele temporariamente caso ele esteja rodando.
|
||||
* [`docker rmi`](https://docs.docker.com/engine/reference/commandline/rmi) remove uma imagem.
|
||||
* [`docker load`](https://docs.docker.com/engine/reference/commandline/load) carrega uma imagem a partir de um arquivo tar no STDIN, incluindo imagess and tags (a partir da versão 0.7).
|
||||
* [`docker save`](https://docs.docker.com/engine/reference/commandline/save) salva uma imagem em um arquivo tar através do STDOUT com todas as camadas pais, tags e versões (a partir do 0.7).
|
||||
|
||||
### Info
|
||||
|
||||
* [`docker history`](https://docs.docker.com/engine/reference/commandline/history) mostra o histórico de todas as imagens.
|
||||
* [`docker tag`](https://docs.docker.com/engine/reference/commandline/tag) dar uma tag a uma imagem (local ou *registry*)
|
||||
|
||||
|
||||
### Fazendo uma limpeza
|
||||
|
||||
Você pode utilizar o comando `docker rmi` para remover imagens específicas, porém, existe uma ferramenta chamada [docker-gc](https://github.com/spotify/docker-gc), que de maneira segura, limpa as imagens que não está sendo utilizada por nenhum container.
|
||||
|
||||
that will safely clean up images that are no longer used by any containers. A partir do docker 1.13, o comando `docker image prune` também está disponível para remover imagens que não estão sendo usadas. Veja a seção [Prune](#prune).
|
||||
|
||||
### Carregar/Salvar imagens
|
||||
|
||||
Carregue uma imagem a partir do arquivo:
|
||||
```
|
||||
docker load < my_image.tar.gz
|
||||
```
|
||||
|
||||
Salve uma imagem existente usando:
|
||||
```
|
||||
docker save my_image:my_tag | gzip > my_image.tar.gz
|
||||
```
|
||||
|
||||
### Importar/Exportar containers
|
||||
|
||||
|
||||
Importe um container com uma imagem a partir de um arquivo:
|
||||
```
|
||||
cat my_container.tar.gz | docker import - my_image:my_tag
|
||||
```
|
||||
|
||||
Exporte um container existente usando:
|
||||
```
|
||||
docker export my_container | gzip > my_container.tar.gz
|
||||
```
|
||||
|
||||
### Diferenças entre carregar uma imagem salva e importar um container exportado como uma imagem
|
||||
|
||||
Carregar uma imagem usanfo o comando `load` cria uma nova imagem, incluindo o seu histórico. Importar um container como uma imagem usando o comando `import` cria uma nova imagem excluindo o seu histórico, o que resulta em uma imamgem de tamanho menor do que usando o comando anterior.
|
||||
|
||||
## Rede
|
||||
|
||||
O Docker possui *features* de [rede](https://docs.docker.com/engine/userguide/networking/). Automaticamente, ele cria 3 interfaces de rede quando você o instala (*bridge*, *host*, *none*). Um novo container é inicializado, por padrão, dentro da rede *bridge*. Para habilitar a comunicação entre multiplos containers, você pode criar uma nova rede e iniciarlizar o mesmo com ela. Isso vai habilitar a comunicação entre os containers dentro dela ao mesmo tempo que os isola dos outros containers que não estejam conectados nesta rede. Além disso, isso permite mapear os nomes dos containers com o seus respectivos endereços IP. Veja [trabalhando com redes](https://docs.docker.com/engine/userguide/networking/work-with-networks/) para mais detalhes.
|
||||
|
||||
### Ciclo de vida
|
||||
|
||||
* [`docker network create <name>`](https://docs.docker.com/engine/reference/commandline/network_create/) cria uma nova rede (tipo padrão: *bridge*).
|
||||
* [`docker network rm <name>`](https://docs.docker.com/engine/reference/commandline/network_rm/) remode uma ou mais redes especificadas pelo nome ou identificador. Nenhum container pode se conectar em uma rede quando deletada.
|
||||
|
||||
### Info
|
||||
|
||||
* [`docker network ls`](https://docs.docker.com/engine/reference/commandline/network_ls/) lista todas as redes.
|
||||
* [`docker network inspect <name>`](https://docs.docker.com/engine/reference/commandline/network_inspect/) mostra informações detalhadas de uma ou mais redes.
|
||||
|
||||
### Conexão
|
||||
|
||||
* [`docker network connect <network> <container>`](https://docs.docker.com/engine/reference/commandline/network_connect/) Conecta um container a uma rede
|
||||
* [`docker network disconnect <network> <container>`](https://docs.docker.com/engine/reference/commandline/network_disconnect/) Desconecta um container de uma rede
|
||||
|
||||
Você pode especificar um [endereço IP para um container](https://blog.jessfraz.com/post/ips-for-all-the-things/):
|
||||
|
||||
```
|
||||
# cria uma nova rede bridge com sua subnet e gateway para seu bloco de endereço IP
|
||||
docker network create --subnet 203.0.113.0/24 --gateway 203.0.113.254 iptastic
|
||||
|
||||
# roda um container nginx com um IP específico para o dado bloco
|
||||
$ docker run --rm -it --net iptastic --ip 203.0.113.2 nginx
|
||||
|
||||
# da um culr no IP a partir de qualquer outro local (assumindo que este seja um IP público)
|
||||
$ curl 203.0.113.2
|
||||
```
|
||||
|
||||
## Registry & Repositório
|
||||
|
||||
Um repositório é uma coleção *hosteada* de imagens com tagas que juntas criam um sistema de arquivo para um container;
|
||||
|
||||
Um *registry* é um *host* -- ou seja, um servidor que armazena repositórios e disponibiliza um API HTTP para [gerencias o upload e download dos repositórios](https://docs.docker.com/engine/tutorials/dockerrepos/).
|
||||
|
||||
O Docker.com *hostea* seus prórpios [índices](https://hub.docker.com/) em uma central de *registries* qie contém um grande número de repositórios. Sendo assim, essa central [não é muito boa em verificar a procedência das imagens](https://titanous.com/posts/docker-insecurity) e deve ser evitada caso segurança seja algo crítico para você.
|
||||
|
||||
|
||||
* [`docker login`](https://docs.docker.com/engine/reference/commandline/login) efetua login em um *registry*.
|
||||
* [`docker logout`](https://docs.docker.com/engine/reference/commandline/logout) efetua logout de um *registry*.
|
||||
* [`docker search`](https://docs.docker.com/engine/reference/commandline/search) busca imagens dentro do *registry*.
|
||||
* [`docker pull`](https://docs.docker.com/engine/reference/commandline/pull) efetua um *pull* de uma imagem do *registry* para sua máquina local.
|
||||
* [`docker push`](https://docs.docker.com/engine/reference/commandline/push) efetua um *push* de uma imagem para o *registry* a partir da sua máquina local.
|
||||
|
||||
### Rodando um *registry* local
|
||||
|
||||
Você pode rodar um *registry* local utilizando o projeto de [distribuição docker](https://github.com/docker/distribution) e seguindo as instruções de [*deploy* local](https://github.com/docker/docker.github.io/blob/master/registry/deploying.md).
|
||||
|
||||
Além disso, você pode se interessar pela [lista de emails](https://groups.google.com/a/dockerproject.org/forum/#!forum/distribution).
|
||||
|
||||
## Dockerfile
|
||||
|
||||
[O arquivo de configuração](https://docs.docker.com/engine/reference/builder/). Prepara um container Docker quando você executa o comando `docker build`. A maioria das pessoas preferem este comando do que o `docker commit`.
|
||||
|
||||
Estes são alguns dos editores de texto que dão suporte, em termos de módulos que destacam a sintaxe, para criar Dockerfiles:
|
||||
* Se você utiliza o [jEdit](http://jedit.org), eu adicionei um módulo para destacar de sintaxe para o [Dockerfile](https://github.com/wsargent/jedit-docker-mode). Sinta-se livre para usar.
|
||||
* [Sublime Text 2](https://packagecontrol.io/packages/Dockerfile%20Syntax%20Highlighting)
|
||||
* [Atom](https://atom.io/packages/language-docker)
|
||||
* [Vim](https://github.com/ekalinin/Dockerfile.vim)
|
||||
* [Emacs](https://github.com/spotify/dockerfile-mode)
|
||||
* [TextMate](https://github.com/docker/docker/tree/master/contrib/syntax/textmate)
|
||||
* [VS Code](https://github.com/Microsoft/vscode-docker)
|
||||
* Veja também [Docker meets the IDE](https://domeide.github.io/)
|
||||
|
||||
### Instruções
|
||||
|
||||
* [.dockerignore](https://docs.docker.com/engine/reference/builder/#dockerignore-file)
|
||||
* [FROM](https://docs.docker.com/engine/reference/builder/#from) Prepara a imagem base para as instruções subsequentes.
|
||||
* [MAINTAINER (depreciado - use a tag LABEL)](https://docs.docker.com/engine/reference/builder/#maintainer-deprecated) Define o autor que gerou a imagem.
|
||||
* [RUN](https://docs.docker.com/engine/reference/builder/#run) executa qualquer comando em uma nova camada em cima de uma imagem e *comita* o resultado.
|
||||
* [CMD](https://docs.docker.com/engine/reference/builder/#cmd) fornecer padrões para um container em execução.
|
||||
* [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose) informa o Docker que o container pode escutar uma determinada porta de rede durante o tempo de execução. NOTA: isso não faz com que a porta seja acessível.
|
||||
* [ENV](https://docs.docker.com/engine/reference/builder/#env) define uma variável de ambiente.
|
||||
* [ADD](https://docs.docker.com/engine/reference/builder/#add) copia novos arquivos, diretórios, ou arquivos remotos em um container. Invalida cache. Evite usar `ADD` e use o comando `COPY`.
|
||||
* [COPY](https://docs.docker.com/engine/reference/builder/#copy) copia um novo arquivo ou diretórios para dentro do container. Por padrão copia como root independente das configurações do USER/WORKDIR. Utilize `--chown=<user>:<group>` para poderes de acesso a outros usuários/grupos. (o mesmo é válido para o comando `ADD`.)
|
||||
* [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint) configura um container que vai rodar como um executável.
|
||||
* [VOLUME](https://docs.docker.com/engine/reference/builder/#volume) cria um ponto de montagem para montar volumes externos ou outros containers.
|
||||
* [USER](https://docs.docker.com/engine/reference/builder/#user) define o nome de usuário para os seguintes comandos: RUN / CMD / ENTRYPOINT.
|
||||
* [WORKDIR](https://docs.docker.com/engine/reference/builder/#workdir) define o diretório de trabalho.
|
||||
* [ARG](https://docs.docker.com/engine/reference/builder/#arg) define uma variável que existe durante o tempo de execução do *build*.
|
||||
* [ONBUILD](https://docs.docker.com/engine/reference/builder/#onbuild) adicionar uma instrução alarme que dispara quando a imagem está sendo usada como base para outra *build*.
|
||||
* [STOPSIGNAL](https://docs.docker.com/engine/reference/builder/#stopsignal) define o sinal de alerta do sistema que vai ser enviado para sair do container.
|
||||
* [LABEL](https://docs.docker.com/config/labels-custom-metadata/) aplica uma chave/valor para suas imagens, containers, ou *daemons*.
|
||||
* [SHELL](https://docs.docker.com/engine/reference/builder/#shell) sobrecarrega o shell padrão para rodar os comandos do docker.
|
||||
* [HEALTHCHECK](https://docs.docker.com/engine/reference/builder/#healthcheck) informa docker como testar o container para testar se tudo está funcionando adequadamente.
|
||||
|
||||
### Tutorial
|
||||
|
||||
* [Tutorial do Flux7 para o Dockerfile](https://www.flux7.com/tutorial/docker-tutorial-series-part-3-automation-is-the-word-using-dockerfile/)
|
||||
|
||||
### Exemplos
|
||||
|
||||
* [Exemplos](https://docs.docker.com/engine/reference/builder/#dockerfile-examples)
|
||||
* [Boas práticas para escrever Dockerfiles](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/)
|
||||
* [Michael Crosby](http://crosbymichael.com/) tem mais algumas [boas práticas para criar Dockerfiles](http://crosbymichael.com/dockerfile-best-practices.html) / [parte 2](http://crosbymichael.com/dockerfile-best-practices-take-2.html).
|
||||
* [Construindo boas imagens Docker](http://jonathan.bergknoff.com/journal/building-good-docker-images) / [Construindo imagens Dockers ainda melhores](http://jonathan.bergknoff.com/journal/building-better-docker-images)
|
||||
* [Gerenciando a configuração de um container com metadados](https://speakerdeck.com/garethr/managing-container-configuration-with-metadata)
|
||||
* [Como escrever excelentes Dockerfiles](https://rock-it.pl/how-to-write-excellent-dockerfiles/)
|
||||
|
||||
## Camadas
|
||||
|
||||
O versionamento dos arquivos de sistema do docker é feito em camadas. Elas funcionam como [comits no git ou *changesets* para arquivos de sistemas](https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/).
|
||||
|
||||
## Links
|
||||
|
||||
Links são como os containers Docker conversam uns com os outros [através de portas TCP/IP](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/). [Atlassian](https://blogs.atlassian.com/2013/11/docker-all-the-things-at-atlassian-automation-and-wiring/) mostra alguns exemplos funcionais. Você também pode determinar [links pelo hostname](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#/updating-the-etchosts-file).
|
||||
|
||||
Este está depreciado para estender algumas [redes definidas por usuário](https://docs.docker.com/network/).
|
||||
|
||||
NOTA: se você deseja que os containers comuniquem uns com os outros apenas utilizando links, inicie o do docker daemon com `-icc=false` para desebilitar os processor de intra-comunicação.
|
||||
|
||||
Se você possui um container com nome CONTAINER (especificado por `docker run --name CONTAINER`) e em um Dockerfile, ele possui uma porta exposta:
|
||||
|
||||
```
|
||||
EXPOSE 1337
|
||||
```
|
||||
|
||||
Então, se nós criarmos qualquer outro container chamado LINKED como este:
|
||||
|
||||
```
|
||||
docker run -d --link CONTAINER:ALIAS --name LINKED user/wordpress
|
||||
```
|
||||
|
||||
Então, as portas expostas e os *aliases* do CONTAINER serão mostrados em LINKED com as seguintes variáveis de ambiente:
|
||||
|
||||
```
|
||||
$ALIAS_PORT_1337_TCP_PORT
|
||||
$ALIAS_PORT_1337_TCP_ADDR
|
||||
```
|
||||
|
||||
Você pode se conectar nele dessa maneira.
|
||||
|
||||
Para deletar os links, utilize o comando `docker rm --link`.
|
||||
|
||||
Geralmente, a *linkagem* entre serviços docker é um subconjunto de um "descobrimento de serviço", um grande problema caso você esteja planejando usar Docker para escalar em produção. Você pode se referir ao livro [The Docker Ecosystem: Service Discovery and Distributed Configuration Stores](https://www.digitalocean.com/community/tutorials/the-docker-ecosystem-service-discovery-and-distributed-configuration-stores) para mais informações.
|
||||
|
||||
## Volumes
|
||||
|
||||
Os volumes no Docker são [arquivos de sistemas flutuantes](https://docs.docker.com/engine/tutorials/dockervolumes/). Eles não possuem uma conexão particular com um container. Você pode usar volumes montados a partir de [container somente de dados](https://medium.com/@ramangupta/why-docker-data-containers-are-good-589b3c6c749e) para fins de portabilidade. A partir do Docker 1.9.0, o Docker passou a nomear volumes que substituem containers apenas de dados. Considere usar volumes nomeados para implementar isso ao invés de containers de dados.
|
||||
|
||||
### Ciclo de vidar
|
||||
|
||||
* [`docker volume create`](https://docs.docker.com/engine/reference/commandline/volume_create/)
|
||||
* [`docker volume rm`](https://docs.docker.com/engine/reference/commandline/volume_rm/)
|
||||
|
||||
### Informações
|
||||
|
||||
* [`docker volume ls`](https://docs.docker.com/engine/reference/commandline/volume_ls/)
|
||||
* [`docker volume inspect`](https://docs.docker.com/engine/reference/commandline/volume_inspect/)
|
||||
|
||||
Volumes são úteis em situações em que você não quer usar links (que são apenas TCP/IP). Por exemplo, se você precisar ter duas instancias docker comunicando através de algo deixado no arquivo de sistema.
|
||||
|
||||
Você pode montar vários containers docker de uma vez usando o comando `docker run --volumes-from`.
|
||||
|
||||
Como os volumes são sistemas de arquivos isolados, frequentemente, eles são usados para armazenar estados de alguma computação que é transiente no container. Isto é, você pode ter um container sem estado e transiente continuado de ponto que útimo container deixou.
|
||||
|
||||
Veja [volumes avançados](http://crosbymichael.com/advanced-docker-volumes.html) para mais detalhes. [Container42](http://container42.com/2014/11/03/docker-indepth-volumes/) também é bem útil.
|
||||
|
||||
Você pode [mapear diretórios hosts do MacOS como volumes docker](https://docs.docker.com/engine/tutorials/dockervolumes/#mount-a-host-directory-as-a-data-volume):
|
||||
|
||||
```
|
||||
docker run -v /Users/wsargent/myapp/src:/src
|
||||
```
|
||||
|
||||
Você pode usar columes NFS remotos se você estiver se
|
||||
You can use remote NFS volumes if you're [sentindo corajoso](https://docs.docker.com/engine/tutorials/dockervolumes/#/mount-a-shared-storage-volume-as-a-data-volume).
|
||||
|
||||
Você também pode considerar rodar containers apenas de dados como descrito [aqui](http://container42.com/2013/12/16/persistent-volumes-with-docker-container-as-volume-pattern/) para obter uma certa portabilidade de dados.
|
||||
|
||||
Saiba que você pode [montar arquivos como volumes](#volumes-can-be-files).
|
||||
|
||||
## Expondo portas
|
||||
|
||||
|
||||
Expor as portas de entrada através do container *host* é [complicado, mas factível](https://docs.docker.com/engine/reference/run/#expose-incoming-ports).
|
||||
|
||||
Isso é feito mapeando a porta do container para com a porta do *host* (apenas usando a interface *localhost*) usando a opção `-p`:
|
||||
|
||||
```
|
||||
docker run -p 127.0.0.1:$HOSTPORT:$CONTAINERPORT --name CONTAINER -t ALGUMA_IMAGEM
|
||||
```
|
||||
|
||||
Você pode informar ao Docker que o container escuta uma porta de rede específica durante a execução ao usar o comando [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose):
|
||||
|
||||
```
|
||||
EXPOSE <CONTAINERPORT>
|
||||
```
|
||||
|
||||
Note que `EXPOSE` não expões a porta propriamente dita -- apenas a opção `-p` faz isso. Para expor uma porta do container na sua porta *localhost*:
|
||||
|
||||
```
|
||||
iptables -t nat -A DOCKER -p tcp --dport <LOCALHOSTPORT> -j DNAT --to-destination <CONTAINERIP>:<PORT>
|
||||
```
|
||||
|
||||
Se você estiver rodando Docker em uma VirtualBox, então você precisa encaminha a porta para lá também usando uma [*forwarded_port*](https://docs.vagrantup.com/v2/networking/forwarded_ports.html). Defina um intervalo de portas que no seu *Vagrantfile* dessa maneira para que vcê possa mapeá-las dinamicamente:
|
||||
|
||||
```
|
||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
...
|
||||
|
||||
(49000..49900).each do |port|
|
||||
config.vm.network :forwarded_port, :host => port, :guest => port
|
||||
end
|
||||
|
||||
...
|
||||
end
|
||||
```
|
||||
|
||||
Se você esquecer o que você mapeou na porta do seu container *host*, utilize `docker port` para mostrar o que você fez:
|
||||
|
||||
```
|
||||
docker port CONTAINER $CONTAINERPORT
|
||||
```
|
||||
|
||||
## Boas práticas
|
||||
|
||||
É aqui onde boas práticas gerais do Docker uma discusão começa:
|
||||
|
||||
* [A toca do coelho do uso do Docker em testes automatizados](http://gregoryszorc.com/blog/2014/10/16/the-rabbit-hole-of-using-docker-in-automated-tests/)
|
||||
* [Bridget Kromhout](https://twitter.com/bridgetkromhout) possui um post muito útil no blog: [rodando Docker em produção](http://sysadvent.blogspot.co.uk/2014/12/day-1-docker-in-production-reality-not.html) no Dramafever.
|
||||
* Também tem o [blog post](http://developers.lyst.com/devops/2014/12/08/docker/) de boas práticas feito pela Lyst.
|
||||
* [Contruindo um ambiente de desenvolvimento com Docker](https://tersesystems.com/2013/11/20/building-a-development-environment-with-docker/)
|
||||
* [Discurso em um container Docker](https://samsaffron.com/archive/2013/11/07/discourse-in-a-docker-container)
|
||||
|
||||
## Docker-Compose
|
||||
|
||||
*Compose* é uma ferramenta para definir e rodar aplicações em vários containers Docker. Com o *compose* você utiliza uma arquivo YAML para configurar os serviços de sua aplicação. Na sequência, com uum único comando, você cria e inicia todos os serviços a partir da sua configuração. Para aprender mais sobre todas as funcionalidades do *Compose*, veja a [lista de funcionalidades](https://docs.docker.com/compose/overview/#features).
|
||||
|
||||
Ao usar este comando, você inicia sua aplicação:
|
||||
|
||||
```
|
||||
docker-compose -f <docker-compose-file> up
|
||||
```
|
||||
|
||||
Você também pode rodar `docker-compose` de maneira desacoplada usando a opção `-d` e parar ele quando quiser utilizando o comando:
|
||||
|
||||
```
|
||||
docker-compose stop
|
||||
```
|
||||
Você pode desligar tudo
|
||||
Você pode desligar tudo, remover os containers inteiramente, com o comando `down`. Passe `--volumes` para remover também o dados.
|
||||
|
||||
## Segurança
|
||||
|
||||
Aqui vão as dicas de segurança do Docker! A página sobre [segurança](https://docs.docker.com/engine/security/security/) do Docker fornece muito mais detalhes.
|
||||
|
||||
Começando do começo: Docker roda como root. Se você está dentro do `docker group`, você [possui acesso root](https://web.archive.org/web/20161226211755/http://reventlov.com/advisories/using-the-docker-command-to-root-the-host). Se você expor um unix socket do docker para um container, você está dando para este container [acesso root para o host](https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container/).
|
||||
|
||||
Docker não pode ser sua única defesa. Você deve protegê-lo da melhor maneira possível.
|
||||
|
||||
Para entender o que os containers deixam exposto, você deveria ler o tutorial [Entendendo e Protegendo Containers Linux](https://www.nccgroup.trust/globalassets/our-research/us/whitepapers/2016/april/ncc_group_understanding_hardening_linux_containers-1-1.pdf) escrito por [Aaron Grattafiori](https://twitter.com/dyn___). Ele um guia completo e compreensível para as questões envolvendo containers com uma grande quantidade de links e notas de rodapés que te leva para conteúdos ainda mais úteis. As dicas de seguranças que vêm a seguir são úteis se você já vem aumentando a segurança dos seus conteiners. Entretanto, elas não substituem o conhecimento sobre o assunto.
|
||||
|
||||
### Dicas de segurança
|
||||
|
||||
Para a maior segurança possível, é desejável rodar o Docker dentro de uma máquina virtual. Essa dica vem direto do líder do time de segurança do Docker -- [slides](http://www.slideshare.net/jpetazzo/linux-containers-lxc-docker-and-security) / [notas](http://www.projectatomic.io/blog/2014/08/is-it-safe-a-look-at-docker-and-security-from-linuxcon/).
|
||||
Na sequência, rode ele com AppArmor / seccomp / SELinux / grsec etc para [limitar as permissões do container](http://linux-audit.com/docker-security-best-practices-for-your-vessel-and-containers/). Veja as [funcionalidades de segurança do Docker 1.10](https://blog.docker.com/2016/02/docker-engine-1-10-security/) para mais detalhes.
|
||||
|
||||
As IDs de imagens do Docker são [informações sensíveis](https://medium.com/@quayio/your-docker-image-ids-are-secrets-and-its-time-you-treated-them-that-way-f55e9f14c1a4) e não devem serem expostas para o mundo. Trate elas como *passwords*.
|
||||
|
||||
Veja o [*Cheat Sheet* de segurança do Docker](https://github.com/konstruktoid/Docker/blob/master/Security/CheatSheet.adoc) por [Thomas Sjögren](https://github.com/konstruktoid): tem bastante coisa boa sobre aumentar a segurança em containers lá.
|
||||
|
||||
Dê uma olhada no [script de segurança docker bench](https://github.com/docker/docker-bench-security), baixe os [*white papers*](https://blog.docker.com/2015/05/understanding-docker-security-and-best-practices/).
|
||||
|
||||
Veja as [10 melhores práticas de segurança para imagens Docker](https://snyk.io/blog/10-docker-image-security-best-practices/) do Snyk.
|
||||
|
||||
|
||||
Você deve começar usando *kernels* com *patches* estáveis do grsecurity / pax compilados, por exemplo, no [Linux Alpine ](https://en.wikipedia.org/wiki/Alpine_Linux). Se você está usando grsecurity em produção, você deve adquirir o [suporte comercial](https://grsecurity.net/business_support.php) para ter [*patches* estáveis](https://grsecurity.net/announce.php), da mesma forma que você faria para o RedHat. Ele custa $200 por mês, o que pe nada para o seu orçamento de DevOps.
|
||||
|
||||
Desde o Docker 1.11, é fácil limitar o número de processos ativos rodando dentro do container para evitar *fork bombs*. É necessário um kernel Linux >= 4.3 com `CGROUP_PIDS=y` estar na configuração do Kernel.
|
||||
|
||||
```
|
||||
docker run --pids-limit=64
|
||||
```
|
||||
|
||||
Também está disponível, desde a versão 1.11, uma maneira de prevenir que processos ganhem novos privilégios. Essa funcionalidade está no *kernel* Linux desde a versão 3.5. Saiba mais sobre ela neste [post](http://www.projectatomic.io/blog/2016/03/no-new-privs-docker/) blog post.
|
||||
|
||||
```
|
||||
docker run --security-opt=no-new-privileges
|
||||
```
|
||||
|
||||
No [*Chear sheet* de segurança do Docker](http://container-solutions.com/content/uploads/2015/06/15.06.15_DockerCheatSheet_A2.pdf) (está em PDF, o que o torna difícil de usar, então esta copiado na sequência) por [Soluções para containers](http://container-solutions.com/is-docker-safe-for-production/):
|
||||
|
||||
Desligue a comunicação entre processor usando:
|
||||
|
||||
|
||||
```
|
||||
docker -d --icc=false --iptables
|
||||
```
|
||||
|
||||
Defina o container como apenas leitura:
|
||||
|
||||
```
|
||||
docker run --read-only
|
||||
```
|
||||
|
||||
Verique as imagens usando `hashsum`:
|
||||
|
||||
```
|
||||
docker pull debian@sha256:a25306f3850e1bd44541976aa7b5fd0a29be
|
||||
```
|
||||
|
||||
Defina os volumes como apenas leitura:
|
||||
|
||||
```
|
||||
docker run -v $(pwd)/secrets:/secrets:ro debian
|
||||
```
|
||||
|
||||
Defina e roda um usuário no seu Dockerfile, assim você não vai rodar como root dentro do container:
|
||||
|
||||
```
|
||||
RUN groupadd -r user && useradd -r -g user user
|
||||
USER user
|
||||
```
|
||||
|
||||
### Usando *Namespaces*
|
||||
|
||||
Também temos que trabalha no [*namespaces* do usuário](https://s3hh.wordpress.com/2013/07/19/creating-and-using-containers-without-privilege/) -- ele está na versão 1.1, mas não está disponível por padrão.
|
||||
|
||||
Para habilitar os *namespaces* do usuário no Ubuntu 15.10, [siga o exemplo descrito neste blog](https://raesene.github.io/blog/2016/02/04/Docker-User-Namespaces/).
|
||||
|
||||
### Vídeos sobre segurança
|
||||
|
||||
* [Usando Docker de maneira segura](https://youtu.be/04LOuMgNj9U)
|
||||
* [Protegendo suas aplicações usando Docker](https://youtu.be/KmxOXmPhZbk)
|
||||
* [Segurança do container: eles realmente a tem?](https://youtu.be/a9lE9Urr6AQ)
|
||||
* [Linux Containers: Futuro ou Fantasia?](https://www.youtube.com/watch?v=iN6QbszB1R8)
|
||||
|
||||
### Roteiro da Segurança
|
||||
|
||||
O roteiro do Docker fala sobre [suporte ao `secomp`] (https://github.com/docker/docker/blob/master/ROADMAP.md#11-security). Existe também o gerador de política AppArmor chamado [bane](https://github.com/jfrazelle/bane), e eles estão rodando dentro dos [perfis de segurança](https://github.com/docker/docker/issues/17142).
|
||||
|
||||
## Dicas
|
||||
|
||||
Fontes:
|
||||
|
||||
* [15 dicas do Docjer em 5 minutos](http://sssslide.com/speakerdeck.com/bmorearty/15-docker-tips-in-5-minutes)
|
||||
* [Docker CodeFresh: hacks para o Docker](https://codefresh.io/blog/everyday-hacks-docker/)
|
||||
|
||||
### *Prune*
|
||||
|
||||
Os novos [comandos de gerenciamento de dados](https://github.com/docker/docker/pull/26108) chegaram no Docker 1.13:
|
||||
|
||||
* `docker system prune`
|
||||
* `docker volume prune`
|
||||
* `docker network prune`
|
||||
* `docker container prune`
|
||||
* `docker image prune`
|
||||
|
||||
### df
|
||||
|
||||
`docker system df` apresenta um resumo do espaço utilizado pelos objetos do Docker.
|
||||
|
||||
### Heredoc Docker Container
|
||||
|
||||
```
|
||||
docker build -t htop - << EOF
|
||||
FROM alpine
|
||||
RUN apk --no-cache add htop
|
||||
EOF
|
||||
```
|
||||
|
||||
### Últimos IDs
|
||||
|
||||
```
|
||||
alias dl='docker ps -l -q'
|
||||
docker run ubuntu echo hello world
|
||||
docker commit $(dl) helloworld
|
||||
```
|
||||
|
||||
### Comitar com comandos (precisa de um Dockerfile)
|
||||
|
||||
```
|
||||
docker commit -run='{"Cmd":["postgres", "-too -many -opts"]}' $(dl) postgres
|
||||
```
|
||||
|
||||
### Obter o endereço IP
|
||||
|
||||
```
|
||||
docker inspect $(dl) | grep -wm1 IPAddress | cut -d '"' -f 4
|
||||
```
|
||||
|
||||
ou com [jq](https://stedolan.github.io/jq/) instalado:
|
||||
|
||||
```
|
||||
docker inspect $(dl) | jq -r '.[0].NetworkSettings.IPAddress'
|
||||
```
|
||||
|
||||
ou usando o [template go](https://docs.docker.com/engine/reference/commandline/inspect):
|
||||
|
||||
```
|
||||
docker inspect -f '{{ .NetworkSettings.IPAddress }}' <container_name>
|
||||
```
|
||||
|
||||
ou quando *buildando* um imagem com Dockerfile, quando você quiser passar um argumento de build:
|
||||
|
||||
```
|
||||
DOCKER_HOST_IP=`ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1`
|
||||
echo DOCKER_HOST_IP = $DOCKER_HOST_IP
|
||||
docker build \
|
||||
--build-arg ARTIFACTORY_ADDRESS=$DOCKER_HOST_IP
|
||||
-t sometag \
|
||||
some-directory/
|
||||
```
|
||||
|
||||
### Obter mapeamento de porta
|
||||
|
||||
```
|
||||
docker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' <containername>
|
||||
```
|
||||
|
||||
### Encontrar container com expressão regular
|
||||
|
||||
```
|
||||
for i in $(docker ps -a | grep "REGEXP_PATTERN" | cut -f1 -d" "); do echo $i; done
|
||||
```
|
||||
|
||||
### Obter configurações de ambiente
|
||||
|
||||
```
|
||||
docker run --rm ubuntu env
|
||||
```
|
||||
|
||||
### Matar containers que estão rodando
|
||||
|
||||
```
|
||||
docker kill $(docker ps -q)
|
||||
```
|
||||
|
||||
### Deletar todos os containers (Forçado!! containers que esteja parados ou rodando)
|
||||
|
||||
```
|
||||
docker rm -f $(docker ps -qa)
|
||||
```
|
||||
|
||||
### Deletar containers antigos
|
||||
|
||||
```
|
||||
docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm
|
||||
```
|
||||
|
||||
### Deletar containers parados
|
||||
|
||||
```
|
||||
docker rm -v $(docker ps -a -q -f status=exited)
|
||||
```
|
||||
|
||||
### Deletar containers depois de para-los
|
||||
|
||||
```
|
||||
docker stop $(docker ps -aq) && docker rm -v $(docker ps -aq)
|
||||
```
|
||||
|
||||
### Deletar imagens pendentes
|
||||
|
||||
```
|
||||
docker rmi $(docker images -q -f dangling=true)
|
||||
```
|
||||
|
||||
### Delete todas as imagens
|
||||
|
||||
```
|
||||
docker rmi $(docker images -q)
|
||||
```
|
||||
|
||||
### Deletar volumes pendentes
|
||||
|
||||
As of Docker 1.9:
|
||||
|
||||
```
|
||||
docker volume rm $(docker volume ls -q -f dangling=true)
|
||||
```
|
||||
|
||||
In 1.9.0, the filter `dangling=false` does _not_ work - it is ignored and will list all volumes.
|
||||
|
||||
### Mostrar dependências das imagens
|
||||
|
||||
```
|
||||
docker images -viz | dot -Tpng -o docker.png
|
||||
```
|
||||
|
||||
### Reduzingo o tamanho dos containers
|
||||
|
||||
- Limpando APT em uma camada RUN
|
||||
|
||||
Isso deve ser feito na mesma camada dos outros comandos `apt`. Caso contrário, as camadas anteriores irão persistir e as informações originais das suas imagens vão contiuar grandes.
|
||||
|
||||
```
|
||||
RUN {apt commands} \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
```
|
||||
|
||||
- Achatar uma imagem
|
||||
```
|
||||
ID=$(docker run -d image-name /bin/bash)
|
||||
docker export $ID | docker import – flat-image-name
|
||||
```
|
||||
|
||||
- Fazendo backup
|
||||
```
|
||||
ID=$(docker run -d image-name /bin/bash)
|
||||
(docker export $ID | gzip -c > image.tgz)
|
||||
gzip -dc image.tgz | docker import - flat-image-name
|
||||
```
|
||||
|
||||
### Monitorar os recursos utilizados pelos containers
|
||||
|
||||
Para verificar CPU, memória, ou I/O de rede em um único container, você pode usar:
|
||||
To check the CPU, memory, and network I/O usage of a single container, you can use:
|
||||
```
|
||||
docker stats <container>
|
||||
```
|
||||
|
||||
Para todos os containers listados por ID:
|
||||
```
|
||||
docker stats $(docker ps -q)
|
||||
```
|
||||
|
||||
Para todos os containers listados por nome:
|
||||
```
|
||||
docker stats $(docker ps --format '{{.Names}}')
|
||||
```
|
||||
|
||||
Para todos os containers listados por imagem:
|
||||
```
|
||||
docker ps -a -f ancestor=ubuntu
|
||||
```
|
||||
|
||||
Remover todas imagens sem tag:
|
||||
```
|
||||
docker rmi $(docker images | grep “^” | awk '{split($0,a," "); print a[3]}')
|
||||
```
|
||||
|
||||
Remover um container usando expressão regular:
|
||||
```
|
||||
docker ps -a | grep wildfly | awk '{print $1}' | xargs docker rm -f
|
||||
```
|
||||
|
||||
Remover todos os containers *exitados*:
|
||||
```
|
||||
docker rm -f $(docker ps -a | grep Exit | awk '{ print $1 }')
|
||||
```
|
||||
|
||||
### Volumes podem ser arquivos
|
||||
|
||||
Saiba que você pode montar arquivos como volumes. Por exemplo, se você pode injetar uma configuração dessa forma:
|
||||
|
||||
``` bash
|
||||
# copia o arquivo para o container
|
||||
docker run --rm httpd cat /usr/local/apache2/conf/httpd.conf > httpd.conf
|
||||
|
||||
# edita o arquivo
|
||||
vim httpd.conf
|
||||
|
||||
# inicia o container com a configuração que foi modificada
|
||||
docker run --rm -it -v "$PWD/httpd.conf:/usr/local/apache2/conf/httpd.conf:ro" -p "80:80" httpd
|
||||
```
|
||||
|
||||
## Contrinbuindo com este *chear sheet*
|
||||
|
||||
Aqui está um pequeno tutorial de como contribuir com este documento.
|
||||
|
||||
### Abra o README.md
|
||||
|
||||
Clique em [README.md](https://github.com/wsargent/docker-cheat-sheet/blob/master/README.md) <-- neste link
|
||||
|
||||

|
||||
|
||||
### Edite a página
|
||||
|
||||

|
||||
|
||||
### Faça as mudanças e commit elas
|
||||
|
||||

|
||||
|
||||

|
||||
824
ru/README.md
824
ru/README.md
|
|
@ -1,824 +0,0 @@
|
|||
# Docker Cheat Sheet
|
||||
|
||||
**Want to improve this cheat sheet? See the [Contributing](#contributing) section!**
|
||||
|
||||
## Содержание
|
||||
|
||||
* [Почему Docker](#Почему-Docker)
|
||||
* [Предпосылки](#Предпосылки)
|
||||
* [Установка](#Установка)
|
||||
* [Контейнеры](#Контейнеры)
|
||||
* [Образы](#Образы)
|
||||
* [Сеть](#Сеть)
|
||||
* [Реестр и репозиторий](#registry--repository)
|
||||
* [Dockerfile](#dockerfile)
|
||||
* [Слои](#layers)
|
||||
* [Ссылка](#links)
|
||||
* [Тома](#volumes)
|
||||
* [Отображение портов](#exposing-ports)
|
||||
* [Лучшая практика](#best-practices)
|
||||
* [Безопасность](#security)
|
||||
* [Советы](#tips)
|
||||
* [Содействие](#contributing)
|
||||
|
||||
## Почему Docker
|
||||
|
||||
"С Docker разработчики могут создавать любое приложение на любом языке, используя любую инструментальную цепочку. Приложения помещаются в контейнер - становятся полностью переносимы и могут работать где угодно - на компьютерах под управлением OS X и Windows, серверах QA, работающих под управлением Ubuntu в облаке, и виртуальных машинах производственного центра обработки данных Red Hat.
|
||||
|
||||
Разработчики могут быстро начать работу, начиная с одного из 13 000 приложений, доступных на Docker Hub. Docker управляет и отслеживает изменения и зависимости, что облегчает для системных администраторов понимание того, как работают приложения, созданные разработчиками. И с Docker Hub разработчики могут автоматизировать свой процес сборки и совместно использовать артефакты с сотрудниками через публичные или частные репозитории.
|
||||
|
||||
Docker помогает разработчикам создавать и отправлять более качественные приложения быстрее " -- [Что такое Docker](https://www.docker.com/what-docker#copy1)
|
||||
|
||||
## Предпосылки
|
||||
|
||||
Я использую [Oh My Zsh](https://github.com/robbyrussell/oh-my-zsh) вместе с [Docker plugin](https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins#docker) для автозаполнения команд docker. Возможно у вас другой подход.
|
||||
|
||||
### Linux
|
||||
|
||||
Ядро 3.10.x [минимальное требование](https://docs.docker.com/engine/installation/binaries/#check-kernel-dependencies) для Docker.
|
||||
|
||||
### MacOS
|
||||
|
||||
10.8 “Mountain Lion” или более новый.
|
||||
|
||||
## Установка
|
||||
|
||||
### Linux
|
||||
|
||||
Быстрый и простой скрипт установки, предоставляемый Docker:
|
||||
|
||||
```
|
||||
curl -sSL https://get.docker.com/ | sh
|
||||
```
|
||||
|
||||
Если вы не хотите запускать случайный сценарий оболочки, см. [Инструкции](https://docs.docker.com/engine/installation/linux/) по установке на ваш дистрибутив.
|
||||
|
||||
Если вы являетесь полноправным новичком Docker, вы должны следовать [сериям учебников](https://docs.docker.com/engine/getstarted/) сейчас.
|
||||
|
||||
### macOS
|
||||
Скачать и установить [Docker Community Edition](https://www.docker.com/community-edition). если у вас есть Homebrew-Cask, просто введите `brew install --cask docker`.
|
||||
Или загрузите и установите [Docker Toolbox](https://docs.docker.com/toolbox/overview/). [Docker для Mac](https://docs.docker.com/docker-for-mac/) это хорошо, но это не совсем так, как установка VirtualBox. [
|
||||
См. Сравнение](https://docs.docker.com/docker-for-mac/docker-toolbox/).
|
||||
|
||||
> ** ПРИМЕЧАНИЕ ** Docker Toolbox является устаревшим. вы должны использовать Docker Community Edition, см. (Docker Toolbox)[https://docs.docker.com/toolbox/overview/]
|
||||
|
||||
После установки Docker Community Edition щелкните значок докера. Затем запустите контейнер:
|
||||
|
||||
```
|
||||
docker run hello-world
|
||||
```
|
||||
|
||||
Вот и все, у вас есть работающий контейнер Docker.
|
||||
|
||||
|
||||
Если вы являетесь полноправным новичком докеров, вы должны, вероятно, исследовать [серию учебников] (https://docs.docker.com/engine/getstarted/) сейчас.
|
||||
|
||||
## Контейнеры
|
||||
|
||||
[Ваш основной изолированный процесс Докера](http://etherealmind.com/basics-docker-containers-hypervisors-coreos/). Контейнеры - это виртуальные машины, поскольку потоки относятся к процессам. Или вы можете думать о них как о chroot на стероидах.
|
||||
|
||||
### Жизненный цикл
|
||||
|
||||
|
||||
* [`docker create`](https://docs.docker.com/engine/reference/commandline/create) создает контейнер, но не запускает его.
|
||||
* [`docker rename`](https://docs.docker.com/engine/reference/commandline/rename/) позволяет переименовать контейнер.
|
||||
* [`docker run`](https://docs.docker.com/engine/reference/commandline/run) создает и запускает контейнер за одну операцию.
|
||||
* [`docker rm`](https://docs.docker.com/engine/reference/commandline/rm) удаляет контейнер.
|
||||
* [`docker update`](https://docs.docker.com/engine/reference/commandline/update/) обновляет ограничения ресурсов контейнера.
|
||||
|
||||
Обычно, если вы запускаете контейнер без параметров, он запускается и останавливается немедленно, если вы хотите его запустить, вы можете использовать команду, `docker run -td container_id` это будет использовать опцию `-t` который будет выделять псевдо-TTY сессию и `-d` который автоматически отсоединяет контейнер (запускает контейнер в фоновом режиме и показыват ID контейнера).
|
||||
|
||||
Если вам нужен переходный контейнер, `docker run --rm` удалит контейнер после его остановки.
|
||||
|
||||
Если вы хотите сопоставить каталог на хосте с контейнером докера, `docker run -v $HOSTDIR:$DOCKERDIR`. Также смотрите [Тома](https://github.com/wsargent/docker-cheat-sheet/#volumes).
|
||||
|
||||
Если вы хотите удалить также тома, связанные с контейнером, удаление контейнера должно включать `-v` измените примерно так `docker rm -v`.
|
||||
|
||||
Существует также [логирование](https://docs.docker.com/engine/admin/logging/overview/) доступны для отдельных контейнеров в докерах 1.10. Чтобы запустить докер с помощью специального лог журнала (например, в syslog), используйте `docker run --log-driver=syslog`.
|
||||
|
||||
Другим полезным вариантом является `docker run --name yourname docker_image` потому что, когда вы укажете `--name` внутри команды run это позволит вам запускать и останавливать контейнер, вызывая его с именем, которое вы указали при его создании.
|
||||
|
||||
### Запуск и остановка
|
||||
|
||||
* [`docker start`](https://docs.docker.com/engine/reference/commandline/start) запускает контейнер, чтобы он работал.
|
||||
* [`docker stop`](https://docs.docker.com/engine/reference/commandline/stop) останавливает запущенный контейнер.
|
||||
* [`docker restart`](https://docs.docker.com/engine/reference/commandline/restart) останавливается и запускает контейнер.
|
||||
* [`docker pause`](https://docs.docker.com/engine/reference/commandline/pause/)
|
||||
приостанавливает работу контейнера, "замораживает" его на месте.
|
||||
* [`docker unpause`](https://docs.docker.com/engine/reference/commandline/unpause/) снимает "заморозку" контейнера.
|
||||
* [`docker wait`](https://docs.docker.com/engine/reference/commandline/wait) блокирует до остановки контейнера.
|
||||
* [`docker kill`](https://docs.docker.com/engine/reference/commandline/kill) посылает SIGKILL к запущеннному контейнеру.
|
||||
* [`docker attach`](https://docs.docker.com/engine/reference/commandline/attach) будет подключаться к работающему контейнеру.
|
||||
|
||||
|
||||
Если вы хотите интегрировать контейнер с [диспетчером хостов](https://docs.docker.com/engine/admin/host_integration/), запустите демона с помощью `-r = false`, а затем используйте` docker start -a `.
|
||||
|
||||
Если вы хотите открыть порты контейнера через хост, см. Раздел [раскрытие портов](#открытие-портов).
|
||||
|
||||
Перезагрузка политик в разбитых экземплярах докеров [рассматривается здесь](http://container42.com/2014/09/30/docker-restart-policies/).
|
||||
|
||||
#### Ограничения процессора
|
||||
|
||||
Вы можете ограничить процессор, используя либо процент от всех процессоров, либо используя определенные ядра.
|
||||
|
||||
Например, вы можете указать параметр [`cpu-shares`](https://docs.docker.com/engine/reference/run/#/cpu-share-constraint). Параметр немного странный - 1024 означает 100% CPU, поэтому, если вы хотите, чтобы контейнер занимал 50% всех ядер процессора, вы должны указать 512. См. https://goldmann.pl/blog/2014/09/11/resource-management-in-docker/#_cpu для получения дополнительной информации:
|
||||
|
||||
|
||||
```
|
||||
docker run -ti --c 512 agileek/cpuset-test
|
||||
```
|
||||
Вы также можете использовать только некоторые ядра процессора, используя [`cpuset-cpus`](https://docs.docker.com/engine/reference/run/#/cpuset-constraint). См. https://agileek.github.io/docker/2014/08/06/docker-cpuset/ для получения дополнительной информации:
|
||||
|
||||
|
||||
```
|
||||
docker run -ti --cpuset-cpus=0,4,6 agileek/cpuset-test
|
||||
```
|
||||
Обратите внимание, что Docker все еще может **видеть** все процессоры внутри контейнера -- он просто не использует все из них. Подробнее см. https://github.com/docker/docker/issues/20770.
|
||||
|
||||
|
||||
#### Ограничения памяти
|
||||
|
||||
Вы также можете установить [ограничения памяти](https://docs.docker.com/engine/reference/run/#/user-memory-constraints) на Docker:
|
||||
|
||||
```
|
||||
docker run -it -m 300M ubuntu:14.04 /bin/bash
|
||||
```
|
||||
|
||||
#### Возможности
|
||||
|
||||
Возможности Linux можно установить, используя `cap-add` и `cap-drop`. См. https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities для подробностей. Это должно использоваться для большей безопасности.
|
||||
|
||||
Чтобы подключить файловую систему на основе FUSE, вам необходимо объединить оба --cap-add и --device:
|
||||
|
||||
```
|
||||
docker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs
|
||||
```
|
||||
|
||||
Обеспечить доступ к одному устройству:
|
||||
|
||||
```
|
||||
docker run -it --device=/dev/ttyUSB0 debian bash
|
||||
```
|
||||
|
||||
Обеспечить доступ ко всем устройствам:
|
||||
|
||||
```
|
||||
docker run -it --privileged -v /dev/bus/usb:/dev/bus/usb debian bash
|
||||
```
|
||||
|
||||
подробнее о привилегированных контейнерах [здесь](
|
||||
https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities)
|
||||
|
||||
|
||||
### Info
|
||||
|
||||
* [`docker ps`](https://docs.docker.com/engine/reference/commandline/ps) показывает запущенные контейнеры.
|
||||
* [`docker logs`](https://docs.docker.com/engine/reference/commandline/logs) получает журналы из контейнера. (Вы можете использовать собственный драйвер журнала, но журналы доступны только для `json-file` и `journald` в 1.10).
|
||||
* [`docker inspect`](https://docs.docker.com/engine/reference/commandline/inspect) просматривает всю информацию о контейнере (включая IP-адрес).
|
||||
* [`docker events`](https://docs.docker.com/engine/reference/commandline/events) получает события из контейнера.
|
||||
* [`docker port`](https://docs.docker.com/engine/reference/commandline/port) показывает открытый порт контейнера.
|
||||
* [`docker top`](https://docs.docker.com/engine/reference/commandline/top) показывает запущенные процессы в контейнере.
|
||||
* [`docker stats`](https://docs.docker.com/engine/reference/commandline/stats) показывает статистику использования ресурсов контейнеров.
|
||||
* [`docker diff`](https://docs.docker.com/engine/reference/commandline/diff) показывает измененные файлы в FS контейнера.
|
||||
|
||||
`docker ps -a` показывает запущенные и остановленные контейнеры.
|
||||
|
||||
`docker stats --all` показывает текущий список контейнеров.
|
||||
|
||||
### Импорт / Экспорт
|
||||
|
||||
* [`docker cp`](https://docs.docker.com/engine/reference/commandline/cp) копирует файлы или папки между контейнером и локальной файловой системой.
|
||||
* [`docker export`](https://docs.docker.com/engine/reference/commandline/export) экспортировать файловую систему контейнера в качестве tar-архива.
|
||||
|
||||
### Выполнение команд
|
||||
|
||||
* [`docker exec`](https://docs.docker.com/engine/reference/commandline/exec) для выполнения команды в контейнере.
|
||||
|
||||
|
||||
Чтобы войти в запущенный контейнер, присоедините новый процесс оболочки к запущенному контейнеру с именем foo, используйте:`docker exec -it foo /bin/bash`.
|
||||
|
||||
## Образы
|
||||
|
||||
Образы - это просто [шаблоны для docker контейнеров](https://docs.docker.com/engine/understanding-docker/#how-does-a-docker-image-work).
|
||||
|
||||
### Жизненный цикл
|
||||
|
||||
* [`docker images`](https://docs.docker.com/engine/reference/commandline/images) показывает все образы.
|
||||
* [`docker import`](https://docs.docker.com/engine/reference/commandline/import) создает образ из архива.
|
||||
* [`docker build`](https://docs.docker.com/engine/reference/commandline/build) создает образ из Dockerfile.
|
||||
* [`docker commit`](https://docs.docker.com/engine/reference/commandline/commit) создает образ из контейнера, временно приостанавливая его, если он запущен.
|
||||
* [`docker rmi`](https://docs.docker.com/engine/reference/commandline/rmi) удаляет образ.
|
||||
* [`docker load`](https://docs.docker.com/engine/reference/commandline/load) загружает образ из архива tar в качестве STDIN, включая образы и теги (начиная с 0.7).
|
||||
* [`docker save`](https://docs.docker.com/engine/reference/commandline/save) сохраняет образ в поток архива tar в STDOUT со всеми родительскими слоями, тегами и версиями (начиная с 0,7).
|
||||
|
||||
### Info
|
||||
|
||||
* [`docker history`](https://docs.docker.com/engine/reference/commandline/history) показывает историю образа.
|
||||
* [`docker tag`](https://docs.docker.com/engine/reference/commandline/tag) теги образа к имени (локальному или реестру).
|
||||
|
||||
## Проверка версии Docker
|
||||
|
||||
Очень важно, чтобы вы всегда знали текущую версию Docker, в которой вы сейчас работаете, в любой момент времени. Это очень полезно, потому что вы узнаете, какие функции совместимы с тем, что вы используете. Это также важно, потому что вы знаете, какие контейнеры запускать из хранилища докеров, когда вы пытаетесь получить контейнеры шаблонов. Это говорит о том, как узнать, какая версия докера у нас работает в настоящее время:
|
||||
|
||||
|
||||
* ['docker version'](https://docs.docker.com/engine/reference/commandline/version/) проверьте, какая версия докера у вас запущена.
|
||||
* [docker version [OPTIONS]]
|
||||
|
||||
Получить версию сервера
|
||||
$ docker version --format '{{.Server.Version}}'
|
||||
|
||||
1.8.0
|
||||
Dump raw JSON data
|
||||
$ docker version --format '{{json .}}'
|
||||
|
||||
{"Client":{"Version":"1.8.0","ApiVersion":"1.20","GitCommit":"f5bae0a","GoVersion":"go1.4.2","Os":"linux","Arch":"am"}
|
||||
|
||||
### Cleaning up
|
||||
Хотя вы можете использовать команду `docker rmi` для удаления определенных образов, есть инструмент под названием [docker-gc](https://github.com/spotify/docker-gc), который будет безопасно очищать образы, которые больше не используются любыми контейнерами.
|
||||
|
||||
### Загрузка/Сохранение образов
|
||||
|
||||
Загрузите образ из файла:
|
||||
```
|
||||
docker load < my_image.tar.gz
|
||||
```
|
||||
|
||||
Сохранить существующий образ:
|
||||
```
|
||||
docker save my_image:my_tag | gzip > my_image.tar.gz
|
||||
```
|
||||
### Импорт/Экспорт контейнера
|
||||
|
||||
Импортировать контейнер как образ из файла:
|
||||
```
|
||||
cat my_container.tar.gz | docker import - my_image:my_tag
|
||||
```
|
||||
|
||||
Экспортировать существующий контейнер:
|
||||
```
|
||||
docker export my_container | gzip > my_container.tar.gz
|
||||
```
|
||||
|
||||
|
||||
### Разница между загрузкой сохраненного образа и импортом экспортированного контейнера в качестве образа
|
||||
|
||||
Загрузка изображения с помощью команды `load` создает новый образ, включая его историю.
|
||||
Импорт контейнера в качестве образа с помощью команды `import` создает новый образ, исключая историю, которая приводит к меньшему размеру образов по сравнению с загрузкой образа.
|
||||
|
||||
## Сети
|
||||
Docker имеет функцию [network](https://docs.docker.com/engine/userguide/networking/). Об этом мало что известно, поэтому это хорошее место для расширения чит-листа. Существует примечание, в котором говорится, что это хороший способ настроить контейнеры докеров, чтобы разговаривать друг с другом без использования портов. Подробнее см. [Работа с сетями](https://docs.docker.com/engine/userguide/networking/work-with-networks/).
|
||||
|
||||
### Жизненный цикл
|
||||
|
||||
* [`docker network create`](https://docs.docker.com/engine/reference/commandline/network_create/)
|
||||
* [`docker network rm`](https://docs.docker.com/engine/reference/commandline/network_rm/)
|
||||
|
||||
### Info
|
||||
|
||||
* [`docker network ls`](https://docs.docker.com/engine/reference/commandline/network_ls/)
|
||||
* [`docker network inspect`](https://docs.docker.com/engine/reference/commandline/network_inspect/)
|
||||
|
||||
### Connection
|
||||
|
||||
* [`docker network connect`](https://docs.docker.com/engine/reference/commandline/network_connect/)
|
||||
* [`docker network disconnect`](https://docs.docker.com/engine/reference/commandline/network_disconnect/)
|
||||
|
||||
Вы можете указать [конкретный IP-адрес для контейнера](https://blog.jessfraz.com/post/ips-for-all-the-things/):
|
||||
|
||||
```
|
||||
# создать новую сеть bridge с вашей подсетью и шлюзом для вашего ip-блока
|
||||
docker network create --subnet 203.0.113.0/24 --gateway 203.0.113.254 iptastic
|
||||
|
||||
# запустите контейнер nginx с определенным ip в этом блоке
|
||||
$ docker run --rm -it --net iptastic --ip 203.0.113.2 nginx
|
||||
|
||||
# curl ip из любого другого места (при условии, что это общедоступный ip-блок)
|
||||
$ curl 203.0.113.2
|
||||
```
|
||||
|
||||
## Реестр и репозиторий
|
||||
|
||||
Репозиторий - это * размещенная * коллекция помеченных образов, которые вместе создают файловую систему для контейнера.
|
||||
|
||||
Реестр - это * хост * - сервер, который хранит репозитории и предоставляет HTTP API для [управления загрузкой и загрузкой репозиториев](https://docs.docker.com/engine/tutorials/dockerrepos/).
|
||||
|
||||
Docker.com размещает свой собственный [index](https://hub.docker.com/) в центральном реестре, который содержит большое количество репозиториев. Сказав это, центральный реестр докеров (не делает хорошую работу по проверке образов)(https://titanous.com/posts/docker-insecurity), и его следует избегать, если вас беспокоит безопасность.
|
||||
|
||||
* [`docker login`](https://docs.docker.com/engine/reference/commandline/login) для входа в реестр.
|
||||
* [`docker logout`](https://docs.docker.com/engine/reference/commandline/logout) для выхода из реестра.
|
||||
* [`docker search`](https://docs.docker.com/engine/reference/commandline/search) ищет реестр для образа.
|
||||
* [`docker pull`](https://docs.docker.com/engine/reference/commandline/pull) вытаскивает образ из реестра на локальный компьютер.
|
||||
* [`docker push`](https://docs.docker.com/engine/reference/commandline/push) толкает образ в реестр с локальной машины.
|
||||
|
||||
### Запуск локального реестра
|
||||
|
||||
Вы можете запустить локальный реестр с помощью проекта [docker distribution](https://github.com/docker/distribution) и посмотреть на [локальное развертывание](https://github.com/docker/docker.github.io/blob/master/registry/deploying.md) инструкци.
|
||||
|
||||
Также см. [Список рассылки](https://groups.google.com/a/dockerproject.org/forum/#!forum/distribution).
|
||||
|
||||
## Dockerfile
|
||||
|
||||
[Файл конфигурации](https://docs.docker.com/engine/reference/builder/). Устанавливает контейнер Docker, когда вы запускаете на нем `docker build`. Крайне предпочтительнее `docker commit`.
|
||||
|
||||
Вот некоторые распространенные текстовые редакторы и их модули подсветки синтаксиса, которые вы могли бы использовать для создания Dockerfiles:
|
||||
* Если вы используете [jEdit](http://jedit.org), я установил модуль подсветки синтаксиса для [Dockerfile](https://github.com/wsargent/jedit-docker-mode) вы можете использовать.
|
||||
* [Sublime Text 2](https://packagecontrol.io/packages/Dockerfile%20Syntax%20Highlighting)
|
||||
* [Atom](https://atom.io/packages/language-docker)
|
||||
* [Vim](https://github.com/ekalinin/Dockerfile.vim)
|
||||
* [Emacs](https://github.com/spotify/dockerfile-mode)
|
||||
* [TextMate](https://github.com/docker/docker/tree/master/contrib/syntax/textmate)
|
||||
* [VS Code](https://github.com/Microsoft/vscode-docker)
|
||||
* Также см. [Docker meets the IDE](https://domeide.github.io/)
|
||||
|
||||
### Инструкции
|
||||
|
||||
* [.dockerignore](https://docs.docker.com/engine/reference/builder/#dockerignore-file)
|
||||
* [FROM](https://docs.docker.com/engine/reference/builder/#from) Устанавливает базовое изображение для последующих инструкций.
|
||||
* [MAINTAINER (устаревший - вместо этого используйте LABEL)](https://docs.docker.com/engine/reference/builder/#maintainer-deprecated) Задайте поле Author созданных образов.
|
||||
* [RUN](https://docs.docker.com/engine/reference/builder/#run) выполнять любые команды в новом слое поверх текущего образа и фиксировать результаты.
|
||||
* [CMD](https://docs.docker.com/engine/reference/builder/#cmd) предоставлять значения по умолчанию для исполняемого контейнера.
|
||||
* [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose) сообщает Docker, что контейнер прослушивает указанные сетевые порты во время выполнения. ПРИМЕЧАНИЕ: на самом деле не делает доступными порты.
|
||||
* [ENV](https://docs.docker.com/engine/reference/builder/#env) устанавливает переменную среды.
|
||||
* [ADD](https://docs.docker.com/engine/reference/builder/#add) копирует в контейнер новые файлы, каталоги или удаленный файл. Недействительный кеш. Избегайте `ADD` и вместо этого используйте` COPY`.
|
||||
* [COPY](https://docs.docker.com/engine/reference/builder/#copy) копирует в контейнер новые файлы или каталоги. Обратите внимание, что это копируется только с правами root, поэтому вы должны вручную управлять вне зависимости от настроек USER / WORKDIR. См. https://github.com/moby/moby/issues/30110
|
||||
* [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint) настраивает контейнер, который будет запускаться как исполняемый файл.
|
||||
* [VOLUME](https://docs.docker.com/engine/reference/builder/#volume) создает точку монтирования для внешних томов или других контейнеров.
|
||||
* [USER](https://docs.docker.com/engine/reference/builder/#user) задает имя пользователя для следующих команд RUN / CMD / ENTRYPOINT.
|
||||
* [WORKDIR](https://docs.docker.com/engine/reference/builder/#workdir) устанавливает рабочий каталог.
|
||||
* [ARG](https://docs.docker.com/engine/reference/builder/#arg) определяет переменную времени сборки.
|
||||
* [ONBUILD](https://docs.docker.com/engine/reference/builder/#onbuild) добавляет инструкцию триггера, когда изображение используется в качестве основы для другой сборки.
|
||||
* [STOPSIGNAL](https://docs.docker.com/engine/reference/builder/#stopsignal) устанавливает сигнал системного вызова, который будет отправлен в контейнер для выхода.
|
||||
* [LABEL](https://docs.docker.com/engine/userguide/labels-custom-metadata/) устанавливает сигнал системного вызова, который будет отправлен в контейнер для выхода.
|
||||
|
||||
### Tutorial
|
||||
|
||||
* [Учебник Flux7's Dockerfile
|
||||
](http://flux7.com/blogs/docker/docker-tutorial-series-part-3-automation-is-the-word-using-dockerfile/)
|
||||
|
||||
### Примеры
|
||||
|
||||
* [Примеры](https://docs.docker.com/engine/reference/builder/#dockerfile-examples)
|
||||
* [Рекомендации по написанию Dockerfiles](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/)
|
||||
* [Michael Crosby](http://crosbymichael.com/) has some more [Dockerfiles best practices](http://crosbymichael.com/dockerfile-best-practices.html) / [take 2](http://crosbymichael.com/dockerfile-best-practices-take-2.html).
|
||||
* [Building Good Docker Images](http://jonathan.bergknoff.com/journal/building-good-docker-images) / [Создание лучших образов docker](http://jonathan.bergknoff.com/journal/building-better-docker-images)
|
||||
* [Управление конфигурацией контейнера с метаданными](https://speakerdeck.com/garethr/managing-container-configuration-with-metadata)
|
||||
* [ Как написать отличный Dockerfiles](https://rock-it.pl/how-to-write-excellent-dockerfiles/)
|
||||
|
||||
## Слои
|
||||
|
||||
Файловая система с версией в Docker основана на слоях. Они похожи на [git комиты или измекнения для файловой системы](https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/).
|
||||
|
||||
## Связи
|
||||
Ссылки, как контейнеры Docker общаются друг с другом [через порты TCP/IP](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/). [Связь с Redis](https://docs.docker.com/engine/examples/running_redis_service/) и [Atlassian](https://blogs.atlassian.com/2013/11/docker-all-the-things-at-atlassian-automation-and-wiring/) показать приведенные примеры. Вы также можете разрешить [ссылки по имени хоста](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#/updating-the-etchosts-file).
|
||||
|
||||
Это в некоторой степени устарело [сетями определяемыми пользователем](https://docs.docker.com/engine/userguide/networking/#user-defined-networks).
|
||||
|
||||
ПРИМЕЧАНИЕ. Если вы хотите, чтобы контейнеры ТОЛЬКО связывались друг с другом по ссылкам, запустите демон docker с помощью `-icc = false`, чтобы отключить межпроцессное общение.
|
||||
|
||||
Если у вас есть контейнер с именем CONTAINER (указанный `docker run -name CONTAINER`) и в Dockerfile, он имеет открытый порт:
|
||||
|
||||
```
|
||||
EXPOSE 1337
|
||||
```
|
||||
Тогда, если мы создадим еще один контейнер LINKED, например:
|
||||
|
||||
```
|
||||
docker run -d --link CONTAINER:ALIAS --name LINKED user/wordpress
|
||||
```
|
||||
Затем открытые порты и псевдонимы CONTAINER будут отображаться в LINKED со следующими переменными среды:
|
||||
|
||||
```
|
||||
$ALIAS_PORT_1337_TCP_PORT
|
||||
$ALIAS_PORT_1337_TCP_ADDR
|
||||
```
|
||||
|
||||
И вы можете подключиться к нему таким образом.
|
||||
|
||||
Чтобы удалить ссылки, используйте `docker rm --link`.
|
||||
|
||||
Как правило, связи между контейнерами Docker является подмножеством «обнаружения сервисов», что является большой проблемой, если вы планируете использовать Docker в производстве. Пожалуйста, прочитайте [The Docker Ecosystem: Service Discovery and Distributed Configuration Stores](https://www.digitalocean.com/community/tutorials/the-docker-ecosystem-service-discovery-and-distributed-configuration-stores) или большей информации.
|
||||
|
||||
## Тома
|
||||
|
||||
Тома Docker - [свободно плавающие файловые системы](https://docs.docker.com/engine/tutorials/dockervolumes/).Они не обязательно должны быть подключены к конкретному контейнеру. Вы должны использовать тома, примонированные из [контейнеров только для данных](https://medium.com/@ramangupta/why-docker-data-containers-are-good-589b3c6c749e) для переносимости.
|
||||
|
||||
### Жизненный цикл
|
||||
|
||||
* [`docker volume create`](https://docs.docker.com/engine/reference/commandline/volume_create/)
|
||||
* [`docker volume rm`](https://docs.docker.com/engine/reference/commandline/volume_rm/)
|
||||
|
||||
### Info
|
||||
|
||||
* [`docker volume ls`](https://docs.docker.com/engine/reference/commandline/volume_ls/)
|
||||
* [`docker volume inspect`](https://docs.docker.com/engine/reference/commandline/volume_inspect/)
|
||||
|
||||
Тома полезны в ситуациях, когда вы не можете использовать ссылки (которые только TCP / IP). Например, если вам нужно, чтобы два экземпляра docker обменивались данными, оставив результат в файловой системе.
|
||||
|
||||
Вы можете смонтировать их в нескольких контейнерах докеров сразу, используя `docker run --volumes-from`.
|
||||
|
||||
Поскольку тома являются изолированными файловыми системами, они часто используются для хранения состояния из вычислений между переходными контейнерами. То есть, у вас может быть контейнер без учета состояния и переходный процесс, запускаемый из скрипта, сдуть его, а затем добавить второй экземпляр переходного контейнера, откуда он остановился.
|
||||
|
||||
|
||||
См. [Расширенные тома](http://crosbymichael.com/advanced-docker-volumes.html) для больших подробностей. Container42 is [also helpful](http://container42.com/2014/11/03/docker-indepth-volumes/).
|
||||
|
||||
You can [map MacOS host directories as docker volumes](https://docs.docker.com/engine/tutorials/dockervolumes/#mount-a-host-directory-as-a-data-volume):
|
||||
|
||||
```
|
||||
docker run -v /Users/wsargent/myapp/src:/src
|
||||
```
|
||||
|
||||
You can use remote NFS volumes if you're [feeling brave](https://docs.docker.com/engine/tutorials/dockervolumes/#/mount-a-shared-storage-volume-as-a-data-volume).
|
||||
|
||||
You may also consider running data-only containers as described [here](http://container42.com/2013/12/16/persistent-volumes-with-docker-container-as-volume-pattern/) to provide some data portability.
|
||||
|
||||
[Вы можете [сопоставлять каталоги хостов MacOS в виде докеровских томов]](#volumes-can-be-files)
|
||||
|
||||
|
||||
## Открытие портов
|
||||
|
||||
|
||||
Exposing incoming ports through the host container is [fiddly but doable](https://docs.docker.com/engine/reference/run/#expose-incoming-ports).
|
||||
|
||||
This is done by mapping the container port to the host port (only using localhost interface) using `-p`:
|
||||
|
||||
```
|
||||
docker run -p 127.0.0.1:$HOSTPORT:$CONTAINERPORT --name CONTAINER -t someimage
|
||||
```
|
||||
|
||||
You can tell Docker that the container listens on the specified network ports at runtime by using [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose):
|
||||
|
||||
```
|
||||
EXPOSE <CONTAINERPORT>
|
||||
```
|
||||
|
||||
Note that EXPOSE does not expose the port itself -- only `-p` will do that. To expose the container's port on your localhost's port:
|
||||
|
||||
```
|
||||
iptables -t nat -A DOCKER -p tcp --dport <LOCALHOSTPORT> -j DNAT --to-destination <CONTAINERIP>:<PORT>
|
||||
```
|
||||
|
||||
If you're running Docker in Virtualbox, you then need to forward the port there as well, using [forwarded_port](https://docs.vagrantup.com/v2/networking/forwarded_ports.html). Define a range of ports in your Vagrantfile like this so you can dynamically map them:
|
||||
|
||||
```
|
||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
...
|
||||
|
||||
(49000..49900).each do |port|
|
||||
config.vm.network :forwarded_port, :host => port, :guest => port
|
||||
end
|
||||
|
||||
...
|
||||
end
|
||||
```
|
||||
|
||||
If you forget what you mapped the port to on the host container, use `docker port` to show it:
|
||||
|
||||
```
|
||||
docker port CONTAINER $CONTAINERPORT
|
||||
```
|
||||
|
||||
## Лучша практика
|
||||
|
||||
This is where general Docker best practices and war stories go:
|
||||
|
||||
* [The Rabbit Hole of Using Docker in Automated Tests](http://gregoryszorc.com/blog/2014/10/16/the-rabbit-hole-of-using-docker-in-automated-tests/)
|
||||
* [Bridget Kromhout](https://twitter.com/bridgetkromhout) has a useful blog post on [running Docker in production](http://sysadvent.blogspot.co.uk/2014/12/day-1-docker-in-production-reality-not.html) at Dramafever.
|
||||
* There's also a best practices [blog post](http://developers.lyst.com/devops/2014/12/08/docker/) from Lyst.
|
||||
* [Building a Development Environment With Docker](https://tersesystems.com/2013/11/20/building-a-development-environment-with-docker/)
|
||||
* [Discourse in a Docker Container](https://samsaffron.com/archive/2013/11/07/discourse-in-a-docker-container)
|
||||
|
||||
## Безопасность
|
||||
|
||||
This is where security tips about Docker go. The Docker [security](https://docs.docker.com/engine/security/security/) page goes into more detail.
|
||||
|
||||
First things first: Docker runs as root. If you are in the `docker` group, you effectively [have root access](http://reventlov.com/advisories/using-the-docker-command-to-root-the-host). If you expose the docker unix socket to a container, you are giving the container [root access to the host](https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container/).
|
||||
|
||||
Docker should not be your only defense. You should secure and harden it.
|
||||
|
||||
For an understanding of what containers leave exposed, you should read [Understanding and Hardening Linux Containers](https://www.nccgroup.trust/globalassets/our-research/us/whitepapers/2016/april/ncc_group_understanding_hardening_linux_containers-1-1.pdf) by [Aaron Grattafiori](https://twitter.com/dyn___). This is a complete and comprehensive guide to the issues involved with containers, with a plethora of links and footnotes leading on to yet more useful content. The security tips following are useful if you've already hardened containers in the past, but are not a substitute for understanding.
|
||||
|
||||
### Советы по безопасности
|
||||
|
||||
For greatest security, you want to run Docker inside a virtual machine. This is straight from the Docker Security Team Lead -- [slides](http://www.slideshare.net/jpetazzo/linux-containers-lxc-docker-and-security) / [notes](http://www.projectatomic.io/blog/2014/08/is-it-safe-a-look-at-docker-and-security-from-linuxcon/). Then, run with AppArmor / seccomp / SELinux / grsec etc to [limit the container permissions](http://linux-audit.com/docker-security-best-practices-for-your-vessel-and-containers/). See the [Docker 1.10 security features](https://blog.docker.com/2016/02/docker-engine-1-10-security/) for more details.
|
||||
|
||||
Docker image ids are [sensitive information](https://medium.com/@quayio/your-docker-image-ids-are-secrets-and-its-time-you-treated-them-that-way-f55e9f14c1a4) and should not be exposed to the outside world. Treat them like passwords.
|
||||
|
||||
See the [Docker Security Cheat Sheet](https://github.com/konstruktoid/Docker/blob/master/Security/CheatSheet.adoc) by [Thomas Sjögren](https://github.com/konstruktoid): some good stuff about container hardening in there.
|
||||
|
||||
Check out the [docker bench security script](https://github.com/docker/docker-bench-security), download the [white papers](https://blog.docker.com/2015/05/understanding-docker-security-and-best-practices/) and subscribe to the [mailing lists](https://www.docker.com/docker-security) (unfortunately Docker does not have a unique mailing list, only dev / user).
|
||||
|
||||
You should start off by using a kernel with unstable patches for grsecurity / pax compiled in, such as [Alpine Linux](https://en.wikipedia.org/wiki/Alpine_Linux). If you are using grsecurity in production, you should spring for [commercial support](https://grsecurity.net/business_support.php) for the [stable patches](https://grsecurity.net/announce.php), same as you would do for RedHat. It's $200 a month, which is nothing to your devops budget.
|
||||
|
||||
Since docker 1.11 you can easily limit the number of active processes running inside a container to prevent fork bombs. This requires a linux kernel >= 4.3 with CGROUP_PIDS=y to be in the kernel configuration.
|
||||
|
||||
```
|
||||
docker run --pids-limit=64
|
||||
```
|
||||
|
||||
Also available since docker 1.11 is the ability to prevent processes from gaining new privileges. This feature have been in the linux kernel since version 3.5. You can read more about it in [this](http://www.projectatomic.io/blog/2016/03/no-new-privs-docker/) blog post.
|
||||
|
||||
```
|
||||
docker run --security-opt=no-new-privileges
|
||||
```
|
||||
|
||||
From the [Docker Security Cheat Sheet](http://container-solutions.com/content/uploads/2015/06/15.06.15_DockerCheatSheet_A2.pdf) (it's in PDF which makes it hard to use, so copying below) by [Container Solutions](http://container-solutions.com/is-docker-safe-for-production/):
|
||||
|
||||
Отключите межпроцессное взаимодействие с:
|
||||
|
||||
```
|
||||
docker -d --icc=false --iptables
|
||||
```
|
||||
|
||||
Установите контейнер только для чтения:
|
||||
|
||||
```
|
||||
docker run --read-only
|
||||
```
|
||||
|
||||
Проверьте образы с помощью хэш-функции:
|
||||
|
||||
```
|
||||
docker pull debian@sha256:a25306f3850e1bd44541976aa7b5fd0a29be
|
||||
```
|
||||
|
||||
Установить тома только для чтения:
|
||||
|
||||
```
|
||||
docker run -v $(pwd)/secrets:/secrets:ro debian
|
||||
```
|
||||
|
||||
Определите и запустите пользователя в вашем файле Docker, чтобы вы не запускались как root внутри контейнера:
|
||||
|
||||
```
|
||||
RUN groupadd -r user && useradd -r -g user user
|
||||
USER user
|
||||
```
|
||||
|
||||
### User Namespaces
|
||||
|
||||
There's also work on [user namespaces](https://s3hh.wordpress.com/2013/07/19/creating-and-using-containers-without-privilege/) -- it is in 1.10 but is not enabled by default.
|
||||
|
||||
To enable user namespaces ("remap the userns") in Ubuntu 15.10, [follow the blog example](https://raesene.github.io/blog/2016/02/04/Docker-User-Namespaces/).
|
||||
|
||||
### Security Videos
|
||||
|
||||
* [Using Docker Safely](https://youtu.be/04LOuMgNj9U)
|
||||
* [Securing your applications using Docker](https://youtu.be/KmxOXmPhZbk)
|
||||
* [Container security: Do containers actually contain?](https://youtu.be/a9lE9Urr6AQ)
|
||||
* [Linux Containers: Future or Fantasy?](https://www.youtube.com/watch?v=iN6QbszB1R8)
|
||||
|
||||
### Security Roadmap
|
||||
|
||||
В дорожной карте docker говорится о [поддержке seccomp]https://github.com/docker/docker/blob/master/ROADMAP.md#11-security).
|
||||
Существует генератор политики AppArmor, называемый [bane](https://github.com/jfrazelle/bane), и они работают над [профилями безопасности](https://github.com/docker/docker/issues/17142).
|
||||
|
||||
## Советы
|
||||
|
||||
Источники:
|
||||
|
||||
* [15 Советы docker за 5 минут](http://sssslide.com/speakerdeck.com/bmorearty/15-docker-tips-in-5-minutes)
|
||||
* [CodeFresh Everyday Hacks Docker](https://codefresh.io/blog/everyday-hacks-docker/)
|
||||
|
||||
### Prune
|
||||
|
||||
Новые [Команды управления данными](https://github.com/docker/docker/pull/26108) Появились с Docker 1.13:
|
||||
|
||||
* `docker system prune`
|
||||
* `docker volume prune`
|
||||
* `docker network prune`
|
||||
* `docker container prune`
|
||||
* `docker image prune`
|
||||
|
||||
### df
|
||||
|
||||
`docker system df` presents a summary of the space currently used by different docker objects.
|
||||
|
||||
### Контейнер для докеров Heredoc
|
||||
|
||||
```
|
||||
docker build -t htop - << EOF
|
||||
FROM alpine
|
||||
RUN apk --no-cache add htop
|
||||
EOF
|
||||
```
|
||||
|
||||
### Последние идентификаторы
|
||||
|
||||
```
|
||||
alias dl='docker ps -l -q'
|
||||
docker run ubuntu echo hello world
|
||||
docker commit $(dl) helloworld
|
||||
```
|
||||
|
||||
### Commit с командой (требуется Dockerfile)
|
||||
|
||||
```
|
||||
docker commit -run='{"Cmd":["postgres", "-too -many -opts"]}' $(dl) postgres
|
||||
```
|
||||
|
||||
### Получить IP-адрес
|
||||
|
||||
```
|
||||
docker inspect $(dl) | grep -wm1 IPAddress | cut -d '"' -f 4
|
||||
```
|
||||
|
||||
или установите [jq](https://stedolan.github.io/jq/):
|
||||
|
||||
```
|
||||
docker inspect $(dl) | jq -r '.[0].NetworkSettings.IPAddress'
|
||||
```
|
||||
|
||||
или используя [go шаблон](https://docs.docker.com/engine/reference/commandline/inspect):
|
||||
|
||||
```
|
||||
docker inspect -f '{{ .NetworkSettings.IPAddress }}' <container_name>
|
||||
```
|
||||
|
||||
или при создании обрзов из файла Docker, когда вы хотите передать аргумент построения:
|
||||
|
||||
```
|
||||
DOCKER_HOST_IP=`ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1`
|
||||
echo DOCKER_HOST_IP = $DOCKER_HOST_IP
|
||||
docker build \
|
||||
--build-arg ARTIFACTORY_ADDRESS=$DOCKER_HOST_IP
|
||||
-t sometag \
|
||||
some-directory/
|
||||
```
|
||||
|
||||
### Получить сопоставление портов
|
||||
|
||||
```
|
||||
docker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' <containername>
|
||||
```
|
||||
|
||||
### Поиск контейнеров путем регулярного выражения
|
||||
|
||||
```
|
||||
for i in $(docker ps -a | grep "REGEXP_PATTERN" | cut -f1 -d" "); do echo $i; done
|
||||
```
|
||||
|
||||
### Получить настройки среды
|
||||
|
||||
```
|
||||
docker run --rm ubuntu env
|
||||
```
|
||||
|
||||
### Убить запущенные контейнеры
|
||||
|
||||
```
|
||||
docker kill $(docker ps -q)
|
||||
```
|
||||
|
||||
### Удалите все контейнеры (принудительные или запущенные контейнеры)
|
||||
|
||||
```
|
||||
docker rm -f $(docker ps -qa)
|
||||
```
|
||||
|
||||
### Удалить старые контейнеры
|
||||
|
||||
```
|
||||
docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm
|
||||
```
|
||||
|
||||
### Удалить остановленные контейнеры
|
||||
|
||||
```
|
||||
docker rm -v $(docker ps -a -q -f status=exited)
|
||||
```
|
||||
|
||||
### Удаление контейнеров после остановки
|
||||
|
||||
```
|
||||
docker stop $(docker ps -aq) && docker rm -v $(docker ps -aq)
|
||||
```
|
||||
|
||||
### Удалить оборванные образы
|
||||
|
||||
```
|
||||
docker rmi $(docker images -q -f dangling=true)
|
||||
```
|
||||
|
||||
### Удалить все образы
|
||||
|
||||
```
|
||||
docker rmi $(docker images -q)
|
||||
```
|
||||
|
||||
### Удалить оборванные тома
|
||||
|
||||
Начиная с Docker 1.9:
|
||||
|
||||
```
|
||||
docker volume rm $(docker volume ls -q -f dangling=true)
|
||||
```
|
||||
|
||||
In 1.9.0, the filter `dangling=false` does _not_ work - it is ignored and will list all volumes.
|
||||
В 1.9.0, фильтр `dangling=false` _не_ работает - он игнорируется и будет перечислять все тома.
|
||||
|
||||
### Показать зависимости образов
|
||||
|
||||
```
|
||||
docker images -viz | dot -Tpng -o docker.png
|
||||
```
|
||||
|
||||
### Похудение Docker контейнеров
|
||||
|
||||
- Очистка APT на уровне RUN
|
||||
|
||||
Это должно быть сделано в том же слое, что и другие команды apt.
|
||||
В противном случае предыдущие слои по-прежнему сохраняют исходную информацию, и ваши образы будут по-прежнему жирными.
|
||||
|
||||
```
|
||||
RUN {apt commands} \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
```
|
||||
|
||||
- Сгладить образ
|
||||
```
|
||||
ID=$(docker run -d image-name /bin/bash)
|
||||
docker export $ID | docker import – flat-image-name
|
||||
```
|
||||
|
||||
- Для резервного копирования
|
||||
```
|
||||
ID=$(docker run -d image-name /bin/bash)
|
||||
(docker export $ID | gzip -c > image.tgz)
|
||||
gzip -dc image.tgz | docker import - flat-image-name
|
||||
```
|
||||
|
||||
### Мониторинг использования ресурсов системы для запуска контейнеров
|
||||
|
||||
Чтобы проверить использование ЦП, памяти и сетевого ввода-вывода в одном контейнере, вы можете использовать:
|
||||
|
||||
```
|
||||
docker stats <container>
|
||||
```
|
||||
|
||||
Для всех контейнеров, перечисленных в id:
|
||||
|
||||
```
|
||||
docker stats $(docker ps -q)
|
||||
```
|
||||
|
||||
Для всех контейнеров, перечисленных по имени:
|
||||
|
||||
```
|
||||
docker stats $(docker ps --format '{{.Names}}')
|
||||
```
|
||||
|
||||
Для всех контейнеров, перечисленных по образам:
|
||||
|
||||
```
|
||||
docker ps -a -f ancestor=ubuntu
|
||||
```
|
||||
|
||||
Удалить все непомеченные образы
|
||||
```
|
||||
docker rmi $(docker images | grep “^” | awk '{split($0,a," "); print a[3]}')
|
||||
```
|
||||
|
||||
Удалить контейнер с помощью регулярного выражения
|
||||
```
|
||||
docker ps -a | grep wildfly | awk '{print $1}' | xargs docker rm -f
|
||||
```
|
||||
Удалить все завершенные контейнеры
|
||||
```
|
||||
docker rm -f $(docker ps -a | grep Exit | awk '{ print $1 }')
|
||||
```
|
||||
|
||||
### Томы могут быть файлами
|
||||
|
||||
Имейте в виду, что вы можете монтировать файлы в виде томов. Например, вы можете ввести файл конфигурации следующим образом:
|
||||
|
||||
``` bash
|
||||
# копировать файл из контейнера
|
||||
docker run --rm httpd cat /usr/local/apache2/conf/httpd.conf > httpd.conf
|
||||
|
||||
# редактировать файл
|
||||
vim httpd.conf
|
||||
|
||||
# запускать контейнер с измененной конфигурацией
|
||||
docker run --rm -ti -v "$PWD/httpd.conf:/usr/local/apache2/conf/httpd.conf:ro" -p "80:80" httpd
|
||||
```
|
||||
|
||||
## Содействие
|
||||
|
||||
Вот как внести свой вклад в этот чит-лист.
|
||||
|
||||
### Открыть README.md
|
||||
|
||||
Click [README.md](https://github.com/wsargent/docker-cheat-sheet/blob/master/README.md) <-- this link
|
||||
|
||||

|
||||
|
||||
### Отредактировать страницу
|
||||
|
||||

|
||||
|
||||
### Внести изменения и зафиксировать
|
||||
|
||||

|
||||
|
||||

|
||||
819
zh-cn/README.md
819
zh-cn/README.md
|
|
@ -1,819 +0,0 @@
|
|||
# Docker Cheat Sheet
|
||||
|
||||
**想要一起来完善这份速查表吗?参见[贡献手册](#贡献手册contributing)部分吧!**
|
||||
|
||||
> 译者注:以下部分链接需科学上网后使用。
|
||||
>
|
||||
> Due to GFW, varies links below could not be accessed in China Mainland.
|
||||
|
||||
## 目录
|
||||
|
||||
* [为何使用 Docker](#为何使用-docker)
|
||||
* [系统环境(Prerequisites)](#系统环境)
|
||||
* [安装(Installation)](#安装)
|
||||
* [容器(Containers)](#容器container)
|
||||
* [镜像(Images)](#镜像images)
|
||||
* [网络(Networks)](#网络networks)
|
||||
* [仓管中心和仓库(Registry & Repository)](#仓管中心和仓库registry--repository)
|
||||
* [Dockerfile](#dockerfile)
|
||||
* [层(Layers)](#层layers)
|
||||
* [链接(Links)](#链接links)
|
||||
* [卷标(Volumes)](#卷标volumes)
|
||||
* [暴露端口(Exposing Ports)](#暴露端口exposing-ports)
|
||||
* [最佳实践(Best Practices)](#最佳实践)
|
||||
* [安全(security)](#安全security)
|
||||
* [小贴士(Tips)](#小贴士)
|
||||
* [贡献手册(Contributing)](#贡献手册contributing)
|
||||
|
||||
## 为何使用 Docker
|
||||
|
||||
「通过 Docker,开发者可以使用任何语言任何工具创建任何应用。“Dockerized” 的应用是完全可移植的,能在任何地方运行 - 不管是同事的 OS X 和 Windows 笔记本,或是在云端运行的 Ubuntu QA 服务,还是在虚拟机运行的 Red Hat 产品数据中心。
|
||||
|
||||
Docker Hub 上有 13000+ 的应用,开发者可以从中选取一个进行快速扩展开发。Docker 跟踪管理变更和依赖关系,让系统管理员能更容易理解开发人员是如何让应用运转起来的。而开发者可以通过 Docker Hub 的共有/私有仓库,构建他们的自动化编译,与其他合作者共享成果。
|
||||
|
||||
Docker 帮助开发者更快地构建和发布高质量的应用。」—— [什么是 Docker](https://www.docker.com/what-docker/#copy1)
|
||||
|
||||
## 系统环境
|
||||
|
||||
我用的是 [Oh My Zsh](https://github.com/robbyrussell/oh-my-zsh) 和 [Docker 插件](https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins#docker),它可以自动补全 Docker 命令。你的环境可能有所不同。
|
||||
|
||||
### Linux
|
||||
|
||||
Docker 对于 Linux 内核版本的 [最低要求](https://docs.docker.com/engine/installation/binaries/#check-kernel-dependencies) 为 `3.10.x`。
|
||||
|
||||
### MacOS
|
||||
|
||||
10.8「Mountain Lion」或更新版本。
|
||||
|
||||
### 检查版本
|
||||
|
||||
时刻关注你当前正在使用的 Docker 版本是十分重要的,这能够帮助你了解可用的特性。同时,可以让你在查找镜像时选择使用的版本。接下来让我们看看如何操作。
|
||||
|
||||
* [`docker version`](https://docs.docker.com/engine/reference/commandline/version/) 查看你正在运行的 Docker 版本。
|
||||
|
||||
获取 Docker 服务版本:
|
||||
|
||||
```
|
||||
$ docker version --format '{{.Server.Version}}'
|
||||
|
||||
1.8.0
|
||||
```
|
||||
|
||||
你也可以输出原始的 JSON 数据:
|
||||
|
||||
```
|
||||
$ docker version --format '{{json .}}'
|
||||
|
||||
{"Client":{"Version":"1.8.0","ApiVersion":"1.20","GitCommit":"f5bae0a","GoVersion":"go1.4.2","Os":"linux","Arch":"am"}
|
||||
```
|
||||
|
||||
## 安装
|
||||
|
||||
### Linux
|
||||
|
||||
Docker 官方提供了快速、易用的安装脚本:
|
||||
|
||||
```
|
||||
curl -sSL https://get.docker.com/ | sh
|
||||
```
|
||||
|
||||
如果你不想执行一个不明不白的 Shell 脚本,那么请看 [安装说明](https://docs.docker.com/engine/installation/linux/),选择你在用的发行版本。
|
||||
|
||||
如果你是一个 Docker 超新手,那么你应当先去看看 [系列教程](https://docs.docker.com/engine/getstarted/)。
|
||||
|
||||
### macOS
|
||||
|
||||
下载并安装 [Docker Community Edition](https://www.docker.com/community-edition)。如果你在使用 Homebrew-Cask,只需在命令行输入 `brew install --cask docker` 即可。下载安装 [Docker Toolbox](https://docs.docker.com/toolbox/overview/) 亦可。[Docker For Mac](https://docs.docker.com/docker-for-mac/) 很赞,但是它的安装过程与 VirtualBox 不太一样。详情请查阅 [比较](https://docs.docker.com/docker-for-mac/docker-toolbox/)。
|
||||
|
||||
> **注意**:Docker Toolbox 已经过时。你应当使用 Docker Community Edition,详见 [Docker Toolbox](https://docs.docker.com/toolbox/overview/)
|
||||
|
||||
安装好 Docker Community Edition 后,点击 Launchpad 内的 Docker 图标。接着即可启动容器了:
|
||||
|
||||
```
|
||||
docker run hello-world
|
||||
```
|
||||
|
||||
好了,现在你有了一个运行中的 Docker 容器了。
|
||||
|
||||
## 容器(Container)
|
||||
|
||||
[关于 Docker 进程隔离的基础](http://etherealmind.com/basics-docker-containers-hypervisors-coreos/)。容器 (Container) 之于虚拟机 (Virtual Machine) 就好比线程之于进程。或者你可以把他们想成是「吃了类固醇的 chroots」。
|
||||
|
||||
### 生命周期
|
||||
|
||||
* [`docker create`](https://docs.docker.com/engine/reference/commandline/create) 创建容器但不启动它。
|
||||
* [`docker rename`](https://docs.docker.com/engine/reference/commandline/rename/) 用于重命名容器。
|
||||
* [`docker run`](https://docs.docker.com/engine/reference/commandline/run) 一键创建并同时启动该容器。
|
||||
* [`docker rm`](https://docs.docker.com/engine/reference/commandline/rm) 删除容器。
|
||||
* [`docker update`](https://docs.docker.com/engine/reference/commandline/update/) 调整容器的资源限制。
|
||||
|
||||
通常情况下,不使用任何命令行选项启动一个容器,该容器将会立即启动并停止。若需保持其运行,你可以使用 `docker run -td container_id` 命令。选项 `-t` 表示分配一个 pseudo-TTY 会话,`-d` 表示自动将容器与终端分离(也就是说在后台运行容器,并输出容器 ID)。
|
||||
|
||||
如果你需要一个临时容器,可使用 `docker run --rm` 会在容器停止之后删除它。
|
||||
|
||||
如果你需要映射宿主机 (host) 的目录到 Docker 容器内,可使用 `docker run -v $HOSTDIR:$DOCKERDIR`。详见 [卷标(Volumes)](#卷标volumes) 一节。
|
||||
|
||||
如果你想同时删除与容器相关联的卷标,那么在删除容器的时候必须包含 `-v` 选项,像这样 `docker rm -v`。
|
||||
|
||||
从 Docker 1.10 起,其内置一套各容器独立的 [日志引擎](https://docs.docker.com/engine/admin/logging/overview/),每个容器可以独立使用。你可以使用 `docker run --log-driver=syslog` 来自定义日志引擎(例如以上的 `syslog`)。
|
||||
|
||||
### 启动和停止
|
||||
|
||||
* [`docker start`](https://docs.docker.com/engine/reference/commandline/start) 启动已存在的容器。
|
||||
* [`docker stop`](https://docs.docker.com/engine/reference/commandline/stop) 停止运行中的容器。
|
||||
* [`docker restart`](https://docs.docker.com/engine/reference/commandline/restart) 重启容器。
|
||||
* [`docker pause`](https://docs.docker.com/engine/reference/commandline/pause/) 暂停运行中的容器,将其「冻结」在当前状态。
|
||||
* [`docker unpause`](https://docs.docker.com/engine/reference/commandline/unpause/) 结束容器暂停状态。
|
||||
* [`docker wait`](https://docs.docker.com/engine/reference/commandline/wait) 阻塞地等待某个运行中的容器直到停止。
|
||||
* [`docker kill`](https://docs.docker.com/engine/reference/commandline/kill) 向运行中的容器发送 SIGKILL 指令。
|
||||
* [`docker attach`](https://docs.docker.com/engine/reference/commandline/attach) 连接到运行中的容器。
|
||||
|
||||
如果你想将容器的端口 (ports) 暴露至宿主机,请见 [暴露端口](#暴露端口exposing-ports) 一节。
|
||||
|
||||
关于 Docker 实例崩溃后的重启策略,详见 [本文](http://container42.com/2014/09/30/docker-restart-policies/)。
|
||||
|
||||
#### CPU 限制
|
||||
|
||||
你可以限制 CPU 资源占用,无论是指定百分比,或是特定核心数。
|
||||
|
||||
例如,你可以设置 [`cpu-shares`](https://docs.docker.com/engine/reference/run/#/cpu-share-constraint)。该配置看起来有点奇怪 -- 1024 表示 100% CPU,因此如果你希望容器使用所有 CPU 内核的 50%,应将其设置为 512:
|
||||
|
||||
```
|
||||
docker run -ti --c 512 agileek/cpuset-test
|
||||
```
|
||||
|
||||
更多信息请参阅 <https://goldmann.pl/blog/2014/09/11/resource-management-in-docker/#_cpu>。
|
||||
|
||||
通过 [`cpuset-cpus`](https://docs.docker.com/engine/reference/run/#/cpuset-constraint) 可使用特定 CPU 内核。
|
||||
|
||||
```
|
||||
docker run -ti --cpuset-cpus=0,4,6 agileek/cpuset-test
|
||||
```
|
||||
|
||||
请参阅 <https://agileek.github.io/docker/2014/08/06/docker-cpuset/> 获取更多细节以及一些不错的视频。
|
||||
|
||||
注意,Docker 在容器内仍然能够 **看到** 全部 CPU -- 它仅仅是不使用全部而已。请参阅 <https://github.com/docker/docker/issues/20770> 获取更多细节。
|
||||
|
||||
#### 内存限制
|
||||
|
||||
同样,亦可给 Docker 设置 [内存限制](https://docs.docker.com/engine/reference/run/#/user-memory-constraints):
|
||||
|
||||
```
|
||||
docker run -it -m 300M ubuntu:14.04 /bin/bash
|
||||
```
|
||||
|
||||
#### 能力(Capabilities)
|
||||
|
||||
Linux 的 Capability 可以通过使用 `cap-add` 和 `cap-drop` 设置。请参阅 <https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities> 获取更多细节。这有助于提高安全性。
|
||||
|
||||
如需要挂载基于 FUSE 的文件系统,你需要结合 `--cap-add` 和 `--device` 使用:
|
||||
|
||||
```
|
||||
docker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs
|
||||
```
|
||||
|
||||
授予对某个设备的访问权限:
|
||||
|
||||
```
|
||||
docker run -it --device=/dev/ttyUSB0 debian bash
|
||||
```
|
||||
|
||||
授予对所有设备的访问权限:
|
||||
|
||||
```
|
||||
docker run -it --privileged -v /dev/bus/usb:/dev/bus/usb debian bash
|
||||
```
|
||||
|
||||
有关容器特权的更多信息请参阅 [本文](https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities)。
|
||||
|
||||
### 信息
|
||||
|
||||
* [`docker ps`](https://docs.docker.com/engine/reference/commandline/ps) 查看运行中的所有容器。
|
||||
* [`docker logs`](https://docs.docker.com/engine/reference/commandline/logs) 从容器中读取日志。(你也可以使用自定义日志驱动,不过在 1.10 中,它只支持 `json-file` 和 `journald`)。
|
||||
* [`docker inspect`](https://docs.docker.com/engine/reference/commandline/inspect) 查看某个容器的所有信息(包括 IP 地址)。
|
||||
* [`docker events`](https://docs.docker.com/engine/reference/commandline/events) 从容器中获取事件 (events)。
|
||||
* [`docker port`](https://docs.docker.com/engine/reference/commandline/port) 查看容器的公开端口。
|
||||
* [`docker top`](https://docs.docker.com/engine/reference/commandline/top) 查看容器中活动进程。
|
||||
* [`docker stats`](https://docs.docker.com/engine/reference/commandline/stats) 查看容器的资源使用量统计信息。
|
||||
* [`docker diff`](https://docs.docker.com/engine/reference/commandline/diff) 查看容器文件系统中存在改动的文件。
|
||||
|
||||
`docker ps -a` 将显示所有容器,包括运行中和已停止的。
|
||||
|
||||
`docker stats --all` 同样将显示所有容器,默认仅显示运行中的容器。
|
||||
|
||||
### 导入 / 导出
|
||||
|
||||
* [`docker cp`](https://docs.docker.com/engine/reference/commandline/cp) 在容器和本地文件系统之间复制文件或目录。
|
||||
* [`docker export`](https://docs.docker.com/engine/reference/commandline/export) 将容器的文件系统打包为归档文件流 (tarball archive stream) 并输出至标准输出 (STDOUT)。
|
||||
|
||||
### 执行命令
|
||||
|
||||
* [`docker exec`](https://docs.docker.com/engine/reference/commandline/exec) 在容器内执行命令。
|
||||
|
||||
例如,进入正在运行的 `foo` 容器,并连接 (attach) 到一个新的 Shell 进程:`docker exec -it foo /bin/bash`。
|
||||
|
||||
## 镜像(Images)
|
||||
|
||||
镜像是 [Docker 容器的模板](https://docs.docker.com/engine/understanding-docker/#how-does-a-docker-image-work)。
|
||||
|
||||
### 生命周期
|
||||
|
||||
* [`docker images`](https://docs.docker.com/engine/reference/commandline/images) 查看所有镜像。
|
||||
* [`docker import`](https://docs.docker.com/engine/reference/commandline/import) 从归档文件创建镜像。
|
||||
* [`docker build`](https://docs.docker.com/engine/reference/commandline/build) 从 Dockerfile 创建镜像。
|
||||
* [`docker commit`](https://docs.docker.com/engine/reference/commandline/commit) 为容器创建镜像,如果容器正在运行则会临时暂停。
|
||||
* [`docker rmi`](https://docs.docker.com/engine/reference/commandline/rmi) 删除镜像。
|
||||
* [`docker load`](https://docs.docker.com/engine/reference/commandline/load) 从标准输入 (STDIN) 加载归档包 (tar archive) 作为镜像,包括镜像本身和标签 (tags, 0.7 起)。
|
||||
* [`docker save`](https://docs.docker.com/engine/reference/commandline/save) 将镜像打包为归档包,并输出至标准输出 (STDOUT),包括所有的父层、标签和版本 (parent layers, tags, versions, 0.7 起)。
|
||||
|
||||
### 其它信息
|
||||
|
||||
* [`docker history`](https://docs.docker.com/engine/reference/commandline/history) 查看镜像的历史记录。
|
||||
* [`docker tag`](https://docs.docker.com/engine/reference/commandline/tag) 给镜像打标签命名(本地或者仓库均可)。
|
||||
|
||||
### 清理
|
||||
|
||||
虽然你可以用 `docker rmi` 命令来删除指定的镜像,不过有个名为 [docker-gc](https://github.com/spotify/docker-gc) 的工具,它可以以一种安全的方式,清理掉那些不再被任何容器使用的镜像。Docker 1.13 起,使用 `docker image prune` 亦可删除未使用的镜像。参见 [清理](#清理)。
|
||||
|
||||
### 加载 / 保存镜像
|
||||
|
||||
从文件中加载镜像:
|
||||
```
|
||||
docker load < my_image.tar.gz
|
||||
```
|
||||
|
||||
保存既有镜像:
|
||||
```
|
||||
docker save my_image:my_tag | gzip > my_image.tar.gz
|
||||
```
|
||||
|
||||
### 导入 / 导出容器
|
||||
|
||||
从文件中导入容器镜像:
|
||||
```
|
||||
cat my_container.tar.gz | docker import - my_image:my_tag
|
||||
```
|
||||
|
||||
导出既有容器:
|
||||
```
|
||||
docker export my_container | gzip > my_container.tar.gz
|
||||
```
|
||||
|
||||
### 加载已保存的镜像 与 导入已导出为镜像的容器 的不同
|
||||
|
||||
通过 `load` 命令来加载镜像,会创建一个新的镜像,并继承原镜像的所有历史。
|
||||
通过 `import` 将容器作为镜像导入,也会创建一个新的镜像,但并不包含原镜像的历史,因此会比使用 `load` 方式生成的镜像更小。
|
||||
|
||||
## 网络(Networks)
|
||||
|
||||
Docker 具备 [网络](https://docs.docker.com/engine/userguide/networking/) 功能。我并不是很了解它,所以这是一个扩展本文的好地方。文档 [使用网络](https://docs.docker.com/engine/userguide/networking/work-with-networks/) 指出,这是一种无需暴露端口即可实现 Docker 容器间通信的好方法。
|
||||
|
||||
### 生命周期
|
||||
|
||||
* [`docker network create`](https://docs.docker.com/engine/reference/commandline/network_create/)
|
||||
* [`docker network rm`](https://docs.docker.com/engine/reference/commandline/network_rm/)
|
||||
|
||||
### 其它信息
|
||||
|
||||
* [`docker network ls`](https://docs.docker.com/engine/reference/commandline/network_ls/)
|
||||
* [`docker network inspect`](https://docs.docker.com/engine/reference/commandline/network_inspect/)
|
||||
|
||||
### 建立连接
|
||||
|
||||
* [`docker network connect`](https://docs.docker.com/engine/reference/commandline/network_connect/)
|
||||
* [`docker network disconnect`](https://docs.docker.com/engine/reference/commandline/network_disconnect/)
|
||||
|
||||
你可以 [为容器指定 IP 地址](https://blog.jessfraz.com/post/ips-for-all-the-things/):
|
||||
|
||||
```
|
||||
# 使用你自己的子网和网关创建一个桥接网络
|
||||
docker network create --subnet 203.0.113.0/24 --gateway 203.0.113.254 iptastic
|
||||
|
||||
# 基于以上创建的网络,运行一个 Nginx 容器并指定 IP
|
||||
$ docker run --rm -it --net iptastic --ip 203.0.113.2 nginx
|
||||
|
||||
# 在其他地方使用 CURL 访问这个 IP(假设该 IP 为公网)
|
||||
$ curl 203.0.113.2
|
||||
```
|
||||
|
||||
## 仓管中心和仓库(Registry & Repository)
|
||||
|
||||
仓库 (repository) 是 *被托管(hosted)* 的已命名镜像 (tagged images) 的集合,这组镜像用于构建容器文件系统。
|
||||
|
||||
仓管中心 (registry) 则是 *托管服务(host)* -- 用于存储仓库并提供 HTTP API,以便 [管理仓库的上传和下载](https://docs.docker.com/engine/tutorials/dockerrepos/)。
|
||||
|
||||
Docker 官方托管着自己的 [仓管中心](https://hub.docker.com/),包含着数量众多的仓库。不过话虽如此,这个仓管中心 [并没有很好地验证镜像](https://titanous.com/posts/docker-insecurity),所以如果你担心安全问题的话,请尽量避免使用它。
|
||||
|
||||
* [`docker login`](https://docs.docker.com/engine/reference/commandline/login) 登入仓管中心。
|
||||
* [`docker logout`](https://docs.docker.com/engine/reference/commandline/logout) 登出仓管中心。
|
||||
* [`docker search`](https://docs.docker.com/engine/reference/commandline/search) 从仓管中心检索镜像。
|
||||
* [`docker pull`](https://docs.docker.com/engine/reference/commandline/pull) 从仓管中心拉取镜像到本地。
|
||||
* [`docker push`](https://docs.docker.com/engine/reference/commandline/push) 从本地推送镜像到仓管中心。
|
||||
|
||||
### 本地仓管中心
|
||||
|
||||
你可以使用 [docker distribution](https://github.com/docker/distribution) 项目搭建本地的仓管中心,详情参阅 [本地发布 (local deploy)](https://github.com/docker/docker.github.io/blob/master/registry/deploying.md) 的介绍。
|
||||
|
||||
科学上网后,也可以看看 [Google+ Group](https://groups.google.com/a/dockerproject.org/forum/#!forum/distribution)。
|
||||
|
||||
## Dockerfile
|
||||
|
||||
当你执行 `docker build` 时,Docker 将会根据 [配置文件](https://docs.docker.com/engine/reference/builder/) 启动 Docker 容器。远优于使用 `docker commit`。
|
||||
|
||||
以下是一些编写 Dockerfile 的常用编辑器,并链接到适配的语法高亮模块︰
|
||||
|
||||
* 如果你在使用 [jEdit](http://jedit.org),你可以使用我开发的 Dockerfile [语法高亮模块](https://github.com/wsargent/jedit-docker-mode)。
|
||||
* [Sublime Text 2](https://packagecontrol.io/packages/Dockerfile%20Syntax%20Highlighting)
|
||||
* [Atom](https://atom.io/packages/language-docker)
|
||||
* [Vim](https://github.com/ekalinin/Dockerfile.vim)
|
||||
* [Emacs](https://github.com/spotify/dockerfile-mode)
|
||||
* [TextMate](https://github.com/docker/docker/tree/master/contrib/syntax/textmate)
|
||||
* 更多信息请参阅 [Docker 遇上 IDE](https://domeide.github.io/)
|
||||
|
||||
### 指令
|
||||
|
||||
* [.dockerignore](https://docs.docker.com/engine/reference/builder/#dockerignore-file)
|
||||
* [FROM](https://docs.docker.com/engine/reference/builder/#from) 为其他指令设置基础镜像 (Base Image)。
|
||||
* [MAINTAINER (deprecated - use LABEL instead)](https://docs.docker.com/engine/reference/builder/#maintainer-deprecated) 为生成的镜像设置作者字段。
|
||||
* [RUN](https://docs.docker.com/engine/reference/builder/#run) 在当前镜像的基础上生成一个新层并执行命令。
|
||||
* [CMD](https://docs.docker.com/engine/reference/builder/#cmd) 设置容器默认执行命令。
|
||||
* [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose) 告知 Docker 容器在运行时所要监听的网络端口。注意:并没有实际上将端口设置为可访问。
|
||||
* [ENV](https://docs.docker.com/engine/reference/builder/#env) 设置环境变量。
|
||||
* [ADD](https://docs.docker.com/engine/reference/builder/#add) 将文件、目录或远程文件复制到容器中。缓存无效。请尽量用 `COPY` 代替 `ADD`。
|
||||
* [COPY](https://docs.docker.com/engine/reference/builder/#copy) 将文件或文件夹复制到容器中。注意:将使用 ROOT 用户复制文件,故无论 USER / WORKDIR 指令如何配置,你都需要手动修改其所有者(`chown`),`ADD` 也是一样。
|
||||
* [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint) 将容器设为可执行的。
|
||||
* [VOLUME](https://docs.docker.com/engine/reference/builder/#volume) 在容器内部创建挂载点 (mount point) 指向外部挂载的卷标或其他容器。
|
||||
* [USER](https://docs.docker.com/engine/reference/builder/#user) 设置随后执行 RUN / CMD / ENTRYPOINT 命令的用户名。
|
||||
* [WORKDIR](https://docs.docker.com/engine/reference/builder/#workdir) 设置工作目录 (working directory)。
|
||||
* [ARG](https://docs.docker.com/engine/reference/builder/#arg) 定义编译时 (build-time) 变量。
|
||||
* [ONBUILD](https://docs.docker.com/engine/reference/builder/#onbuild) 添加触发指令,当该镜像被作为其他镜像的基础镜像时该指令会被触发。
|
||||
* [STOPSIGNAL](https://docs.docker.com/engine/reference/builder/#stopsignal) 设置停止容器时,向容器内发送的系统调用信号 (system call signal)。
|
||||
* [LABEL](https://docs.docker.com/config/labels-custom-metadata/) 将键值对元数据 (key/value metadata) 应用到镜像、容器或是守护进程。
|
||||
|
||||
### 教程
|
||||
|
||||
* [Flux7's Dockerfile Tutorial](http://flux7.com/blogs/docker/docker-tutorial-series-part-3-automation-is-the-word-using-dockerfile/)
|
||||
|
||||
### 例子
|
||||
|
||||
* [Examples](https://docs.docker.com/engine/reference/builder/#dockerfile-examples)
|
||||
* [Best practices for writing Dockerfiles](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/)
|
||||
* [Michael Crosby](http://crosbymichael.com/) 还有更多的 [Dockerfiles best practices](http://crosbymichael.com/dockerfile-best-practices.html) / [take 2](http://crosbymichael.com/dockerfile-best-practices-take-2.html)
|
||||
* [Building Good Docker Images](http://jonathan.bergknoff.com/journal/building-good-docker-images) / [Building Better Docker Images](http://jonathan.bergknoff.com/journal/building-better-docker-images)
|
||||
* [Managing Container Configuration with Metadata](https://speakerdeck.com/garethr/managing-container-configuration-with-metadata)
|
||||
|
||||
## 层(Layers)
|
||||
|
||||
Docker 的版本化文件系统是基于层的。就像 [Git 的提交或文件变更系统](https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/) 一样。
|
||||
|
||||
## 链接(Links)
|
||||
|
||||
链接 (links) [通过 TCP/IP 端口](https://docs.docker.com/userguide/dockerlinks/) 实现 Docker 容器之间的通讯。[Atlassian](https://blogs.atlassian.com/2013/11/docker-all-the-things-at-atlassian-automation-and-wiring/) 展示了可用的例子。你还可以 [通过主机名 (hostname) 链接](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#/updating-the-etchosts-file)。
|
||||
|
||||
在某种意义上来说,该特性已经被 [自定义网络](https://docs.docker.com/network/) 所替代。
|
||||
|
||||
注意: 如果你希望容器之间**只**通过链接进行通讯,在启动 Docker 守护进程时,请使用 `-icc=false` 来禁用内部进程通讯。
|
||||
|
||||
假设你有一个名为 CONTAINER 的容器(通过 `docker run --name CONTAINER` 指定)并且在 Dockerfile 中,暴露了一个端口:
|
||||
|
||||
```
|
||||
EXPOSE 1337
|
||||
```
|
||||
|
||||
然后,我们创建另外一个名为 LINKED 的容器:
|
||||
|
||||
```
|
||||
docker run -d --link CONTAINER:ALIAS --name LINKED user/wordpress
|
||||
```
|
||||
|
||||
然后 CONTAINER 暴露的端口和别名将会以如下的环境变量出现在 LINKED 中:
|
||||
|
||||
```
|
||||
$ALIAS_PORT_1337_TCP_PORT
|
||||
$ALIAS_PORT_1337_TCP_ADDR
|
||||
```
|
||||
|
||||
那么你便可以通过这种方式来连接它了。
|
||||
|
||||
使用 `docker rm --link` 即可删除链接。
|
||||
|
||||
通常,Docker 容器(亦可理解为「服务」)之间的链接,是「服务发现」的一个子集。如果你打算在生产中大规模使用 Docker,这将是一个很大的问题。请参阅[The Docker Ecosystem: Service Discovery and Distributed Configuration Stores](https://www.digitalocean.com/community/tutorials/the-docker-ecosystem-service-discovery-and-distributed-configuration-stores) 获取更多信息。
|
||||
|
||||
## 卷标(Volumes)
|
||||
|
||||
Docker 的卷标 (volumes) 是 [独立的文件系统](https://docs.docker.com/engine/tutorials/dockervolumes/)。它们并非必须连接到特定的容器上。
|
||||
|
||||
### 生命周期
|
||||
|
||||
* [`docker volume create`](https://docs.docker.com/engine/reference/commandline/volume_create/)
|
||||
* [`docker volume rm`](https://docs.docker.com/engine/reference/commandline/volume_rm/)
|
||||
|
||||
### 信息
|
||||
|
||||
* [`docker volume ls`](https://docs.docker.com/engine/reference/commandline/volume_ls/)
|
||||
* [`docker volume inspect`](https://docs.docker.com/engine/reference/commandline/volume_inspect/)
|
||||
|
||||
卷标在不能使用链接(只有 TCP/IP)的情况下非常有用。例如,如果你有两个 Docker 实例需要通讯并在文件系统上留下记录。
|
||||
|
||||
你可以一次性将其挂载到多个 docker 容器上,通过 `docker run --volumes-from`。
|
||||
|
||||
因为卷标是独立的文件系统,它们通常被用于存储各容器之间的瞬时状态。也就是说,你可以配置一个无状态临时容器,关掉之后,当你有第二个这种临时容器实例的时候,你可以从上一次保存的状态继续执行。
|
||||
|
||||
查看 [卷标进阶](http://crosbymichael.com/advanced-docker-volumes.html) 来获取更多细节。[Container42](http://container42.com/2014/11/03/docker-indepth-volumes/) 非常有用。
|
||||
|
||||
你可以 [将宿主 MacOS 的文件夹映射为 Docker 卷标](https://docs.docker.com/engine/tutorials/dockervolumes/#mount-a-host-directory-as-a-data-volume):
|
||||
|
||||
```
|
||||
docker run -v /Users/wsargent/myapp/src:/src
|
||||
```
|
||||
|
||||
你也可以用远程 NFS 卷标,如果你觉得你 [有足够勇气](https://docs.docker.com/engine/tutorials/dockervolumes/#/mount-a-shared-storage-volume-as-a-data-volume)。
|
||||
|
||||
还可以考虑运行一个纯数据容器,像 [这里](http://container42.com/2013/12/16/persistent-volumes-with-docker-container-as-volume-pattern/) 所说的那样,提供可移植数据。
|
||||
|
||||
记得,[文件也可以被挂载为卷标](#将文件挂载为卷标)。
|
||||
|
||||
## 暴露端口(Exposing ports)
|
||||
|
||||
通过宿主容器暴露输入端口相当 [繁琐但有效的](https://docs.docker.com/engine/reference/run/#expose-incoming-ports)。
|
||||
|
||||
例如使用 `-p` 将容器端口映射到宿主端口上(只使用本地主机 (localhost) 接口):
|
||||
|
||||
```
|
||||
docker run -p 127.0.0.1:$HOSTPORT:$CONTAINERPORT --name CONTAINER -t someimage
|
||||
```
|
||||
|
||||
你可以使用 [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose) 告知 Docker,该容器在运行时监听指定的端口:
|
||||
|
||||
```
|
||||
EXPOSE <CONTAINERPORT>
|
||||
```
|
||||
|
||||
但是注意 EXPOSE 并不会直接暴露端口,你需要用参数 `-p` 。比如说你要在 localhost 上暴露容器的端口:
|
||||
|
||||
```
|
||||
iptables -t nat -A DOCKER -p tcp --dport <LOCALHOSTPORT> -j DNAT --to-destination <CONTAINERIP>:<PORT>
|
||||
```
|
||||
|
||||
如果你是在 Virtualbox 中运行 Docker,那么你需要配置端口转发 (forward the port)。使用 [forwarded_port](https://docs.vagrantup.com/v2/networking/forwarded_ports.html) 在 Vagrantfile 上配置暴露的端口范围,这样你就可以动态地映射了:
|
||||
|
||||
```
|
||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
...
|
||||
|
||||
(49000..49900).each do |port|
|
||||
config.vm.network :forwarded_port, :host => port, :guest => port
|
||||
end
|
||||
|
||||
...
|
||||
end
|
||||
```
|
||||
|
||||
如果你忘记了将什么端口映射到宿主机上的话,可使用 `docker port` 查看:
|
||||
|
||||
```
|
||||
docker port CONTAINER $CONTAINERPORT
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
这里有一些最佳实践,以及争论焦点:
|
||||
|
||||
* [The Rabbit Hole of Using Docker in Automated Tests](http://gregoryszorc.com/blog/2014/10/16/the-rabbit-hole-of-using-docker-in-automated-tests/)
|
||||
* [Bridget Kromhout](https://twitter.com/bridgetkromhout) has a useful blog post on [running Docker in production](http://sysadvent.blogspot.co.uk/2014/12/day-1-docker-in-production-reality-not.html) at Dramafever.
|
||||
* There's also a best practices [blog post](http://developers.lyst.com/devops/2014/12/08/docker/) from Lyst.
|
||||
* [A Docker Dev Environment in 24 Hours!](https://engineering.salesforceiq.com/2013/11/05/a-docker-dev-environment-in-24-hours-part-2-of-2.html)
|
||||
* [Building a Development Environment With Docker](https://tersesystems.com/2013/11/20/building-a-development-environment-with-docker/)
|
||||
* [Discourse in a Docker Container](https://samsaffron.com/archive/2013/11/07/discourse-in-a-docker-container)
|
||||
|
||||
## 安全(Security)
|
||||
|
||||
这节准备讨论一些关于 Docker 安全性的问题。Docker 官方文档 [安全](https://docs.docker.com/articles/security/) 页面讲述了更多细节。
|
||||
|
||||
首先第一件事:Docker 是有 root 权限的。如果你在 `docker` 组,那么你就有 [root 权限](https://web.archive.org/web/20161226211755/http://reventlov.com/advisories/using-the-docker-command-to-root-the-host)。如果你将 Docker 的 Unix Socket 暴露给容器,意味着你赋予了容器 [宿主机 root 权限](https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container/)。
|
||||
|
||||
Docker 不应当作为唯一的防御措施。你应当使其更加安全可靠。
|
||||
|
||||
为了更好地理解容器暴露了什么,可参阅由 [Aaron Grattafiori](https://twitter.com/dyn___) 编写的 [Understanding and Hardening Linux Containers](https://www.nccgroup.trust/globalassets/our-research/us/whitepapers/2016/april/ncc_group_understanding_hardening_linux_containers-1-1.pdf)。这是一个完整全面且包含大量链接和脚注的容器问题指南,介绍了许多有用的内容。即使你已经加固过容器,以下的安全提示依然十分有帮助,但并不能代替理解的过程。
|
||||
|
||||
### 安全提示
|
||||
|
||||
为了最大的安全性,你应当考虑在虚拟机上运行 Docker。这是直接从 Docker 安全团队拿来的资料 -- [slides](http://www.slideshare.net/jpetazzo/linux-containers-lxc-docker-and-security) / [notes](http://www.projectatomic.io/blog/2014/08/is-it-safe-a-look-at-docker-and-security-from-linuxcon/)。之后,可使用 AppArmor、seccomp、SELinux、grsec 等来 [限制容器的权限](http://linux-audit.com/docker-security-best-practices-for-your-vessel-and-containers/)。更多细节,请查阅 [Docker 1.10 security features](https://blog.docker.com/2016/02/docker-engine-1-10-security/)。
|
||||
|
||||
Docker 镜像 ID 属于 [敏感信息](https://medium.com/@quayio/your-docker-image-ids-are-secrets-and-its-time-you-treated-them-that-way-f55e9f14c1a4) 所以它不应该向外界公开。请将它们当作密码来对待。
|
||||
|
||||
阅读由 [Thomas Sjögren](https://github.com/konstruktoid) 编写的 [Docker Security Cheat Sheet](https://github.com/konstruktoid/Docker/blob/master/Security/CheatSheet.adoc):关于加固容器的不错的建议。
|
||||
|
||||
查看 [Docker 安全测试脚本](https://github.com/docker/docker-bench-security),下载 [最佳实践白皮书](https://blog.docker.com/2015/05/understanding-docker-security-and-best-practices/)。
|
||||
|
||||
你应当远离使用非稳定版本 grsecurity / pax 的内核,比如 [Alpine Linux](https://en.wikipedia.org/wiki/Alpine_Linux)。如果在产品中用了 grsecurity,那么你应该考虑使用有 [商业支持](https://grsecurity.net/business_support.php) 的 [稳定版本](https://grsecurity.net/announce.php),就像你对待 RedHat 那样。虽然要 $200 每月,但对于你的运维预算来说不值一提。
|
||||
|
||||
从 Docker 1.11 开始,你可以轻松的限制在容器中可用的进程数,以防止 fork 炸弹。 这要求 Linux 内核 >= 4.3,并且要在内核配置中打开 CGROUP_PIDS=y。
|
||||
|
||||
```
|
||||
docker run --pids-limit=64
|
||||
```
|
||||
|
||||
同时,你也可以限制进程再获取新权限。该功能是 Linux 内核从 3.5 版本开始就拥有的。你可以从 [这篇博客](http://www.projectatomic.io/blog/2016/03/no-new-privs-docker/) 中阅读到更多关于这方面的内容。
|
||||
|
||||
```
|
||||
docker run --security-opt=no-new-privileges
|
||||
```
|
||||
|
||||
以下内容摘选自 [Container Solutions](http://container-solutions.com/is-docker-safe-for-production/) 的 [Docker Security Cheat Sheet](http://container-solutions.com/content/uploads/2015/06/15.06.15_DockerCheatSheet_A2.pdf)(PDF 版本,难以使用,故复制至此):
|
||||
|
||||
关闭内部进程通讯:
|
||||
|
||||
```
|
||||
docker -d --icc=false --iptables
|
||||
```
|
||||
|
||||
设置容器为只读:
|
||||
|
||||
```
|
||||
docker run --read-only
|
||||
```
|
||||
|
||||
通过 hashsum 来验证卷标:
|
||||
|
||||
```
|
||||
docker pull debian@sha256:a25306f3850e1bd44541976aa7b5fd0a29be
|
||||
```
|
||||
|
||||
设置卷标为只读:
|
||||
|
||||
```
|
||||
docker run -v $(pwd)/secrets:/secrets:ro debian
|
||||
```
|
||||
|
||||
在 Dockerfile 中定义用户并以该用户运行,避免在容器中以 ROOT 身份操作:
|
||||
|
||||
```
|
||||
RUN groupadd -r user && useradd -r -g user user
|
||||
USER user
|
||||
```
|
||||
|
||||
### 用户命名空间(User Namespaces)
|
||||
|
||||
还可以通过使用 [用户命名空间](https://s3hh.wordpress.com/2013/07/19/creating-and-using-containers-without-privilege/) -- 自 1.10 版本起已内置,但默认并未启用。
|
||||
|
||||
要在 Ubuntu 15.10 中启用用户命名空间 (remap the userns),请 [跟着这篇博客的例子](https://raesene.github.io/blog/2016/02/04/Docker-User-Namespaces/) 来做。
|
||||
|
||||
### 安全相关视频
|
||||
|
||||
* [Using Docker Safely](https://youtu.be/04LOuMgNj9U)
|
||||
* [Securing your applications using Docker](https://youtu.be/KmxOXmPhZbk)
|
||||
* [Container security: Do containers actually contain?](https://youtu.be/a9lE9Urr6AQ)
|
||||
* [Linux Containers: Future or Fantasy?](https://www.youtube.com/watch?v=iN6QbszB1R8)
|
||||
|
||||
### 安全路线图
|
||||
|
||||
Docker 的路线图提到关于 [seccomp 的支持](https://github.com/docker/docker/blob/master/ROADMAP.md#11-security)。
|
||||
一个名为 [bane](https://github.com/jfrazelle/bane) 的 AppArmor 策略生成器正在实现 [安全配置文件](https://github.com/docker/docker/issues/17142)。
|
||||
|
||||
## 小贴士
|
||||
|
||||
链接:
|
||||
|
||||
* [15 Docker Tips in 5 minutes](http://sssslide.com/speakerdeck.com/bmorearty/15-docker-tips-in-5-minutes)
|
||||
* [CodeFresh Everyday Hacks Docker](https://codefresh.io/blog/everyday-hacks-docker/)
|
||||
|
||||
### 清理
|
||||
|
||||
最新的 [数据管理命令](https://github.com/docker/docker/pull/26108) 已在 Docker 1.13 实现:
|
||||
|
||||
* `docker system prune`
|
||||
* `docker volume prune`
|
||||
* `docker network prune`
|
||||
* `docker container prune`
|
||||
* `docker image prune`
|
||||
|
||||
### df 命令
|
||||
|
||||
`docker system df` 将显示当前 Docker 各部分占用的磁盘空间。
|
||||
|
||||
### Heredoc 声明 Docker 容器
|
||||
|
||||
```
|
||||
docker build -t htop - << EOF
|
||||
FROM alpine
|
||||
RUN apk --no-cache add htop
|
||||
EOF
|
||||
```
|
||||
|
||||
### 最近一次的容器 ID
|
||||
|
||||
```
|
||||
alias dl='docker ps -l -q'
|
||||
docker run ubuntu echo hello world
|
||||
docker commit $(dl) helloworld
|
||||
```
|
||||
|
||||
### 带命令的提交(需要 Dockerfile)
|
||||
|
||||
```
|
||||
docker commit -run='{"Cmd":["postgres", "-too -many -opts"]}' $(dl) postgres
|
||||
```
|
||||
|
||||
### 获取 IP 地址
|
||||
|
||||
```
|
||||
docker inspect $(dl) | grep -wm1 IPAddress | cut -d '"' -f 4
|
||||
```
|
||||
|
||||
或使用 [jq](https://stedolan.github.io/jq/):
|
||||
|
||||
```
|
||||
docker inspect $(dl) | jq -r '.[0].NetworkSettings.IPAddress'
|
||||
```
|
||||
|
||||
或使用 [go 模板](https://docs.docker.com/engine/reference/commandline/inspect):
|
||||
|
||||
```
|
||||
docker inspect -f '{{ .NetworkSettings.IPAddress }}' <container_name>
|
||||
```
|
||||
|
||||
或在通过 Dockerfile 构建镜像时,通过构建参数 (build argument) 传入:
|
||||
|
||||
```
|
||||
DOCKER_HOST_IP=`ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1`
|
||||
echo DOCKER_HOST_IP = $DOCKER_HOST_IP
|
||||
docker build \
|
||||
--build-arg ARTIFACTORY_ADDRESS=$DOCKER_HOST_IP
|
||||
-t sometag \
|
||||
some-directory/
|
||||
```
|
||||
|
||||
### 获取端口映射
|
||||
|
||||
```
|
||||
docker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' <containername>
|
||||
```
|
||||
|
||||
### 通过正则匹配容器
|
||||
|
||||
```
|
||||
for i in $(docker ps -a | grep "REGEXP_PATTERN" | cut -f1 -d" "); do echo $i; done`
|
||||
```
|
||||
|
||||
### 获取环境变量配置
|
||||
|
||||
```
|
||||
docker run --rm ubuntu env
|
||||
```
|
||||
|
||||
### 强行终止运行中的容器
|
||||
|
||||
```
|
||||
docker kill $(docker ps -q)
|
||||
```
|
||||
|
||||
### 删除所有容器(强行删除!无论容器运行或停止)
|
||||
|
||||
```
|
||||
docker rm -f $(docker ps -qa)
|
||||
```
|
||||
|
||||
### 删除旧容器
|
||||
|
||||
```
|
||||
docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm
|
||||
```
|
||||
|
||||
### 删除已停止的容器
|
||||
|
||||
```
|
||||
docker rm -v `docker ps -a -q -f status=exited`
|
||||
```
|
||||
|
||||
### 停止并删除容器
|
||||
|
||||
```
|
||||
docker stop $(docker ps -aq) && docker rm -v $(docker ps -aq)
|
||||
```
|
||||
|
||||
### 删除无用 (dangling) 的镜像
|
||||
|
||||
```
|
||||
docker rmi $(docker images -q -f dangling=true)
|
||||
```
|
||||
|
||||
### 删除所有镜像
|
||||
|
||||
```
|
||||
docker rmi $(docker images -q)
|
||||
```
|
||||
|
||||
### 删除无用 (dangling) 的卷标
|
||||
|
||||
Docker 1.9 版本起:
|
||||
|
||||
```
|
||||
docker volume rm $(docker volume ls -q -f dangling=true)
|
||||
```
|
||||
|
||||
1.9.0 中,参数 `dangling=false` 居然 _没_ 用 - 它会被忽略然后列出所有的卷标。
|
||||
|
||||
### 查看镜像依赖
|
||||
|
||||
```
|
||||
docker images -viz | dot -Tpng -o docker.png
|
||||
```
|
||||
|
||||
### Docker 容器瘦身
|
||||
|
||||
- 在某层 (RUN layer) 清理 APT
|
||||
|
||||
这应当和其他 apt 命令在同一层中完成。
|
||||
否则,前面的层将会保持原有信息,而你的镜像则依旧臃肿。
|
||||
|
||||
```
|
||||
RUN {apt commands} \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
```
|
||||
|
||||
- 压缩镜像
|
||||
```
|
||||
ID=$(docker run -d image-name /bin/bash)
|
||||
docker export $ID | docker import – flat-image-name
|
||||
```
|
||||
|
||||
- 备份
|
||||
```
|
||||
ID=$(docker run -d image-name /bin/bash)
|
||||
(docker export $ID | gzip -c > image.tgz)
|
||||
gzip -dc image.tgz | docker import - flat-image-name
|
||||
```
|
||||
|
||||
### 监视运行中容器的系统资源利用率
|
||||
|
||||
检查某个容器的 CPU、内存以及网络 I/O 使用情况,你可以:
|
||||
```
|
||||
docker stats <container>
|
||||
```
|
||||
|
||||
按 ID 列出所有容器:
|
||||
```
|
||||
docker stats $(docker ps -q)
|
||||
```
|
||||
|
||||
按名称列出所有容器:
|
||||
```
|
||||
docker stats $(docker ps --format '{{.Names}}')
|
||||
```
|
||||
|
||||
按指定镜像名称列出所有容器:
|
||||
```
|
||||
docker ps -a -f ancestor=ubuntu
|
||||
```
|
||||
|
||||
删除所有未标签命名 (untagged) 的容器:
|
||||
```
|
||||
docker rmi $(docker images | grep “^” | awk '{split($0,a," "); print a[3]}')
|
||||
```
|
||||
|
||||
通过正则匹配删除指定容器:
|
||||
```
|
||||
docker ps -a | grep wildfly | awk '{print $1}' | xargs docker rm -f
|
||||
```
|
||||
|
||||
删除所有已退出 (exited) 的容器:
|
||||
```
|
||||
docker rm -f $(docker ps -a | grep Exit | awk '{ print $1 }')
|
||||
```
|
||||
|
||||
### 将文件挂载为卷标
|
||||
|
||||
文件也可以被挂载为卷标。例如你可以仅仅注入单个配置文件:
|
||||
|
||||
``` bash
|
||||
# 从容器复制文件
|
||||
docker run --rm httpd cat /usr/local/apache2/conf/httpd.conf > httpd.conf
|
||||
|
||||
# 编辑文件
|
||||
vim httpd.conf
|
||||
|
||||
# 挂载修改后的配置启动容器
|
||||
docker run --rm -ti -v "$PWD/httpd.conf:/usr/local/apache2/conf/httpd.conf:ro" -p "80:80" httpd
|
||||
```
|
||||
|
||||
## 贡献手册(Contributing)
|
||||
|
||||
以下是如何贡献本速查表的说明。
|
||||
|
||||
### 打开 README.md
|
||||
|
||||
点击 [README.md](https://github.com/wsargent/docker-cheat-sheet/blob/master/README.md) <-- 这个链接
|
||||
|
||||

|
||||
|
||||
### 编辑页面
|
||||
|
||||

|
||||
|
||||
### 更新并提交
|
||||
|
||||

|
||||
|
||||

|
||||
Loading…
Add table
Add a link
Reference in a new issue