Docker

备注:

学习内容资源来源于狂神说:https://www.bilibili.com/video/BV1og4y1q7M4

docker是一个应用容器,可以将应用打包发布到一个可以移植的镜像当中。

采用沙箱机制

docker、k8s都是go语言开发的

1. 安装

1.1 centos 安装

# 1、移除旧版本
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
    
    
 # 2、设置镜像仓库
sudo yum install -y yum-utils
sudo yum-config-manager \
    --add-repo \
     http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 更新软件包缓存索引
yum makecache fast

#3、安装
# ce是社区版, ee是企业版
yum install docker-ce docker-ce-cli containerd.io
 
#4、启动docker
systemctl start docker    
    
    
# 5、查看版本
docker version 
    
# 若提示无权限
[xuyaohua@localhost ~]$ docker ps
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json: dial unix /var/run/docker.sock: connect: permission denied
[xuyaohua@localhost ~]$ sudo chmod a+rw /var/run/docker.sock

1.2 阿里云镜像加速

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://epyzwowj.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

1.3 底层原理

docker是一个client-server结构的系统,docker守护进程运行在主机上,然后通过socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。

容器,是一个运行时的环境,就是我们说的集装箱。

为什么docker比虚拟机vm快?

1)、docker有着比虚拟机更少的抽象层。

由于docker不需要hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的是实际物理机的硬件资源。因此在cpu、内存利用率上docker将会在效率上有明显的而优势;

2)、docker利用的是宿主机的内核,而不需要guest os。

因此当建立一个容器时,docker不需要和虚拟机一样重新加载一个操作系统的内核。从而避免加载操作系统内核返回比较费时的资源过程,当新建一个虚拟机时,虚拟机软件需要加载guest os,返回新建过程是分钟级的。而docker由于直接利用宿主机的操作系统,则省略了加载过程,因此新建一个docker容器只需要几秒。

2. 常用命令

2.1 帮助命令

docker version     # 版本信息
docker info 	   # 系统信息,包括镜像和容器
docker command --help # 帮助命令

2.2 镜像命令

查看所有镜像
docker images # 查看本机所有镜像
	option: 
    	-a    # 查看所有
    	-q    # 只显示镜像id    
搜索镜像
docker search images_name --filter=stars=3000   # 查找镜像
下载镜像
docker pull images_name:version # 拉取镜像
删除镜像
docker rmi -f $(docker images -qa) # 删除全部镜像

2.3 容器命令

新建容器
# 新建容器并启动, 若没有找到镜像,会自动下载最新版
docker run [options] images_name

--name  # 容器名字,用以区分
-d      # 后台方式运行
-it     # 交互方式运行,进入容器内部
-p      # 主机端口:容器端口
--rm    # 运行完就删除,常用于测试

# 测试
[root@localhost ~]# docker run -it centos /bin/bash
WARNING: IPv4 forwarding is disabled. Networking will not work.
[root@9bac75e8963f /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@9bac75e8963f /]# exit
exit
[root@localhost ~]# 
查看容器
# 列出所有运行的容器
docker ps 
	option:
		-a   # 显示运行的容器,会带有历史运行
退出容器
exit
ctrl + p + q  # 容器不停止退出

注意: Docker容器后台运行,就必须有一个前台进程,容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的, 所以指定了端口映射的应用都不会自动退出

 docker run -d -v hello:/world busybox ls /world
删除容器
docker rm container_id
docker rm -f $(docker ps -qa)
docker ps -q -a|xargs docker rm  # 管道符
启动和停止
docker start container_id
docker restart container_id
docker kill container_id
docker stop container_id
docker stop $(docker ps -q)

2.4 常用其他命令

日志
 docker logs -ft --tail 10 30c147332443 container_id
进程
docker top container_id  # 容器中运行的进程信息
元数据
docker inspect container_id 
docker image inspect image_id/image_name 
exec

运行的容器中执行命令

docker exec -it mynginx /bin/sh /root/runoob.sh 
attach

进入容器正在运行的终端

docker attach container_id

2.5 小结

在这里插入图片描述

2.6 Portainer

https://documentation.portainer.io/v2.0/deploy/ceinstalldocker/

docker run -d -p 9001:9001 --name portainer_test --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

3. 镜像分层原理

参考资料: https://blog.csdn.net/pjsdsg/article/details/90445128

镜像是什么

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件, 它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。

镜像加载原理

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等等。

在这里插入图片描述

平时我们安装虚拟机的CentOS都是好几个G,为什么docker这里才200M?

在这里插入图片描述

对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就行了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以共用bootfs。

虚拟机启动是分钟级别的,容器启动是秒级别的!

分层理解

分层的镜像

镜像下载都是一层一层下载,已有的文件系统层次不在需要下载!

在这里插入图片描述

镜像分层下载的依据:

docker image inspect centos
在这里插入图片描述

镜像分层最大的好处

最大的一个好处就是共享资源

比如:有多个镜像都从相同的base镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,同时内存中也只需加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

在这里插入图片描述

镜像的特点

Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。
这一层通常被称作为"容器层",“容器层”之下的都叫"镜像层"。

在这里插入图片描述

commit镜像

docker commit -a “作者” -m “备注” container_id 镜像名字:版本号

[root@localhost ~]# docker exec -it ea857ec9eead bash
root@ea857ec9eead:/usr/local/tomcat# ls
BUILDING.txt  CONTRIBUTING.md  LICENSE  NOTICE  README.md  RELEASE-NOTES  RUNNING.txt  bin  conf  lib  logs  native-jni-lib  temp  webapps  webapps.dist  work
root@ea857ec9eead:/usr/local/tomcat# cp -r webapps.dist/*  webapps/
root@ea857ec9eead:/usr/local/tomcat# exit
exit
[root@localhost ~]# docker commit -a "xuyaohua" -m "my apache tomcat add webapps" ea857ec9eead  mytomcat:v1 
sha256:2b77aa06f9a64dd8a110c9ff245f80b3fe19fb94519504b84e9a4c7589ac3fc4
[root@localhost ~]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
mytomcat              v1        2b77aa06f9a6   11 seconds ago   672MB
tomcat                latest    5505f7218e4d   32 hours ago     667MB
nginx                 latest    d1a364dc548d   3 weeks ago      133MB
portainer/portainer   latest    580c0e4e98b0   3 months ago     79.1MB

4. 数据卷volumes

docker是将应用和环境打包成一个镜像。

数据都在容器中,如果容器删除,数据也就丢失了!需求:数据实现持久化

数据卷, 通过挂载目录,可以实现容器中的数据共享!将容器中的数据,同步到本地。

数据卷可以不仅可以实现数据同步本地,还可以实现容器内的数据共享!

volume create

volume create 匿名和指定名字方式都将数据卷存储在: /var/lib/docker/volumes/

ApI1.21+

volume create

/var/lib/docker/volumes/hello

docker volume create hello
# 运行时-v指定已创建本地挂载数据卷
docker run -d -v hello:/world busybox ls /world # 没有提供前台服务,自动退出

docker volume create # 自定创建匿名卷,不推荐
volume inspect
[root@localhost volumes]# docker volume inspect hello
[
    {
        "CreatedAt": "2021-06-19T08:25:21+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/hello/_data",
        "Name": "hello",
        "Options": {},
        "Scope": "local"
    }
]
volume prune
[root@localhost volumes]# docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
78963cdfe74cb775e98476dde76a129ee74035614ee0929501f0e7cdcf0f5c0d
01bf50d9438a9e9a9216940389455d4003f3dbb49c91b8de4d8fcb628a9e9867

Total reclaimed space: 131.9kB
volume ls

只会列出在该目录下的数据卷:/var/lib/docker/volumes/hello

docker run -v

创建容器时,设置数据卷挂载

-e  # 指定环境变量

docker run  -v /宿主机路径:容器内路径  # 指定存放位置的具名数据卷
docker run  -v 容器内路径		    # 匿名
docker run  -v 卷名:容器内路径	       # 具名挂载,使用数据卷默认存放位置

未指定宿主机路径,都将存放在/var/lib/docker/volumes/目录下

匿名挂载
docker run -it -v /home --name centos02 centos /bin/bash
docker inspect centos02

在这里插入图片描述

具名挂载1
docker run -it -v centos03:/home --name centos03 centos /bin/bash
docker inspect centos03

在这里插入图片描述

具名挂载2

实现MySQL数据同步

docker run -d -p 3333:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=111111 --name mysql01 mysql:5.7

在这里插入图片描述

容器删除,数据卷数据也不会删除

设置读写权限
container_path:rw  # 容器具有读写权限,默认
container_path:ro  # 容器只有读权限

–volumes-from

实现容器间的数据共享

具名挂载数据同步
docker run -d -p 8888:8080 --name tomcat01 -v /home/tomcat/webapps:/usr/local/tomcat/webapps/ROOT/ mytomcat:v1 
docker run -d -p 8889:8080 --name tomcat02 --volumes-from tomcat01  mytomcat:v1
docker run -d -p 8890:8080 --name tomcat03 --volumes-from tomcat02  mytomcat:v1
docker exec -it tomcat02 /bin/bash
cd /usr/local/tomcat/webapps/ROOT
echo "tomcat02<br/>" >> index.jsp
...

在这里插入图片描述

数据备份与恢复

例如:

tomcat01是自制镜像 mytomcat:v1启动的应用

docker run --rm --volumes-from tomcat01: tomcat01同步到临时容器

临时容器中 /usr/local/tomcat/webapps目录压缩备份成webapps.tar

通过数据卷映射将webapps.tar同步到当前目录下

删除临时容器

docker run --rm --volumes-from tomcat01 -v $(pwd):/backup mytomcat:v1 tar cvf /backup/webapps.tar /usr/local/tomcat/webapps

恢复自身容器:直接进入容器,解压容器备份目录,拷贝到指定目录即可

恢复到新容器:

通过数据卷映射将webapps.tar同步到临时容器 backup目录下

解压临时容器 backup目录下webapps.tar到指定目录即可

docker run -d -p 9999:8080 -v $(pwd):/backup --name tomcat02 tomcat 
docker exec -it tomcat02 /bin/bash
cd /backup
tar -xvf webapps.tar -C /usr/local/tomcat

# -C 指定解压到的目的路径
# c  tar 压缩
# x  tar 解压

小结

数据卷好处:

1、实现持久化

mysql

2、数据共享

通过修改本地文件,来修改容器配置文件数据

3、数据备份

–volume-from

5. dockerfile

用来构建docker镜像,是一个镜像编写脚本,构建镜像的步骤

dockerfile面向开发,发布项目,发布镜像,就需要使用到dockerfile

企业交付

dockfile指令

FROM       # 基础镜像
MAINTAINER # 维护者 姓名+邮箱
RUN	       # 构建时候需要运行的命令
ADD        # 添加内容
WORKDIR    # 镜像工作目录
VOLUME     # 挂载的目录
EXPOSE     # 指定暴露的端口
CMD        # 指定容器启动运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定容器启动运行的命令,可以追加命令
ONBUILD    # 当构建一个被继承的dockerfiles时候,就会触发ONBUILD指令
COPY       # 添加命令,添加文件到镜像中
ENV        # 设置环境变量

构建centos

构建1
FROM centos
MAINTAINER Jxnuxyh<2466743619@qq.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN yum install -y vim
RUN yum install -y net-tools

EXPOSE 80

CMD "----end---"
CMD /bin/bash	
 
 
 docker build -f centos-dockerfile -t mycentos:1.0 .

add 和 entrypoint区别

示例: docker run image_id -l

add [“ls”, “-a”] 生成的镜像在run的时候追加命令时会被替换

-l 会找不到命令

entrypoint [“ls”, “-a”] 生成的镜像在run的时候追加命令直接拼接

ls -al

构建2

centos添加tomcat, jdk

小结

在这里插入图片描述

6. Docker网络

docker0

查看宿主机ip addr:172.17.0.1

交换机、网关格式的ip, 充当docker的路由器

在这里插入图片描述

启动一个tomcat: docker run -d --name tomcat01 tomcat

查看tomcat01 ip: 126: eth0@if127

[root@localhost ~]# docker exec -it tomcat01 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
126: eth0@if127: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

宿主机多了一个对应tomcat01 IP: 127: vethd845067@if126

[root@localhost ~]# ip addr   # 
127: vethd845067@if126: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 0a:bf:e3:04:77:b3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::8bf:e3ff:fe04:77b3/64 scope link 
       valid_lft forever preferred_lft forever

tomcat01容器能够ping通宿主机

[root@localhost ~]# docker exec -it tomcat01 ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.122 ms
64 bytes from 172.17.0.1: icmp_seq=2 ttl=64 time=0.080 ms
64 bytes from 172.17.0.1: icmp_seq=3 ttl=64 time=0.094 ms
64 bytes from 172.17.0.1: icmp_seq=4 ttl=64 time=0.071 ms
64 bytes from 172.17.0.1: icmp_seq=5 ttl=64 time=0.061 ms
64 bytes from 172.17.0.1: icmp_seq=6 ttl=64 time=0.077 ms

宿主机能够ping通tomcat01容器

[root@localhost ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.051 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.055 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.061 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.055 ms
64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.053 ms

容器间互通

再创建一个tomcat02, 两个容器之间也是能够互通的

[root@localhost ~]# docker exec -it tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.100 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.062 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.064 ms

evth-pair技术

安装了docker,就会有一个网卡(docker0),网络模式为桥接模式,使用的是 evth-pair技术

每启动一个容器docker就会为它分配一个IP地址,对应的也会多一对网卡!

容器和linux主机可以ping通,而且每个容器之间也可以通过ip地址ping通

docker容器带来的网卡都是一对一对的,evth-pair 就是一对的虚拟设备接口,都是成对出现的,一段连着协议,

一段彼此连接,evth-pair 就像一个桥梁,连接各种虚拟网络设备。
在这里插入图片描述

–link

发布一个微服务,database url=ip, 项目不重启,数据库ip换掉了,希望可以通过名字来访问容器?

在这里插入图片描述

docker run -d --name tomcat03 --link tomcat02 tomcat

新建容器tomcat03 --link tomcat02

[root@localhost ~]# docker run -d --name tomcat03 --link tomcat02 tomcat
6e4c6784f888c2e300cacf1b9e75ff56d41a5ccc366faaaeb23f0d86765df30f
[root@localhost ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
[root@localhost ~]# docker exec -it tomcat03 ping tomcat02 # 单向
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.075 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.084 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.058 ms
[root@localhost ~]# docker exec -it tomcat03 cat /etc/hosts # 修改hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3      tomcat02 055ef50c1eea
172.17.0.4      6e4c6784f888

–link是单向的, A —link B 就是在A的hosts文件中添加B的映射

通过docker0自动分配ip,无法实现通过容器名之间访问,需要借助–link,而且–link在容器中创建是应用,显得有些

乏力,还不如直接修改/etc/hosts来的直接。

自定义网络可以解决docker0的局限性。

自定义网络

容器互联可以通过docker0 + --link,但是不优雅。

查看docker网络支持的方式

docker run 默认是–net bridge

[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
37ae3e698670   bridge    bridge    local  # 桥接, 默认
2e0feba19ae5   host      host      local  # 主机模式
c5043c8ce6b2   none      null      local  # 不配置

创建自己的网段docker network create --driver=bridge --subnet=192.168.0.0/16 --gateway=192.168.0.1 mynet

[root@localhost ~]# docker network create --help

Usage:  docker network create [OPTIONS] NETWORK

Create a network

Options:
      --attachable           Enable manual container attachment
      --aux-address map      Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
      --config-from string   The network from which to copy the configuration
      --config-only          Create a configuration only network
  -d, --driver string        Driver to manage the Network (default "bridge")
      --gateway strings      IPv4 or IPv6 Gateway for the master subnet
      --ingress              Create swarm routing-mesh network
      --internal             Restrict external access to the network
      --ip-range strings     Allocate container ip from a sub-range
      --ipam-driver string   IP Address Management Driver (default "default")
      --ipam-opt map         Set IPAM driver specific options (default map[])
      --ipv6                 Enable IPv6 networking
      --label list           Set metadata on a network
  -o, --opt map              Set driver specific options (default map[])
      --scope string         Control the network's scope
      --subnet strings       Subnet in CIDR format that represents a network segment
[root@localhost ~]# docker network create  --driver=bridge --subnet=192.168.0.0/16  --gateway=192.168.0.1 mynet
f411dabc8b369d63c4ae0ff5da35e3e8584d55f320caa7b63e980bd244db78df
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
37ae3e698670   bridge    bridge    local
2e0feba19ae5   host      host      local
f411dabc8b36   mynet     bridge    local
c5043c8ce6b2   none      null      local
[root@localhost ~]# docker run -d --name tomcat04 --net mynet tomcat
64791eb330994fa30ddee3b13b164b51df79a20d603372f24f1e39b8d3917f63
[root@localhost ~]# docker run -d --name tomcat05 --net mynet tomcat

查看自定义网络详情, Containers记录了使用该网段的容器信息

[root@localhost ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "f411dabc8b369d63c4ae0ff5da35e3e8584d55f320caa7b63e980bd244db78df",
        "Created": "2021-06-20T15:14:02.433386737+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
             "Containers": {
            "35e4348202c7141f7187de48653dc48e9546e3556dc95383100c868c92fb7a5c": {
                "Name": "tomcat05",
                "EndpointID": "cf75e4f90d32d7a912bf071acc1d1b66ad203b989a9998cada0e49afca2dea62",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "64791eb330994fa30ddee3b13b164b51df79a20d603372f24f1e39b8d3917f63": {
                "Name": "tomcat04",
                "EndpointID": "a7c98a8f266ca5ff5e6b70e857de25aebccda5c8da30ca3be973abb94b73d180",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

使用同一个网段的创建的容器可以通过容器名互联,解决了docker0的局限性

[root@localhost ~]# docker exec -it tomcat04 ping tomcat05
PING tomcat05 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat05.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.060 ms
64 bytes from tomcat05.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.086 ms
[root@localhost ~]# docker exec -it tomcat05 ping tomcat04
PING tomcat04 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat04.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.036 ms
64 bytes from tomcat04.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.074 ms
64 bytes from tomcat04.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.099 ms

docker跨网络

通过docker network connect可以实现

docker network connect [OPTIONS] NETWORK CONTAINER

docker network connect tomcat01 mynet

本质就是将容器tomcat01添加到指定网段中,达到容器与网络互联

在这里插入图片描述

docker打包微服务镜像

idea打包生成jar包,编写Dockerfile文件, 上传文件Dockerfile和jar包到服务器

服务器通过Dockerfile构建生成镜像

docker通过镜像创建容器启动应用

[root@localhost idea]# docker build -t spring-boot-demo .
Sending build context to Docker daemon  17.31MB
Step 1/5 : FROM java:8
8: Pulling from library/java
5040bd298390: Pull complete 
fce5728aad85: Pull complete 
76610ec20bf5: Pull complete 
60170fec2151: Pull complete 
e98f73de8f0d: Pull complete 
11f7af24ed9c: Pull complete 
49e2d6393f32: Pull complete 
bb9cdec9c7f3: Pull complete 
Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d
Status: Downloaded newer image for java:8
 ---> d23bdf5b1b1b
Step 2/5 : COPY *.jar /app.jar
 ---> 24d343b58a97
Step 3/5 : CMD ["--server.port","8080"]
 ---> Running in 64adcd45ddd1
Removing intermediate container 64adcd45ddd1
 ---> 979890b5cbd6
Step 4/5 : EXPOSE 8080
 ---> Running in 70f355218c24
Removing intermediate container 70f355218c24
 ---> 99c8ed066ae2
Step 5/5 : ENTRYPOINT ["java", "-jar", "/app.jar"]
 ---> Running in 4e2909800526
Removing intermediate container 4e2909800526
 ---> 79cdc3f4b30d
Successfully built 79cdc3f4b30d
Successfully tagged spring-boot-demo:latest
[root@localhost idea]# docker images
REPOSITORY         TAG       IMAGE ID       CREATED          SIZE
spring-boot-demo   latest    79cdc3f4b30d   17 seconds ago   661MB
tomcat             latest    5505f7218e4d   3 days ago       667MB
java               8         d23bdf5b1b1b   4 years ago      643MB
[root@localhost idea]# docker run -d -P --name boot-demo spring-boot-demo
badcfd6ab702607824b662150ce805daff9fc77e3faa45d69757811d4ef0eab6
[root@localhost idea]# docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS          PORTS                                         NAMES
badcfd6ab702   spring-boot-demo   "java -jar /app.jar …"   14 seconds ago   Up 12 seconds   0.0.0.0:49153->8080/tcp, :::49153->8080/tcp   boot-demo
[root@localhost idea]# curl localhost:49153
{"timestamp":"2021-06-20T12:20:11.529+00:00","status":404,"error":"Not Found","path":"/"}
[root@localhost idea]# curl localhost:49153/hello
docker package test demo....

7. Compose

Compose介绍

https://docs.docker.com/compose/install/

前面我们使用 Docker 的时候,定义 Dockerfile 文件,然后使用 docker build、docker run 等命令操作容器。然而微服务架构的应用系统一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,那么效率之低,维护量之大可想而知

使用 Docker Compose 可以轻松、高效的管理容器,它是一个用于定义和运行多容器 Docker 的应用程序工具

在这里插入图片描述

安装

sudo curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

docker-compose.yml

编写规则:https://docs.docker.com/compose/compose-file/compose-file-v3/

version: "3"
services:
  dockerapp:
    build: .
    image: dockerapp
    depends_on:
      - redis
    ports:
    - "8080:8080"
  redis:
    image: redis

运行

docker-compose up

[root@localhost dockercompose]# docker-compose up
Building dockerapp
Step 1/5 : FROM java:8
 ---> d23bdf5b1b1b
Step 2/5 : COPY *.jar /app.jar
 ---> f99b4bf986d8
Step 3/5 : CMD ["--server.port","8080"]
 ---> Running in 5ca32ab5cc61
Removing intermediate container 5ca32ab5cc61
 ---> a7d893fd5ab6
Step 4/5 : EXPOSE 8080
 ---> Running in 044df1274c83
Removing intermediate container 044df1274c83
 ---> b06bd12a6de8
Step 5/5 : ENTRYPOINT ["java", "-jar", "/app.jar"]
 ---> Running in e84673f03b17
Removing intermediate container e84673f03b17
 ---> 150dac1fd598
Successfully built 150dac1fd598
Successfully tagged dockerapp:latest
WARNING: Image for service dockerapp was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`. # dockerapp不存在,按照yml该服务指定build目录指定的Dockerfile构建image
Creating dockercompose_redis_1 ... done
Creating dockercompose_dockerapp_1 ... done
Attaching to dockercompose_redis_1, dockercompose_dockerapp_1
redis_1      | 1:C 20 Jun 2021 20:06:22.746 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1      | 1:C 20 Jun 2021 20:06:22.746 # Redis version=6.2.4, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1      | 1:C 20 Jun 2021 20:06:22.746 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis_1      | 1:M 20 Jun 2021 20:06:22.747 * monotonic clock: POSIX clock_gettime
redis_1      | 1:M 20 Jun 2021 20:06:22.756 * Running mode=standalone, port=6379.
redis_1      | 1:M 20 Jun 2021 20:06:22.756 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis_1      | 1:M 20 Jun 2021 20:06:22.756 # Server initialized
redis_1      | 1:M 20 Jun 2021 20:06:22.756 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
redis_1      | 1:M 20 Jun 2021 20:06:22.757 * Ready to accept connections
dockerapp_1  | 
dockerapp_1  |   .   ____          _            __ _ _
dockerapp_1  |  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
dockerapp_1  | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
dockerapp_1  |  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
dockerapp_1  |   '  |____| .__|_| |_|_| |_\__, | / / / /
dockerapp_1  |  =========|_|==============|___/=/_/_/_/
dockerapp_1  |  :: Spring Boot ::                (v2.5.0)
dockerapp_1  | 
dockerapp_1  | 2021-06-20 20:06:25.281  INFO 1 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication v0.0.1-SNAPSHOT using Java 1.8.0_111 on 013af94cb46b with PID 1 (/app.jar started by root in /)
dockerapp_1  | 2021-06-20 20:06:25.291  INFO 1 --- [           main] 

dockerapp不存在,按照yml该服务指定build目录指定的Dockerfile构建image

docker-compose up执行解析yml, 创建的服务都指定了镜像名,会先在本地找;若没有找到,同时指定了Dockerfile构建文件,就会在本地构建该镜像名的镜像;若本地没找到,同时也没有指定构建文件,就会去远程找到并下载到本地。

在这里插入图片描述

dockercompose会创建一个属于自己的网络

8. Swarm

不管是docker run还是docker-compose都是单机下创建容器服务

Swarm是管理docker集群的平台,几乎全部用GO语言来完成的开发的

代码开源在https://github.com/docker/swarm, 它是将一群Docker宿主机变成一个单一的虚拟主机。

Docker Swarm 和 Docker Compose 一样,都是 Docker 官方容器编排项目,但不同的是,Docker Compose 是

一个在单个服务器或主机上创建多个容器的工具,而 Docker Swarm 则可以在多个服务器或主机上创建容器集群

服务,对于微服务的部署,显然 Docker Swarm 会更加适合。

从 Docker 1.12.0 版本开始,Docker Swarm 已经包含在 Docker 引擎中(docker swarm),并且已经内置了服务发现工具。

并且,swarm可以实现扩缩容。

在这里插入图片描述

Swarm是典型的master-slave结构,通过发现服务来选举manager。

manager是中心管理节点,各个node上运行agent接受manager的统一管理,集群会自动通过Raft协议分布式选

举出manager节点,无需额外的发现服务支持,避免了单点的瓶颈问题,同时也内置了DNS的负载均衡和对外部

负载均衡机制的集成支持

9. CI/CD

附录

1. 端口映射错误

docker: Error response from daemon: driver failed programming external connectivity on endpoint tomcat02 (659114ceffa773dbc45a3b389f7c9ccb1a8b087e373b06e8b281f851c6dca6da):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 9999 -j DNAT --to-destination 172.17.0.3:8080 ! -i docker0: iptables: No chain/target/match by that name.

解决方案: systemctl restart docker

重启docker

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值