1. 物理机 虚拟化 容器化
Docker是用GO语言开发的
08年发布了LXC,13年发布了第一版的docker并开源,16年分为se和ee版本
虚拟化技术可以追溯到上世纪 60 年代,为解决多用户/单计算机问题,一种是如今盛行的分时系统,另外一种是虚拟化,例如 Hypervisor(虚拟机监控程序),是在几十年前开发的,它让多个用户能够同时访问执行批处理的计算机。
但是分时日益盛行,虚拟化裹足不前,90年代才开始推进
- 物理机时代:部署慢,成本高,资源浪费,难于扩展迁移
- 虚拟机时代:多部署,易扩展,可以对硬件进行隔离给不同的虚拟机使用,但是虚拟机还是需要安装OS的,如果只要部署小应用,比如一个mysql,也需要安装一个操作系统,重量大
- 容器化时代:容器也需要OS,但是十分微小,自动化部署,集群管理。
容器化和虚拟化解决的方面是不同的,所以这两种技术今后会并驾齐驱。虚拟化是硬件层面的隔离,而容器化是APP级别的隔离。
如今云产品都是虚拟化和容器化一起用
2. docker架构
cs架构
docker daemon就是服务端
外面封装了REST API提供 HTTP访问
docker CLI 就是客户端
之所以采用CS架构,是可以方便一个客户端可以连接多个docker
3. Docker 使用
客户端client发送命令会,docker daemon(docker守护进程)收到请求,执行操作,比如拉取操作镜像就会从仓库register拉取,拉取到本地镜像image中,从而生成容器
镜像 image 是docker中的模板,根据模板构造容器,一个镜像可以创建多个容器
Docker公司运营的公共仓库叫做 Docker Hub (https://hub.docker.com/),存放了数量庞大的镜像供
用户下载,国内的公有仓库包括阿里云 、网易云 等
4. docker镜像
文件系统叠加而成,由文件引导系统(里面有os内核),往上叠加就成为镜像了
5. docker 安装与卸载
- 安装
1. 卸载旧版本
yum remove docker docker-common docker-selinux docker-engine
2. 安装所需软件包
yum install -y yum-utils device-mapper-persistent-data lvm2
3. 设置阿里镜像仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
4. 安装docker ce
yum install docker-ce
- 设置开机自启和启动
systemctl enable docker
systemctl start docker
- 配置国内镜像加速器,创建
vim /etc/docker/daemon.json,
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
- 重启配置和docker
systemctl daemon-reload
systemctl restart docker
- 查看,拉取镜像,创建容器,
docker image
docker pull xxx
docker run [OPTIONS] 镜像名:标签名
-i 表示交互式运行容器(就是创建容器后,马上会启动容器,并进入容器 ),通常与 -t 同时使用 。
-t 启动后会进入其容器命令行, 通常与 -i 同时使用; 加入 -it 两个参数后,容器创建就能登录进去。即分配一个伪终端。
--name 为创建的容器指定一个名称 。
-d 创建一个守护式容器在后台运行,并返回容器ID;
这样创建容器后不会自动登录容器,如果加 -i 参数,创建后就会运行容器。
-v 表示目录映射, 格式为: -p 宿主机目录:容器目录
注意:最好做目录映射,在宿主机上做修改,然后共享到容器上。
-p 表示端口映射,格式为: -p 宿主机端口:容器端口
-it:运行容器并进入该容器的终端
-id:后台运行容器
下面展示了创建并进入centos容器,退出
退出不停止运行 ctrl+q+p【启动退出交互 -it 换为-id】
启动或停止容器 用name或者id
docker start mycentos
docker skill mycentos
- 查看容器的信息
6. 理解
docker基本原理前面说过,有一个内核,所以我们每当进入一个容器时,会发现里面就是一个os
所以在挂载的时候,我们需要了解到docker安装后的默认位置,来进行挂载比如nginx中,docker安装的默认位置
日志目录 : /var/log/nginx
配置目录 : /etc/nginx/conf.d
配置文件 : /etc/nginx/nginx.conf
项目目录 : /usr/share/nginx/html
所以在挂载时需要如下写 ( 本地目录:docker内目录 = map : docker) map是我专门为docker挂载设置的
-v /map/nginx/html:/usr/share/nginx/html \
-v /map/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /map/nginx/conf.d:/etc/nginx/conf.d \
-v /map/nginx/logs:/var/log/nginx \
6.1 mysql
docker pull mysql:5.7
docker run -id --name=mysql -p 33306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
-p 代表端口映射,格式为 宿主机映射端口:容器运行端口
-e 代表添加环境变量, MYSQL_ROOT_PASSWORD 是 root 用户的登陆密码
firewall-cmd --zone=public --add-port=33306/tcp --permanent
如果是云服务器上的,需要配置端口开启
6.2 vsftpd
# 拉取镜像
docker pull fauria/vsftpd
docker run -it --name vsftpd fauria/vsftpd
# 拷贝文件
docker cp vsftpd:/etc/vsftpd/vsftpd.conf /map/vsftpd/vsftpd.conf
# 拷贝完之后就停止并删除容器
docker stop vsftpd
docker rm vsftpd
# 运行与挂载
docker run -id --name vsftpd \
--restart=always \
-p 21:21 -p 21100-21104:21100-21104 \
-e FTP_USER=ftpuser -e FTP_PASS=123 \
-e PASV_ADDRESS=42.192.69.94 -e PASV_MIN_PORT=21100 -e PASV_MAX_PORT=21104 \
-e LOCAL_UMASK=0 -e FILE_OPEN_MODE=0777 -e ANON_UMASK=0777 \
-v /map/vsftpd/file/ftpuser:/home/vsftpd/ftpuser --privileged=true \
-v /map/vsftpd/vsftpd.conf:/etc/vsftpd/vsftpd.conf \
fauria/vsftpd
# 关闭防火墙
firewall-cmd --zone=public --add-port=21/tcp --permanent
firewall-cmd --zone=public --add-port=21100-21104/tcp --permanent
–privileged=true 如果映射的是多级目录,防止有可能出现没有权限的问题,所以加上此参数
特别注意:-e LOCAL_UMASK=0 -e FILE_OPEN_MODE=0777 -e ANON_UMASK=0777 配置权限非常重要,不会导致ftp上传的文件无法转发访问
6.3 nginx (包括挂载ftp)
前面部署好了ftp之后,要想代理转发,但是两个容器是隔离的,所以我们需要挂载同一个主机目录来实现ftp文件加的共享
# 拉取镜像
docker pull nginx:latest
# 简单运行
docker run -id --name nginx -p 80:80 nginx
#拷贝文件
docker cp nginx:/etc/nginx/nginx.conf /map/nginx/nginx.conf
docker cp nginx:/etc/nginx/conf.d /map/nginx/conf.d
docker cp nginx:/usr/share/nginx/html /map/nginx/html
docker cp nginx:/var/log/nginx /map/nginx/logs
# 拷贝完之后就停止并删除容器
docker stop nginx
docker rm nginx
# 运行挂载
docker run -id --name nginx -p 80:80 -p 8001:8001 -p 8002:8002 \
-v /map/nginx/html:/usr/share/nginx/html \
-v /map/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /map/nginx/conf.d:/etc/nginx/conf.d \
-v /map/nginx/logs:/var/log/nginx \
-v /map/vsftpd/file/ftpuser:/var/local \
nginx
# 关闭防火墙
firewall-cmd --zone=public --add-port=8001/tcp --permanent
本地目录:docker安装位置
-v 挂载配置到本地,修改本地就可以同步修改docker里面的nginx了,注意目录也存在或者是对应类型吗,这里需要根据你的nginx安装方法
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
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;
include /etc/nginx/conf.d/*.conf;
server {
listen 8001;
server_name 42.192.69.94;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /var/local/;
add_header Access-Control-Allow-Origin *;
}
}
server {
listen 8002;
server_name 42.192.69.94;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /var/local/;
add_header Access-Control-Allow-Origin *;
}
}
}
docker exec -t nginx nginx -t
docker exec -t nginx nginx -s reload
6. 容器保存为镜像
docker inspect --format='{{.Mount}}' 容器
无数据挂载的
docker commit -m="first nginx commit" -a "666" nginx nginx2:1.1
有数据挂载的
如果强行使用无数据挂载方式,那么bind的目录的内容都会被丢弃
注意:像mysql 创建数据库会自动挂载
使用拷贝,创建完成新文件之后就将