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
# 进入到容器,看到数据库还在
posted @ 2022-08-24 23:45  Edmond辉仔  阅读(140)  评论(0编辑  收藏  举报