一、什么是docker
Docker 是一个开源项目,诞生于2013年初,最初是dotCloud公司内部的一个业余项目。它基于Google公司推出的Go语言实现。项目后来加入了Linux基金会,遵从了Apache 2.0协议,项目代码在GitHub上进行维护。
Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。 Docker的基础是Linux容器(LXC)等技术。相对于虚拟机,更加原生和高性能。
二、应用场景
2.1 快速交付,高效部署
2.2 便于管理
标准化开发、测试、生产环境,避免环境不一致带来的问题,极大的简化服务配置和迁移工作
三、docker架构
Docker是一个C/S架构的程序,由两部分组成:
服务端(server):Docker守护进程,负责处理Docker指令,管理镜像、容器
客户端(client):通过命令或Restful API向Docker服务端发送指令。可同时在本地或远程向服务端发送指令。
四、核心概念
4.1 镜像(image)
将应用程序及其依赖、环境、配置打包在一起,是一个 read-only 文件,可以理解成一个模板
可以自己制作(Dockerfile),也可以从镜像源拉取
利用Dockerfile制作镜像,可参考 python flask 镜像
4.2 容器(container)
一个镜像运行起来,就是一个容器,基于一个镜像可以运行多个容器
其实质是复制image,并在image最上层加上一层 read-write 的层 (称为container layer,容器层)
4.3 仓库(repository)
托管镜像的服务器,除了官方的docker.hub,还有https://registry.cn-hangzhou.aliyuncs.com、http://hub-mirror.c.163.com等
五、基本操作
docker 常用基础命令
docker container run -d --publish 80:80 --name webhost nginx
一条命令背后到底做了什么?
1 在本地查找是否有nginx这个image镜像,但是没有发现
2 去远程的image registry查找nginx镜像(默认的registry是Docker Hub)
3 下载最新版本的nginx镜像 (nginx:latest 默认)
4 基于nginx镜像来创建一个新的容器,并且准备运行
5 docker engine分配给这个容器一个虚拟IP地址
6 在宿主机上打开80端口并把容器的80端口转发到宿主机上
7 启动容器,运行指定的命令(这里是一个shell脚本去启动nginx)
六、容器编排
容器编排就是批量管理容器
pip install docker-compose
docker-compose,常用命令集合(与docker命令几乎一致)
Commands:
build Build or rebuild services
config Validate and view the Compose file
create Create services
down Stop and remove resources
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 version information and quit
编排配置文件:
docker-compose.yml
基本语法结构
version: "3.8"
services: # 容器
servicename: # 服务名字,这个名字也是内部 bridge网络可以使用的 DNS name
image: # 镜像的名字
command: # 可选,如果设置,则会覆盖默认镜像里的 CMD命令
environment: # 可选,相当于 docker run里的 --env
volumes: # 可选,相当于docker run里的 -v
networks: # 可选,相当于 docker run里的 --network
ports: # 可选,相当于 docker run里的 -p
servicename2:
volumes: # 可选,相当于 docker volume create
networks: # 可选,相当于 docker network create
七、基于docker构建PHP运行环境
nginx.conf 配置
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
gzip on;
server {
listen 88;
root /www; #查找php文件的目录
location ~ \.php$ { #解析.php后缀的文件
fastcgi_pass php:9000; #转发到php容器
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
www/index.html
<div>
This is Beijing!
</div>
www/test.php
<?php
phpinfo();
docker-compose.yml文件
version: '3.1' #版本
services: #服务配置
nginx: #nginx服务
image: nginx #镜像名
container_name: my_nginx #启动容器名
restart: always #重启配置
ports: #容器内外端口映射,外部访问使用8001
- 8001:88
volumes: #数据卷映射
- ./nginx.conf:/etc/nginx/nginx.conf
- ./www:/www
php: #php服务
image: php:7.4-fpm #镜像名
container_name: php_7.4 #启动后容器名
depends_on:
- nginx
restart: always #重启配置
volumes: #数据卷映射(容器内的www目录映射宿主机的当前目录下的www目录)
- ./www:/www
接下来运行,命令会在当前目录下查找docker-compose.yml文件
docker-compose run -d
[@bx /opt/projects/docker]# docker-compose up -d
Creating network "docker_default" with the default driver
Creating my_nginx ... done
Creating php_7.4 ... done
访问1:http://宿主机ip:8001
访问2:http://宿主机ip:8001/index.html,等同于 http://宿主机ip:8001
访问3:http://宿主机ip:8001/index.php
访问4:http://宿主机ip:8001/test.php
前两种请求:访问index.html时,nginx去容器中的www目录找,www目录映射到宿主机的www目录,所以,最终是去宿主机的www目录访问,找到index.html,展示其内容。
第三种请求:访问index.php,nginx解析到是php文件,就会去nginx配置php server的root目录查找,该目录同样映射到宿主机的www目录,那么最终就会到宿主机的www目录查找,由于宿主机上没有该文件,所以显示file not found
第四种请求:同第三种请求,宿主机上有该文件,就会解析并显示该文件内容
八、图解
参考文档
1 http://www.dockerinfo.net/document
2 https://dockertips.readthedocs.io/en/latest/index.html
3 https://docs.docker.com/engine/reference/builder/
4 https://www.homenethowto.com/advanced-topics/traffic-example-the-full-picture/