Docker
1. 容器技术
容器 用于代码和依赖资源打包
同一台主机可运行多个容器 共享操作系统内核 同时各自作为独立进程运行
相较于虚拟机 容器占用空间小 启动速度块
1.1 VM虚拟机 &&Docker
VM虚拟机 通过模拟硬件 并在硬件上安装操作系统实现虚拟化应用
Docker最优虚拟程序所需的环境配置
特性 | Docker | VM |
启动速度 | 秒级 | 分钟级 |
硬盘使用 | MB | GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 通常几十个 |
1.2 Docker容器技术多用于搭建和配置开发环境
2. Docker (C/S架构)
2.1 Docker安装
# Windows10 Docker-CE社区版 安装
# 在控制面板-程序与功能-开启Hyper-V
# 安装Docker-Desktop url:https://www.docker.com/products/docker-desktop
# 适用于Windows10 专业版或企业版(部分版本 版本号尽量最新)
# Linux(Ubuntu) 安装
sudo apt-get update
sudo apt-get install docker-ce
# 启动docker服务
sudo systemctl enable docker
sudo systemctl start docker
2.2 Docker-images(镜像)
# Docker镜像是特殊的文件系统 提供容器运行所需的程序 库 资源配置文件 还包含运行时的配置参数(环境变量 用户 挂载等等) 分层构建且每层都是只读
# 修改镜像加速源 提高下载速度
-----------ubutun /etc/docker/daemon.json
{
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://hub-mirror.c.163.com"
]
}
-------------------------------------------
# 修改默认的镜像下载目录
-----------ubutun /etc/docker/daemon.json
{
"graph":"自定义的镜像下载目录",
}
# 配置文件参数问题 根据docker版本号查看指定的daemon.json配置文件参数设置
# https://docs.docker.com/engine/reference/commandline/dockerd/
# 重启服务
sudo systemctl daemon-reload
sudo systemctl restart docker
# 查看是否生效Registry-Mirros
docker info
# Docker-images常用命令
# 查看镜像
docker images | docker image ls # 所有顶层镜像
docker image ls -a # 所有 中间层镜像 + 顶层镜像 -q:显示镜像id
docker images 镜像 # 查看指定镜像
docker history 镜像id # 查看指定镜像创建历史记录
docker inspect 镜像id # 查看镜像具体信息(id, 执行命令, 环境变量, 网络信息,挂载等)
# 搜索镜像
docker search 镜像
# 下载镜像(不写版本默认最新)
docker pull 镜像:版本号
# 标记镜像到指定仓库(重命名)
docker tag [options] image[:tag] [registryhost/][username/] name[:tag]
# 删除镜像
docker rmi -f 镜像id # -f:强制删除
docker image prune # 删除悬空镜像(因版本更新迭代重名原因成为None标记的镜像)
# 通过源镜像创建的容器构建新镜像(不推荐 分层构建的镜像内容不可见 且容易造成新镜像臃肿)
docker commit [options] 容器id | 容器名 新镜像名称:标签
# 其他操作--镜像持久化(默认tar包) 实现本地 网络共享
# 保存
docker save 镜像id > ./xx.tar | docker save -o ./xx.tar 镜像id
# 加载
docker load -i ./xx.tar
# 这种方式创建的新镜像保留源镜像(通过build)分层创建的历史 可执行理论上回滚操作docker tag 回滚层id 镜像id
# 如若出现新镜像为None情况 请使用镜像名:版本号方式进行
2.3 Docker-container(容器)
#Docker-Container 实质是在镜像的基础上添加一个可写层 用来保存容器运行过程的修改信息
# 通过镜像创建容器
docker run -it --rm -d 镜像:版本号 |镜像id 命令
# 常用参数:
#-it:终端交互| -rm:退出删除容器| -d:守护进程 后台运行| --name 容器名| -p 主机port:容器port
#-e 环境变量| --link 关联其他容器名| -v 主机目录:容器目录 >实现挂载卷共享数据
# 查看容器
docker ps # 查看运行容器 -a:查看所有容器
# 已有容器操作
docker start 容器id | 容器名 # 运行停止(多个)容器
docker restart 容器id | 容器名 # 重启
docker stop 容器id | 容器名 # 停止
docker inspect 容器id # 查看容器详细信息
docker exec -it 容器id | 容器名 命令 # 交互界面进入运行中容器进行操作 exit不会导致容器停止
docker attach 容器id | 容器名 # exit会导致容器停止(不推荐)
# docker exec -it xxx bash shell界面进入xxx容器
# 删除容器(支持多个容器同时删除)
docker rm 容器id | 容器名 # -f:强制删除 -l:只删除容器间网络连接 -v:删除挂载卷+容器
# 容器文件与其他主机文件复制操作
docker cp 源目录 目录
docker cp 源目录 容器:目的目录 || docker cp 容器:目录 目的目录
# 其他操作(通过容器持久化操作实现容器共享)
# 导出容器到指定tar包
# 默认以tar方式对容器进行持久化存储(记录下容器参数-command) docker inspect 容器id 查看详情
docker export 容器id | 容器名 > ./xxx.tar | docker export -o xxx.tar 容器id
# 导入tar包生成新镜像
docker import ./tar文件 新镜像名:版本
# 运行生成的新镜像创建的容器
docker run 新镜像id command(导出容器)
# 这种方式创建出的新镜像丢失了源镜像内分层构建的详情 同时对于(多层构建build的新镜像)无法执行回滚操作
2.4 Docker-Repository(仓库)
#---------镜像上传到公有仓库docker hub
# 登录账号
docker login -u username -p password # 登录https://hub.docker.com/ 输入用户账号&密码
# 标记上传的镜像
docker tag 上传的镜像id 用户账号/新镜像名称:版本号
# 上传到docker hub仓库(默认不允许https方式上传镜像)
docker push 用户账号/新镜像名称:版本号
#----------镜像上传到私有仓库docker-registry
# 登录私有仓库
docker login 私有仓库url(ip:port)
# 下载私有仓库镜像
docker pull registry
# 后台运行 & 同步数据到主机 & 映射ip&端口(访问localhost:6666)
docker run -d --restart=always -v ./registry:/var/lib/registry -p 6666:6666 registry:latest
# 标记上传的镜像
docker tag 镜像id 私有仓库地址(ip:port)/镜像id
# 上传到私有仓库(curl localhost:6666/v2/_catalog查看上传的镜像)
docker push ip:port/新镜像名:版本号
# 下载私有仓库镜像
docker pull localhost:6666/镜像:版本号
# 注意点:局域网内私有仓库搭建需要配置docker settings信息
------------json-----------/etc/docker/daemon.json
{
"insecure-registries":["局域网ip:port", 192.xxx.xxx.xxx:6666]
}
------------------------------------------------
3. Dockerfile可视化制作镜像
3.1 Dockerfile常用指令
# Dockerfile脚本文件自定义镜像(单个)
# Dockerfile常用指令
#-----------Dockerfile
# 基础镜像
FROM 指定基础镜像 # 指定基础镜像
# 维护者信息
MAINTAINER username | email
# 构建镜像执行指令
ENV key value |key=value # 指定环境变量
WORKDIR 目录路径 # 指定工作目录
RUN 执行命令 # 多用于程序安装执行命令
COPY 源路径 目标路径 # 复制文件
ADD 源路径 目标路径 # 复制文件(源路径:文本+URL+tar压缩文件)下载链接文件&&自动解压缩文件
VOLUME /目录 # 指定持久化存储目录
EXPOSE port1, port2 # 映射端口号 docker run -P 自动映射port1, port2;
# 容器启动时执行的指令
CMD shell命令 | ["par1", "par2",...] # 指定容器主进程需要的参数(容器=进程)
ENTRYPOINT shell命令 | ["par1", "par2"] # 可对CMD命令进行重定义 容器启动前预处理配置
# 使用Dockerfile构建新镜像
docker build -t 镜像名:版本 上下文路径/URL # 上下文路径 != 目录
# 注意点:
# Docker(c/s)架构 上下文路径实则是server对用于构建镜像的资源进行打包的地址
# Dockerfile构建新镜像会对所属目录下所有资源文件进行打包到docker-server 方便其构建使用
# Dockerfile 可指定脚本文件执行并不需要一定在上下文目录中 docker build -t -f 指定的文件名 新镜像 上下文路径
# Dockerfile可添加忽略文件 避免被打包使用 >添加.dockerignore(类比:.gitignore)
# Dockerfile v17版本支持多阶段构建 尽可能减少分层构建带来的镜像资源冗余
3.2 Dockerfile实例
# 简易搭建Django环境
----------requirements.txt
asgiref==3.2.10
Django==3.1.1
django-redis==4.12.1
mysqlclient==2.0.1
pytz==2020.1
redis==3.5.3
sqlparse==0.3.1
-----------Dockerfile
# 指定基础镜像
FROM python:3.7
# 配置Django环境&创建Django项目
COPY requirements.txt /home
WORKDIR /home
RUN pip3 install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple \
&& django-admin startproject project
WORKDIR /home/project
EXPOSE 8000
# 设置容器启动后执行的命令
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
----------------------------------------------------------
# 构建镜像
docker build -t django:1.0 .
# 运行容器
docker run -it --name web_django -p:8888:8000 django:1.0
4. Docker-compose
4.1 认识
Docker compose 是用于快速部署分布式应用的一个docker官方编排项目(python实现)
为了方便编排管理多个容器而生
通过docker-compose.yml文件(YAML格式)来定义一组相关联的容器为一个项目并进行管理
Compose:
服务(service):一个应用容器
项目(project):由一组关联的应用容器组成的一个完整业务单元 在 docker-compose.yml 文件中定义
4.2 Docker-compose 安装
# Mac or win10 Docker Desktop 自带docker compose
# 查看信息
docker-compose version
# Linux
pip install -U docker-compose
4.3 Docker-compose使用
#Compose模板文件 :docker-compose.yml YAML语法
version:"3" # 指定compose版本
services: # 服务
app: # 项目应用
image: 镜像 # 加载指定镜像指令
ports:
- "5555:5555" # 端口映射
volumes:
- "/home" # 挂载卷
# 服务:
# 应用:
# 指令:
4.4 Docker-compose 常用命令
#Docker-compose常用命令
# 测试语法是否书写正确
docker-compose config
# 构建服务
docker-compose build 应用
# 查看所有(特定)服务构建日志
docker-compose logs (可选:应用)
# 自动构建镜像 创建服务 启动服务
docker-compose up
# 查看compose项目中包含的镜像
docker-compose images
# 查看compose项目所有容器
docker-compose ps
# 停止所有(特定)应用服务
docker-compose stop (可选:应用)
# 停止并删除docker-compose up启动的服务 删除网络
docker-compose down
# 重启所有(特定)应用服务
docker-compose restart (可选:应用)
# 进入特定启动中的应用服务
docker-compose exec 应用 命令(如:bash)
4.5 Docker-compose 服务常用指令
# Docker-compose常用指令(必须优先声明服务)
1.build: . # 指定Dockerfile文件上下文路径 构建镜像并使用
#build:
context: ./test # 指定Dockerfile文件路径
dockerfile: xxx # 指定Dockerfile文件名
2.image: redis # 加载镜像(本地仓库不存在自动pull)
3.expose: # 映射端口(不映射到宿主机)
- 8000
4.container_name: docker-mysql # 指定容器名
5.depends_on: # 优先级启动容器设置
#app1:
build: .
depends_on:
- app2
#app2
images: mysql
6.ports: # 映射端口(映射到宿主机 外部以可访问)
- "8001:8000" # (ip:host:container)
7.secrets:存储隐私数据
#mysql:
image: mysql
environment:
MYSQL_ROOT_PASSOWRD_FILE: /run/secrets/mysql_psw
secrets:
- mysql_psw
#secrets:
db_psw:
file: ./xxx.txt
8.volumes: # 挂载卷路径(宿主机:容器:访问模式[ro])
- ./mysql:/var/lib/mysql
9.command: python manage.py runserver # 替换容器启动后默认执行的命令(Dockerfile CMD指令)
10.entrypoint: /xx.sh # 应用服务容器启动后执行的入口文件
11.networks: # 设置应用服务容器连接网络
- 自定义网络
12.environment: # 设置应用服务容器运行的环境变量
par1: 1
4.6 Docker-compose 实例
# 实例:Docker-compose 构建 Django + Mysql + Redis服务
#目录结构
#-->compose
#------->docker-compose.yml
#------->mysql
#------->redis
#------->django
#-------------->requirements.txt
#-------------->Dockerfile
#-------------->project
###---->django/project/project/settings.py
# 宿主机在虚拟环境下创建一个Django工程(django-admin startproject project) 到./django
# Mysql配置(pip install pymysql)
# Django操作Mysql需要Mysqldb驱动程序
# Django版本低 可以使用pymsyql替代(pymysql.install_as_MySQLdb())
# 因为Django版本与Mysqldb驱动关联 所以特别注意 Django3使用(pip install mysqlclient)关联数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 数据库引擎
'HOST': 'mysql', # 数据库主机&docker-compose服务名
'PORT': 3306, # 数据库端口
'USER': 'root', # 数据库用户名
'PASSWORD': 'python', # 数据库用户密码
'NAME': 'test_db' # 数据库名字
}
}
# Redis配置(pip install django-redis)
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://redis:6379/0",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
}
###---->django/Dockerfile
FROM python:3.7
COPY requirements.txt /home
WORKDIR /home
RUN pip3 install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple \
&& django-admin startproject project
WORKDIR /home/project
EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
###---->django/requirements.txt
asgiref==3.2.10
Django==3.1.1
django-redis==4.12.1
mysqlclient==2.0.1
pytz==2020.1
redis==3.5.3
sqlparse==0.3.1
###---->docker-compose.yml
version: "3"
services:
web:
build: ./django
volumes:
- ./django/project:/home/project
ports:
- "8000:8000"
depends_on:
- mysql
- redis
mysql:
image: mysql:8.0.1
expose:
- 3306
ports:
- "3307:3306"
environment:
MYSQL_USER: root
MYSQL_ROOT_PASSWORD: python
volumes:
- ./mysql:/var/lib/mysql
redis:
image: redis
expose:
- 6379
ports:
- "6380:6379"
volumes:
- ./redis:/var/lib/redis
5. Docker 网络链接
# 外部访问容器内
# 通过ip:port映射(可多个)
docker run -p 宿主机ip:宿主机端口:容器端口 镜像id # -P 会映射EXPOSE 端口
# 查看映射端口信息
docker port 容器id 端口号
# 内部多容器通信
# 查看docker默认网络连接类型
docker network ls # 默认有三种bridge host null
# 查看网络连接方式详情
docker network inspect 网络id
# 创建新的网络连接
docker network create -d 网络连接方式 新网络名
# 创建容器时指定特定网络连接
docker run --network 新网络名 镜像id
# docker-compose 会创建新的bridge网络连接(文件名+_default)
# 多个容器间通信亦可使用参数: --link 关联容器