Docker入门学习笔记

Docker-不仅仅是运行环境

学习目标

  • 命令 ✔️
  • 镜像 ✔️
  • 容器数据卷 ✔️
  • DockerFile ✔️
  • Docker网络原理 ✔️
  • SpringBoot整合Docker ✔️
  • 集群Docker Compose ✖️
  • Docker Swarm 简化-k8s ✖️

Docker

应用更快速的交付和部署

更便捷的升级和扩缩容

更简单的系统运维,开发测试环境都是高度一致的

更高效的计算资源利用----即使内存就2g都可以跑几十个tomcat

docker容器与传统虚拟机的比较:

都什么年代还在用传统虚拟机技术?

  • 传统虚拟机是自身虚拟出一个完整的操作系统然后运行起来,然后在这个系统上安装和运行软件,十分麻烦

,并且浪费硬盘空间、内存空间。

  • 容器没有像传统虚拟机那样的一个内核,也没有虚拟硬件,它的应用直接应用在宿主机的内核上,因为那个Kernel的复用性强,不必重复安装好多个。
  • 每个容器是互相隔离的,每个容器内都有一个属于自己的文件系统,互不影响。

docker的基本组成

镜像:

可以理解为一个模版,可以通过这个模版来创建容器服务。

容器:

利用容器技术,独立运行一个活着一个组应用,通过镜像来创建。

可以理解为一个简易的linux系统。

仓库:

存放镜像的地方。

DockerHub…

命令

docker run ------- 在本机寻找这个镜像 ------ 有镜像:使用这个镜像来运行

​ ------ 无:上DockerHub下载到本地------运行

Docker是怎么工作的

Docker是一个C-S结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问。

DockerServer接收到Client的指令,然后执行这条指令。

Docker为什么比VM快

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rokUKQgj-1671432973335)(https://ts1.cn.mm.bing.net/th/id/R-C.d68ffd189931aaed580ae407ded21ead?rik=stQ89ljaHTBgxg&riu=http%3a%2f%2ffavorites.ren%2fassets%2fimages%2f2018%2fdocker%2fdocker_vs_vm.png&ehk=KaRMZJ9Vqmljxt%2fpYhkN%2fWtOMuOOPPvy01Xcfptoc%2f8%3d&risl=&pid=ImgRaw&r=0)]

  1. docker有着比虚拟机更少的抽象层。
  2. docker利用的是宿主机的内核,vm需要Guest Kernel

在新建一个容器是,docker不需要像虚拟机一样重新加载一个操作系统内核KErnel,避免引导。虚拟机这样搞太慢了,是分钟级别的,docker则省略了复杂的过程,是秒级的。

帮助命令

docker info
docker version
docker --help

镜像命令

docker images
# options
-a, --all 列出所有信息
-q, --quiet 只显示名字
# 搜索命令
docker search
# 删除命令
docker rmi -f IMAGESID 指定ID删除
docker rmi -f $(docker images -aq) 删除全部容器

容器命令

docker run [可选参数] image
# options
--name 容器名字
-d 后台方式运行 like nohup
-it 使用交互方式运行,进入容器查看内容
-p 指定端口 主机端口:容器端口
-P 随机指定端口

# 启动并进入容器
ubuntu@VM-4-17-ubuntu:~$ sudo docker run --name learn -it ubuntu:20.04 /bin/bash
root@26f55927fbe6:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@26f55927fbe6:/#
#exit 即可退出,但会停止容器
Ctrl+P+Q 容器不停止并且退出


docker ps 
#options
-a 列出当前正在运行的容器+历史运行过的容器
-n=? 显示最近运行过的容器

#删除容器
docker rm 容器ID
docker rm -f

#启动和停止容器
docker start 容器ID
docker stop 容器ID

常用的其他命令

#查看日志
docker logs -tf --tail 显示条数

#查看容器内进程信息
docker top 容器ID

#查看镜像的元数据
docker inspect 容器ID 

进入当前正在运行的容器

docker exec -it 容器ID /bin/bash # 进入容器后开启一个新的终端,可以在里面操作 ·常用

docker attach 容器ID /bin/bash #  进入容器正在执行的终端,不会启动新的进程。

从容器内拷贝文件到主机上

docker cp 容器ID:容器内路径 主机路径

具体实际操作可见我的另一篇笔记《用docker挂载方式部署Nginx》

可视化

  • portainer

图形化界面管理工具,提供一个后台面板供我们操作

docker run -d -p 8088:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

还挺帅。

狠狠学镜像

轻量级、可执行的独立软件包。所有的应用,直接打包docker镜像,就可以直接跑起来。

自己制作一个镜像------DockerFile

联合文件系统 UnionFS

是一种分层、轻量级并且高性能的文件系统。支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂在到同一个虚拟文件系统下。这个系统是DOcker镜像的基础。镜像可以通过分层来继承,基于基础镜像,可以制作各种具体的应用镜像。

镜像加载原理

Docker镜像的最底层是bootfs,这一层和典型Linux系统是一样的,包含boot加载器和内核。当boot加载完成后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核。

----即电脑开机加载的过程。

rootfs,在bootfs之上,包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不用的操作系统发行版,比如CentOS和Ubuntu等。。。

img

分层理解

docker镜像默认都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。

这一层就是所谓的容器层,我们只能在这一层上面进行操作。

一旦run了,就新增了一层了。我们自己写的容器打包之后成为镜像之后,会把我们自己的容器层打包到一个新的镜像中。

docker commit -m="提交的描述信息" -a="作者" 容器ID 目标镜像名:TAG

容器数据卷

数据都在容器中,一般删除容器,数据就会丢失。因此需要:数据可以持久化。

比如:MySQL,容器出问题了,就完蛋了。需要把数据存储在本地。

容器数据卷:容器之间数据共享的技术。

=目录的挂载

使用方式

方式一:使用 -v

docker run -it -v 主机目录:容器内部目录

具体用例可见我的另一篇笔记《使用Docker通过挂载的方式配置Nginx方式》。

可以在docker inspect 容器ID 获取的信息中,查看Mounts的值,获取挂载的信息。

*不管容器是否运行,变化也会同步。但也会占用两倍的存储。

MySQL持久化

首先要记得配置密码:

-e MYSQL_ROOT_PASSWORD=******** 
# -e 环境配置

运行时就要挂载。

容器内mysql的配置文件在 /etc/mysql/conf.d

数据在 /var/lib/mysql

具名和匿名挂载

匿名挂载

只写-v 和容器内路径,就是匿名挂载。

docker volume ls 查看所有的卷的情况
docker volume inspect volumeID 查看卷的详细信息

我们在-v时没写容器外的路径,就会形成以乱码为名字的匿名卷。

具名挂载

-v 卷名:容器内路径 ,这样就给卷命名了,形成具名挂载。

  • 所有docker容器内的卷,在没有指定目录的情况下,都是在/var/lib/docker/volumes/xxxxx/_data/文件下。

通过具名挂载可以方便的找到一个卷,大多数情况使用具名挂载

在容器内路径后面加:ro或者rw,表示只读或者读写。

方式二:用dockerfile VOLUME匿名挂载。

是构建Docker镜像的文件,命令脚本。

docker build 
-f dockerfile路径
-t 镜像的名字及标签,通常 name:tag 或者 name 格式
. 单独一个点代表生成在当前目录下

使用dockerfile的命令VOLUME 来挂载数据卷,情况是这样的:在镜像里面就设置好了挂载,每当生成一个容器,可以通过inspect命令查看详细信息,去查看Mounts信息,可以发现已经为每个新容器都匿名挂载了【VOLUME挂载时数据卷数量】个数据卷。

数据卷容器

如果容器之间需要数据同步。

--volumes-from 让不同容器间数据同步。
#类似于 Java中的son extend father

即使父容器没了,子容器中的数据不会有改变。

数据是以双向拷贝的形式进行共享的,虽然会占用多倍空间,但是可以真正实现持久化。灾备的重要性远高于硬盘!

数据卷容器的生命周期一直持续到没有容器使用为止。

但是一旦持久化到了本地,本地的那一份是一定不会被删除的,呦西!

并且如果是3—2—1链式挂载的形式,即使2断了,1和3也不会有任何影响。

DockerFile

----命令参数脚本

每一个指令都会创建提交一个新的镜像层并且提交。

FROM 					# 基础镜像 ubuntu centos

MAINTAINER 		#维护者+邮箱 WZL

RUN 					#在命令前加个RUN即可

ADD 					# 本地已有的镜像,用ADD添加压缩包

WORKDIR 			#镜像的工作目录 / 或者 /bin/bash 等等

VOLUME 				#挂载的目录

EXPOSE 				#暴露端口配置

CMD 					#指定容器启动时 需要运行的脚本命令 !!!!!但只有最后一个会生效,可被替代!!!!!

ENTRYPOINT 		#指定容器启动时 需要运行的脚本命令,可以追加命令

ONBUILD 			#触发指令,在构建一个被继承DockerFile时,就会运行这个命令

COPY 					#类似ADD

ENV 					#构建时设置环境变量

以前都是使用别的人的,现在就可以自己写镜像了。

docker hub 中99%的镜像都是从scratch基础镜像构造起来的。

如下:centos的官方dockerfile

FROM scratch
ADD centos-7-x86_64-docker.tar.xz /

LABEL \
    org.label-schema.schema-version="1.0" \
    org.label-schema.name="CentOS Base Image" \
    org.label-schema.vendor="CentOS" \
    org.label-schema.license="GPLv2" \
    org.label-schema.build-date="20201113" \
    org.opencontainers.image.title="CentOS Base Image" \
    org.opencontainers.image.vendor="CentOS" \
    org.opencontainers.image.licenses="GPL-2.0-only" \
    org.opencontainers.image.created="2020-11-13 00:00:00+00:00"

CMD ["/bin/bash"]

发布到DockerHub

首先注册好自己的账号

#先登录
docker login 
-p Password
-u username

docker push IMAGEID

#修改镜像名字或版本号
docker tag IMAGEID newID:newVersion 

Docker网络

Docker0

ubuntu@VM-4-17-ubuntu:~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 52:54:00:c4:f8:29 brd ff:ff:ff:ff:ff:ff
    inet 10.0.4.17/22 brd 10.0.7.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fec4:f829/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:48:c4:bb:b9 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:48ff:fec4:bbb9/64 scope link
       valid_lft forever preferred_lft forever
  • lo:本机回环地址
  • Eth0: 服务器内网地址
  • Docker0 :docker自己生成的网卡

分表代表三种不同环境

内部容器之间是怎么互相连接访问的?

容器外可以ping通容器内吗?

测试一下,比如查看一个tomcat容器内部的网卡

#首先进入到容器内部,我这边是进入了/bin/bash
docker exec -it tomcat /bin/bash
#如果下面ip的命令运行报错,那么应该是容器内部阉割版的Linux命令不够,装一个iproute2就行,运行下面两个命令即可
	#### apt update  &&  apt install -y iproute2
root@fd9cbbe589e4:/usr/local/tomcat# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
40: eth0@if41: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:06 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.6/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

eth0@if41

这是容器启动时,docker分配的ip地址。然后ping一下这个172.17.0.6

PING 172.17.0.6 (172.17.0.6) 56(84) bytes of data.
64 bytes from 172.17.0.6: icmp_seq=1 ttl=64 time=0.037 ms
64 bytes from 172.17.0.6: icmp_seq=2 ttl=64 time=0.047 ms
64 bytes from 172.17.0.6: icmp_seq=3 ttl=64 time=0.044 ms

答案是可以的。

那么,容器之间可以ping通吗?

我们每启动一个docker 容器,docker就会给容器分配一个IP,只要电脑安装了Docker,就会有一个网卡叫docker0 。

是桥接模式,使用的技术是evth-pair技术。

这时候再去主机的ip addr里面找,就能找到新创建的这个tomcat的网卡了,

41: veth9a89274@if40: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    link/ether 3e:65:41:ec:f2:f5 brd ff:ff:ff:ff:ff:ff link-netnsid 4
    inet6 fe80::3c65:41ff:feec:f2f5/64 scope link
       valid_lft forever preferred_lft forever

和上面容器内的网卡是一对的(40/41)

这就是evth-pair技术

是一对的虚拟设备接口,都是成对出现的,一端连着协议,一端彼此相连,可以通信。

正因为有这个特性,这个技术就可以当做一个桥梁来使用,来连接各种虚拟网络设备的。

openstack、docker容器之间的连接,OVS的连接,都是使用这个技术。

ok,现在来试试不同容器间能否ping通吧

sudo docker run -d --name tomcat-pair -p 8089:8080  tomcat:8.5.81

root@15d4dfa764ee:/usr/local/tomcat# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
44: eth0@if45: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:07 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.7/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
       
       # 44/45  ok 开始ping测试
       
       #。。。。。。无语,连net-tools都没有,还是需要自己 apt install net-tools && apt install iputils-ping
root@15d4dfa764ee:/usr/local/tomcat# ping 127.17.0.6
PING 127.17.0.6 (127.17.0.6) 56(84) bytes of data.
64 bytes from 127.17.0.6: icmp_seq=1 ttl=64 time=0.015 ms
64 bytes from 127.17.0.6: icmp_seq=2 ttl=64 time=0.031 ms

答案是可以ping通的~

docker0类似于一个交换机,会给容器分配一个默认的可用IP。

Docker中的所有网络接口都是虚拟的,因为虚拟的是最快的。

细节的东西我也不懂了,我还没学计算机网络原理,所以就先学到这边吧。

–link

两个容器之间不用通过地址来ping通,想要只用名字来通信。

ubuntu@VM-4-17-ubuntu:~$ sudo docker exec -it tomcat-pair ping tomcat
ping: tomcat: Name or service not known

无法ping通,遗憾离场

这时候就需要–link来了,在run容器的时候加入命令 --link 【需要链接的容器名字】 之后就可以在这个容器里ping通link的容器了。但是反向之后就不行了,所以这是一个单项网络。

SpringBoot打包Docker镜像

首先可以在IDEA里面下载Docker的插件,然后在项目根目录下创建Dockerfile,就能使用到插件带来的高亮提示和自动补齐dockerfile语句的功能了,以下给出一个示例

FROM java:8

MAINTAINER "luke <348358584@qq.com>"

COPY *.jar /app.jar

CMD ["--server.port=8080"]

EXPOSE 8080

ENTRYPOINT ["java","-jar","/app.jar"]

然后上传到服务器时就把jar包和Dockerfile上传就行了,在服务器上build之后run一下,直接起飞。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值