Docker02--docker挂载、迁移与备份、其他操作、Dockerfile、私有仓库、Docker-compose、容器通信、数据卷
1 部署应用-映射外部目录
### 注:
通常docker起的mysql、redis服务,都需要将服务配置和数据文件 挂载到本机上
防止容器挂掉,数据丢失。
# 部署redis 并把配置文件和数据目录映射出来
# 操作步骤
# 1 创建目录
mkdir /redis /redis/conf /redis/data
# 2 创建配置文件
vim /redis/conf/redis.conf
# 配置文件
bind 0.0.0.0 # 绑定本地回环地址
daemonize NO # 不以后台运行
protected-mode no # 这是严格模式
requirepass 123456 # 设置连接密码
# 3 创建并运行容器 并执行命令 '以配置文件 启动redis-server'
docker run -p 6378:6379 --name redis_6379 -v /redis/conf/redis.conf:/etc/redis/redis.conf -v /redis/data:/data -di redis redis-server /etc/redis/redis.conf
# 4 redis数据持久化
好处:
在宿主机的/redis/data路径下就能看到一个数据文件
不管多少次重启redis容器,数据都还在
原来的redis容器没了,按照第三步再启动一遍,数据依旧存在
方式一:配置默认持久化 直接写在redis.conf中
# 待补充
方式二:每次操作数据后,手动保存持久化
# cmd中 保存数据 (数据持久化到 /redis/data文件夹下 )
save 或者 bgsave (后台运行保存数据)
# 5 本地连接 并访问操作redis
# 1 cmd窗口下 连接redis 或 redis软件工具 连接操作数据
redis-cli -h 101.133.225.166 -p 6378
# 2 密码权限认证
auth 123456
# 3 写入数据
set name lqz
# 4 手动保存 或 配置默认持久化
2 迁移与备份
2.1 容器保存为镜像
# 命令
docker commit 容器名字/id 镜像名字
# eg:
# 装有python的容器里安装django
pip install django==1.11.11 -i https://pypi.douban.com/simple/
# 将容器保存为镜像
docker commit 19b mydjango
2.2 镜像备份
把镜像打包成压缩包
# 命令
docker save -o 镜像压缩包名 镜像名字
# eg:
docker save -o mydjango.tar mydjango
2.3 镜像恢复与迁移
把压缩包回复为镜像
# 命令
docker load -i 镜像压缩包名
# eg:
docker load -i mydjango.tar
3 其他操作
# 删除所有容器 最好不用 !!!
docker rm `docker ps -a -q`
# 删除所有镜像 最好不用 !!!
docker rmi `docker images -q`
# 若面试被问到,不要说不知道
回答:具体命令忘了,因为不常用,但原理是 删除 后面跟 过滤容器或镜像的id
# 查看容器运行日志
docker logs 容器id
# 自定义制作django的镜像,并运行容器 的操作步骤
1 启动一个python容器
docker run -di --name=python3 python:3.6
2 进入容器装软件
docker exec -it python3 /bin/bash
mkdir /project
pip install django==1.11.11 # 正常项目:pip install -r requirements.txt
exit
### 方式一:代码文件通过目录挂载
3 把容器做成镜像
docker commit python3 mydjango
4 基于自定义的镜像运行容器
docker run -id --name=mydjango -p 8088:8088 -v /opt/lqz/django_test:/project/django_test mydjango python /project/django_test/manage.py runserver 0.0.0.0:8088
### 方式二:将代码文件也做到镜像文件里
3 把项目文件拷贝到容器内部
docker cp /opt/lqz/django_test python3:/project/django_test
4 把容器做成镜像
docker commit python3 mydjango
5 基于自定义的镜像运行容器
docker run -id --name=mydjango -p 8088:8088 mydjango python /project/django_test/manage.py runserver 0.0.0.0:8088
4 Dockerfile(***)
# 1 Dockerfile介绍
Dockerfile是由一系列命令和参数构成的脚本,通过这个文件可以生成镜像
# 2 Dockerfile常用指令
命令 作用
FROM image_name:tag # 定义了使用哪个基础镜像启动构建流程
MAINTAINER user_name # 声明镜像的创建者
ENV key value # 设置环境变量 (可以写多条)
RUN command # 是Dockerfile的核心部分(可以写多条) 制作镜像时 执行的命令
ADD source_dir/file dest_dir/file # 将宿主机的文件复制到容器内,如果是一个压缩文件tar,将会在复制后自动解压
COPY source_dir/file dest_dir/file # 和ADD相似,但是如果有压缩文件并不能解压
WORKDIR path_dir # 设置工作目录 (表示一进去,就在哪个目录下)
# 下面两个可以命令 启动容器 再指定
EXPOSE 端口号 # 设置对外暴露的端口
VOLUME ["目录"] # 添加数据卷 目录挂载(映射)
CMD ['命令', '参数项', '参数值'] # 添加 启动容器时 默认执行的命令。多条只有最后一条生效 可以在启动容器时被覆盖和修改
USER # 指定以哪个用户的名义执行RUN, CMD 和ENTRYPOINT等命令
# 3 通过Dockerfile文件 生成镜像
docker build -t='镜像名' .
# 注意:
后边的空格和点,不要省略 # 表示以 当前目录下的dockerfile 构建
4.1 案例:Dockerfile部署项目
# 案例:使用Dockerfile 部署django项目
# 0.前提
# 项目目录
django_test
-项目文件
-requirements.txt # django环境文件
-Dockerfile # docker部署镜像文件
-uwsgi.ini # uwsgi启动配置文件
# uwsgi.ini的配置编写 以往采用xml格式编写,现采用ini的格式
[uwsgi]
# 采用socket 连接nginx
# socket=0.0.0.0:8080 # Nginx配置中 uwsgi_pass应指向uWSGI服务器IP和端口
# 也可采用http 连接nginx
http=0.0.0.0:8080 # Nginx配置中 proxy_pass应指向uWSGI服务器IP和端口
chdir=/home/django_test/ # 项目路径 项目所在目录
wsgi-file=django_test/wsgi.py # wsgi接口模块文件路径
processes=4 # 启动的进程数
threads=2 # 每个进程的线程数
master=True # 启动管理主进程
pidfile=uwsgi.pid # 存放主进程的进程号文件 以后可通过该进程号 关闭uwsgi服务
daemonize=uwsgi.log # 以后台守护进程运行 并存放日志记录文件
容器就没有一个前台进程在夯住了,故需要额外的阻塞命令!!!
# 1.编写一个Dockerfile 文件名字必须为Dockerfile
vim Dockerfile
FROM python:3.6
MAINTAINER lqz
EXPOSE 8080
ADD ./requirement.txt /home/
RUN pip install -r /home/requirement.txt -i https://pypi.douban.com/simple/
RUN pip install uwsgi -i https://pypi.douban.com/simple/
VOLUME ["/home"]
WORKDIR /home/django_test
CMD ["uwsgi", "--ini", "uwsgi.ini"]
# 2 通过dockerfile构建出镜像
docker build -t='django_1.11.11' . # 注意后边的空格和点,不要省略 表示以 当前目录下的Dockerfile 构建
# 3 查看镜像是否建立完成
docker images
# 4 启动容器
docker run -di --name=my_django1 -v /opt/web_django/django_test:/home/django_test -p 8080:8080 django_1.11.11
# 5 在外部访问即可
###### 此时 项目已经通过uwsgi正常启动 再通过nginx容器配置转发到80端口访问
# 1 配置nginx转发
# 创建文件夹
mkdir -p /opt/nginx/conf /opt/nginx/html /opt/nginx/logs
# 新建配置文件
vim /opt/nginx/conf/nginx.conf
# 写入
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
# 采用http 与 uwsgi 通信时
proxy_pass http://101.133.225.166:8080;
}
}
}
# 2 docker中运行nginx
docker run --name=my_nginx -id -p 80:80 -v /opt/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /opt/nginx/html:/etc/nginx/html -v /opt/nginx/logs:/var/log/nginx nginx
###### 此时 单个项目通过uwsgi启动 并nginx配置转发 增加并发 采用nginx的负载均衡配置
# 1 配置负载均衡
# 修改nginx配置文件
vim /opt/nginx/conf/nginx.conf
# 写入
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 负载均衡配置
upstream node {
server 101.133.225.166:8080;
server 101.133.225.166:8081;
server 101.133.225.166:8082;
}
server {
listen 80;
server_name localhost;
# 对 "/" 启用反向代理
location / {
# 负载均衡配置
proxy_pass http://node;
}
}
}
# 2 多启动几个django的docker容器
docker run -di --name=my_django2 -v /opt/web_django/django_test:/home/django_test/ -p 8081:8080 django_1.11.11
docker run -di --name=my_django3 -v /opt/web_django/django_test:/home/django_test/ -p 8082:8080 django_1.11.11
# 3 重启nginx
docker restart my_nginx
# nginx负载均衡的好处:
假设8080/8081的容器挂了,但8082依旧可正常提供服务
再把django的docker容器 启动起来即可
5 私有仓库
# Docker仓库
就是存放docker镜像并有docker pull方法下载的云环境
# 分类
分为公有仓库和私有仓库
公有仓库指 Docker Hub(官方)等开放给用户使用、允许用户管理镜像
私有仓库指 由用户自行搭建的存放镜像的云环境
# 私有仓库本质
就是一个web项目,通过docker拉取创库镜像,然后docker运行起来 即可!
# 如何把自定义的镜像传到docker hub上
0 Docker hub官网 注册账号
1 登录docker
docker login 输入用户名/密码
2 上传的image打个标签
docker tag 镜像id/镜像名 用户名/镜像名:tag名
# eg: docker tag 5452fa6715c0 liuqingzheng/django1.11.9:v1
3 再查看下 打完tag标签的镜像
docker images
4 上传镜像到Docker hub
docker push 带tag标签的镜像名
# eg: docker push liuqingzheng/django1.11.9
5.1 私有仓库搭建与配置
# 1 拉取私有仓库镜像
docker pull registry
# 2 启动私有仓库容器
docker run -di --name=registry -p 5000:5000 registry
# 3 打开浏览器输入地址 http://服务器IP:5000/v2/_catalog
看到{"repositories":[]} # 表示私有仓库搭建成功并且内容为空
# 4 配置指定 docker push上传时,仓库的地址
vi /etc/docker/daemon.json # 修改daemon.json
# 添加以下内容,保存退出
{"insecure-registries":["服务器IP:5000"]}
# 此步用于让 docker信任私有仓库地址
# 5 重启docker服务
systemctl restart docker
5.2 镜像上传至私有仓库
# 1 重启私有仓库容器
docker start registry
# 2 标记上传镜像为私有仓库的镜像
docker tag 镜像id/镜像名 服务器IP:端口/镜像名:tag名
# eg: docker tag 5452fa6715c0 101.133.225.166:5000/django1.11.11
# 3 上传标记的镜像 到私有仓库
docker push 服务器IP:5000/镜像名
# 4 从私有仓库 拉取镜像
docker pull 服务器IP:5000/镜像名
6 docker-compose
6.1 介绍和使用
# 1 介绍
是一个单机情况下容器编排的工具
是一个能一次性定义和管理多个Docker容器的工具
# 2 详细地说
Compose中定义和启动的每一个容器都相当于 一个服务(service)
Compose中能定义和启动多个服务,且它们之间通常具有协同关系
# 3 管理方式
使用YAML文件来配置定义多个容器 # .yml后缀文件
# 默认名字docker-compose.yml
# 4 配置参数概述
Docker Compose File 顶级配置项:
version : # 指定Docker Compose File版本号
services: # 定义多个服务并配置启动参数
volumes : # 声明或创建在多个服务中共同使用的数据卷对象
networks: # 定义在多个服务中共同使用的网络对象
configs : # 声明将在本服务中要使用的一些配置文件
secrets : # 声明将在本服务中要使用的一些秘钥、密码文件
x-*** : # 自定义配置 主要用于复用相同的配置
# 5 强调
# 5.1 三个重要配置:service networks volumes
一个service代表一个container
这个container可以从docker hub的image来创建
或者从本地dockerfile build的image来创建
services的启动类似docker run
可以在services中的单个docker里 指定network和volume
也可以在顶级配置中 指定network和volume
# 5.2 版本
version:有1、2、3版本 # 目前都用"3"
# 6 安装
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
# 7 验证安装成功
docker-compose -v
# 8 docker-compose命令
# 启动管理容器
docker-compose up # 会自动搜索当前路径下的 docker-compose.yml文件
docker-compose -f 指定文件 up
docker-compose up -d # 后台执行,一般我们看日志输出,不用这个
docker-compose stop # 停止,不会删除容器和镜像
docker-compose down # 停止,并删除关联的容器
docker-compose start # 启动yml文件管理的容器
docker-compose ps # 查看正在运行的容器
docker-compose images # 查看docker-compose管理的镜像
docker-compose exec yml文件中写的service容器名 /bin/bash # 进入到容器内
6.2 docker-compose.yml 主要配置项
# docker-compose.yml 如何写
# 第一步:编写docker-compose.yml 主要配置项
version: '3' # 指定版本
services:
wordpress: # 容器名字 实际是内部自行定义 也可参数指定
image: wordpress # 基于哪个镜像 本地没有 去docker hub拉取
ports: # 等同于 docker run -p
- 8080:80
environment: # 等同于 docker run -e
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_PASSWORD: root
volumes: # 等同于 docker run -v
- mysql-data:/var/lib/mysql # 多个目录挂载 就在下面继续 - 宿主机目录:容器目录
# 第二步:启动--运行
docker-compose up
6.3 案例--部署多应用
# eg:部署flask redis
# 1 创建Dockerfile
vim Dockerfile
FROM python:3.6
COPY . /app # 将当前文件夹 都拷贝在容器的 /app路径下
WORKDIR /app
RUN pip install flask redis
EXPOSE 5000
CMD [ "python", "app.py" ]
# 2 创建docker-compose文件
vim docker-compose.yml
version: "3"
services:
redis:
image: redis # image: 通过宿主机上(或远程仓库)的镜像 创建容器
web:
build: # build: 通过宿主机上的Dockerfile文件构建的镜像 创建容器
context: . # context: Dockerfile文件的路径
dockerfile: Dockerfile # dockerfile: Dockerfile文件的名字
ports: # 端口映射
- 8080:5000
environment: # 容器里 设置环境变量
REDIS_HOST: redis
# 3 创建app.py
vim app.py
from flask import Flask
from redis import Redis
import os
import socket
app = Flask(__name__)
redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)
@app.route('/')
def hello():
redis.incr('hits')
return '你好! 查看 %s 次, hostname 是 %s.\n' % (redis.get('hits'),socket.gethostname())
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=True)
# 4 启动--运行
docker-compose up
6.4 水平拓展
# 案例:把flask_redis项目扩展成三个
docker-compose up --help # 通过--help 查看参数
# --scale SERVICE=NUM # 将某个服务容器 设置成指定数量
docker-compose up --scale web=3 # 执行有问题,因为8080端口已经被映射了
### 实际解决办法:
1.删除原docker-compose.yml中web容器的port
2.再启动
docker-compose up --scale web=3
docker-compose start
docker-compose ps # 可以看到三个web启动了
### 3个web服务容器,可在前面加一个负载均衡器HAProxy
HAProxy和Nginx的区别?万能的百度
# 1.app.py 监听的端口由5000改为80
# 2.Dockerfile不需要改
# 3.修改docker-compose.yml
version: "3"
services:
redis:
image: redis
web:
build:
context: .
dockerfile: Dockerfile
environment:
REDIS_HOST: redis
lb: # 增加一个HAProxy的负载均衡器 load balance 缩写 lb
image: dockercloud/haproxy
links:
- web
ports:
- 8080:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# 4.启动,从浏览器查看
docker-compose up
# 5.把web扩展为3个从浏览器查看
docker-compose up --scale web=3 -d
# 6.减掉为1个
docker-compose up --scale web=1 -d
7 多个容器直接通信方式
# 方式1
端口映射到宿主机,直接访问宿主机ip + 端口
# 方式2
通过容器的ip地址 相互访问
# 方式3
run的时候指定 --link 容器 # 这个是单方向的
# eg:
docker run -di --name=centos1 centos:centos7
docker run -di --name=centos2 --link centos1 centos:centos7
进入到centos2中 ping centos1 # 可以ping通
# 跨主机的容器通信
-端口映射 到宿主机 然后宿主机ip+端口访问
8 数据卷拓展 (了解)
http://www.liuqingzheng.top/linux/Docker/7-Docker之数据卷/
# Docker挂载容器数据卷的方式
# 1.基于本地的Volume:
在容器创建或者run的时候,通过 -v指定
# 2.基于插件(plugin)的Volume:
插件方式,第三方方案,如NAS,aws
# volume的类型
1 受管理的data Volume,由docker后台自动创建(Data volume)
2 绑定挂载的Volume,具体挂载可以由用户指定 (Bind Mouting)
##### Data volume
# 启动一个mysql的容器
docker run -d --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
docker volume ls # 查看 刚刚创建容器的voluem
docker volume rm id号 # 删除voluem
docker inspect id号 # 查看容器详细信息 可以看到mount到的本地某个位置
# 再创建,也会创建一个volume
# 删除容器,volume是不会被删除的(数据不会丢)
# 两个容器可以共用一个volume 挂载同样的宿主机文件夹目录
docker run -di -v mysql:/var/lib/mysql --name=mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
docker run -di -v mysql:/var/lib/mysql --name=mysql2 -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 mysql:5.7
# 进入到容器,创建一个数据库
# 停掉容器,删除容器
docker volume ls # volume文件还在
# 重新一个容器,使用该volume
docker run -di -v mysql:/var/lib/mysql --name=mysql3 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
# 进入到容器,看到数据库还在