通过本篇文章,就可以达到在 Window 或 Linux 上手 Docker(有点长,可以根据目录选择你需要的内容看)

文章图片没有带过来,涉及的图片较多,就不一一挪了,大家可以直接看我 GitChat : ​​[Docker 快速入门]​

  1. 什么是容器
    1.1 用大白话介绍下什么是容器
    1.2 再看下稍微正式些的说法
    1.3 物理机、虚拟机、容器的区别
  2. Docker 为什么这么火
    2.1 什么是 Docker
    2.2 Docker 火的原因
  3. Docker 在企业的应用(应用场景)
    3.1 快速部署
    3.2 同步开发环境和生产环境
    3.3 当然还有其他应用场景
  4. 如何在 Win10 或者 Win7 下结合 Spring Boot 运行 Docker 程序
    4.1 准备工作
    4.2 Win10 安装 Docker
    4.3 IDEA 安装 Docker 插件
    4.4 IDEA 连通 Docker,并指定项目生成 Docker 镜像
    4.5 IDEA 运行镜像
  5. Linux 下安装 Docker 及运行 Springboot 项目
    5.1 Docker 安装
    5.2 运行容器
    5.4 更改 Docker 镜像仓库地址
    5.5 Docker 运行 Spring Boot 项目
    5.5.1 上传服务器
    5.5.2 创建影像
    5.5.3 查看镜像
    5.5.4 运行镜像
    5.5.4 查看镜像
    5.5.5 访问接口
    5.5.6 查看容器下的日志
    5.5.7 容器日志挂载到磁盘中
  6. 详解 Dockerfile 文件
    6.1 什么是 Dockerfile
    6.2 Dockerfile 文件结构
    6.3 用一个完整例子说明 Dockerfile 中的关键字
  7. 上传下载镜像
  8. 常用的 Docker 命令
    8.1 先了解下 Docker 关键字:
    8.2 常见命令详解
  9. Docker 进一步学习
    Docker 三剑客:Machine、Compose、Swarm
    Docker 与 Kubernetes(K8S)
    致谢
  10. 什么是容器
    1.1 用大白话介绍下什么是容器
    容器就是一个存放东西的地方,就像书包可以装各种文具、衣柜可以放各种衣服、鞋架可以放各种鞋子一样。我们现在所说的容器存放的东西可能更偏向于应用比如网站、程序甚至是系统环境,如大家常用的容器存放 Nginx、MySQL、Java 接口服务。

1.2 再看下稍微正式些的说法
容器就是将软件打包成标准化单元,以用于开发、交付和部署。

容器镜像是轻量的、可执行的独立软件包 ,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置。
容器化软件适用于基于 Linux 和 Windows 的应用,在任何环境中都能够始终如一地运行。
容器赋予了软件独立性,使其免受外在环境差异(例如开发和预演环境的差异)的影响,从而有助于减少团队间在相同基础设施上运行不同软件时的冲突。
以上内容部分参考:什么是容器?为什么需要它?

1.3 物理机、虚拟机、容器的区别
三张图让你明白:

物理机

enter image description here

虚拟机

enter image description here

容器

enter image description here

以上三张图片引自:物理机、虚拟机、容器的比较

  1. Docker 为什么这么火
    2.1 什么是 Docker
    Docker 是世界上领先的容器软件平台,用户可以方便地创建和使用 Docker,把自己的应用放入 Docker 容器中来运行。

Docker 的镜像还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。

Docker 三个基本概念:

镜像(Image)
容器(Container)
仓库(Repository)
Docker 三个关键动作:Build、Ship、 Run。

Build(构建镜像):镜像就像是集装箱包括文件以及运行环境等等资源
Ship(运输镜像):主机和仓库间运输,这里的仓库就像是超级码头一样
Run (运行镜像):运行的镜像就是一个容器,容器就是运行程序的地方
以上内容部分引自:《Docker 技术入门与实战》

2.2 Docker 火的原因
一致的运行环境:Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现“这段代码在我机器上没问题啊”这类问题。
更快速的启动时间:可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
隔离性:避免公用的服务器,资源会容易受到其他用户的影响。
弹性伸缩,快速扩展:善于处理集中爆发的服务器使用压力。
迁移方便:可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
持续交付和部署:使用Docker可以通过定制应用镜像来实现持续集成、持续交付、部署。
3. Docker 在企业的应用(应用场景)
不同的公司应用场景不同,大部分公司主要是用于下两个方面(个人理解)。

3.1 快速部署
尤其是集群服务,把各个服务及依赖的环境都打包成一个个镜像,上传镜像到私有仓库中,集群各个节点从私有仓库下拉镜像然后运行即可,不需要再给每个服务器安装 JDK、Nginx 等环境。

3.2 同步开发环境和生产环境
大家都经常遇到过:程序在自己电脑运行正常,放到服务器上就报错了,这就是运行环境不同造成的,而通过 Docker在本机配置好 Dockerfile 文件后创建镜像,上传镜像库,再从镜像库下载到生产服务器,直接运行,这样就保证了开发和生产环境的一致。

3.3 当然还有其他应用场景
大家可以看下下面的文章:8 个 Docker 真实应用场景 。

  1. 如何在 Win10 或者 Win7 下结合 Spring Boot 运行 Docker 程序
    4.1 准备工作
    工具:

Win10
IDEA 2018
Maven 3.5
JDK 8
这里提醒下:Win10 家庭版相当于 Win7 系统,不能直接装 Docker,需要安装 Docker Toolbox,安装完之后会有以下三个图标(自己有一台笔记本系统是 Win10 家庭版,为了给大家说明白,自己手动安装了一遍):

enter image description here

点击 Docker Quickstart 就进入 Docker 环境,就可以操作 Docker 命令,用这个工具就相当于在 Windows 系统上开了个虚机,是有 IP 的,所以访问 Docker 服务的时候不能用 localhost,而是用 Docker 虚机的 IP,默认是:运行命令 docker-machine ip default 查看虚拟机的 IP 地址,默认为 192.168.99.100。

4.2 Win10 安装 Docker
Win10 安装 Docker 参考:Window Docker 安装。

安装完毕后,点击任务栏上的小鲸鱼,选择 Settings:

enter image description here

点击 Daemon,在 Registry mirrors 输入镜像加速地址,国内选的是 DaoCloud 提供的。

地址:https://www.daocloud.io/mirror#accelerator-doc

注册一个账号或用 GitHub 账号登陆。选择 Windows,复制地址粘贴到 Registry mirrors 里:

enter image description here

进入 cmd,输入 docker version,查看版本,能正常显示 Docker 版本信息就表示安装成功。

4.3 IDEA 安装 Docker 插件
点击扳手按钮:

enter image description here

在输入框输入 plguin,点击 Plugins,选择 Browse:

enter image description here

在输入框输入 docker,并选择安装,然后重启 IDEA:

enter image description here

4.4 IDEA 连通 Docker,并指定项目生成 Docker 镜像
打开设置中心,也就是扳手按钮,在输入框输入 docker,点击 + 号:

enter image description here

需要注意的是 Win7 的地址输入,是 https,并且是 2376 端口!

enter image description here

Win7 下 IP 一般是 192.168.99.100,Win7 下需要通过 Oracle VM VirtualBox 开一个 Linux 系统,会给个默认 IP。

设置 Docker,点击小鲸鱼,选择 Settings,General,勾选最后一项,就打通了 Docker 与 IDEA 的连接。

enter image description here

4.5 IDEA 运行镜像
新建一个简单的 Spring Boot 项目,设置端口号为 8761:

server.port= 8761
建一个 Spring Boot 测试项目,结构如下:

enter image description here

新建一个文件夹 docker,src/main/docker,在 docker 里新建一个 Dockerfile 文件,配置文件内容:

FROM java:8
VOLUME /tmp
ADD dockerTest-0.0.1-SNAPSHOT.jar app.jar
RUN bash -c 'touch /app.jar'
EXPOSE 8761
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
#ADD后面跟的是项目jar包,在运行之前我们需要打包,然后把jar包放在 docker 文件里

编辑 Dockerfile 文件:

enter image description here

前面两个是镜像名字和容器名字,Bind ports 前面那个是我们启动后访问的端口,后面那个是 Dockerfile 里设置的端口:

enter image description here

点击 Run 运行:到 doc 窗口输入 docker ps 查看进程:

enter image description here

可以看到,程序已运行,然后我们访问:localhost:8123 (Win10):

enter image description here

(Win7)访问:http://192.168.99.100:8123/hello

enter image description here

当然也可以在 Windows 下用命令生成镜像,并运行容器(命令和 Linux 一样的,我就直接在 Linux 环境下介绍了)。

  1. Linux 下安装 Docker 及运行 Springboot 项目
    5.1 Docker 安装
    #安装
    yum -y install docker-io
    #运行docker服务
    service docker start
    #再运行查看版本
    docker -v
    enter image description here

5.2 运行容器
学 Java 的都知道 hello world,Docker 也有 hello world 镜像,看下 Docker 如何运行 hello-world 的。

#尝试运行第一个容器
docker run hello-world

enter image description here

从结果可以看出本地没有 hello-world 镜像,尝试去远程仓库去拉,然后运行,其实刚才运行了两个命令:

docker pull hello-world
docker run hello-world

#查看所有容器
docker ps -a
#查看镜像
docker images

enter image description here

#删除镜像,删除前要关闭镜像运行的容器
docker rmi 镜像名称

5.4 更改 Docker 镜像仓库地址
#编辑文件
vim /etc/docker/daemon.json
添加如下内容(还是用 DaoCloud):

{
"registry-mirrors": ["https://get.daocloud.io/daotools/set_mirror.sh"]
}

重启服务

#重新加载配置
sudo systemctl daemon-reload
#重启docker服务
sudo systemctl restart docker

5.5 Docker 运行 Spring Boot 项目
5.5.1 上传服务器
把在 Windows 下打包的 Jar 包和 Dockerfile 文件上传到 Linux 服务器上:

enter image description here

enter image description here

5.5.2 创建影像
语法:docker build -t 要生成的镜像名 .

docker build -t spring/dockertest .
#最后的”.”不要忘记加上,表示当前目录

5.5.3 查看镜像
语法:docker images

enter image description here

5.5.4 运行镜像
docker run -d -p 8086:8761 --name spring-dockertest spring/dockertest

#-d 后台启动 
#-p 8086:8761 把镜像启动的端口(右)映射到linux机的端口(左)
#–name spring-dockertest 给你的容器命名
#spring/dockertest 你的镜像名

运行结果看下面图,一起截的。

5.5.4 查看镜像
enter image description here

5.5.5 访问接口
enter image description here

5.5.6 查看容器下的日志
#查看对应容器的启动日志:docker logs containerId
docker logs 46a9447ff6fb
enter image description here

到这里你就学会了在 Windows 和 Linux 下运行 Spring Boot 项目,并对 Docker 概念有了初步的认识,是不是感觉 Docker 也挺简单的,接下来说下细节。

5.5.7 容器日志挂载到磁盘中
做过开发的都知道日志的重要性,日志放容器中肯定是不安全的,等容器一删,历史日志就找不到了,所以需要持久化到磁盘上。这里拿启动 Nginx 服务来举例:

docker run --name nginx -d -p 80:80 -v /mnt/resource/data/nginx/html:/usr/share/nginx/html  -v /mnt/resource/data/nginx/logs:/var/log/nginx nginx

可以看出关键字:-v,/mnt/resource/data/nginx/logs 为服务器磁盘目录,/var/log/nginx 为容器目录,查看容器目录命令:

docker exec -it containerID /bin/bash

进入容器查看;看上面例子不仅是日志可以挂载,其他文件目录也是可以的。

  1. 详解 Dockerfile 文件
    6.1 什么是 Dockerfile
    Dockerfile 是一个包含用于组合映像的命令的文本文档。可以使用在命令行中调用任何命令。 Docker 通过读取 Dockerfile 中的指令自动生成镜像。

docker build 命令用于从 Dockerfile 构建镜像。可以在 docker build 命令中使用 -f 标志指向文件系统中任何位置的 Dockerfile:

docker build -f /path/to/a/Dockerfile

6.2 Dockerfile 文件结构
Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,’#’ 为 Dockerfile 中的注释。

Docker 以从上到下的顺序运行 Dockerfile 的指令。为了指定基本映像,第一条指令必须是 FROM。一个声明以#字符开头则被视为注释。可以在 Docker 文件中使用RUN、CMD、FROM、EXPOSE、ENV 等指令。

6.3 用一个完整例子说明 Dockerfile 中的关键字
# This my first nginx Dockerfile
# Version 1.0

# Base images 基础镜像
FROM centos

#MAINTAINER 维护者信息
MAINTAINER tianfeiyu

#ENV 设置环境变量
ENV PATH /usr/local/nginx/sbin:$PATH

#ADD 文件放在当前目录下,拷过去会自动解压
ADD nginx-1.8.0.tar.gz /usr/local/
ADD epel-release-latest-7.noarch.rpm /usr/local/

#RUN 执行以下命令
RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpm
RUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean all
RUN useradd -s /sbin/nologin -M www

#WORKDIR 相当于cd
WORKDIR /usr/local/nginx-1.8.0

RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-pcre && make && make install

RUN echo "daemon off;" >> /etc/nginx.conf

#EXPOSE 映射端口
EXPOSE 80

#CMD 运行以下命令
CMD ["nginx"]

上面的 DockerFile 算比较复杂的了,常用的 Spring Boot 项目的 DockerFile 几句话就能满足要求:

FROM java:8
VOLUME /tmp
ADD test_service.jar app.jar
RUN bash -c 'touch /app.jar'
EXPOSE 8086
ENTRYPOINT ["java","Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
#Linux下设置时区,容器的时区也要改,否则总是少8个小时
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
  1. 上传下载镜像
    首先你得准备一个 Hub 的帐号,去 https://hub.docker.com 注册。

在 Hub 那里新建一个仓库,这个就类似于 GitHub 那边的 create —> create repository(创建知识库)然后随便搞个名字,我这里就叫 ubuntu,所以路径就是 breakli/ubuntu 了。

运行 docker ps 查看容器,这里就是要获取到 CONTAINER ID。

enter image description here

commit 一个容器的命令:

docker commit CONTAINER ID breakli/ubuntu
接下来就是登录一个 Hub 帐号了。命令:

docker login
将刚才的镜像 push 到你的 Hub 那里去,命令:

docker push breakli/ubuntu:latest
这个 latest 其实就是一个 Tag name 会在 Hub 的 Tags 那里显示。注意:有时 push 会超时的,没关系,再 push 一次就好了。

现在验证一下,命令:

docker inspect breakli/ubuntu
最后看一下你的 Hub 中的 Tags 是否有新的更新,下图就是成功了:

enter image description here

下载镜像命令前面有说过:

docker pull 镜像名称
当然在开发实际中,镜像一般是上传到公司私有仓库中,方便上传下载。

  1. 常用的 Docker 命令
    8.1 先了解下 Docker 关键字:
    镜像:images
    镜像名:image_name
    镜像 id:image_id
    容器:container
    容器名:con_name
    容器 id:con_id
    8.2 常见命令详解
    从公网拉取一个镜像
    docker pull images_name
    查看已有的 Docker 镜像
    docker images
    查看帮助
    docker command --help
    查看镜像列表
    docker search nginx
    启动一个容器
    docker run hello-world
    导出镜像
    docker save -o image_name.tar image_name
    删除镜像
    docker rmi image_name
    启动一个容器
    docker run --name=con_name images

–name #设置容器名,基于创建好的容器自定义docker镜像

docker commit -m "con_name" con_id image_name

创建一个容器的同时进入这个容器

docker run -it --name=con_name images

把物理机 80 端口映射到容器的80端口

docker run -d -p 81:80 image_name

看容器的端口映射情况

docker port con_id

查看正在运行的容器

docker ps

查看所有的容器

docker ps -a

动态查看容器日志

docker logs -f con_name

进入容器

docker attach con_name

退出容器

exit

删除容器

docker rm  con_name
#强制删除需要加-f,不加-f不能删除正在运行中的容器,非常危险,最好不用

查看 Docker 网络

[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
3f91f2097286 bridge bridge local
d7675dbd247c docker_gwbridge bridge local
5b36c7e947fd host host local
ims6qkpikafu ingress overlay swarm
85ba10e7ef79 none null local

创建一个 Docker 网络 mydocker

docker network create -d bridge \
--subnet=192.168.0.0/24 \
--gateway=192.168.0.100 \
--ip-range=192.168.0.0/24 \
mydocker

利用刚才创建的网络启动一个容器

#docker run --network=mydocker --ip=192.168.0.5 -itd --name=con_name -h lb01 image_name

--network #指定容器网络
--ip #设定容器ip地址
-h #给容器设置主机名

查看容器 pid

docker top con_name

运行 Dockerfile 并给 Dockerfile 创建的镜像建立名字

docker build -t mysql:3.6.34 `pwd`

MariaDB 容器启动前需先设置密码方法

docker run -d -P -e MYSQL_ROOT_PASSWORD=password  img_id

Docker 修改镜像名

docker tag imageid name:tag

进入 Docker 容器脚本

[root@docker ~]# cat nsenter.sh 
PID=`docker inspect --format "{{.State.Pid}}" $1`
nsenter -t $PID -u --mount -i -n -p
  1. Docker 进一步学习
    因本篇文章主要是一个对 Docker 的入门,让大家对容器、 Docker 概念有所了解,并会在 Windows 和 Linux 下编写 Dockerfile 文件、创建镜像、运行镜像、查看容器日志、并持久化日志到磁盘中等,以及熟练使用 Docker 常用命令,基本上就达到了会用 Docker。大家想进一步学习,可以在以下几个方面深入:

Docker 三剑客:Machine、Compose、Swarm
学习 Machine,你可以更方便快速地搭建 Docker 环境及节点。
学习 Compose,你可以更好地编排你的 Docker 命令,方便管理你项目中的多个容器。
学习 Swarm,你可以用 Swarm 部署微服务,Swarm 是 Docker 原生的,同时也是最简单最省资源的,比较适合中小型公司使用。
在这里写一下以前在搭建 Swarm 集群用到常用命令。

  1. 安装完 Docker 后,初始化集群(哪个节点初始,哪个是主节点,Docker 比较新的版本是带着 Swarm 的)

docker swarm init
2. 设置开机启动

systemctl start dockersystemctl enable docker
3. 其他节点加入集群(后面的命令在初始化后会自动输出):

$ docker swarm join \ --token SWMTKN-123s7yf7fmeh9zouq417u74n9vafl5me6hwwbi1xs0w7qw7jogr-9ynuvbegff0gkvho7xz5zxtky 10.1.1.1:237
4. 注意:如果集群搭建错误,直接执行以下命令离开集群

docker swarm leave -f
5. 删除集群服务

docker service rm nginx
6. Swarm 下运行集群服务,没法用前面说的 -v 来挂载日志目录等,需用数据卷来持久化,如:

docker service create --mount type=volume,src=log,dst=/var/log --name test_service --publish 8080:8080 --replicas 2 test_service
这样 test_service 服务的日志就持久化到了 /var/lib/docker/volumes/log 下,这里我对应的目录比较大,可以具体细到 test_service 单独的日志目录。

Docker 与 Kubernetes(K8S)
K8S:是一个用于管理集群环境中的容器化应用程序的开源系统。以正确的方式使用 Kubernetes 可帮助 DevOps 即服务团队自动扩展应用程序并以零停机时间进行更新。

学习 K8S,可以让你管理更复杂更大的容器集群,可以有更多的场景来选择应对复杂的业务逻辑。

致谢
感谢大家抽出时间看我的 Chat,希望对大家有所帮助,希望通过这一篇 Chat,大家能很快上手 Docker,可能有不少写得不好的地方,欢迎大家提出意见,我会继续努力,及时改正,写出更好的 Chat。

大家可以关注我的公众号“Java海洋”,和我一起成长,一起学习JAVA

Docker 快速入门(一文上手 Docker)_Docker