通过本篇文章,就可以达到在 Window 或 Linux 上手 Docker(有点长,可以根据目录选择你需要的内容看)
文章图片没有带过来,涉及的图片较多,就不一一挪了,大家可以直接看我 GitChat : [Docker 快速入门]
1.2 再看下稍微正式些的说法
容器就是将软件打包成标准化单元,以用于开发、交付和部署。
容器镜像是轻量的、可执行的独立软件包 ,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置。
容器化软件适用于基于 Linux 和 Windows 的应用,在任何环境中都能够始终如一地运行。
容器赋予了软件独立性,使其免受外在环境差异(例如开发和预演环境的差异)的影响,从而有助于减少团队间在相同基础设施上运行不同软件时的冲突。
以上内容部分参考:什么是容器?为什么需要它?
1.3 物理机、虚拟机、容器的区别
三张图让你明白:
物理机
enter image description here
虚拟机
enter image description here
容器
enter image description here
以上三张图片引自:物理机、虚拟机、容器的比较
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 真实应用场景 。
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 环境下介绍了)。
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
进入容器查看;看上面例子不仅是日志可以挂载,其他文件目录也是可以的。
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
在 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 镜像名称
当然在开发实际中,镜像一般是上传到公司私有仓库中,方便上传下载。
常用的 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
Docker 三剑客:Machine、Compose、Swarm
学习 Machine,你可以更方便快速地搭建 Docker 环境及节点。
学习 Compose,你可以更好地编排你的 Docker 命令,方便管理你项目中的多个容器。
学习 Swarm,你可以用 Swarm 部署微服务,Swarm 是 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。
本文免费首发于 GitChat,未经授权不得转载,转载需与 Gitchat 或 本人 联系。