Docker是一个开发、打包和运行应应用的开放平台,让你的应用和你的基础设置隔离开来,从而加速应用发布。使用Docker,可以让你用管理基础设施一样的方式去管理应用。
Docker解决了什么
部署一套运行运行环境会涉及到多个服务。
- 负载均衡nginx
- 数据库MySQL、MongoDB等
- 应用python、Java等
- 搜索ElasticSearch
- 监控Promethus、Grafana等
部署的差异
每个服务部署和配置各不相同,比如不同的环境下安装部署MySQL。
# centos7 部署MySQL
rpm -Uvh http://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm
yum -y install mysql-community-server
systemctl start mysqld
systemctl enable mysqld
# Centos8
dnf -y install @mysql
#运行以下命令启动MySQL,并设置为开机自启动
systemctl enable --now mysqld
# ubuntu部署mysql
sudo apt update
sudo apt install mysql-server
sudo systemctl status mysql
如果使用Docker呢?创建一个docker-compose.yaml,使用命令docker-compose up -d
,无论在什么样的操作系统之下,只要安装docker都可以启动。
# docker-compose.yaml MySQL一主一从
version: "3"
services:
db1:
image: mysql:5.7
container_name: db1
ports:
- 3308:3306
volumes:
- /home/dev/docker/mysql/ms/db1:/var/lib/mysql
- /home/dev/docker/mysql/ms/db1.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf
- /home/dev/docker/timezone:/etc/timezone
- /etc/localtime:/etc/localtime
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: sharding
MYSQL_USER: test
MYSQL_PASSWORD: 123456
db2:
image: mysql:5.7
container_name: db2
ports:
- 3309:3306
volumes:
- /home/dev/docker/mysql/ms/db2:/var/lib/mysql
- /home/dev/docker/mysql/ms/db2.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf
- /home/dev/docker/timezone:/etc/timezone
- /etc/localtime:/etc/localtime
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: sharding
MYSQL_USER: test
MYSQL_PASSWORD: 123456
部署的依赖环境
此外,在QA、PRE和PROD,服务器环境或多或少会有不同。所以常常会发生QA可以,到了PRE或者PROD就不行。如果采用Docker,镜像包括了应用所需要的所有依赖。无论是JAVA、Python还是Redis、MySQL,我们只需要保证服务器已安装Docker运行环境,就可以在QA和PRE等环境直接运行服务而不需要在服务器上再安装依赖,就可以最大程度的减少应用运行环境的差异。
所以,我认为Docker主要解决的问题就是应用发布的标准化和运行环境的隔离。
Docker架构
Docker使用的是CS架构。Docker Daemon承担着创建,运行和分发Docker Container的重任,Docker Client直接与Docker daemon交互。Docker client 和 daemon 使用 REST API, UNIX sockets 或者网络接口交互.
- The Docker daemon: Docker daemon (
dockerd
) 处理 Docker API 的请求并且管理docker镜像、容器、网络和存储卷等对象。daemon 也能够与其他的daemon联系,从而管理docker services。 - The Docker client: Docker client是大多数用户首选的与Docker交互的方式。
- Docker registries: 是存储docker镜像的仓库。
- Docker Objects: image、container、networks, volumes, plugins, 和其他对象
- images:镜像是包含创建容器的指令的只读模板。通常,一个镜像是基于另一个镜像外加部分用户自定义的部分组成。例如,基于ubuntu创建一个镜像,镜像安装了apache服务器和开发的应用,以及应用需要的详细配置。
- containers:容器是镜像运行的一个实例。可以通过docker api创建,修改,停止和删除一个容器。也可以通过网络连接容器,为它添加存储甚至以容器的当前状态创建镜像。
- services:Services 允许扩展容器跨越多个Docker daemons。Docker daemons多个管理节点和工作节点组成一个*swarm。每个swarm成员即为一个Docker daemon, 并且daemons通过Docker API沟通。service允许定义预期的状态,例如服务的集群副本数。service默认负载均衡到所有的worker节点。
Docker 常用命令
# 创建镜像
# docker build
docker build . -t test:1.0.0 # 使用当前文件夹下面的Dockerfile创建名为test:1.0.0的镜像
# 查看已有镜像 docker images
# 查看运行的容器 docker ps
# 查看所有容器 docker ps -a
# 删除镜像 docker rmi
docker rmi test:1.0.0 # 删除名为test:1.0.0的镜像,也可以使用image id
# 修改镜像名 docker tag
# 将镜像test:1.0.0的名称修改为test:1.0.0
docker tag test:1.0.0 test:1.0.0
# 从仓库中拉取镜像 docker pull
docker pull mysql # 从hub.docker.com拉取mysql镜像
# 推送镜像到registry docker push
# 将test:1.0.0推送到docker hub
docker push test:1.0.0
# 运行容器
# docker run
# 使用镜像test:latest运行名为test的容器,容器内的8080端口映射到主机的8087端口,容器的/data目录挂在到主机的/data目录
docker run -d -p 8087:8080 -v /data:/data --name test test
# 启动容器 docker start
docker start test # 启动名称为test的容器,如果容器不存在则启动失败
# 停止运行中的容器 docker stop
docker stop test # 停止名称为test的容器
# 重启容器 docker restart
docker restart test # 重启名称为test的容器
# 删除容器 docker rm
docker rm test # 删除已停止的容器test,如果容器运行中,则删除删除失败
# 在容器中执行命令 docker exec
docker exec mysql ls # 查看容器mysql工作目录下的文件
# 查看docker容器的控制台日志 docker logs
docker logs -f --tail 200 mysql # 查询mysql容器的最后200行日志,并保持更新
Docker-compose
Compose是一个定义和运行多个容器应用的工具。使用Compose通常有三个步骤:
- 通过
Dockerfile
定义一个应用的运行环境,从而能够在任何地方重新创经镜像。 - 在
docker-compose.yml
定义应用组成的services,使他们能够一起在一个隔离的环境中运行。 - 在
docker-compose.yml
所在目录运行命令docker-compose up
来启动整个应用。
# 服务包括两个容器,名为web和redis
version: '3.0'
services:
web:
build: . # 使用目录中的Dockerfile创建web所需要的镜像
ports:
- "5000:5000" # 将web容器的端口5000映射到主机5000端口
volumes:
- .:/code # 挂在docker容器的code目录到当其目录
- logvolume01:/var/log # 挂在容器/var/log到存储卷logvolume01
links:
- redis # 让web可以通过redis作为host访问到redis
redis:
image: redis # 使用redis最新镜像启动redis容器
volumes:
logvolume01: {}
docker-compose命令
Usage:
docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
docker-compose -h|--help
Options:
-f, --file FILE Specify an alternate compose file
(default: docker-compose.yml)
-p, --project-name NAME Specify an alternate project name
(default: directory name)
--verbose Show more output
--log-level LEVEL Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
--no-ansi Do not print ANSI control characters
-v, --version Print version and exit
-H, --host HOST Daemon socket to connect to
--tls Use TLS; implied by --tlsverify
--tlscacert CA_PATH Trust certs signed only by this CA
--tlscert CLIENT_CERT_PATH Path to TLS certificate file
--tlskey TLS_KEY_PATH Path to TLS key file
--tlsverify Use TLS and verify the remote
--skip-hostname-check Don't check the daemon's hostname against the
name specified in the client certificate
--project-directory PATH Specify an alternate working directory
(default: the path of the Compose file)
--compatibility If set, Compose will attempt to convert keys
in v3 files to their non-Swarm equivalent
Commands:
build Build or rebuild services
bundle Generate a Docker bundle from the Compose file
config Validate and view the Compose file
create Create services
down Stop and remove containers, networks, images, and volumes
events Receive real time events from containers
exec Execute a command in a running container
help Get help on a command
images List images
kill Kill containers
logs View output from containers
pause Pause services
port Print the public port for a port binding
ps List containers
pull Pull service images
push Push service images
restart Restart services
rm Remove stopped containers
run Run a one-off command
scale Set number of containers for a service
start Start services
stop Stop services
top Display the running processes
unpause Unpause services
up Create and start containers
version Show the Docker-Compose version information