Docker概览
Docker架构
Docker采用client-server架构,client和daemon间使用REST API进行通讯。client和daemon可以运行在相同或不同的机器。daemon间也可以通过Docker API通讯。
Docker Registry存储image,Docker Hub和Docker Cloud是两个公用的Registry,默认使用Docker Hub,也可以配置使用私有的Registry。
当使用Docker时,会创建和使用image, container, network, volume, plugin和其他对象。
- Image是用来创建Container的只读模板。一个Image可以建立在另一个Image之上,构建image时使用Dockerfile文件,Dockerfile内的每一指令在image创建一个layer。当更改Dockerfile重建image时,仅更改的layer被重建。
- Container是Image的运行实例。
Docker版本
- Community Edition (CE)
- Enterprise Edition (EE)
Capabilities | Community Edition | Enterprise Edition Basic | Enterprise Edition Standard | Enterprise Edition Advanced |
---|---|---|---|---|
Container engine and built in orchestration, networking, security | yes | yes | yes | yes |
Certified infrastructure, plugins and ISV containers | yes | yes | yes | |
Image management | yes | yes | ||
Container app management | yes | yes | ||
Image security scanning | yes |
自17年3月,Docker版本号采用YY.mm.patch格式,YY.mm代表年月。
安装和卸载
操作系统Linux CentOS或RHEL 7。
卸载旧版本
旧版本Docker称为docker或docker-engine,如曾安装先卸载:
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
目录/var/lib/docker/下的内容不会删除,包含images, containers, volumes, networks等。
安装Docker CE
- 更新系统
sudo yum update
安装最新版的container-selinux
sudo yum install -y http://mirror.centos.org/centos/7/extras/x86_64/Packages/container-selinux-2.66-1.el7.noarch.rpm
如未更新container-selinux,在安装Docker CE时可能会显示如下错误:
Error: Package: docker-ce-18.06.0.ce-3.el7.x86_64 (docker-ce-edge)
Requires: container-selinux >= 2.9
- 安装必须的Package
yum-utils提供yum-config-manager工具,devicemapper storage driver需要device-mapper-persistent-data和lvm2$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2
- 配置Docker Repository
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
默认stable repository是启用的,若要启用edge或test repository(stable repository是必须的),执行如下命令:
$ sudo yum-config-manager --enable docker-ce-edge
$ sudo yum-config-manager --enable docker-ce-test
- 安装Docker CE
$ sudo yum install docker-ce
docker安装后创建了docker group,但不会启动,没有新增用户。
启动docker:
$ sudo systemctl enable docker // 自启动
$ sudo systemctl start docker
验证docker是否成功安装:
$ sudo docker run hello-world
$ sudo docker --version
$ sudo docker info
$ sudo docker version
$ sudo docker image ls
$ sudo docker container ls --all
- 用户管理
Docker Daemon绑定了Unix socket,而不是TCP端口,默认Unix socket由root和其他有sudo权限的用户拥有。为了运行docker命令时不使用sudo,创建Unix group "docker",将用户添加到docker group即可。当docker daemon启动时,让docker group有读/写Unix Socket权限。$ sudo groupadd docker $ sudo usermod -aG docker $USER
卸载Docker CE
$ sudo yum remove docker-ce
Images、 containers、 volumes、customized configuration files不会自动删除,执行以下命令删除:
$ sudo rm -rf /var/lib/docker
Docker CLI
CLI | Description |
---|---|
Engine CLI | The main CLI for Docker, includes all docker and dockerd commands |
Compose CLI | The CLI for Docker Compose, which allows you to build and run multi-container applications |
Machine CLI | Manages virtual machines that are pre-configured to run Docker |
DTR CLI | Deploy and manage Docker Trusted Registry |
UCP CLI | Deploy and manage Universal Control Plane |
Docke支持多方面的CLI,下面仅涉及Engine CLI docker。
运行不带任何参数的docker命令或docker help,可列出所有可用的docker命令。
为了查看某一命令的帮助,执行如下命令:
$ docker run --help
option参数可以组合在一起:
docker run -i -t --name test busybox sh
可以写成:
docker run -it --name test busybox sh
docker run
$ docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]
启动docker container有两种模式:Detached、Foreground,默认是Foreground模式。
Foreground模式
Options:
-a=[] : Attach to `STDIN`, `STDOUT` and/or `STDERR`
-t : Allocate a pseudo-tty
--sig-proxy=true: Proxy all received signals to the process (non-TTY mode only)
-i : Keep STDIN open even if not attached
-i -t组合在一起使用,可以与容器进行交互:
$ docker run -a stdin -a stdout -i -t ubuntu /bin/bash
运行以上命令后,会执行如下操作:
- 如本地没有ubuntu image,将从registry获取,相当于手动执行docker pull ubuntu
- Docker创建新的容器,相当于运行docker container create
- Docker给容器分配可读写的文件系统
- Docker创建网络接口连接容器到默认网络
- Docker启动容器并执行/bin/bash
容器启动后,可以执行shell命令,如下:root@f7cbdac22a02:/# hostname root@f7cbdac22a02:/# cat /etc/hosts root@f7cbdac22a02:/# yum install -y vim
- 输入exit,终止/bin/bash,容器停止但不会被删除,可以重新启动。
root@f7cbdac22a02:/# exit
Detached模式
当指定-d选项后,启用Detached模式,container将在后台运行。
$ docker run -d -p 80:80 my_image nginx -g 'daemon off;'
Container identification
有三种方式:
Identifier type | Example value |
---|---|
UUID long identifier | “f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778” |
UUID short identifier | “f78375b1c487” |
Name | “evil_ptolemy” |
当运行container时,如未使用--name指定容器名,daemon将生成一随机字符串作为名字。
Attach to and detach from a running container
$ docker run -d --name topdemo ubuntu /usr/bin/top -b
$ docker attach topdemo
docker commit
使用docker commit可以从container创建image。
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Options
Name, shorthand | Default | Description |
---|---|---|
--author , -a | Author (e.g., “John Hannibal Smith [email protected]”) | |
--change , -c | Apply Dockerfile instruction to the created image | |
--message , -m | Commit message | |
--pause , -p | true | Pause container during commit |
先创建一个Container
$ docker run -t -i training/sinatra /bin/bash
然后运行shell脚本更新container
$ root@0b2616b0e5a8:/# yum install vim
更新完毕后,运行exit退出。
最后使用docker commit创建image:
$ docker commit -m "Added json gem" -a "Kate Smith" 0b2616b0e5a8 ouruser/sinatra:v2
还可以使用--change修改后再创建image:
$ docker commit --change='CMD ["apachectl", "-DFOREGROUND"]' -c "EXPOSE 80" c3f279d17e0a svendowideit/testimage:version4
docker build
从Dockerfile创建image,这是最常用的方式。
docker build [OPTIONS] PATH | URL | -
下面演示从Dockerfile创建image:
Dockerfile
创建一个空目录,在其内创建名为Dockerfile的文件,内容如下:
# Use an official Python runtime as a parent image
FROM python:2.7-slim
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE 80
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python", "app.py"]
Dockerfile引用了文件app.py 和 requirements.txt,下面在相同目录创建这两个文件:
requirements.txt
Flask
Redis
app.py
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
app = Flask(__name__)
@app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
visits = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>" \
"<b>Visits:</b> {visits}"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
Build
$ docker build -t friendlyhello .
Container相关命令
Command | Description |
---|---|
docker attach | Attach local standard input, output, and error streams to a running container |
docker container | Manage containers |
docker cp | Copy files/folders between a container and the local filesystem |
docker create | Create a new container |
docker diff | Inspect changes to files or directories on a container’s filesystem |
docker exec | Run a command in a running container |
docker export | Export a container’s filesystem as a tar archive |
docker kill | Kill one or more running containers |
docker logs | Fetch the logs of a container |
docker pause | Pause all processes within one or more containers |
docker port | List port mappings or a specific mapping for the container |
docker ps | List containers |
docker rename | Rename a container |
docker restart | Restart one or more containers |
docker rm | Remove one or more containers |
docker run | Run a command in a new container |
docker start | Start one or more stopped containers |
docker stats | Display a live stream of container(s) resource usage statistics |
docker stop | Stop one or more running containers |
docker top | Display the running processes of a container |
docker unpause | Unpause all processes within one or more containers |
docker update | Update configuration of one or more containers |
docker wait | Block until one or more containers stop, then print their exit codes |
示例:
List containers
$ docker ps -a
-a Show all containers. Only running containers are shown by default.
Start a stopped container
$ docker start my_container
Fetch the logs of a container
$ docker logs -f --until=2s my_container
Run a command in a running container
$ docker exec -d my_container touch /tmp/execWorks
Delete all containers
$ docker rm `docker ps -a -q`
Image相关命令
Command | Description |
---|---|
docker build | Build an image from a Dockerfile |
docker commit | Create a new image from a container’s changes |
docker history | Show the history of an image |
docker image | Manage images |
docker images | List images |
docker import | Import the contents from a tarball to create a filesystem image |
docker load | Load an image from a tar archive or STDIN |
docker manifest | Manage Docker image manifests and manifest lists |
docker pull | Pull an image or a repository from a registry |
docker push | Push an image or a repository to a registry |
docker rmi | Remove one or more images |
docker save | Save one or more images to a tar archive (streamed to STDOUT by default) |
docker search | Search the Docker Hub for images |
docker tag | Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE |
docker trust | Manage trust on Docker images |
示例:
Download an ubuntu image
$ docker pull ubuntu
Push image
$ docker push ouruser/sinatra:v2
List images
$ docker images
Search images
$ docker search centos
Delet an image
This only deletes the image locally
$ docker rmi ouruser/sinatra:v2
Registry
Registry命令
Command | Description |
---|---|
docker login | Log in to a Docker registry |
docker logout | Log out from a Docker registry |
docker pull | Pull an image or a repository from a registry |
docker push | Push an image or a repository to a registry |
创建Registry
Run a registry from a container
$ docker run -p 5000:5000 registry
This will launch a container running the registry application and bind port 5000 to the local host.
Tag our image for our new registry
$ docker tag 8dbd9e392a96 localhost:5000/ouruser/sinatra:v2
push image to our new registry
$ docker push localhost:5000/ouruser/sinatra:v2
Run a container from our local registry
$ docker run -t -i localhost:5000/ouruser/sinatra:v2 /bin/bash
参考文档
Docker Documentation
Product Manuals
Docker Glossary
Reference Documentation
Docker Samples
Best practices for writing Dockerfiles
Jenkins与Docker的自动化CI/CD实战