# 初识 Docker
# docker 概念
- Docker 是一个开源的应用容器引擎
- 诞生于 2013 年初,基于 Go 语言实现
- Docker 可以让开发者打包他们的应用以及依赖到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上
- 容器是完全使用沙箱机制,相互隔离
- 容器性能开销极低
- Docker 从 17.03 版本之后分为 CE(社区版)和 EE(企业版)
# 安装 docker
Docker 可以运行在 MAC、Windows、CentOS、UBUNTU 等操作系统上
| |
| yum update |
| |
| yum install -y yum-utils device-mapper-persistent-data lvm2 |
| |
| yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo |
| |
| yum install -y docker-ce |
| |
| docker -v |
# docker 架构
- 镜像(Image):Docker 镜像,相当于是一个 root 文件系统
- 容器(Container):镜像和容器的关系,就像面向对象程序设计中的类和对象一样,镜像是静态的定义,容器是镜像运行的实体,容器可以被创建、启动、停止、删除、暂停
- 仓库(Repository):仓库可以看成一个控制中心,用来保存镜像
# Docker 命令
# 进程相关命令
# 启动 docker 服务
# 停止 docker 服务
# 重启 docker 服务
# 查看 docker 服务状态
# 设置开机启动 docker 服务
# 镜像相关命令
# 查看镜像:查看本地所有镜像
| docker images |
| docker images -q |
# 搜索镜像:从网络中查找所有镜像
# 拉取镜像
# 删除镜像
| docker rmi 镜像id |
| docker rmi `docker images -q` |
# 容器相关命令
# 查看容器
# 创建并启动容器
-i
:保持容器运行。通常与 -t 同时使用。加入 it 这两个参数后,容器创建后自动进入容器中,退出容器后,容器自动关闭
-t
:为容器重新分配一个伪输入终端,通常与 -i 同时使用
-d
:以守护(后台)模式运行容器。创建一个容器在后台运行,需要使用 docker exec 进入容器。退出后,容器不会关闭
-it
:创建新的容器一般称为交互式容器,-id 创建的容器一般称为守护式容器
--name
:为创建的容器命名
# 进入容器
# 停止容器
# 启动容器
# 删除容器
# 查看容器信息
# Docker 容器的数据卷
# 数据卷的概念和作用
# 数据卷概念
- 数据卷是宿主机中的一个目录或文件 1
- 当容器目录和数据卷目录绑定后,对方的修改会立即同步
- 一个数据卷可以被多个容器同时挂载
- 一个容器也可以被挂载多个数据卷
# 数据卷作用
- 容器数据持久化
- 外部机器和容器间接通信
- 容器之间数据交换
# 配置数据卷
# 创建启动容器时
| docker run ... -v 宿主机目录(文件):容器内目录(文件) ... |
- 目录必须是绝对路径
- 如果目录不存在,会自动创建
- 可以挂载多个数据卷
# 配置数据卷容器
# 创建启动 c3 数据卷容器
| docker run -it --name=c3 -v /volume centos:7 /bin/bash |
# 创建启动 c1,c2 容器
| docker run -it --name=c1 --volumes-from c3 centos:7 /bin/bash |
| docker run -it --name=c2 --volumes-from c3 centos:7 /bin/bash |
# Docker 应用部署
# MySQL 部署
# MySQL 部署注意
- 容器内的网络服务和外部机器不能直接通信
- 外部机器和宿主机可以直接通信
- 宿主机和容器可以直接通信
- 当容器中网络服务需要外部机器访问时,可以将容器中提供服务的端口映射到宿主机的端口上,此部机器访问宿主机的该端口,从而间接访问容器的服务
- 这种操作称为:端口映射
# MySQL 部署实现
- 搜索 mysql 镜像
- 拉取 mysql 镜像
- 创建容器,设置端口映射、目录映射
| docker run -id \ |
| -p 3307:3306 \ |
| --name=c_mysql \ |
| -v $PWD/conf:/etc/mysql/conf.d \ |
| -v $PWD/logs:/logs \ |
| -v $PWD/data:/var/lib/mysql \ |
| -e MYSQL_ROOT_PASSWORD=123456 \ |
| mysql:5.6 |
- 参数说明:
- -p 3307:3306:将容器的 3306 端口映射到宿主机的 3307 端口。
- -v $PWD/conf:/etc/mysql/conf.d:将主机当前目录下的 conf/my.cnf 挂载到容器的 /etc/mysql/my.cnf。配置目录
- -v $PWD/logs:/logs:将主机当前目录下的 logs 目录挂载到容器的 /logs。日志目录
- -v $PWD/data:/var/lib/mysql :将主机当前目录下的 data 目录挂载到容器的 /var/lib/mysql 。数据目录
- **-e MYSQL_ROOT_PASSWORD=123456:** 初始化 root 用户的密码。
- 进入容器,操作 mysql
| docker exec –it c_mysql /bin/bash |
- 使用外部机器连接容器中的 mysql
# Tomcat 部署
# Tomcat 部署步骤
- 搜索 tomcat 镜像
- 拉取 tomcat 镜像
- 创建容器
- 部署项目
- 测试访问
# Tomcat 部署实现
- 搜索 tomcat 镜像
- 拉取 tomcat 镜像
- 创建容器,设置端口映射、目录映射
| |
| mkdir ~/tomcat |
| cd ~/tomcat |
| docker run -id --name=c_tomcat \ |
| -p 8080:8080 \ |
| -v $PWD:/usr/local/tomcat/webapps \ |
| tomcat |
- 使用外部机器访问 tomcat
# Nginx 部署
# Nginx 部署步骤
- 搜索 Nginx 镜像
- 拉取 Nginx 镜像
- 创建容器
- 测试访问
# Nginx 部署实现
- 搜索 nginx 镜像
- 拉取 nginx 镜像
- 创建容器,设置端口映射、目录映射
| |
| mkdir ~/nginx |
| cd ~/nginx |
| mkdir conf |
| cd conf |
| |
| vim nginx.conf |
| 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; |
| |
| |
| keepalive_timeout 65; |
| |
| |
| |
| include /etc/nginx/conf.d/*.conf; |
| } |
| docker run -id --name=c_nginx \ |
| -p 80:80 \ |
| -v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf \ |
| -v $PWD/logs:/var/log/nginx \ |
| -v $PWD/html:/usr/share/nginx/html \ |
| nginx |
- 参数说明:
- -p 80:80:将容器的 80 端口映射到宿主机的 80 端口。
- -v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf:将主机当前目录下的 /conf/nginx.conf 挂载到容器的 :/etc/nginx/nginx.conf。配置目录
- -v $PWD/logs:/var/log/nginx:将主机当前目录下的 logs 目录挂载到容器的 /var/log/nginx。日志目录
- 使用外部机器访问 nginx
# Redis 部署
# Redis 部署步骤
- 搜索 Redis 镜像
- 拉取 Redis 镜像
- 创建容器
- 测试访问
# Redis 部署实现
- 搜索 redis 镜像
- 拉取 redis 镜像
- 创建容器,设置端口映射
| docker run -id --name=c_redis -p 6379:6379 redis:5.0 |
- 使用外部机器连接 redis
| ./redis-cli.exe -h 192.168.1 -p 6379 |
# Dockerfile
# Docker 镜像原理
- Docker 镜像是由特殊文件的系统叠加而成
- 最底端是 bootfs,并使用宿主机的 bootfs
- 第二层是 root 文件系统 rootfs,称之为 base image
- 然后再往上可以叠加其它镜像文件
- 统一文件系统技术能够将不同的层整合成一个文件系统,为这些提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统
- 一个镜像可以放在另一个镜像的上面,位于下面的镜像称为父镜像,最底部的镜像称之为基础镜像
- 当从一个镜像启动容器时,Docker 会在最顶层加载一个读写文件系统作为容器
# 镜像制作
容器转换为镜像
| docker commmit 容器id 镜像名称:版本号 |
| docker save -o 压缩文件名称 镜像名称:版本号 |
| docker load -i 压缩文件名称 |
# Dockerfile 概念
- Dockerfile 是一个文本文件
- 包含了一条条指令
- 每一条指令构建一层,基于基础镜像,最终构建出一个新的镜像
- 对于开发人员,可以为开发团队提供一个完整一致的开发环境
- 对于测试人员:可以直接拿开发环境所构建的镜像或者通过 Dockerfile 文件构建一个新的镜像开始工作
- 对于运维人员:在部署时,可以实现应用的无缝衔接
# Dockerfile 关键字
关键字 |
作用 |
备注 |
FROM |
指定父镜像 |
指定 dockerfile 基于那个 image 构建 |
MAINTAINER |
作者信息 |
用来标明这个 dockerfile 谁写的 |
LABEL |
标签 |
用来标明 dockerfile 的标签 可以使用 Label 代替 Maintainer 最终都是在 docker image 基本信息中可以查看 |
RUN |
执行命令 |
执行一段命令 默认是 /bin/sh 格式: RUN command 或者 RUN ["command" , "param1","param2"] |
CMD |
容器启动命令 |
提供启动容器时候的默认命令 和 ENTRYPOINT 配合使用。格式 CMD command param1 param2 或者 CMD ["command" , "param1","param2"] |
ENTRYPOINT |
入口 |
一般在制作一些执行就关闭的容器中会使用 |
COPY |
复制文件 |
build 的时候复制文件到 image 中 |
ADD |
添加文件 |
build 的时候添加文件到 image 中 不仅仅局限于当前 build 上下文 可以来源于远程服务 |
ENV |
环境变量 |
指定 build 时候的环境变量 可以在启动的容器的时候 通过 - e 覆盖 格式 ENV name=value |
ARG |
构建参数 |
构建参数 只在构建的时候使用的参数 如果有 ENV 那么 ENV 的相同名字的值始终覆盖 arg 的参数 |
VOLUME |
定义外部可以挂载的数据卷 |
指定 build 的 image 那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME ["目录"] |
EXPOSE |
暴露端口 |
定义容器运行的时候监听的端口 启动容器的使用 - p 来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp |
WORKDIR |
工作目录 |
指定容器内部的工作目录 如果没有创建则自动创建 如果指定 / 使用的是绝对地址 如果不是 / 开头那么是在上一条 workdir 的路径的相对路径 |
USER |
指定执行用户 |
指定 build 或者启动的时候 用户 在 RUN CMD ENTRYPONT 执行的时候的用户 |
HEALTHCHECK |
健康检查 |
指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制 |
ONBUILD |
触发器 |
当存在 ONBUILD 关键字的镜像作为基础镜像的时候 当执行 FROM 完成之后 会执行 ONBUILD 的命令 但是不影响当前镜像 用处也不怎么大 |
STOPSIGNAL |
发送信号量到宿主机 |
该 STOPSIGNAL 指令设置将发送到容器的系统调用信号以退出。 |
SHELL |
指定执行脚本的 shell |
指定 RUN CMD ENTRYPOINT 执行命令的时候 使用的 shell |
# 服务编排
# 服务编排概念
服务编排:按照一定的业务规则批量管理容器
微服务架构的应用系统中会包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,维护的工作量会很大
- 要从 Dockerfile build image 或者 dockerhub 拉取 image
- 要创建多个 container
- 要管理这些 container
# Docker Compose
# 概述
- 利用 Dockerfile 定义运行环境镜像
- 利用 docker-compose.yml 定义组成应用的各服务
- 运行 docker-compose up 启动应用
# Docker Compose 安装
# 安装 Docker Compose
| |
| curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose |
| |
| chmod +x /usr/local/bin/docker-compose |
| |
| docker-compose -version |
# 卸载 Docker Compose
| |
| rm /usr/local/bin/docker-compose |
# 使用 docker compose 编排 nginx+springboot 项目
- 创建 docker-compose 目录
| mkdir ~/docker-compose |
| cd ~/docker-compose |
- 编写 docker-compose.yml 文件
| version: '3' |
| services: |
| nginx: |
| image: nginx |
| ports: |
| - 80:80 |
| links: |
| - app |
| volumes: |
| - ./nginx/conf.d:/etc/nginx/conf.d |
| app: |
| image: app |
| expose: |
| - "8080" |
- 创建./nginx/conf.d 目录
- 在./nginx/conf.d 目录下 编写 itheima.conf 文件
| server { |
| listen 80; |
| access_log off; |
| |
| location / { |
| proxy_pass http://app:8080; |
| } |
| |
| } |
- 在~/docker-compose 目录下 使用 docker-compose 启动容器
- 测试访问
| http://192.168.149.135/hello |
# Docker 私有仓库
# 搭建私有仓库
| |
| docker pull registry |
| |
| docker run -id --name=registry -p 5000:5000 registry |
| |
| |
| vim /etc/docker/daemon.json |
| |
| {"insecure-registries":["私有仓库服务器ip:5000"]} |
| |
| systemctl restart docker |
| docker start registry |
# 上传镜像到私有仓库
| |
| docker tag centos:7 私有仓库服务器IP:5000/centos:7 |
| |
| docker push 私有仓库服务器IP:5000/centos:7 |
# 从私有仓库拉取镜像
| |
| docker pull 私有仓库服务器ip:5000/centos:7 |