docker
大家好呀,我们今天又又又来开新坑了,今天这个坑就是Docker了,我们今天开始就要来了解一下Docker了。
博客地址: 云边日落
作者:酒笙
什么是docker
- docker发展史
- 在最开始的时候,docker不叫docker,叫dotcloud。这是由几个年轻人成立的小公司,在当时这样的一个小公司混的还算不错,但是还是打不过大厂,paas市场竞争激烈,dotcloud举步维艰,最后这些年轻人不甘心,不能让自己的坚持与努力付之东流,于是便把他们的核心技术开源,也就是docker,在当时的话,docker的主要功能就是把Linux的代码打包,应用在其他开发平台中。最后这个docker就风靡全球,于是乎,dotcloud就索性改名docker了,并且就全身心的投入到了docker的开发之中
- docker的应用场景
-
Web应用的自动化打包和发布
-
自动化测试和持续继承、发布
-
在服务型环境中部署和调试数据库或其他后台应用
-
从头编译或者拓展现有的openshift或cloud foundry平台来搭建自己的PaaS环境。
- docker的优势
-
docker 启动快速属于秒级别。虚拟机通常需要几分钟去启动
-
docker 需要的资源更少, docker 在操作系统级别进行虚拟化, docker 容器和内核交互,几乎没有性能损耗,性能优于通过 Hypervisor 层与内核层的虚拟化
-
docker 更轻量, docker 的架构可以共用一个内核与共享应用程序库,所占内存极小。同样的硬件环境, Docker 运行的镜像数远多于虚拟机数量,对系统的利用率非常高
-
与虚拟机相比, docker 隔离性更弱, docker 属于进程之间的隔离,虚拟机可实现系统级别隔
-
安全性: docker 的安全性也更弱。 Docker 的租户 root 和宿主机 root 等同,一旦容器内的用户从普通用户权限提升为root权限,它就直接具备了宿主机的root权限,进而可进行无限制的操作。虚拟机租户 root 权限和宿主机的 root 虚拟机权限是分离的,并且虚拟机利用如 Intel 的 VT-d 和 VT-x 的 ring-1 硬件隔离技术,这种隔离技术可以防止虚拟机突破和彼此交互,而容器至今还没有任何形式的硬件隔离,这使得容器容易受到攻击
-
可管理性: docker 的集中化管理工具还不算成熟。各种虚拟化技术都有成熟的管理工具,例如 VMware vCenter 提供完备的虚拟机管理能力
-
高可用和可恢复性: docker 对业务的高可用支持是通过快速重新部署实现的。虚拟化具备负载均衡,高可用,容错,迁移和数据保护等经过生产实践检验的成熟保障机制, VMware 可承诺虚拟机 99.999% 高可用,保证业务连续性
-
快速创建、删除:虚拟化创建是分钟级别的, Docker 容器创建是秒级别的, Docker 的快速迭代性,决定了无论是开发、测试、部署都可以节约大量时间
-
交付、部署:虚拟机可以通过镜像实现环境交付的一致性,但镜像分发无法体系化。 Docker 在 Dockerfile 中记录了容器构建过程,可在集群中实现快速分发部署
dockers的三个基本概念
-
image(镜像)
-
container(容器)
-
repository(仓库)
-
image(镜像)
-
镜像是docker运行的前提,仓库是存放镜像的地方,那么镜像就是核心了。
-
Docker镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。 -
我们简单来说一下,这个储存格式-联合文件系统,这是一个分层的问阿金系统,可以将不同的目录挂载到同一个虚拟文件下。那么我们docker的镜像就是使用的这样一个文件系统。
-
下图就是镜像的存储格式,这张图是分层的,最下面一层,上面也是一层层的好像集装箱罗列在一起.这就是镜像最直观的存储方式.下面是操作系统的引导,上面是linux操作系统,再上面是一些相关的软件,如果是我们自己的程序,就可以是tomcat,jdk,再往上是应用代码,每一层是我们自己都可以控制得,最上面一层先忽略不看,因为这是和容器有关的.注意一点,docker镜像系统的每一层都是只读的,然后把每一层加载完成之后这些文件都会被看成是同一个目录,相当于只有一个文件系统.docker的这种文件系统被称之为镜像.
-
container(容器)
为了便于理解,大家可以把容器想象成虚拟机,每个虚拟机都有自己的文件系统,可以把图1整个一部分看成是文件系统,与虚拟机系统的区别是这里面的文件系统是一层一层的,并且最下面的n层都是只读的,只有上面一层是可写的.为什么要有可写的这层呢?大家的程序运行起来,势必会要写一些日志,写一些文件,或者对系统的某一些文件做一些修改,所以容器在最上面一层创建了可读可写的文件系统.
在程序的运行过程中,如果要写镜像文件时,因为镜像的每一层都是只读的,它会把文件的每一层拷到文件的最上层,然后再对它进行修改,修改之后,当我们的应用读一个文件时会从顶层进行查找,如果没有才会找下一层.
由于容器的最上一层是可以修改的,镜像是不能修改的,这样就能保证镜像可以生成多个容器独立运行,没有任何干扰.
简要的概括就是:容器 = 镜像 + 读写层。
-
repository(仓库)
-
Docker仓库是集中存放镜像文件的场所。镜像构建完成后,可以很容易的在当前宿主上运行,但是, 如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry(仓库注册服务器)就是这样的服务。有时候会把仓库(Repository)和仓库注册服务器(Registry)混为一谈,并不严格区分。Docker仓库的概念跟Git类似,注册服务器可以理解为GitHub这样的托管服务。实际上,一个Docker Registry中可以包含多个仓库(Repository),每个仓库可以包含多个标签(Tag),每个标签对应着一个镜像。所以说,镜像仓库是Docker用来集中存放镜像文件的地方类似于我们之前常用的代码仓库。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本 。我们可以通过
<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以latest作为默认标签.。
仓库又可以分为两种形式:
-
public(公有仓库)
-
private(私有仓库)
-
Docker Registry公有仓库是开放给用户使用、允许用户管理镜像的Registry服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。 -
除了使用公开服务外,用户还可以在本地搭建私有
Docker Registry。Docker官方提供了Docker Registry镜像,可以直接使用做为私有Registry服务。当用户创建了自己的镜像之后就可以使用push命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上pull下来就可以了。 -
我们主要把
Docker的一些常见概念如Image,Container,Repository做了详细的阐述,也从传统虚拟化方式的角度阐述了docker的优势,我们从下图可以直观地看到Docker的架构: -
Docker使用C/S结构,即客户端/服务器体系结构。Docker客户端与Docker服务器进行交互,Docker服务端负责构建、运行和分发Docker镜像。Docker客户端和服务端可以运行在一台机器上,也可以通过RESTful、stock或网络接口与远程Docker服务端进行通信。
- 这张图展示了 Docker 客户端、服务端和
Docker仓库(即Docker Hub和Docker Cloud),默认情况下Docker会在Docker中央仓库寻找镜像文件,这种利用仓库管理镜像的设计理念类似于Git,当然这个仓库是可以通过修改配置来指定的,甚至我们可以创建我们自己的私有仓库。
docker安装
1.下载关于Docker的依赖环境
yum -y install yum-utils device-mapper-persistent-data lvm2
2.设置下载Docker的镜像源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
3.安装Docker
yum makecache fast
yum -y install docker-ce
4.启动Docker,并设置为开机自动启动,测试
# 启动Docker服务
systemctl start docker
# 设置开机自动启动
systemctl enable docker
# 测试
docker run hello-world
- 查看刚才下载的hello-word镜像
docker images
卸载docker
- 删除依赖
yum remove docker-ce docker-ce-cli containerd.io
- 删除资源
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
# /var/lib/docker docker工作的默认路径
阿里云镜像加速
- 登录阿里云
{abtn icon="fa-heart-o" color="#f86dc5" href="www.aliyun.com/" radius="17px" content="阿里云"/}
- 在弹性计算找到容器计算服务
- 创建账号然后点击镜像工具里面的镜像加速
- 配置使用
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://vjtmk5k2.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
- 查看是否配置成功
cat /etc/docker/daemon.json
/*返回如下
{
"registry-mirrors": ["https://vjtmk5k2.mirror.aliyuncs.com"]
}
*/
运行过程
底层原理
docker是怎样工作做的?
-
Docker Engine是一个客户端-服务器应用程序,具有以下主要组件:
-
一个服务器,它是一种长期运行的程序,称为守护进程(dockerd命令)。
-
一个REST API,它指定程序可以用来与守护进程对话并指示它做什么的接口。
-
命令行接口(CLI)客户端(docker命令)。
-
Docker是一个Client Server结构的系统,Docker守护进程运行在主机上,然后通过Socket连接从客户 端访问,守护进程从客户端接受命令并管理运行在主机上的容器。
docker为什么比VM快?
- Docker不需要Hypervisor实现硬件资源虚拟化,运行在Docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上Docker将会在效率上有明显优势。
- Docker利用的是宿主机的内核,而不需要GuestOS。因此,当新建一个容器时,Docker不需要和虚拟机一样重新加载一个操作系统内核。可避免引导寻址、加载操作系统内核返回这个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载GuestOS,返回新增过程是分钟级别的。而Docker由于利用宿主机的操作系统,则省略了返回的过程,因此新建一个Docker容器只需要几秒钟。
docker基本命令
作者:酒笙
{music id="1486593195" color="#cf4abf" autoplay="autoplay"/}
帮助命令
docker version #版本信息
docker info #系统信息
docker 命令 --help #帮助命令
帮助文档地址:docs.docker.com/engine/refe…
镜像命令
docker images 查看本机所有镜像
[root@jiusheng]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 4 months ago 13.3kB
#REPOSITORY 镜像仓库源
#TAG 镜像标签
#IMAGE ID 镜像id
# CREATED 镜像创建的时间
#SIZE 镜像大小
#可选项
-a , --all #列出所有镜像
-q , --quiet #显示镜像id
docker search 搜索镜像
# 官网搜索: https://hub.docker.com/
docker search 搜索名
#搜索MySQL镜像
docker search mysql
[root@jiusheng]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 11147 [ OK]
mariadb MariaDB Server is a high performing open sou… 4228 [OK]
#条件搜索
--filter=STARS=5000 #搜索出来的镜像就是STARS大于5000的
[root@jisuheng]# docker search mysql --filter=STARS=5000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 11147 [OK]
docker pull 下载镜像
#下载镜像 docker pull 镜像名[:tag] 下载指定版本
docker pull 镜像名 #默认下载最新版本
[root@jiusheng]# docker pull mysql
Using default tag: latest #不填写指定版本,默认下载最新版本
latest: Pulling from library/mysql
b4d181a07f80: Pull complete #分层下载,也就是 docker iamge核心,联合文件系统
b4d181a07f80: Pull complete
a462b60610f5: Pull complete
578fafb77ab8: Pull complete
524046006037: Pull complete
d0cbe54c8855: Pull complete
aa18e05cc46d: Pull complete
fd6f649b1d0a: Pull complete
2a97d48c2fdc: Pull complete
30f0c7db48fc: Pull complete
f5dda8df049e: Pull complete
671b83fd7448: Pull complete
5d9cc55fa997: Pull complete
Digest: sha256:18d8d109aa64673c78aebfb845b929cfdac97a553332f4310f4de8d67ceb03d2
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest
#真实地址等价于 docker pull mysql = docker pull docker.io/library/mysql:latest
#下载指定版本
docker pull mysql:5.7
#具体有哪些版本可以去官网查看,不要乱写
[root@jiusheng]# docker pull mysql:5.7
5.7: Pulling from library/mysql
b4d181a07f80: Already exists #这就是分层下载的好处,只下载不一样的。
a462b60610f5: Already exists
578fafb77ab8: Already exists
524046006037: Already exists
d0cbe54c8855: Already exists
aa18e05cc46d: Already exists
fd6f649b1d0a: Already exists
8a2b858b000b: Pull complete
322182b17422: Pull complete
070e28050a88: Pull complete
613bdfd8796e: Pull complete
Digest: sha256:956e11ac581cad9ac8747a9a1d61b8ffcfa6845e0f23bdbab6ba20a2ad792cbf #这是一个签名
Status: Downloaded newer image for mysql:5.7 #版本
docker.io/library/mysql:5.7
docker rmi 删除镜像
docker rmi -f 镜像id #删除指定镜像
docker rmi -f 镜像id,镜像id #删除多个指定镜像
docker rmi -f $(docker images -aq) #使用递归删除所有镜像
容器命令
有了镜像之后,才可以创建容器,容器依赖于镜像。
我们这里下载一个centos的镜像
docker pull centos
新建容器并启动
docker run [可选参数] images
#参数说明
--name="Name" #容器名字,用于区分容器
-d #后台方式运行
-it #使用交互式运行,并进入容器查看内容
-p #指定容器端口
-p ip : 主机端口 : 容器端口
-p 主机端口 :容器端口 常用
-p 容器端口
-P 随机容器端口
测试,启动并进入容器
[root@jiusheng]# docker run -it centos /bin/bash
[root@2d13e5147554 /]# ls #查看容器内的centos
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
[root@2d13e5147554 /]#
退出容器
exit #停止容器并退出
Ctrl + p + q #容器不停止退出
列出所有运行的容器
#docker ps (可选参数)
docekr ps #列出正在运行的容器
docker ps -a #列出当前正在运行的容器和历史运行的容器
docker ps -n=? #显示最近创建的容器,?是数字,表示显示几个
docker -p #显示容器编号
#示例
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps -n=1
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2d13e5147554 centos "/bin/bash" 6 minutes ago Exited (0) 4 minutes ago heuristic_tu
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps -n=4
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2d13e5147554 centos "/bin/bash" 6 minutes ago Exited (0) 4 minutes ago heuristic_tu
ff7056f81cfe d1165f221234 "/hello" 25 hours ago Exited (0) 25 hours ago nervous_kalam
删除容器
和前面删除镜像的方式一样,只是镜像是rmi而容器是rm,殊途同归
docker rm 容器id #删除指定容器,同时如果容器在运行,就不能删除
docker rm -f $(docker ps -aq) #使用递归删除所有容器
docker ps -a -q |xargs docker rm #删除所有容器,也可写作docker ps -aq|xargs docker rm
启动和停止容器
docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止当前运行容器
docker kill 容器id #强制停止当前容器
其他常用命令
后台启动容器
#docker run -d 镜像名
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker run -d centos
3c7893d0514ae66e0d31bc9efb725b98504467599376e494dcea47d629a13dbf
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@iZj6c5ctiawsbu90vbskdwZ ~]#
#这里我们通过docker ps 发现容器停止了,那么是怎么一会事,我们说一说。
#docekr 容器在使用后台运行的时候,如果说没有一个前台进程,那么就会自动停止,也就是说,如果要使用后台运行,就必须要有一个前台进程!
查看日志
docker logs -f -t --tail ?容器id #?表示数字,即你要显示多少条日志,同时-f -t可以写在一起即-tf
docker logs -f t 容器id #显示全部日志
显示容器进程信息
docker top 容器id
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker top 1ff8b6186c5f
UID PID PPID C STIME TTY TIME CMD
root 22368 22349 0 11:08 pts/0 00:00:00 /bin/bash
查看镜像元数据
docker inspect top 容器id
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1ff8b6186c5f centos "/bin/bash" 10 seconds ago Up 9 seconds inspiring_thompson
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker inspect 1ff8b6186c5f
[
{
"Id": "1ff8b6186c5f5d19b715a5c320b7ecb330f9e570e9bba2ff82bce2ceb7344262",
"Created": "2021-07-21T03:08:39.027552726Z",
"Path": "/bin/bash",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 22368,
"ExitCode": 0,
"Error": "",
"StartedAt": "2021-07-21T03:08:39.311797803Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55",
"ResolvConfPath": "/var/lib/docker/containers/1ff8b6186c5f5d19b715a5c320b7ecb330f9e570e9bba2ff82bce2ceb7344262/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/1ff8b6186c5f5d19b715a5c320b7ecb330f9e570e9bba2ff82bce2ceb7344262/hostname",
"HostsPath": "/var/lib/docker/containers/1ff8b6186c5f5d19b715a5c320b7ecb330f9e570e9bba2ff82bce2ceb7344262/hosts",
"LogPath": "/var/lib/docker/containers/1ff8b6186c5f5d19b715a5c320b7ecb330f9e570e9bba2ff82bce2ceb7344262/1ff8b6186c5f5d19b715a5c320b7ecb330f9e570e9bba2ff82bce2ceb7344262-json.log",
"Name": "/inspiring_thompson",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "host",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/f374005ba37d8dd511a5663780d1a6d9f73721853d0f865f93fa06c294099b6e-init/diff:/var/lib/docker/overlay2/95fb52765b6ea97468e0c38889f47d9e3c95d2e69d556c18798f00ebb3e2cfb1/diff",
"MergedDir": "/var/lib/docker/overlay2/f374005ba37d8dd511a5663780d1a6d9f73721853d0f865f93fa06c294099b6e/merged",
"UpperDir": "/var/lib/docker/overlay2/f374005ba37d8dd511a5663780d1a6d9f73721853d0f865f93fa06c294099b6e/diff",
"WorkDir": "/var/lib/docker/overlay2/f374005ba37d8dd511a5663780d1a6d9f73721853d0f865f93fa06c294099b6e/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "1ff8b6186c5f",
"Domainname": "",
"User": "",
"AttachStdin": true,
"AttachStdout": true,
"AttachStderr": true,
"Tty": true,
"OpenStdin": true,
"StdinOnce": true,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
"Image": "centos",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.label-schema.build-date": "20201204",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "236a57971cd0b33ec1fd5b3c8cd725fabd85aef3a796de461a699c42b6e289f6",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/236a57971cd0",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "03ed818c13a101bd6254b5e5c18ede6f9c776efb2e65ac382f711b8f8b265b2b",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "3be7a57080be0d228e4f459c30ed8bc85ab61b84ac10ddbeaa546ad97f294539",
"EndpointID": "03ed818c13a101bd6254b5e5c18ede6f9c776efb2e65ac382f711b8f8b265b2b",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
}
}
]
进入当前正在运行的容器
我们通常都是通过后台方式运行,需要进入容器修改配置信息
#方式一
docker exec -it 容器id BashShell
[root@jiusheng]# docker exec -it 1ff8b6186c5f /bin/bash
[root@1ff8b6186c5f /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
#方式二
docker attach 容器id
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker attach 1ff8b6186c5f
[root@1ff8b6186c5f /]#
#区别
docker exec 进入容器后开启新的终端
docker attach 进入容器正在执行的终端,不会启动新终端
从容器拷贝数据到本机
docker cp 容器id:容器内路径 目的路径
#进入容器内部
[root@1ff8b6186c5f /]# cd /home
[root@1ff8b6186c5f home]# ls
#在容器内部新建一个文件
[root@1ff8b6186c5f home]# touch jiusheng.np
[root@1ff8b6186c5f home]# exit
exit
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1ff8b6186c5f centos "/bin/bash" 3 hours ago Exited (0) 16 seconds ago inspiring_thompson
3c7893d0514a centos "/bin/bash" 3 hours ago Exited (0) 3 hours ago clever_lalande
#把文件拷贝到本机
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker cp 1ff8b6186c5f:/home/jiusheng.np /home
[root@iZj6c5ctiawsbu90vbskdwZ ~]# cd /home
[root@iZj6c5ctiawsbu90vbskdwZ home]# ls
admin jiusheng.np
#我们可以卡看到哈,在容器里面建立的jiusheng.np,我们已经复制到了本机的home目录里面。
小结
勤能补拙,温故而知新
attach Attach to a running container #当前 shell 下 attach 连接指定运行镜像
build Build an image from a Dockerfile #通过 Dockerfile 定制镜像
commit create a new image from a container changes #提交当前容器为新的镜像
cp copy files/folders from the containers filesystem to the host path #从容器中拷贝指定文件或者目录到宿主机中
create Create a new container #创建一个新的容器,同 run,但不启动容器
diff Inspect changes on a container's filesystem #查看 docker 容器变化
events Get real time events from the server #从docker 服务获取容器实时事件
exec Run a command in an existing container #在已存在的容器上运行命令
export Stream the contents of a container as a tar archive #导出容器的内容流作为一个 tar 归档文件[对应import ]
history Show the history of an image #展示一个镜像形成历史
images List images # 列出系统当前镜像
import create a new filesystem image from the contents of a tarball #从tar包中的内容创建一个新的文件系统映像[对应export]
info Display system-wide information # 显示系统相关信息
inspect Return low-level information on a container #查看容器详细信息
kill Kill a running container #kill 指定 docker 容器
load Load an image from a tar archive # 从一个 tar 包中加载一个镜像[对应 save]
login Register or Login to the docker registry server # 注册或者登陆一个 docker 源服务器
logout Log out from a Docker registry server # 从当前 Docker registry 退出
logs Fetch the logs of a container #输出当前容器日志信息
port Lookup the public-facing port which is NAT-ed to PRIVATE_PORT #查看映射端口对应的容器内部源端
pause pause all processes within a container #暂停容器
ps List containers #列出容器列表
pull the docker registry server #从docker镜像源服务器拉取指定镜像
push Push an image or a repository to the docker registry server # 推送指定镜像或者库镜像至docker源服务器
restart Restart a running container #重启运行的容器
rm Remove one or more containers # 移除一个或者多个容器
rmi Remove one or more images #移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才可继续或 -f 强制删除]
run Run a command in a new container #创建一个新的容器并运行一个命令
save Save an image to a tar archive # 保存一个镜像为一个 tar 包[对应 load]
search Search for an image on the Docker Hub #在 docker hub 中搜索镜像
start Start a stopped containers # 启动容器
stop Stop a running containers #停止容器
tag Tag an image into a repository #给源中镜像打标签
top Lookup the running processes of a container #查看容器中运行的进程信息
unpause Unpause a paused container # 取消暂停容器
version Show the docker version information #查看 docker 版本号
wait Block until a container stops, then print its exit code #截取容器停止时的退出状态值
格式
# 1. 拉取镜像到本地
docker pull 镜像名称[:tag]
# 举个例子 tomcat
docker pull daocloud.io/library/tomcat:8.5.15-jre8
# 2. 查看全部本地的镜像
docker images
# 3. 删除本地镜像
docker rmi 镜像的标识
# 4. 镜像的导入导出(不规范)
# 将本地的镜像导出
docker save -o 导出的路径 镜像id
# 加载本地的镜像文件
docker load -i 镜像文件
# 修改镜像名称
docker tag 镜像id 新镜像名称:版本
# 1. 运行容器
# 简单操作
docker run 镜像的标识|镜像名称[tag]
# 常用的参数
docker run -d -p 宿主机端口:容器端口 --name 容器名称 镜像的标识|镜像名称[tag]
# -d: 代表后台运行容器
# -p: 宿主机端口:容器端口: 为了映射当前Linux的端口和容器的端口
# --name 容器名称: 指定容器的名称
# 2. 查看正在运行的容器
docker ps [OPTIONS]
# OPTIONS说明:
# -a: 代表查看全部的容器,包括没有运行
# -q: 只查看容器的标识
# -f: 根据条件过滤显示的内容
# --format: 指定返回值的模板文件
# -l: 显示最近创建的容器
# -n: 列出最近创建的n个容器
# --no-trunc: 不截断输出
# -s: 显示总的文件大小
# 3. 查看容器的日志
docker logs -f 容器id
# -f: 可以滚动查看日志的最后几行
# 4. 进入到容器内部
docker exec -it 容器id bash
# 5. 删除容器(删除容器前,需要先停止容器)
docker stop 容器id
# 停止指定的容器
docker stop $(docker ps -qa)
# 停止全部容器
docker rm 镜像id
# 删除指定容器
docker rm $(docker ps -qa)
# 删除全部容器
#6. 启动容器
docker start 容器id
作业练习
安装Nginx
- 安装nginx
docker search nginx
- 下载镜像
docker pull nginx
- 运行镜像
# -d 后台运行
# --name 给容器命名
# -p 端口映射,本机端口:容器内部端口
docker run -d --name jiusheng -p 520:80 nginx
#查看是否启动
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
82e88fd7529c nginx "/docker-entrypoint.…" 12 seconds ago Up 10 seconds 0.0.0.0:520->80/tcp jiusheng
#查看端口是否连通
[root@iZj6c5ctiawsbu90vbskdwZ ~]# curl localhost:520
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
- 进入容器
docker exec -it jiusheng /bin/bach
- 端口映射概念
安装tomcat
注意,在官网上的使用方法如下:
docker run -it --rm tomcat:9.0
这里我们不推荐,我们一般是使用后台启动,停止了容器后,还可以查找到, 但是docker run -it --rm ,使用之后就会直接删除,查找不到,也就是说是一个即用即删的,多用于测试!
- 搜索tomcat镜像
docker searce tomcat
- 下载tomcat
docker pull tomcat
- 启动运行
docker run -d -p 250:8080 --name tomcat01 tomcat
- 测试访问
curl localhost:250
访问ip:250
- 访问的通,没有出现想要的页面
#进入容器
docker exec -it tomcat01 /bin/bash
#发现少了命令,同时没有web。
#原因:默认最小安装,剔除了不必要的东西,保证最小化运行环境。
#解决方法
cp -r webapps.dist/* webapps
#之后就可以访问量
部署elasticsearch简称es+kibana
#官方命令
#--net somenetwork 网络配置
#"discovery.type=single-node" 集群配置,默认单节点
docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:tag
#我们做一些修改
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e EC_JAVA_OPTS="=-Xms64m -Xm512m" elasticsearch:7.6.2
#去掉了网络服务
#改了名字
#增加了环境限制,别问,问就是这个非常耗内存,我的机子托不动,然后指定了版本号
docker run -d --name=es2 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
- 查看容器占用内存
docker stats 容器id
- 检查是否启动成功
curl localhost:9200
#参考
[root@iZj6c5ctiawsbu90vbskdwZ ~]# curl localhost:9200
{
"name" : "62ee34017bec",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "3OGmDOBLSOOYOeQQ23F7dQ",
"version" : {
"number" : "7.6.2",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
"build_date" : "2020-03-26T06:34:37.794943Z",
"build_snapshot" : false,
"lucene_version" : "8.4.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
部署可视化面板
Portainer
这里需要主要的是,我们安装ce版本即可,因为这是开源切免费的!
官网地址:
Portainer 服务器部署
docker volume create portainer_data
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce
Portainer 仅代理部署
docker run -d -p 9001:9001 --name portainer_agent --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/docker/volumes:/var/lib/docker/volumes portainer/agent
#查看是否启动成功
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8b100ad7b90f portainer/agent "./agent" 24 seconds ago Up 23 seconds 0.0.0.0:9001->9001/tcp portainer_agent
访问测试
这是一个登录界面,在这里我们需要建立管理员角色
创建成功之后,我们进入后台界面
这样就完安装完成了,我们也不使用,就简单的了解就好了
镜像讲解
Docker镜像加载原理
镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件
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镜像要采用这种分层的结构呢?
- 最大的好处,我觉得莫过于是资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。查看镜像分层的方式可以通过 docker image inspect 命令!
所有的 Docker 镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。 举一个简单的例子,假如基于 Ubuntu Linux 16.04 创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。该镜像当前已经包含 3 个镜像层,如下图所示(这只是一个用于演示的很简单的例子
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含 3 个文件,而镜像包含了来自两个镜像层的 6 个文件。
上图中的镜像层跟之前图中的略有区别,主要目的是便于展示文件。 下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有 6 个文件,这是因为最上层中的文件7 是文件 5 的一个更新版本。
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。 Docker 通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。 Linux 上可用的存储引擎有 AUFS、Overlay2、Device Mapper、Btrfs 以及 ZFS。顾名思义,每种存储引擎都基于 Linux 中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。 Docker 在 Windows 上仅支持 windowsfilter 一种存储引擎,该引擎基于 NTFS 文件系统之上实现了分层和 CoW[1]。下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图
特点
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层
commit
commit的作用相当于快照
提交镜像
docker commit -m="提交信息" -a="作者" 容器id 目标镜像名:[tag]
测试
-
启动tomcat
docker run -it -p 432:8080 comcat -
进入comcat
docker exec -it 容器id /bin/bash -
拷贝数据
cp -r webapps.dist/* webapps -
访问地址是否修改成功
http://47.243.161.30:432/ -
退出容器并提交新的修改
#退出容器 exit #提交修改 docker commit -a="jiusheng" -m="webapps" 0cee6cf8bd57 comcat02:1.1 -
查看是否生成成功
docker images comcat02 1.1 31ea9dda1fda 8 seconds ago 677MB portainer/portainer-ce latest 865cf8021627 2 weeks ago 210MB portainer/agent latest 3cdf856343c6 2 weeks ago 138MB nginx latest 4cdc5dd7eaad 2 weeks ago 133MB tomcat latest 36ef696ea43d 3 weeks ago 667MB centos latest 300e315adb2f 7 months ago 209MB kibana 7.6.2 f70986bc5191 16 months ago 1.01GB elasticsearch 7.6.2 f29a1ee41030 16 months ago 791MB
容器数据卷
docker数据卷概念
Docker的理念是:将运用与运行的环境打包形成容器运行 ,运行可以伴随着容器。
Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了。
所以我们希望:数据可以持久化、容器之间(甚至容器与宿主机之间)可以数据共享。为了能保存数据可以在docker中使用卷。卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。
卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:
- 数据卷可在容器之间共享或重用数据
- 卷中的更改可以直接生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
为什么使用数据卷
Docker的镜像是由一系列的只读层组合而来,当启动一个容器的时候,Docker加载镜像的所有只读层,并在最上层加入一个读写层。这个设计使得Docker可以提高镜像构建、存储和分发的效率,节省了时间和存储空间,然而也存在如下问题。
容器中的文件在宿主机上存在形式复杂,不能在宿主机上很方便的对容器中的文件进行访问
- 多个容器之间的数据无法共享
- 当删除容器时,容器产生的数据将丢失
为了解决这些问题,Docker引入了数据卷(volume)机制。volume是存在一个或多个容器中的特定文件或文件夹,这个目录能够独立于联合文件系统的形式在宿主机中存在,并为数据的共享与持久提供一下便利。
- volume在容器创建时就初始化,在容器运行时就可以使用其中的文件
- volume能在不同的容器之间共享和重用
- volume中的数据的操作会马上生效
- volume中数据操作不会影响到镜像本身
- volume的生存周期独立于容器的生存周期,即使删除容器,volume仍然会存在,没有任何容器使用的volume也不会被Docker删除
volume命令
了解volume的命令
- 使用帮助文档查看命令
docker volume --help
- 参数说明
create #创建卷
inspect #显示一个或多个数据卷的详细信息
ls #列出所有卷
prune #删除所有未使用的数据卷
rm #删除一个或多个卷
- 创建一个数据卷
基本格式如下:
docker volume create 名字
docker volume create jiu
此时,数据卷默认会放到/var/lib/docker/volumes路径下,会发现所新建的数据卷位置,查看命令如下: ## 参数可以为数字“1”,字母L:大小写均可,但效果不一样 ls -1 /var/lib/docker/volumes
为什么会在这里,我们可以来看一下docker的文件目录:
docker的默认目录为/var/lib/docker/
里面的结构如下
├── containers #用来存储容器信息 ├── image #用来存储镜像中间件及本身信息,大小,依赖信息 │ └── overlay2 │ ├── distribution │ ├── imagedb │ │ ├── content │ │ │ └── sha256 │ │ └── metadata │ │ └── sha256 │ ├── layerdb │ └── repositories.json ├── network #网络信息 │ └── files │ └── local-kv.db ├── overlay2 #存放镜像 │ └── l ├── plugins │ ├── storage │ │ └── blobs │ │ └── tmp │ └── tmp ├── swarm ├── tmp #docker临时目录 ├── trust #docker信任目录 └── volumes #docker卷目录 └── metadata.db
- 列出所有数据卷
docker volume ls
- 查询数据卷信息
格式:
docker volume inspect 数据卷名
docker volume inspect jiu
[root@iZj6c5ctiawsbu90vbskdwZ docker]# docker volume inspect jiu
[
{
"CreatedAt": "2021-07-27T16:49:41+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/jiu/_data", #存放位置
"Name": "jiu", #数据卷名
"Options": {},
"Scope": "local"
}
]
- 删除一个数据卷
格式:
docker volume rm 数据卷名
docker volume rm jiu
[root@iZj6c5ctiawsbu90vbskdwZ docker]# docker volume ls
DRIVER VOLUME NAME
local jiu
[root@iZj6c5ctiawsbu90vbskdwZ docker]# docker volume rm jiu
jiu
[root@iZj6c5ctiawsbu90vbskdwZ docker]# docker volume ls
DRIVER VOLUME NAME
#可以看到已经删除成功了
- 删除所有没有使用的数据卷
格式:
docker volume prune
docker volume prune
#这里我们提前创建了一些数据卷
[root@iZj6c5ctiawsbu90vbskdwZ docker]# 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:
jiu
sheng
hahha
Total reclaimed space: 0B
#可以看到没有使用的数据均已经全部删除完毕了
数据卷的使用
数据卷目前有两种方式来进行使用,一种是直接通过命令来进行挂载,一种是通过DockerFile来进行添加
命令格式:
docker run -it -v 主机目录:容器内目录
测试
- 启动并挂载数据卷
docker run -it -v /home/ceshi:/home centos /bin/bash
- 查看是否生成挂载目录测试,并成功挂载
[root@iZj6c5ctiawsbu90vbskdwZ /]# cd /home/
[root@iZj6c5ctiawsbu90vbskdwZ home]# ls
admin ceshi
[root@iZj6c5ctiawsbu90vbskdwZ home]#
[root@iZj6c5ctiawsbu90vbskdwZ ceshi]# docker inspect 1795f7f64501
[
{
"Id": "1795f7f64501188c8e74a8f9f5b2fb8703a84f0d7b36606f3f98ce2c06b93f3f",
"Created": "2021-07-27T09:33:28.066660046Z",
"Path": "/bin/bash",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 8000,
"ExitCode": 0,
"Error": "",
"StartedAt": "2021-07-27T09:33:28.409923354Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55",
"ResolvConfPath": "/var/lib/docker/containers/1795f7f64501188c8e74a8f9f5b2fb8703a84f0d7b36606f3f98ce2c06b93f3f/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/1795f7f64501188c8e74a8f9f5b2fb8703a84f0d7b36606f3f98ce2c06b93f3f/hostname",
"HostsPath": "/var/lib/docker/containers/1795f7f64501188c8e74a8f9f5b2fb8703a84f0d7b36606f3f98ce2c06b93f3f/hosts",
"LogPath": "/var/lib/docker/containers/1795f7f64501188c8e74a8f9f5b2fb8703a84f0d7b36606f3f98ce2c06b93f3f/1795f7f64501188c8e74a8f9f5b2fb8703a84f0d7b36606f3f98ce2c06b93f3f-json.log",
"Name": "/gallant_sanderson",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": [
"/home/ceshi:/home"
],
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "host",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/9952b87bf9c7b7b84fbbdb2ac08fdc7ceb96b8cdf21c4f2d1d2f49bd8595ee1f-init/diff:/var/lib/docker/overlay2/95fb52765b6ea97468e0c38889f47d9e3c95d2e69d556c18798f00ebb3e2cfb1/diff",
"MergedDir": "/var/lib/docker/overlay2/9952b87bf9c7b7b84fbbdb2ac08fdc7ceb96b8cdf21c4f2d1d2f49bd8595ee1f/merged",
"UpperDir": "/var/lib/docker/overlay2/9952b87bf9c7b7b84fbbdb2ac08fdc7ceb96b8cdf21c4f2d1d2f49bd8595ee1f/diff",
"WorkDir": "/var/lib/docker/overlay2/9952b87bf9c7b7b84fbbdb2ac08fdc7ceb96b8cdf21c4f2d1d2f49bd8595ee1f/work"
},
"Name": "overlay2"
},
"Mounts": [
{
"Type": "bind",
"Source": "/home/ceshi", #我们可以看到这里是挂载上去了的,那我们接着来测试
"Destination": "/home", #容器内的地址
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
"Config": {
"Hostname": "1795f7f64501",
"Domainname": "",
"User": "",
"AttachStdin": true,
"AttachStdout": true,
"AttachStderr": true,
"Tty": true,
"OpenStdin": true,
"StdinOnce": true,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
"Image": "centos",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.label-schema.build-date": "20201204",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "c5803986c1107b2e97d534aab5c2725f355b7cef1c171afd8486f72d0b83a382",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/c5803986c110",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "f6f8cedcc0ad532f2c01910f84e3436c1c33ec8aa0d2e47236de75bde44c8384",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "3be7a57080be0d228e4f459c30ed8bc85ab61b84ac10ddbeaa546ad97f294539",
"EndpointID": "f6f8cedcc0ad532f2c01910f84e3436c1c33ec8aa0d2e47236de75bde44c8384",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
}
}
]
- 在本机添加文件
#生成一个jiusheng.666的文件
[root@iZj6c5ctiawsbu90vbskdwZ ceshi]# touch jiusheng.666
[root@iZj6c5ctiawsbu90vbskdwZ ceshi]# ls
jiusheng.666
- 到容器里面查看是否同步
#可以看到是已经同步的了
[root@1795f7f64501 /]# cd /home/
[root@1795f7f64501 home]# ls
jiusheng.666
- 在容器内删除文件
[root@1795f7f64501 home]# rm jiusheng.666
rm: remove regular empty file 'jiusheng.666'? y
[root@1795f7f64501 home]#
#这里我们在容器里面已经吧文件jiusheng.666删除掉了,我们去宿主机看看文件还在不在
[root@iZj6c5ctiawsbu90vbskdwZ ceshi]# ls
[root@iZj6c5ctiawsbu90vbskdwZ ceshi]#
#可以看到是没有任何文件的,也就是说这里目录下的文件是双向绑定的,同时,你停止或者删除容器,里面的内容也是不会变得,出给你认为的去修改或者删除!
挂载之后的文件就是共享,同时不管你删除容器还是停止容器,映射出来的文件不会随之消失!
这里删除或者停止容器的测试就不在赘述了。
拓展
我们在实际使用的过程中,会发现有一些的命令会多一个ro 或者rw
这个是读取权限:
ro 只读
rw 可读可写
不设置的话,默认.rw
docker run -it -v /myDataVolume:/dataVolumeContainer:ro centos
-v #代表数据卷
/myDataVolume #宿主机绝对路径目录
:/dataVolumeContainer #容器内目录
centos #镜像名
:ro #设置权限为只读
安装MySQL
- 下载mysql
docker pull mysql:5.6
- 运行容器并进行数据挂载
#这是官方给的方式,我们进行就该
#my-secret-pw -d 表示密码,进行修改
#-e 是环境变量
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
docker run -p 3306:3306 --name mymysql -v $PWD/conf:/etc/mysql/conf.d -v $PWD/logs:/logs -v $PWD/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
参数解释:
-p 3306:3306:将容器的 3306 端口映射到主机的 3306 端口。
-v $PWD/conf:/etc/mysql/conf.d:将主机当前目录下的 conf/my.cnf 挂载到容器的 /etc/mysql/my.cnf。
-v $PWD/logs:/logs:将主机当前目录下的 logs 目录挂载到容器的 /logs。
-v $PWD/data:/var/lib/mysql :将主机当前目录下的data目录挂载到容器的 /var/lib/mysql 。
-e MYSQL_ROOT_PASSWORD=123456:初始化 root 用户的密码。
- 连接看测试
可以看到连接成功,下面我们创建一个表来测试
这个时候我们来数据是否同步
- 我们停止掉原来的数据库,同时新开一个数据库
docker run -p 3307:3306 --name mysql01 -v $PWD/conf:/etc/mysql/conf.d -v $PWD/logs:/logs -v $PWD/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
我们来进行连接
我们之前创建的数据都还在
至此,我们可以很明确的知道,数据卷的使用,可以实现数据的持久化。不再一删除容器就什么都没有了!
具名和匿名挂载
什么是具名挂载和匿名挂载?
我们前面挂载数据卷的时候是通过 -v 主机路径:容器内路径 ,来进行挂载的,那么我们不指定主机的挂载路径只指定容器内路径,-v 容器内路径 那么这个就是匿名挂载, 反之如果我们吧主机路径变成别名,那么就是具名挂载在,比如: -v jiusheng:容器内路径
匿名挂载
- 使用匿名挂载启动nginx
docker run -d -P --name nginx01 -v /etc/nginx nginx
参数解读:
-P 随机端口
-v 匿名挂载会随机生成挂载路径
- 使用volume查看数据卷
docker volume ls
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker volume ls
DRIVER VOLUME NAME
local 0ba2accbb52f84f4ddd1b92995db0ce4e8adbb3f710595f26823f9f01f014c65
local 8f054507bd037b086e742d764f415df0fcbb08e7d1e71f3c83c1e112f7c28ca1
local 81e46324431241ff7b95a6cceb4b5dd85d9b9eefb03aa55d46f153b101a8502f
local 82a3da984765cbbdb73797cec9038650e035a2511a07479370587787fc331501
local 53050314ad0cf8d879280a1c1df3a587f497ae93315da31cc5d97ae7a0907f3c
local bc56b1d4485fb0a171f5807204408a6257109311e37365bbfd79387afc940cb9
local cb7e41c8d674d05d355c10b0a7101bf7569500b78c38d8f50ca6f87ed5c265d6
local f4785b207baa99a0214b40816dcc51e265a5ea5a66e4f55a1ab1b6d286ab47f9
- 查看匿名挂载路径
docker volume inspect
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker volume inspect f4785b207baa99a0214b40816dcc51e265a5ea5a66e4f55a1ab1b6d286ab47f9
[
{
"CreatedAt": "2021-07-29T08:56:05+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/f4785b207baa99a0214b40816dcc51e265a5ea5a66e4f55a1ab1b6d286ab47f9/_data",
"Name": "f4785b207baa99a0214b40816dcc51e265a5ea5a66e4f55a1ab1b6d286ab47f9",
"Options": null,
"Scope": "local"
}
]
具名挂载
- 使用具名挂载nginx
docker run -d -P --name nginx02 -v jumingguazai:/etc/nginx nginx
- 查看数据卷
docker volume ls
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker volume ls
DRIVER VOLUME NAME
local jumingguazai
- 查看具名挂载地址
docker volume inspect jumingguazai
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker volume inspect jumingguazai
[
{
"CreatedAt": "2021-07-29T10:46:44+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/jumingguazai/_data",
"Name": "jumingguazai",
"Options": null,
"Scope": "local"
}
]
我们可以看到,不管是匿名挂载还是具名挂载,默认的挂载目录地址都是在/var/lib/docker/volumes/xxx/_data
我们通过具名挂载可以方便的找到我们挂载的卷,所以大多数情况也就使用具名挂载
区分挂载类型
| -v 容器内路径 | 匿名挂载 |
|---|---|
| -v 卷名:容器内路径 | 具名挂载 |
| -v /宿主机路径:容器内路径 | 指定路径挂载 ,注意有/ |
dockerfile挂载数据卷
编写脚本
FROM centos
VOLUME ["jiusheng01","jiusheng02"]
CMD echo "-------jiushengzuishuai------"
CMD /bin/bash
基本格式
docker build -f 脚本名 -t 镜像名 .
创建一个自己的镜像
docker build -f dockerfile -t jiu/centos .
#我这是在创建的文件里面,所以没有写绝对路径,注意!
[root@iZj6c5ctiawsbu90vbskdwZ jiusheng]# docker build -f dockerfile -t jiu/centos .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
latest: Pulling from library/centos
7a0437f04f83: Pull complete
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Status: Downloaded newer image for centos:latest
---> 300e315adb2f
Step 2/4 : VOLUME ["jiusheng01","jiusheng02"]
---> Running in 493198964ebc
Removing intermediate container 493198964ebc
---> 708ee122fc35
Step 3/4 : CMD echo "-------jiushengzuishuai------"
---> Running in 4fa544e52a5d
Removing intermediate container 4fa544e52a5d
---> 1636e3ed06f7
Step 4/4 : CMD /bin/bash
---> Running in 8e41d980a363
Removing intermediate container 8e41d980a363
---> e812a670c034
Successfully built e812a670c034
Successfully tagged jiu/centos:latest
#我这里没有centos,所以多了一个下载
查看是否构建成功
docker images
[root@iZj6c5ctiawsbu90vbskdwZ jiusheng]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jiu/centos latest e812a670c034 30 seconds ago 209MB
nginx latest 08b152afcfae 6 days ago 133MB
mysql 5.7 8cf625070931 6 days ago 448MB
centos latest 300e315adb2f 7 months ago 209MB
运行镜像
docker run -it e812a670c034 /bin/bash
[root@85a2c18ffc33 /]# ls -l
total 56
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Jul 29 07:22 dev
drwxr-xr-x 1 root root 4096 Jul 29 07:22 etc
drwxr-xr-x 2 root root 4096 Nov 3 2020 home
drwxr-xr-x 2 root root 4096 Jul 29 07:22 jiusheng01
drwxr-xr-x 2 root root 4096 Jul 29 07:22 jiusheng02
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 4096 Dec 4 2020 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 102 root root 0 Jul 29 07:22 proc
dr-xr-x--- 2 root root 4096 Dec 4 2020 root
drwxr-xr-x 11 root root 4096 Dec 4 2020 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 Jul 29 01:08 sys
drwxrwxrwt 7 root root 4096 Dec 4 2020 tmp
drwxr-xr-x 12 root root 4096 Dec 4 2020 usr
drwxr-xr-x 20 root root 4096 Dec 4 2020 var
查看挂载地址
docker inspect 85a2c18ffc33
"Mounts": [
{
"Type": "volume",
"Name": "d6f8d3df6d8bf7a8067a547550ecf24ec6d8e2217a6f66ec4b694175eca015e9",
"Source": "/var/lib/docker/volumes/d6f8d3df6d8bf7a8067a547550ecf24ec6d8e2217a6f66ec4b694175eca015e9/_data",
"Destination": "jiusheng02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "29cbc761ed2c5cfad7360e0b30918f29011d2a6b4962f50a245501b25323380b",
"Source": "/var/lib/docker/volumes/29cbc761ed2c5cfad7360e0b30918f29011d2a6b4962f50a245501b25323380b/_data",
"Destination": "jiusheng01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
#我们可以看到也是挂载到了对于的目录下,后面的操作就不在演示了
数据卷容器
定义:命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器
容器间的传递共享
docker run -it --name 子容器名 --volumes-from 父容器名 镜像名
- 启动一个子容器
docker run -it --name jiu01 --volumes-from 85a2c18ffc33 e812a670c034
#这里直接使用上面创建的容器为父容器,估不再新建,直接创建子容器
- 在子容器里面创建一个文件
[root@3f816b8ff216 /]# cd jiusheng01
[root@3f816b8ff216 jiusheng01]# touch jiushengya.txt
- 到父容器里面查看
[root@85a2c18ffc33 /]# cd jiusheng01
[root@85a2c18ffc33 jiusheng01]# ls
jiushengya.txt
#数据同步共享
所有子容器数据与父容器以及父容器的其它子容器同步,同时删除容器不会删除数据,父容器停止或者删除,不会影响子容器
DocKerFile
dockerfile概念
dockerfile 是用来构建docker镜像文件的,一个命令参数脚本!
构建步骤
- 编写一个dockerfile文件
- 使用doicker build 构建一个镜像
- 使用docker run 运行镜像
- 使用docker push 发布一个镜像
Dockerfile优点
- 易于版本化管理,Dockerfile 本身是一个文本文件,方便存放在代码仓库做版本管理,可以很方便地找到各个版本之间的变更历史
- 过程可追溯,Dockerfile 的每一行指令代表一个镜像层,根据 Dockerfile 的内容即可很明确地查看镜像的完整构建过程
- 屏蔽构建环境异构,使用 Dockerfile 构建镜像无须考虑构建环境,基于相同 Dockerfile 无论在哪里运行,构建结果都一致
Dockerfile构建过程解析
基础
-
每条指令都必须大写字母,后面跟随至少一个参数
-
指令从上到下按序执行
-
#表示注释
-
每条指令都会创建一个镜像层,并对镜像进行提交
Dockerfile 书写原则
- 单一原则
- 由于容器的本质是进程,一个容器代表一个进程,因此不同功能的应用应该尽量拆分为不同的容器,每个容器只负责单一业务进程。
- 注释信息
- Dockerfile 也是一种代码,我们应该保持良好的代码编写习惯,晦涩难懂的代码尽量添加注释,让协作者可以一目了然地知道每一行代码的作用,并且方便扩展和使用。
- 保持容器最小化
- 应该避免安装无用的软件包,比如在一个 nginx 镜像中,我并不需要安装 vim 、gcc 等开发编译工具。这样不仅可以加快容器构建速度,而且可以避免镜像体积过大。
- 合理选择基础镜像
- 容器的核心是应用,因此只要基础镜像能够满足应用的运行环境即可。例如一个Java类型的应用运行时只需要JRE,并不需要JDK,因此我们的基础镜像只需要安装JRE环境即可。
- 使用 .dockerignore 文件
- 在使用git时,我们可以使用.gitignore文件忽略一些不需要做版本管理的文件。同理,使用.dockerignore文件允许我们在构建时,忽略一些不需要参与构建的文件,从而提升构建效率。.dockerignore的定义类似于.gitignore。
- 尽量使用构建缓存
-
Docker 构建过程中,每一条 Dockerfile 指令都会提交为一个镜像层,下一条指令都是基于上一条指令构建的。如果构建时发现要构建的镜像层的父镜像层已经存在,并且下一条命令使用了相同的指令,即可命中构建缓存。
Docker 构建时判断是否需要使用缓存的规则如下:
-
从当前构建层开始,比较所有的子镜像,检查所有的构建指令是否与当前完全一致,如果不一致,则不使用缓存;
-
一般情况下,只需要比较构建指令即可判断是否需要使用缓存,但是有些指令除外(例如ADD和COPY)。
-
对于ADD和COPY指令不仅要校验命令是否一致,还要为即将拷贝到容器的文件计算校验和(根据文件内容计算出的一个数值,如果两个文件计算的数值一致,表示两个文件内容一致 ),命令和校验和完全一致,才认为命中缓存。
-
因此,基于 Docker 构建时的缓存特性,我们可以把不轻易改变的指令放到 Dockerfile 前面(例如安装软件包),而可能经常发生改变的指令放在 Dockerfile 末尾(例如编译应用程序)。
- 正确设置时区
-
我们从 Docker Hub 拉取的官方操作系统镜像大多数都是 UTC 时间(世界标准时间)。如果你想要在容器中使用中国区标准时间(东八区),请根据使用的操作系统修改相应的时区信息
#Dockerfile 几种常用操作系统的修改方式: #Ubuntu 和Debian 系统 RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime RUN echo "Asia/Shanghai" >> /etc/timezone #CentOS系统 RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
- 使用国内软件源加快镜像构建速度
- 由于我们常用的官方操作系统镜像基本都是国外的,软件服务器大部分也在国外,所以我们构建镜像的时候想要安装一些软件包可能会非常慢。
- 最小化镜像层数
-
在构建镜像时尽可能地减少 Dockerfile 指令行数。例如我们要在 CentOS 系统中安装make和net-tools两个软件包,应该在 Dockerfile 中使用以下指令:
-
RUN yum install -y make net-tools -
而不应该写成这样:
-
RUN yum install -y make RUN yum install -y net-tools
dockerfile指令
所有的关键字都必须是大写,同时第一行不能是注释,必须是FROM
#表示注释
1.FROM : 基础镜像 2.MANTAINER:镜像维护作者名和邮箱 3.RUN:容器构建需要的命令 4.EXPOSE:暴露端口 5.WORKDIR:登录后默认的工作目录 6.ENV:构建镜像过程中设置的环境变量 7.ADD:将宿主机目录下的文件拷贝进镜像并且会自动处理url和解压tar压缩包 8.COPY:将从构建上下文目录中(源路径)的文件/目录复制到新的一层的镜像内的(目标路径)位置 9.VOLUME:容器数据卷 10.CMD:指定容器启动时需要运行的命令,dockerFile中可以有多个cmd指令,但只有最后一个生效,cmd会被docker run之后的参数替换 11.ENTRYPOINT:指定一个容器启动时要运行的命令,可以有多条,都会生效 12.ONBUILD:当构建一个被继承的dockerFile时的运行命令,父镜像在被子镜像继承后,父镜像的onbuild被触发
实战测试
官方配置
Docker Hub 中 99% 镜像都是从这个基础镜像过来的 FROM scratch,然后配置需要的软件和配置来进行构建的
FROM scratch 指定镜像
ADD centos-7-x86_64-docker.tar.xz / #cenos7压缩包
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"]
创建一个自己的镜像
#进入home目录
cd home/
#创建DocKerFile文件
mkdir DocKerFile
#进入dockerfile
cd DocKerFile/
#随便创建一个文件名,写脚本
vim mycenos
#写入如下信息
FROM centos
#指定镜像
MAINTAINER jiusheng<2936688581@qq.com> #作者信息
ENV MYPATH /usr/local #工作目录
WORKDIR $MYPATH
RUN yum -y install vim net-tools #下载vim 和net-tools
EXPOSE 80 #暴露端口
CMD echo $MYPATH
CMD echo "-----jiusheng--" #输出信息
CMD /bin/bash
运行命令,构建镜像
基本格式:
注意,后面是有一个 .
docker build -f 文件路径 -t 镜像名:[tag] .
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker build -f mycenos -t jiu_centos .
Sending build context to Docker daemon 2.048kB
Step 1/9 : FROM centos
---> 300e315adb2f
Step 2/9 : MAINTAINER jiusheng<2936688581@qq.com>
---> Running in 591cbf9c38f9
Removing intermediate container 591cbf9c38f9
---> cbdb558b172f
Step 3/9 : ENV MYPATH /usr/local
---> Running in f9c692dbac96
Removing intermediate container f9c692dbac96
---> 51316b596261
Step 4/9 : WORKDIR $MYPATH
---> Running in 3d4f6d2f173d
Removing intermediate container 3d4f6d2f173d
---> 51338bb008c2
Step 5/9 : RUN yum -y install vim net-tools
---> Running in cf3421730130
CentOS Linux 8 - AppStream 6.8 MB/s | 8.3 MB 00:01
CentOS Linux 8 - BaseOS 4.9 MB/s | 4.5 MB 00:00
CentOS Linux 8 - Extras 22 kB/s | 9.8 kB 00:00
Dependencies resolved.
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
net-tools x86_64 2.0-0.52.20160912git.el8 baseos 322 k
vim-enhanced x86_64 2:8.0.1763-15.el8 appstream 1.4 M
Installing dependencies:
gpm-libs x86_64 1.20.7-17.el8 appstream 39 k
vim-common x86_64 2:8.0.1763-15.el8 appstream 6.3 M
vim-filesystem noarch 2:8.0.1763-15.el8 appstream 48 k
which x86_64 2.21-12.el8 baseos 49 k
Transaction Summary
================================================================================
Install 6 Packages
Total download size: 8.1 M
Installed size: 31 M
Downloading Packages:
(1/6): gpm-libs-1.20.7-17.el8.x86_64.rpm 395 kB/s | 39 kB 00:00
(2/6): vim-enhanced-8.0.1763-15.el8.x86_64.rpm 13 MB/s | 1.4 MB 00:00
(3/6): vim-filesystem-8.0.1763-15.el8.noarch.rp 909 kB/s | 48 kB 00:00
(4/6): which-2.21-12.el8.x86_64.rpm 2.3 MB/s | 49 kB 00:00
(5/6): vim-common-8.0.1763-15.el8.x86_64.rpm 30 MB/s | 6.3 MB 00:00
(6/6): net-tools-2.0-0.52.20160912git.el8.x86_6 2.9 MB/s | 322 kB 00:00
--------------------------------------------------------------------------------
Total 7.4 MB/s | 8.1 MB 00:01
warning: /var/cache/dnf/appstream-02e86d1c976ab532/packages/gpm-libs-1.20.7-17.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
CentOS Linux 8 - AppStream 1.4 MB/s | 1.6 kB 00:00
Importing GPG key 0x8483C65D:
Userid : "CentOS (CentOS Official Signing Key) <security@centos.org>"
Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : which-2.21-12.el8.x86_64 1/6
Installing : vim-filesystem-2:8.0.1763-15.el8.noarch 2/6
Installing : vim-common-2:8.0.1763-15.el8.x86_64 3/6
Installing : gpm-libs-1.20.7-17.el8.x86_64 4/6
Running scriptlet: gpm-libs-1.20.7-17.el8.x86_64 4/6
Installing : vim-enhanced-2:8.0.1763-15.el8.x86_64 5/6
Installing : net-tools-2.0-0.52.20160912git.el8.x86_64 6/6
Running scriptlet: net-tools-2.0-0.52.20160912git.el8.x86_64 6/6
Running scriptlet: vim-common-2:8.0.1763-15.el8.x86_64 6/6
Verifying : gpm-libs-1.20.7-17.el8.x86_64 1/6
Verifying : vim-common-2:8.0.1763-15.el8.x86_64 2/6
Verifying : vim-enhanced-2:8.0.1763-15.el8.x86_64 3/6
Verifying : vim-filesystem-2:8.0.1763-15.el8.noarch 4/6
Verifying : net-tools-2.0-0.52.20160912git.el8.x86_64 5/6
Verifying : which-2.21-12.el8.x86_64 6/6
Installed:
gpm-libs-1.20.7-17.el8.x86_64
net-tools-2.0-0.52.20160912git.el8.x86_64
vim-common-2:8.0.1763-15.el8.x86_64
vim-enhanced-2:8.0.1763-15.el8.x86_64
vim-filesystem-2:8.0.1763-15.el8.noarch
which-2.21-12.el8.x86_64
Complete!
Removing intermediate container cf3421730130
---> 96c4435f5f36
Step 6/9 : EXPOSE 80
---> Running in a5363e9470cd
Removing intermediate container a5363e9470cd
---> ee1bd76b09e4
Step 7/9 : CMD echo $MYPATH
---> Running in 110b43851555
Removing intermediate container 110b43851555
---> bcb634848307
Step 8/9 : CMD echo "-----jiusheng--"
---> Running in e8acecac7db8
Removing intermediate container e8acecac7db8
---> 700270977443
Step 9/9 : CMD /bin/bash
---> Running in 5df30afb5f3f
Removing intermediate container 5df30afb5f3f
---> aeeaf736a24e
Successfully built aeeaf736a24e
Successfully tagged jiu_centos:latest
查看是否构建成功
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jiu_centos latest aeeaf736a24e 13 minutes ago 275MB
nginx latest 08b152afcfae 9 days ago 133MB
mysql 5.7 8cf625070931 9 days ago 448MB
centos latest 300e315adb2f 7 months ago 209MB
测试运行
docker run -it jiu_centos
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker run -it jiu_centos
#查看工作目录
[root@c2538f1711ea local]# pwd
/usr/local
#是我们设定的工作目录
#检测功能是否能用
[root@c2538f1711ea local]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 8 bytes 656 (656.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@c2538f1711ea local]# vim jiu
[1]+ Stopped vim jiu
#完全能用,构建成功
列出本地镜像的变更历史
docker history 镜像名
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker history jiu_centos
IMAGE CREATED CREATED BY SIZE COMMENT
aeeaf736a24e 26 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
700270977443 26 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
bcb634848307 26 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
ee1bd76b09e4 26 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
96c4435f5f36 26 minutes ago /bin/sh -c yum -y install vim net-tools 66MB
51338bb008c2 27 minutes ago /bin/sh -c #(nop) WORKDIR /usr/local 0B
51316b596261 27 minutes ago /bin/sh -c #(nop) ENV MYPATH=/usr/local 0B
cbdb558b172f 27 minutes ago /bin/sh -c #(nop) MAINTAINER jiusheng<29366… 0B
300e315adb2f 7 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 7 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 7 months ago /bin/sh -c #(nop) ADD file:bd7a2aed6ede423b7… 209MB
CMD 和 ENTRYPOINT 区别
测试CMD
# 编写dockerfile文件
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# vim ceshi
FROM centos
CMD ["ls","-a"]
# 构建镜像
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker build -f ceshi -t ceshiya .
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM centos
---> 300e315adb2f
Step 2/2 : CMD ["ls","-a"]
---> Running in f4f284cd463d
Removing intermediate container f4f284cd463d
---> c9afee7729d7
Successfully built c9afee7729d7
Successfully tagged ceshiya:latest
# run 运行 发现我们的 ls -a 命令生效
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker run ceshiya
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
# 想追加一个命令 -l ls -al
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker run ceshiya -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
# cmd 的情况下 -l 替换了 CMD ["ls","-a"] 命令 -l 不是命令 所以报错
测试ENTRYPOINT
# 编写dockerfile文件
[root@root dockerfile]# vi ceshi01
FROM centos
ENTRYPOINT ["ls","-a"]
# 构建镜像
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker build -f ceshi01 -t ceshiya01 .
Sending build context to Docker daemon 4.096kB
Step 1/2 : FROM centos
---> 300e315adb2f
Step 2/2 : ENTRYPOINT ["ls","-a"]
---> Running in 5490b3031487
Removing intermediate container 5490b3031487
---> 6102c6aeb29c
Successfully built 6102c6aeb29c
Successfully tagged ceshiya01:latest
# run 运行 发现我们的 ls -a 命令生效
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker run ceshiya01
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
# 想追加一个命令 -l ls -al 发现生效
[root@iZj6c5ctiawsbu90vbskdwZ DocKerFile]# docker run ceshiya01 -l
total 56
drwxr-xr-x 1 root root 4096 Aug 1 03:02 .
drwxr-xr-x 1 root root 4096 Aug 1 03:02 ..
-rwxr-xr-x 1 root root 0 Aug 1 03:02 .dockerenv
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 340 Aug 1 03:02 dev
drwxr-xr-x 1 root root 4096 Aug 1 03:02 etc
drwxr-xr-x 2 root root 4096 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 4096 Dec 4 2020 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 109 root root 0 Aug 1 03:02 proc
dr-xr-x--- 2 root root 4096 Dec 4 2020 root
drwxr-xr-x 11 root root 4096 Dec 4 2020 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 Jul 29 01:08 sys
drwxrwxrwt 7 root root 4096 Dec 4 2020 tmp
drwxr-xr-x 12 root root 4096 Dec 4 2020 usr
drwxr-xr-x 20 root root 4096 Dec 4 2020 var
发布镜像
发布到官方 docker hub 上
需要注册账号!
查看登录命令
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker login --help
Usage: docker login [OPTIONS] [SERVER]
Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.
Options:
-p, --password string Password
--password-stdin Take the password from stdin
-u, --username string Username
[root@iZj6c5ctiawsbu90vbskdwZ ~]#
登录账号
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker login -u jiusheng
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
#这样就算成功了
Login Succeeded
[root@iZj6c5ctiawsbu90vbskdwZ ~]#
提交镜像
docker push 信息/镜像:版本号
docker push jiusheng/centos:1.0
发布到阿里云
-
登录阿里云
-
找到容器镜像服务
- 点击个人实例
- 点击创建镜像仓库
- 点击本地仓库创建
- 查看阿里云帮助文档
docker网络
初识docker0
- 这是我们没有安装docker时候的网络
[root@iZj6c5ctiawsbu90vbskdwZ ~]# ip a
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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:01:9e:7a brd ff:ff:ff:ff:ff:ff
inet 172.21.27.152/18 brd 172.21.63.255 scope global dynamic eth0
valid_lft 315359962sec preferred_lft 315359962sec
- 我们安装好docker之后会发现多了一个docker0
[root@iZj6c5ctiawsbu90vbskdwZ ~]# ip a
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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:01:9e:7a brd ff:ff:ff:ff:ff:ff
inet 172.21.27.152/18 brd 172.21.63.255 scope global dynamic eth0
valid_lft 315359848sec preferred_lft 315359848sec
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:4c:03:0f:26 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
- 安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、 none 、host
- docker network 指令了解
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker network --help
Usage: docker network COMMAND
Manage networks
Commands:
connect Connect a container to a network # 将容器连接到网络
create Create a network #创建网络
disconnect Disconnect a container from a network # 断开容器与网络的连接
inspect Display detailed information on one or more networks # 显示一个或多个网络的详细信息
ls List networks #列出所有网络
prune Remove all unused networks #删除所有未使用的网络
rm Remove one or more networks #删除一个或者多个网络
Run 'docker network COMMAND --help' for more information on a command.
- 验证一下docker0默认网络
#启动一个容器
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker run -d -P --name tomcat01 tomcat
Unable to find image 'tomcat:latest' locally
latest: Pulling from library/tomcat
627b765e08d1: Pull complete
c040670e5e55: Pull complete
073a180f4992: Pull complete
bf76209566d0: Pull complete
f10db7ba7580: Pull complete
5b2f970878fa: Pull complete
ed434bfebf18: Pull complete
f6c437110aa9: Pull complete
a772951f83db: Pull complete
752225c3768e: Pull complete
Digest: sha256:6e40250d8fac4eca05c2067cb81f79427e4ddbaf4e78d5ecd21c35e8c5f2bfcf
Status: Downloaded newer image for tomcat:latest
6017ba277147c0b023ee2aa475108a4f8b88e8f7d182180308fc60ff0f41c714
#查看网络
[root@iZj6c5ctiawsbu90vbskdwZ ~]# ip a
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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:01:9e:7a brd ff:ff:ff:ff:ff:ff
inet 172.21.27.152/18 brd 172.21.63.255 scope global dynamic eth0
valid_lft 315358148sec preferred_lft 315358148sec
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:4c:03:0f:26 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
7: veth961d52c@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether b2:82:8d:b4:75:6b brd ff:ff:ff:ff:ff:ff link-netnsid 0
#查看容器里面的网络
root@6017ba277147:/usr/local/tomcat# ip a
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
6: eth0@if7: <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
#我们可以看到容器内有一个eth0@if7的网络,同时可以发现eth0@if7和veth961d52c@if6是相互绑定的,也是成对出现的。
#查看能否ping通容器
[root@iZj6c5ctiawsbu90vbskdwZ ~]# 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.095 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.078 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.041 ms
#发现可以ping通
原理
我们每启动一个容器,docker就会给我们的容器分配一个ip,docker使用的是桥接模式,使用的技术evth-pair技术
同时ip是成对出现的
evth-pair起到一个连接的桥梁,一般用来连接虚拟网络设备
- 在启动一个容器
#查看网卡
[root@iZj6c5ctiawsbu90vbskdwZ ~]# 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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:01:9e:7a brd ff:ff:ff:ff:ff:ff
inet 172.21.27.152/18 brd 172.21.63.255 scope global dynamic eth0
valid_lft 315357189sec preferred_lft 315357189sec
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:4c:03:0f:26 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
7: veth961d52c@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether b2:82:8d:b4:75:6b brd ff:ff:ff:ff:ff:ff link-netnsid 0
9: veth3880b7f@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether b6:23:87:6f:bc:ef brd ff:ff:ff:ff:ff:ff link-netnsid 1
#可以看到有多了一对
- 容器ping容器
[root@iZj6c5ctiawsbu90vbskdwZ ~]# 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.082 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.050 ms
#我们可以看到,是可以相互ping通的
网络图
--link
不推荐使用,只做了解
不通过ip来访问容器,直接通过容器名访问
- 容器和容器进行ping
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker exec -it tomcat01 ping tomcat02
ping: tomcat02: Name or service not known
- 使用--link
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
4438f44dd6ff78a67892c526fcd5cf7ca7f1177699f0a3d8e24217e42515c673
- 查看是否可以ping通
[root@iZj6c5ctiawsbu90vbskdwZ ~]# 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.074 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.055 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.058 ms
#发现可以通过容器名ping通
- 反向是否可以ping通
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
#发现是ping不同的,应为没有配置
- 查看网络信息
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
f4e21fcb0d76 bridge bridge local
3c7452c40eb3 host host local
a122752ffd10 none null local
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker network inspect f4e21fcb0d76
[
{
"Name": "bridge",
"Id": "f4e21fcb0d76f6a60dd870d02ed9604686240449350685f8100a9525fc564be1",
"Created": "2021-08-01T16:00:00.258764824+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16" #docker0
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"21b9e1bdfe0988f74199afb82805e502cfda94fccc8e269728c98b54f26637de": {
"Name": "tomcat02",
"EndpointID": "bd4419e2ca78725ddae30f95adc0d523680ff16c95960971d8fbaa823b531f1d",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"4438f44dd6ff78a67892c526fcd5cf7ca7f1177699f0a3d8e24217e42515c673": {
"Name": "tomcat03",
"EndpointID": "070b04e67e1dfbdeb5039b9db6d61e1ee0989953467b4edd9cc0641adbbab21f",
"MacAddress": "02:42:ac:11:00:04",
"IPv4Address": "172.17.0.4/16",
"IPv6Address": ""
},
"6017ba277147c0b023ee2aa475108a4f8b88e8f7d182180308fc60ff0f41c714": {
"Name": "tomcat01",
"EndpointID": "717371bbe0ff45dd69480cd95bc1bfb41c0a02b10fef0df3a11fe46b2bf6cbe6",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
#查看tomcat03
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker inspect 4438f44dd6ff
[
{
"Id": "4438f44dd6ff78a67892c526fcd5cf7ca7f1177699f0a3d8e24217e42515c673",
"Created": "2021-08-01T09:41:06.910147871Z",
"Path": "catalina.sh",
"Args": [
"run"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 13874,
"ExitCode": 0,
"Error": "",
"StartedAt": "2021-08-01T09:41:07.368939358Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:46cfbf1293b176161813fa05bb8f7e82df1ec7def5c226c48bc48a60ed305ac7",
"ResolvConfPath": "/var/lib/docker/containers/4438f44dd6ff78a67892c526fcd5cf7ca7f1177699f0a3d8e24217e42515c673/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/4438f44dd6ff78a67892c526fcd5cf7ca7f1177699f0a3d8e24217e42515c673/hostname",
"HostsPath": "/var/lib/docker/containers/4438f44dd6ff78a67892c526fcd5cf7ca7f1177699f0a3d8e24217e42515c673/hosts",
"LogPath": "/var/lib/docker/containers/4438f44dd6ff78a67892c526fcd5cf7ca7f1177699f0a3d8e24217e42515c673/4438f44dd6ff78a67892c526fcd5cf7ca7f1177699f0a3d8e24217e42515c673-json.log",
"Name": "/tomcat03",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": [
"e2d063fb5a968904b5e3ec6def704cc3790f9b1efcd9ce7c0240a939383ee549"
],
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "host",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": [
"/tomcat02:/tomcat03/tomcat02" #这里可以发现tomcat03里面的配置出现了tomcat02
],
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": true,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
#进入Tomcat03查看
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker exec -it tomcat03 cat /etc/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 21b9e1bdfe09
172.17.0.4 4438f44dd6ff
#我们可以发现,这里直接就绑定了Tomcat02
自定义网络
容器互联
- 创建一个jiusheng网络
#删除之前的所有容器
docker rm -f $(docker ps -aq)
#创建网络
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 jiusheng
db61398754c4de6d331db1788071e11ad9fa5883167cba1f0bf021bf671527c8
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
f4e21fcb0d76 bridge bridge local
3c7452c40eb3 host host local
db61398754c4 jiusheng bridge local
a122752ffd10 none null local
- 查看创建网络信息
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker network inspect db61398754c4
[
{
"Name": "jiusheng",
"Id": "db61398754c4de6d331db1788071e11ad9fa5883167cba1f0bf021bf671527c8",
"Created": "2021-08-01T17:58:35.111862913+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": {},
"Options": {},
"Labels": {}
}
]
- 使用jiushneg网络
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker run -d -P --name tomcat02 --net jiusheng tomcat
1a04efb744627d546dbb8e22ed162062c56718b24836a45ee28d5f33af83f994
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker run -d -P --name tomcat01 --net jiusheng tomcat
ecccd3d1869c3d95d6e28787765bf26eea01866bf317b4ea3fe01f8549fea281
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ecccd3d1869c tomcat "catalina.sh run" 4 seconds ago Up 3 seconds 0.0.0.0:49160->8080/tcp tomcat01
1a04efb74462 tomcat "catalina.sh run" 12 seconds ago Up 12 seconds 0.0.0.0:49159->8080/tcp tomcat02
- 容器互相ping
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker exec -it tomcat01 ping tomcat02
PING tomcat02 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat02.jiusheng (192.168.0.2): icmp_seq=1 ttl=64 time=0.061 ms
64 bytes from tomcat02.jiusheng (192.168.0.2): icmp_seq=2 ttl=64 time=0.051 ms
64 bytes from tomcat02.jiusheng (192.168.0.2): icmp_seq=3 ttl=64 time=0.063 ms
#发现可以直接ping通
自定义网络好处
- 不同集群的网络是相对的
- 让容器的网络基于dns的域名解析
- 拥有与宿主机之间安全的隔离环境
- 自由的选择或放弃一个网络
不同网络之间的连通
- 创建两个不通网络的容器
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker run -d -P --name tomcat01 --net jiusheng tomcat
76ab3aba3e19257a29e6b4702a9145d7da4f59150e63de4af865cec4d8f94dfa
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker run -d -P --name tomcat02 tomcat
8ad64e755f65f210eac46fd61c4ea2251810f4307b5d84e8aa67f764b30db50b
- 查看是否运行
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8ad64e755f65 tomcat "catalina.sh run" 6 seconds ago Up 5 seconds 0.0.0.0:49162->8080/tcp tomcat02
76ab3aba3e19 tomcat "catalina.sh run" 16 seconds ago Up 15 seconds 0.0.0.0:49161->8080/tcp tomcat01
- 把tomcat加入jiusheng网络
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker network connect jiusheng tomcat02
- 查看jiusheng网络
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker network inspect jiusheng
[
{
"Name": "jiusheng",
"Id": "db61398754c4de6d331db1788071e11ad9fa5883167cba1f0bf021bf671527c8",
"Created": "2021-08-01T17:58:35.111862913+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": {
"76ab3aba3e19257a29e6b4702a9145d7da4f59150e63de4af865cec4d8f94dfa": {
"Name": "tomcat01",
"EndpointID": "dd654b8cb571b23e2fa206b08097bf35ea4ea901b420b8cfd2309bda48f18b06",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
#我们可以看到,这里直接就把tomcat02加入了进来
"8ad64e755f65f210eac46fd61c4ea2251810f4307b5d84e8aa67f764b30db50b": {
"Name": "tomcat02",
"EndpointID": "65c3a8b0634c77c689b512b5b9ee0a8473776cb63a8d45c44451f6bd41b8690f",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
- 测试ping通
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker exec -it tomcat01 ping tomcat02
PING tomcat02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat02.jiusheng (192.168.0.3): icmp_seq=1 ttl=64 time=0.088 ms
64 bytes from tomcat02.jiusheng (192.168.0.3): icmp_seq=2 ttl=64 time=0.061 ms
64 bytes from tomcat02.jiusheng (192.168.0.3): icmp_seq=3 ttl=64 time=0.048 ms
#发现是可以ping通的
- 反向ping
[root@iZj6c5ctiawsbu90vbskdwZ ~]# docker exec -it tomcat02 ping tomcat01
PING tomcat01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat01.jiusheng (192.168.0.2): icmp_seq=1 ttl=64 time=0.034 ms
64 bytes from tomcat01.jiusheng (192.168.0.2): icmp_seq=2 ttl=64 time=0.052 ms
64 bytes from tomcat01.jiusheng (192.168.0.2): icmp_seq=3 ttl=64 time=0.050 ms
#也是可以ping通的
部署redis,就不在演示了,也简单,自行百度
结语
文章因为字数限制,没有写全,需要观看全文的,可移步到本文博客,转载请注明出处。