Docker概述
Docker为什么会出现?
环境配置的难题:开发环境,测试环境,模拟环境
开发者常常会说:它在我的机器可以跑了(It works on my machine),言下之意就是,其他机器很可能跑不了.
安装的时候,可不可以把原始环境一模一样地复制过来.
Docker针对上面的问题,提出了解决方案
通过隔离机制将服务器压榨到极致
Docker的历史
2010年,几个年轻人开了家公司dotCloud
做一些pass的云计算技术,容器的技术
他们的技术命名为Docker
后来干不下去了…要倒闭
2013年Docker就开源了,就火了
2014年4月9日Docker1.0发布了
为什么这么火🔥?十分的轻巧!
容器技术之前,都是用的VMware虚拟机,十分笨重
Docker容器,也是一种虚拟机
Docker是基于Go语言开发的
Docker能干啥!
虚拟机技术缺点:
- 资源占用多
- 冗余步骤多
- 启动慢
容器技术
- 容器化技术模拟的不是一台完整的电脑
Docke与虚拟机技术的不同
- 传统虚拟机:虚拟一堆硬件,运行一个完整的系统,然后再这个系统上安装和运行软件
- Docker容器:直接使用宿主机的内核,容器没有自己的内核
- 每个容器间是相互隔离的,没个容器都都有一个自己的文件系统
DevOps(开发,运维)
应用更快的交付和部署
传统:一堆帮助文档,安装程序
Docker:打包镜像,发布测试,一键运行
更便捷的升级和扩缩容
使用了Docker后,项目部署就像搭积木
项目打包为一个镜像,直接在服务器A,服务器B上部署
更简单的系统运维
容器化之后,开发,测试,环境高度一致
更高效的计算资源利用
Docker是内核级的虚拟化,可以在一个物理机上运行很多实例!服务器的性能被压榨到极致!
Docker 的安装
Docker的基本组成
- 镜像(Image):
- Docker镜像相当于一个模板,可以通过这个模板来创建容器,镜像==>run==>容器,通过一个镜像可以常见多个容器
- 容器(container)
- Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的
- 启动,停止,删除等命令
- 可以理解为一个建议的linux系统
- 仓库(repository)
- 仓库就是存放镜像的地方
- 仓库分为公有仓库和私有仓库
- 默认是国外的仓库,可以配置为国内的镜像
安装
安装
1
$ curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
安装完成后,Docker 服务将会自动启动。输入下面的命令来验证:
1
systemctl status docker
查看安装的Docker的版本
1
docker version
Zsh插件的使用
确认安装了Zsh
修改
~/.zshrc
文件找到插件配置项
plugins=()
,增加docker docker-compose
两个插件source ~/.zshrc
使用
运行hello-world
1
docker run hello-world
查看安装的镜像
1
2
3docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 11 months ago 13.3kB
容器加速镜像
1 | mkdir -p /etc/docker |
底层原理
Docker是怎么工作的
Docker是一个Client-Server(C/S)结构的系统,Docker的守护进程运行在主机上,通过Socket等方式从客户端访问
Server收到Client的命令,就会执行这个命令
默认我们安装的Docker包含了服务端与客户端,所以我们在同一台服务商的操作也是经过客户端==>服务端这个过程的
我们可以在本机安装一个客户端==>远程连接远程服务器上的docker服务端
Docker为什么比VM块?
Docker比虚拟机有着更少的抽象层
Docker利用的是宿主机的内核,VM是需要Guest OS
新建一个容器的时候,Docker不需要像VM一样重新加载一个操作系统内核,避免引导
Docker的常用命令
帮助命令
1 | docker version # 显示docker的版本 |
镜像命令
- dokcer images: 查看本地主机上的镜像
1 | dokcer images # 查看本地主机上的镜像 |
- docker search:搜索镜像
1 | docker search nginx |
- docker pull:下载镜像
1 | 可以指定docker 镜像的版本 |
- docker rmi:删除镜像
1 | 两种形式 |
容器命令
docker run:新建容器并启动
1
2
3
4
5
6
7
8
9
10
11
12docker run [可选参数] images
参数说明
--name="name" 容器名称 tomcat01,mysql3306,用来区分容器
-d 后台方式运行
-p 指定容器的端口
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用的)
-p 容器端口
-p 指定随机端口
-i 以交互模式运行容器,通常与 -t 同时使用
-t 为容器重新分配一个伪输入终端,通常与 -i 同时使用
--rm 用完就删除,一般用来测试测试启动容器
1
2启动centos容器,基础版本,很多命令都是不完善的
docker run -it centos /bin/bashdocker ps列出所有正在运行的容器
1
2
3
4
5docker ps
参数说明
-a 显示所有容器,包括没有在运行的容器
-n=2 显示返回条数
-q 只显示容器的编号docker rm删除容器
1
2
3docker rm 容器id # 删除指定的容器
参数说明
-f 强制删除启动和停止容器
1
2
3
4docker start 容器id # 启动容器
docker stop 容器id # 停止容器
docker restart 容器id # 重启容器
docker kill 容器id # 强制停止容器
组合命令(删库跑路)
列出所有容器id
1
docker ps -aq
停止所有的容器
1
docker stop $(docker ps -aq)
删除所有的容器
1
docker rm $(docker ps -aq)
删除所有的镜像
1
docker rmi $(docker images -q)
组合删库跑路
1
docker stop $(docker ps -aq) && docker rm $(docker ps -aq) && docker rmi $(docker images -q)
常用其他命令
docker stats 查看容器使用资源情况
1
2
3
4
5
6
7
8返回容器资源使用情况,一秒刷新一次
docker stats
返回容器资源使用情况,不刷新
docker stats --no-stream
返回容器资源使用情况,已经停掉的也显示
docker stats -a
返回指定容器资源使用情况
docker stats 容器id后台启动容器**-d**
1
2-d 后台启动
docker run -d centosdocker logs查看日志
1
2
3
4
5
6
7docker logs -tf --tail 10 容器id
docker logs [OPTIONS] CONTAINER
OPTIONS说明:
-f 跟踪日志输出
-t 显示时间戳
--since 显示某个开始时间的所有日志
--tail 仅列出最新N条容器日志docker top查看容器中的进程信息
1
2docker top 容器id
docker top 919121a5a1a6docker inspect 查看容器的元数据
1
2docker inspect 容器id
docker inspect 919121a5a1a6进入当前正在运行的容器
通常都是后台运行的,需要进入容器,修改配置之类的
方式一docker exec
1
2
3# 命令
# docker exec -it 容器id /bin/bash
$ docker exec -it 919121a5a1a6 /bin/bash方式二docker attach
1
2
3命令
docker attach 容器id
docker attach 919121a5a1a6两种方式的区别
- docker exec 在容器中启动新的终端
- docker attach 进入容器正在执行命令的那个终端.
docker cp从容器拷贝文件到主机上
1
2
3
4
5
6docker cp 容器id:容器内的文件名 宿主机上的文件名
docker cp 919121a5a1a6:/root/123456.txt /root
docker cp 宿主机上的文件名 容器id:容器内的文件名
docker cp /root/123456.txt 919121a5a1a6:/root
不常用其他命令
docker network对网络的相关操作
1
2
3
4
5
6
7
8
9
10
11
12docker network ls
选项:
connect 将容器连接到网络
create 新建一个网络
--driver 网络类型,默认是bridge桥接
--subnet 子网掩码
--gateway 网关
disconnect 断开容器与网络的连接
inspect 显示一个或多个网络的详细信息
ls 列出网络
prune 删除所有未使用的网络
rm 删除一个或多个网络docker tag 对已经存在的镜像添加标签
1
2docker tag 已存在的镜像id dockerhub用户名/镜像名:TAG
docker tag 69b72121b45e sowevo/diytomcat:1.0docker login登录命令:登录到dockerHub,可以发布自己的镜像了~
1
2
3
4docker login
选项:
-p, --password 密码
-u, --username 账号docker save镜像导出成文件
1
2docker save 镜像id -o 保存的文件名
docker save sowevo/diytomcat:1.0 -o diytomcat.tardocker load从文件导入镜像
1
2docker load -i 遇到导入的文件名
docker load -i diytomcat.tar
案例
nginx
1 | docker run -d -p 1234:80 --name nginx-1234 nginx |
tomcat
1 | docker run -it -p 8080:8080 --name tomcat8080 tomcat |
elasticsearch
1 | docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.10.1 |
总结
可视化
Prtainer
安装
1
docker run -d -p 8000:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
用的比较少
Rancher
Docker镜像
镜像是什么
镜像是一种轻量级.可执行的独立软件,用来打包运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码,运行时,库,环境和配置文件
所有的应用,直接打包Docker镜像,就可以直接跑起来
如何得到镜像
- 从远程仓库下载
- 从别处拷贝
- 自己制作一个镜像Dockerfile
Docker镜像加载原理
UnionFS联合文件系统
我们下载的时候看到的一层层就是这个!
UnionFS (联合文件系统) : Union文件系统( UnionFS )是-种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来-层层的叠加,同时可以将不同录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性: 一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
Docker镜像加载原理
docker的镜像实际上由一层层的文件 系统组成 ,这种层级的文件系统UnionFS。
bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs.这一层与我们典型的Linux/Unix系统是一样的 ,包含boot加载器和内核.当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs.
rootfs (root file system) ,在bootfs之上.包含的就是典型Linux系统中的/dev, /proc, /bin, /etc等标准目录和文件.rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
对于一个精简的OS,rootfs可以很小,只要包含最基本的命令,工具和程序库就可以,底层直接使用宿主机的kernel,对于不同的linux发行版本,bootfs基本一致,rootfs会有差别,因此可以共用bootfs
分层
Docker镜像由一些松耦合的只读镜像层组成
Docker负责堆叠这些镜像层,并且将它们表示为单个统一的对象。
举一个简单的例子.
commit提交镜像
1 | docker commit 将一个容器提交到本地成为一个新的镜像 |
容器数据卷
什么是容器数据卷
将容器内的目录挂载到宿主机上,容器中的数据可以存储到本地,这就是数据卷.
为了容器数据的持久化和数据同步操作
使用数据卷
命令挂载
docker run -v 使用命令来挂载
1
2
3
4
5
6
7docker run it -v 主机目录:容器目录 镜像名称
两个文件夹互相同步
-v
-v 容器内路径 匿名挂载
-v 卷名:容器内路径 具名挂载
-v 容器外路径:容器内路径 指定路径挂载,与具名挂载的区别是,开头是/
docker run -it -v /root/test:/root ubuntu具名挂载和匿名挂载
挂载的三种形式
匿名挂载
-v 容器内路径,卷名是随机hash值
文件会在
/var/lib/docker/volumes/{hash值}/_data
下1
docker run -it -v /root ubuntu
具名挂载
-v 卷名:容器内路径
文件会在
/var/lib/docker/volumes/{卷名}/_data
下1
docker run -it -v 卷名:/root ubuntu
指定路径挂载
-v 宿主机路径:容器内路径
文件会在指定的宿主机路径下
1
docker run -it -v /root/test:/root ubuntu
==当挂载宿主机不存在的文件时,会将容器中的文件给覆盖成空的==
读写权限的控制
默认建的卷都是可读可写的权限
1
2
3
4指定权限rw:可读可写
docker run -it -v /root/test:/root:rw ubuntu
指定权限ro:可读不可写,只有宿主机可以修改,容器内只能读取
docker run -it -v /root/test:/root:ro ubuntu例子:Mysql同步数据
1
2
3
4
5-d 后台运行
-p 端口
-v 挂载路径 将mysql的数据目录和配置目录挂载出来,具体要挂载哪些路径,要看镜像的文档
-e 镜像的环境参数 具体由镜像来指定,看下镜像的文档
docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql01 mysql:5.7
DockerFile挂载
DockerFile就是用来构建docker镜像的脚本文件
1 | FROM centos |
Docker中可以指定挂载文件VOLUME
,只能匿名挂载
如果启动容器时制定了相同的卷,DockerFile里面的会被覆盖
数据卷容器:–volumes-from
顾名思义,就是从另一个容器当中挂载容器中已经创建好的数据卷
可以做到两个容器之间的容器共享
1 | 先建立一个有挂载文件容器 |
可以做到多个容器之间的配置文件信息的传递
DockerFile
Dockerfile介绍
用来构建Docker镜像的文件!是个脚本
构建步骤
- 编写Dockerfile文件
- docker bulid 构建成为一个镜像
- docker run 运行这个镜像
- docker push 发布这个镜像(Dockerhub,阿里云仓库,私有仓库)
官方镜像很多都是基础包,很多功能没有,我们通常会构建自己的镜像
Dockerfile构建过程
Dockerfile是面向开发的,我们以后发布项目,作镜像,就需要编写Dockerfile文件,这个文件十分简单
docker镜像已经逐渐成为企业交付的一个标准,有必要掌握!
步骤
Dockerfile:构建文件,定义了一切的步骤,源代码
DockerImage:镜像,通过Dockerfile构建生成,最终发布和运行的产品
Docker容器:容器就是镜像运行起来的服务
DockerFile的指令
脚本有很多指令
- 基础知识
- 每个指令都是大写
- 执行顺序从上到下
- # 是注释
- 每一个直径都会创建提交一个新的镜像层,并提交
1 | FROM # 基础镜像,一切从这里开始 |
实战测试
DockerHub中99%的镜像是从scratch
来的,最基础的镜像
构建自己的centos,安装一些依赖
编写Dockerfile
1
2
3
4
5
6
7
8
9
10FROM centos
MAINTAINER sowevo<i@sowevo.com>
ENV MYPATH /user/local
WORKDIR $MYPATH # 指定工作路径
RUN yum -y install vim # 安装个软件
RUN yum -y install net-tools # 安装个软件
EXPOSE 80
CMD echo $MYPATH
CMD echo "---end---"
CMD /bin/bashdocker build构建镜像
1
docker build -f myDcokerFile-centos -t sowevo/centos .
运行这个镜像
1
docker run -it 8410af091bf5 sowevo/centos
构建自己的tomcat
从下载一个JDK和Tomcat开始
编写DockerFile,最好使用
Dockerfile
,官方推荐用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24# 以centos为基础
FROM centos
MAINTAINER sowevo<i@sowevo.com>
# 环境变量:工作目录
ENV WORKPATH /usr/local
# 拷贝帮助文档
COPY README $WORKPATH/README
# 拷贝java和tomcat的安装包,会自动解压到指定路径
ADD apache-tomcat-9.0.41.tar.gz $WORKPATH
ADD jdk-8u251-linux-x64.tar.gz $WORKPATH
# 安装一个vim
RUN yum -y install vim
# java和tomcat需要的 环境变脸
ENV JAVA_HOME $WORKPATH/jdk1.8.0_251
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/lib/tools.jar
ENV CATALINA_HOME $WORKPATH/apache-tomcat-9.0.41
ENV CATALINA_BASH $WORKPATH/apache-tomcat-9.0.41
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/lib
# 指定工作目录
WORKDIR $WORKPATH
# 开放端口
EXPOSE 8080
# 启动时要执行的命令
CMD $CATALINA_HOME/bin/startup.sh && tail -F $CATALINA_HOME/logs/catalina.outdocker build构建镜像
1
2如果Dockerfile的名字标准的话,可以不写-f 参数
docker build -t diytomcat .运行这个镜像
1
2
3
4-d 后台运行
-p 端口映射
-v 文件挂载
docker run -d -p 8080:8080 --name diytomcat -v /root/dockerfile/tomcat/webapps/test:/usr/local/apache-tomcat-9.0.41/webapps/test -v /root/dockerfile/tomcat/logs:/usr/local/apache-tomcat-9.0.41/logs diytomcat项目文件丢进宿主机的
/root/dockerfile/tomcat/webapps/test
路径即可访问
发布镜像
DockerHub
注册账号
登录
1
docker login
加一个标签
1
2
3
4如果镜像标签不对,会被拒绝
可以加一个规范的tag
对已经存在的镜像添加tag 使用tag命令加一个标签
docker tag 69b72121b45e sowevo/diytomcat:1.0提交自己的镜像
1
2网不好,推不上去,多尝试几次!
docker push sowevo/diytomcat:1.0发布成功!
腾讯云镜像仓库
登录腾讯云
找到容器镜像服务,并开通
创建命名空间
![image-20201225170110909](/Users/sowevo/Library/Application Support/typora-user-images/image-20201225170110909.png)
创建容器镜像
登录腾讯云仓库
1
sudo docker login --username=23642660 ccr.ccs.tencentyun.com
加一个标签
1
sudo docker tag [ImageId] ccr.ccs.tencentyun.com/sowevo/diytomcat:[tag]
提交自己的镜像
1
sudo docker push ccr.ccs.tencentyun.com/sowevo/diytomcat:[tag]
提交成功!
其他镜像仓库
操作类似,都有提供文档
总结
Docker网络
安装docker会自动安装一个虚拟网卡Dokcer0
多个容器不指定网络的话,默认使用连接这个虚拟网卡Docker0路由,docker会给我们分配一个默认的可用的IP
使用docker network查看所有的docker网络
Docker的几种网络模式
- bridge:桥接网络,默认的
- none:不配置网络
- host:主机模式,和宿主机共享网络
- container:容器间网络联通!(用的少)
容器互连
想要实现容器间网络互连的方式
使用**–link**
多个服务间使用服务名进行服务间的网络调用
1 | 先建立一个容器 |
实际上–link命令就是在建立新容器tomcat02
的时候,修改新容器的 /etc/hosts
文件,给容器tomcat01
的ip绑定一个域名,域名是容器名
现在已经不建议使用–link了~
自定义网络
使用docker network创建网络
1
2
3
4
5创建一个自定义网络
--driver bridge 网络类型,桥接
--subnet 10.0.0.0/24 子网掩码 10.0.0.2~10.0.0.255
--gateway 10.0.0.1 网关
docker network create --driver bridge --subnet 10.0.0.0/24 --gateway 10.0.0.1 customnetwork
建立容器时指定使用这个自定义网络
1
2docker run -d -P --name tomcat-net-01 --net customnetwork tomcat
docker run -d -P --name tomcat-net-02 --net customnetwork tomcat现在两个容器之间可以通过容器名互相访问
网络联通
实际上就是一个容器链接两个不同的网络
相当于现在现实中一台电脑两根网线连接两个路由器
双网卡!
将一个容器连接到其他网络
1
2
3docker network connect 网络名 容器名
docker network connect customnetwork tomcat-01
docker network connect customnetwork tomcat-02
实战
装一个redis集群
分片+高可用+负载均衡
1 | flowchart TD |
1 | 创建网卡 |
这样创建的外网访问有问题…
SpringBoot微服务打包Docker镜像
构建SpringBoot项目
打包应用
编写Dockerfile
1
2
3
4
5
6
7
8
9
10# 以java为基础
FROM java:8
# 复制打包出来的jar文件,名字叫app.jar
COPY target/*.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]构建镜像
1
docker build -t docker-test:0.0.1-SNAPSHOT .
发布运行