一.Docker简介
1.Docker是什么?
产生背景:

  • 开发与运维之间因为环境不同而导致的矛盾(不同的操作系统、软件环境、应用配置等)DevOps
  • 集群环境下每台服务器都配置相同的环境,太麻烦()
  • 解决“在我的机器上可以正常工作”的问题”

Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器 中,然后发布到任何留下的Linux机器上,也可以实现虚拟化。
阿里云、百度云都支持Docker技术
官网:https://ww.docker.com/
中文官网:http://www.docker-cn.com
2.Dokcer作用
Docker是 一种容器技术,使用Docker可以:

  • 将软件环境安装并配置好,打包成一个镜像images,然后发布这个镜像(Docker仓库:分私有仓库、共有仓库)
  • 其他使用者可以在仓库中下载获取这个镜像
  • 通过Docker运行这个镜像,可以获取同样的环境(容器)

Docker简化了环境部署和配置,实现“一次构建,处处运行”,避免了因运行环境不一致而导致的异常。可将Docker认为就是一个虚拟机,可以运行各种软件环境的虚拟机,但与传统的虚拟机技术有所不同。
Docker与传统虚拟机区别:

  • 传统虚拟机:模拟一个完整的操作系统,先虚拟出一套硬件,然后在上面安装操作系统,最后在系统上运行应用程序

缺点:资源占用多,启动慢

  • Docker容器技术:默认情况下,模拟最小化操作系统,没有硬件虚拟,而是对进程进行隔离,封装成容器,容器内的应用程序是直接使用宿主机的内核,而且容器之间是互相隔离,互不影响

优点:更轻便、效率高、启动快、秒级
3.基本术语

  1. 术语:
  • 宿主机(Host)

安装Docker的主机,运行Docker的守护进程

  • Docker镜像

将软件环境打包好的模板,用来创建容器的,一个镜像可以创建多个容器

  • Docker容器

运行镜像后生成的实例称为容器,每运行一次镜像就会产生一个容器,容器可以启动、停止、删除等
容器使用是沙箱机制,互相隔离,是独立安全的。
可以把容器看做一个是简易版的Linux环境,包括用户权限、文件系统和运行的应用等

  • Docker仓库(Repostiory)

用来保存镜像,仓库中包含许多镜像,每个镜像都有不同的标签Tag
官方仓库:https://hub.docker.com
可以创建阿里云、腾讯云镜像仓库
如阿里云(注册并登陆,下面会有解释):http://dev.aliyun.com

  1. 使用Docker的步骤:

1.安装Docker
2.从Dokcer仓库中下载(拉取)对应的镜像
3.运行这个镜像,此时会生成一个Docker容器
4.对容器的启动/定制就是对软件的启动、停止

二.准备Liunx系统
1.安装虚拟机软件
VMware、VirtualBox
Ubuntu、RHEL、Centos、Debian、SLEL(SUSE)
2.新建虚拟机
版本:Red Hat (64-bit)
网络:桥接网络
光驱:选择操作系统的ISO文件
3.安装CentoOS
4.连接Linux服务器

  • 查看服务器IP地址
    • 在虚拟机中执行 ip addr
  • 连接服务器
    • 在客户端执行ssh 服务器账户@服务器地址,输入密码
    • >

    • 注:SSH是Secure Shell的缩写,用于远程登录访问的协议 >

    • 常用SSH工具Mobaxterm、Xshell、SecureCRT、Putty >

    • >

5.基本操作
常用命令

  • 查看CPU信息

    • cat /proc/cpuinfo
  • 查看内存信息

    • cat /proc/meminfo
  • 查看内核信息,Dcoker要求Centos必须是64位,且内核是3.10及以上

    • uname -r
  • 重启,sudo表示以管理员身份执行

    • sudo reboot
  • 关机

    • sudo halt
  • 安装软件

使用yum,是一个基于rpm的软件包管理工具,用来安装软件包,可以自动解决软件包之间的依赖关系

  • 安装

    • yum install 软件包名
  • 卸载

    • yum remove 软件包名

三.Docker安装

  1. 安装

Docker版本:社区版CE、企业版EE

  1. 启动停止
  • 查看版本

    • docker version
  • 启动Docker

    • systemctl start docker
  • 停止Docker

    • systemctl stop docker
  • 查看Docker状态

    • systemctl status docker
  • 重启Docker

    • systemctl restart docker
  • 开机自启Docker

    • systemctl enable docker
  • 验证

    • docker run hello-world
  1. 配置Docker镜像加速

使用阿里云提供的镜像加速(镜像仓库),也可以使用网易云、腾讯云等
步骤:

  1. 注册并登陆“阿里云开发者平台” http://dev.aliyun.com
  2. 查看专属的加速器地址
  3. 配置自己的Docker加速器

cat > /etc/docker/daemon.json << EOF { “registry-mirrors”: [“https://nl6ae6qz.mirror.aliyuncs.com“] } EOF systemctl daemon-reload systemctl restart docker

四.Docker操作
输入docker 可以查看Docker的命令用法,输入docker COMMAND —help 可以查看指定命令的详细方法

  1. 镜像操作 | 操作 | 命令 | 说明 | | :—-: | :—-: | :—-: | | 查找 | docker search 关键字 | 可以在Docker Hub网站查看镜像的详细信息,如镜像的tag标签、Dockerfile等 | | 抽取 | docker pull 镜像名:tag | :tag表示软件的版本,如果不指定默认是latest | | 列表 | docker images | 查看所有本地镜像 | | 获取元信息 | docker inspect 镜像id | 获取镜像的元信息,详细信息 | | 删除 | docker rmi -f 镜像ID或镜像名:tag | 删除指定的本地镜像,-f表示强制删除 |

  2. 容器操作 | 操作 | 命令 | 说明 | | :—-: | :—-: | :—-: | | 运行 | docker run - name 容器名 -it -p 主机端口:容器端口 -d -v 主机目录:容器目录:ro 镜像id或镜像名称:tag | —name指定容器名,名称自定义,如果不指定会自动命名;
    -i 以交互模式运行,即以交互模式运行容器;
    -t 分配一个伪终端,即命令行,通常组合使用-it;
    -p 指定端口映射,将主机端口映射到容器内的端口;
    -d 表示后台运行,即守护式运行容器;
    -v 指定挂载主机目录到容器目录,默认为rw读写模式,ro表示只读 | | 列表 | docker -ps -a -q | 查看正在运行的容器
    -a 表示显示所有容器
    -q 表示只显示容器id | | 启动 | docker start 容器id或容器名称 | 启动容器 | | 停止 | docker stop 容器id或容器名称 | 停止正在运行的容器 | | 删除 | docker rm -f 容器id或容器名称 | 删除容器,-f表示强制删除 | | 日志 | docker logs 容器id或容器名称 | 获取容器的日志 | | 进入容器 | docker exec -it 容器id或容器名称 bash | 进入正在运行的容器中并开启一个交互模式的终端,可以在容器中执行操作 | | 拷贝文件 | docker cp 主机中的文件路径 容器id或容器名称:容器路径;
    docker cp 容器id或容器名称:容器中的文件路径 主机中的文件路径 | 将宿主机中的文件拷贝到容器中;
    将容器中的文件拷贝的宿主机中 | | 获取元信息 | docker inspect 容器id | 获取容器的元信息 |

以安装一个只有CentOS的容器为例:

  • 搜索镜像

    • docker serach centos
  • 拉取镜像

    • docker pull centos
  • 查看镜像

    • dcoker images
  • 运行镜像并且定义容器名为mycantos

    • docker run —name mycentos -it centos:latest
  • 查看容器运行状态

    • docker ps -a
  • 停止容器运行可以写容器名或容器ID

    • docker stop mycentos
  • 启动容器运行可以写容器名或容器ID

    • docker start mycentos
  • 删除容器名为mycentos的容器,-f 强制删除

    • docker rm mycentos
  • 强制删除所有容器

    • docker rm -f $(docker ps -aq)
  • 强制删除最近一个启动的容器

    • docker rm -f $(docker ps -qn 1)

注:Docker容器内实际上是至少运行着一个精简版的Linux系统
以tomcat为例:
#示例1:基本用法

  • 搜索镜像

    • docker serach tomcat
  • 拉取镜像

    • docker pull tomcat
  • 查看镜像

    • dcoker images
  • 运行镜像并且定义容器名为mytomcat并且将容器内8080端口映射到宿主机上的8888端口,并后台守护式运行该容器

    • docker run —name mytomcat -p 8888:8080 -d tomcat
  • 查看容器运行状态

    • docker ps -a
  • 停止容器运行可以写容器名或容器ID

    • docker stop mytomcat
  • 启动容器运行可以写容器名或容器ID

    • docker start mytomcat
  • 测试:访问

#示例2:拷贝文件和挂载目录

  • 再次运行一个tomcat容器

    • docker run -p 8080:8080 -d tomcat
  • 以交互模式进入到最近一个tomcat容器中

    • docker exec -it $(docker ps -qn 1) bash
  • 确认tomcat默认页面目录 /usr/local/tomcat/webapps/ROOT/index.jsp

    • cd /usr/local/tomcat/webapps/ROOT && ls
  • 退出容器

    • exit
  • 创建一个index.jsp、自定义内容

    • echo welcome to tomcat > index.jsp
  • 将这个index.jsp复制到容器中的tomcat默认页面目录

    • docker cp index.jsp $(docker ps -qn 1):/usr/local/tomcat/webapps/ROOT
  • 访问宿主机的8080端口即可看到默认页面的变化

问题:如果项目更改了需要重新拷贝war包到容器下面,那多麻烦,于是我们可以考虑挂载目录(也称为数据库Volume,这边没有war包就以*.war代替了,以供参考)

  • 首先在宿主机上创建一个存放tomcat-war包的目录

    • mkdir -p /my/tomcat/webapps/
    • docker run \
    • -p 8080:8080 \
    • -v /my/tomcat/webapps/.war:/usr/local/tomcat/webapps/.war \
    • -d tomcat

#示例3:一个镜像可以启动多个容器,并且这些容器默认情况下是互相隔离、独立的

  • 启动多个容器测试
    • docker run -p 8081:8080 -d tomcat
    • docker run -p 8082:8080 -d tomcat
    • docker run -p 8083:8080 -d tomcat
    • docker ps -a
  1. 镜像的分层结构

tomcat镜像为什么这么大?
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境的软件,包含运行某个软件所需要的所有依赖。
基于UnionFS联合文件系统,采用分层结构,一层一层的堆叠起来,像一个同心圆,但从外面来说,只能看到最外层的文件系统。

分层结构:共享资源、便于服用(许多镜像都是从相同的Base基础镜像构建而来的,基础镜像只需要保存一份)
镜像都是只读的,而由镜像生成的容器是可修改的。
4.创建镜像
有时从Docker镜像仓库中下载的镜像不能满足我们的要求,此时可以基于这个镜像(基础镜像)封装一个自己的镜像
两种方式:

  • 更新镜像:使用docker commit命令
  • 构建镜像:使用docker build命令(需要创建自定义Dockerfile)

5.更新镜像
先使用基础镜像创建一个容器,然后对容器进行修改,最后使用commit命令提交为一个新的镜像
步骤:

  • 根据基础镜像,创建容器
    • docker run —name mytomcat -p 8080:8080 -d tomcat
  • 修改容器
    • docker exec -it $(docker ps -qn 1) /bin/bash
      • cd webapps/ROOT
      • rm -f index.jsp
      • echo welcome to tomcat > index.html
      • exit
  • 提交为新镜像,语法:docker commit -m=”描述消息” -a=”作者” 容器id容器名 镜像名:tag
    • docker commit -m=”修改默认索引页” -a=”伟伟” $(docker ps -qn 1) weiwei/tomcat:v1
  • 使用新镜像运行容器
    • docker run —name tomcat_v1 -p:8080:8080 -d weiwei/tomcat:v1

6.构建镜像
根据Dockerfile文件来自动构建镜像
Dockerfile是一个包含创建镜像是所有命令的脚本文件,使用docker build命令可以根据Dockerfile的内容创建镜像
步骤:

  • 创建一个Dockerfile文件vi Dockerfile
    • 基础镜像

    • FROM tomcat
    • 作者

    • MAINTAINER dobixu@163.com
    • 执行命令

    • RUN rm -f /usr/local/tomcat/webapps/ROOT/index.jsp
    • RUN ECHO “WELCOME TO DOCKER TOMCAT!” > /usr/local/tomcat/webapps/ROOT/index.html
  • 构建新镜像,语法docker build -f Dockerfile文件的路径 -t 镜像名:tag 命令执行的上下文
    • docker bulid -f Dockerfile -t weiwei/tomcat:v2
  • 查看镜像
    • docker images
  • 使用新镜像运行容器
    • docker run -p 9999:8080 -d weiwei/tomcat:v2

五.Dockerfile详解
1.简介
Dockerfile是用来构建Docker镜像的文件,是由一系列命令和参数构成的脚本。
Dockerfile从FROM命令开始,紧接着各种命令、参数等,最终会生成一个新的镜像。
使用Dockerfile构建镜像的步骤:
1.编写Dockerfile文件
2.使用docker build构建镜像
3.使用docker run运行容器
2.用法
语法规则

  • 指令不行要大写,而且后面必须跟参数
  • 第一条指令必须是FROM,指定Base Image 基础镜像
  • 指令按从上往下的顺序,依次执行
  • 每条指令都会创建一个新的镜像层并提交
  • 表示注释

3.常用指令

指令 解释
FROM 指定基础镜像,即当前新镜像是基于哪个镜像的
MAINTAINER 指定作者
RUN 指定构建过程中要运行的命令
ENV 设置环境变量
WORKDIR 指定默认的工作目录,即进入容器后默认进入的目录
VOLUME 创建挂载点,也称容器数据卷,用于数据共享和持久化
CMD 指定容器启动时要运行的命令,与RUN不同的是,这些命令不是在镜像构建过程中执行的
ENTRYPOINT 指定容器启动时要运行的命令,与CMD有区别
COPY 拷贝文件/目录到镜像中
ADD 拷贝文件到镜像中,且会自动解压缩
EXPOSE 指定对外暴露的端口

4.案例
案例1:自定义centos镜像

  • 编写Dockerfile文件

  • vi Dockerfile2
    • FROM centos
    • MAINTAINER dobixu@163.com
    • ENV MYPATH /usr/local/centos
    • RUN mkdir -p $MYPATH
    • WORKDIR $MYPATH
    • RUN yum -y install vim
    • RUN yum -y install wget
    • 创建挂载点,无法指定宿主机上对应的目录,是自动生成的

    • VOLUME [“/data1”,”/data2”]
    • CMD [“/bin/bash”]
  • 使用docker build构建镜像(执行中可以看到构建过程)

    • docker build -f Dockerfile2 -t weiwei/centos:v1 .
  • 使用docker run运行容器(测试vim wget是否使用)

    • docker run -it -d weiwei/centos:v1
    • mkdir /data1/testfile
  • 查看镜像的变更历史(可以看到构建时的步骤,即每个镜像的Dockerfile)

    • docker history weiwei/centos:v1
  • 验证挂载点(在宿主机上的挂载点目录是自动生成的)

    • find / -name -tpye d testfile

CMD和ENTRYPOINT的区别(面试题):
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  • CMD

在Dockerfiel中,可以有多个CMD命令,但只有最后一条CMD指令生效,所以一般只有一条CMD指令
CMD指令在会被docker run之后的参数覆盖,例如
vi abc

  • FROM centos
  • CMD [“/bin/ls”]
  • CMD [“/bin/bash”]

docker build -f abc -t weiwei/abc .
docker run -t weiwei/abc
docker run -it weiwei/abc /bin/pwd

  • ENTRYPOINT

docker run 之后的参数会被作为ENTRYPOINT指令的参数,组合形成新的命令

  • vi nba
    • FROM centos
    • ENTRYPOINT [“/bin/ls”.”/usr/local”]

docker build -f nba -t weiwei/nba .
docker run -it weiwei/nba
#实际上执行结果为ls /usr/local -l
docker run -it weiwei/nba -l
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
案例2:自定义tomcat镜像(自行下载jdk+tomcat)

  • 编写Dockerfile文件

  • vi Dockerfile
    • FROM centos
    • MAINTAINER dobixu@163.com
    • 拷贝文件,文件必须与Dockerfile在同一个目录下

    • ADD jdk-8u171-linux-x64.tar.gz /usr/local
    • ADD apache-tomcat-8.5.30.tar.gz /usr/local
    • 配置环境变量

    • ENV JAVA_HOME /usr/local/jdk1.8.0_171
    • ENV CLASSPATH .:$JAVA_HOME/lib
    • ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.30
    • ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin
    • WORKDIR $CATALINA_HOME
    • RUN yum -y install vim
    • EXPOSE 8080
    • CMD [“catalina.sh”,”run”]
  • 使用Docker build 构建镜像

    • docker build weiwei/tomcat:v1
  • 创建一个自定义默认页面

    • mkdir -p /data/tomcat/webapps/ROOT/
    • echo “welcome to user-define d-tomcat” > /data/tomcat/webapps/ROOT/index.jsp
  • 使用docker run运行容器

    • docker run \
    • —name mytomcat \
    • -p 8888:8080 \
    • -v /data/tomcat/webapps/ROOT/index.jsp:usr/local/tomcat/webapps/ROOT/index.jsp \
    • -d weiwei/tomcat:v1
  • 访问宿主机8888端口

六.使用Docker搭建环境
各个镜像的配置、数据、日志路径存放路径可以在hub.docker.com自行搜索其文档中有说明
1.安装MySQL

  • 拉取指定版本镜像

    • docker pull mysql:5.7
  • 运行容器

    • docker run \
    • —name mysql \
    • -p 3306:3306 \
    • -e MYSQL_ROOT_PASSWORD=root \
    • -d mysql:5.7
  • 进入容器查看mysql数据文件,配置文件,日志存放位置(将其挂载出来,以便于非正常关闭mysql容器数据丢失)

    • docker exec -it mysql /bin/bash
    • find / -name “mysql”
    • exit
  • 创建用于挂载的目录

    • mkdir -p /data/mysql/{conf,data,logs}
  • 拷贝配置文件并修改

    • docker cp mysql:/etc/mysql/mysql.conf.d/mysqld.cnf /data/mysql/conf/
    • vi /data/mysql/conf/mysqld.conf
  • 将默认创建数据库格式加入配置文件中

    • character-set-server=utf8
  • 关闭最近一个创建的容器

    • docker rm -f $(docker ps -qn 1)
  • 重新运行容器

    • docker run \
    • —name mysql \
    • -p 3306:3306 \
    • -v /data/mysql/conf/:/etc/mysql/mysql.conf.d/ \
    • -v /data/mysql/data:/var/lib/mysql \
    • -v /data/mysql/logs:/logs \
    • -e MYSQL_ROOT_PASSWORD=root \
    • -d mysql:5.7
  • 本地访问

    • docker exec -it $(docker ps -qn 1) /bin/bash
    • mysql -u root -p
  • 远程访问(navicat等)

    • mysql -u root -p -h 宿主机地址 -P 3306

2.安装Redis

  • 拉取最新版本镜像

    • docker pull redis
  • 创建用于挂载的目录

    • mkdir -p /data/redis/{conf,data,logs}
  • 拷贝配置文件并修改

  • 运行容器

    • docker run \
    • —name myredis \
    • -p 6379:6379 \
    • -v /data/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf \
    • -v /data/redis/data:/data \
    • -d redis
  • 本地访问

    • docker exec -it myredis /bin/bash
    • redis-cli
  • 远程访问
    • 使用RedisDesktopManager等工具连接

3.安装Nginx

  • 拉取镜像

    • docker pull nginx
  • 运行容器

    • docker run —name mynginx -p 80:80 -d nginx
  • 创建用于挂载的目录

    • mkdir -p /data/nginx/{conf.d,html}
  • 拷贝配置文件

    • docker cp mynginx:/etc/nginx/nginx.conf /data/nginx
  • 拷贝虚拟主机的配置文件

    • docker cp mynginx:/etc/nginx/conf.d /data/nginx/conf.d
  • 自定义索引页

    • echo “welcome to mynginx” > /data/nginx/html/index.html
  • 关闭之前的容器

    • docker rm -f mynginx
  • 启动容器
    • docker run \
    • -p 80:80 -p 443:443 \
    • -v /data/nginx/nginx.conf:/etc/nginx/nginx.conf \
    • -v /data/nginx/html/:/usr/share/nginx/html/:ro \
    • -v /data/nginx/conf.d:/usr/nginx/conf.d \
    • -d nginx
  • 测试

七.将本地镜像发布到阿里云(也可以自荐仓库如harbor)
步骤:
1.登录”阿里云-开发者平台”,创建命名空间和镜像仓库
2.将镜像推送到阿里云

  • 登录阿里云的docker仓库

    • docker login —username=dobixu@163.com registry.cn-hangzhou.aliyuncs.com
  • 创建指定镜像的tag,归入某个仓库

    • docker tag $(docker ps -qn 1) registry.cn-hangzhou.aliyuncs.com/weiwei/nginx:v1.0
  • 将镜像推送到仓库中

    • docker push registry.cn-hangzhou.aliyuncs.com/weiwei/nginx:v1.0
  • 拉取镜像

    • docker pull registry.cn-hangzhou.aliyuncs.com/weiwei/nginx:v1.0