目录
一、全虚拟化、半虚拟化及容器各自的特点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZVD4CbpD-1642349143323)(D:\桌面\容器\图片\Snipaste_2022-01-10_15-25-45.png)]
全虚拟化:基于操作系统,用kernel+kvm组件分割内核资源,vmm+qemu抽象层调度管理,上面的vm1、vm2对应各自的接口,去使用内核资源(每个vm1、vm2都是使用vcpu)
半虚拟化:不基于操作系统,硬件服务器完全是裸金属,没有操作系统。半虚拟化直接用软件模拟硬件功能,所以有自己的内核
容器:基于linux操作系统,容器共享内核、内存等资源,一个容器对应一个进程,所以可以有多个容器。容器引擎类似插件(相当于管理虚拟机的软件vmeare)-----容器共享宿主机内核
二、docker容器
1、docker介绍
Docker是一个用于开发,交付和运行应用程序的开放平台。Docker使您能够将应用程序与基础架构分开,从而可以快速交付软件。是一个开源的应用容器引擎,让开发者可以打包大门的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或者Windows机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口
沙箱(Sandbox):在计算机安全领域,沙箱是一种程序的隔离运行机制Docker在2013年一炮而红,直到现在,已经成为容器技术的代名词。Docker 从一开始就以提供标准化的运行时环境为目标,真正做到“build once,run anywhere",可以将同一个构建版本用于开发、测试、预发布、生产等任何环境,并且做到了与底层操作系统的解耦。在此基础上还进一步发展出了CaaS(容器即服务)技术。
2013年发布了docker
把容器化技术做成了标准化平台
使用docker有什么意义
docker引擎统一了基础设施环境-docker容器环境(引擎)
docker引擎统一了程序打包(装箱)方式-docker镜像
docker引擎统一了程序部署(运行)方式-docker容器
镜像————》封装的某一个时刻的服务/应用状态
容器————》应用跑起来的状态(正常提供服务的状态-运行时)
2、Docker的使用场景
打包应用程序简单部署
可脱离底层硬件任意迁移(实现了应用的隔离,将应用拆分并进行解耦),例如:服务器从腾讯云迁移到阿里云
持续集成和持续交付(CI/CD):开发到测试发布
·
部署微服务
提供PAAS产品(平台即服务){OpenStack的云主机类似于阿里云的ECs,属于IAAS、Docker (K8S)属于PAAS}
lAAS:基础设施即服务(基础设施指裸金属,cpu、磁盘、内存、网络、i/o等)
SAAS :应用即服务(应用:例如,lnmp)
PAAS:平台即服务(平台:docker)
3、Docker 引擎(Docker Engine)
Docker Engine是具有以下主要组件的客户端-服务器应用程序(C/s端):
服务器是一种长期运行的程序,称为守护程序进程( dockerd
命令)。
REST API,它指定程序可以用来与守护程序进行通信并指示其操作的
接口。
命令行界面(CLI))客户端(docker命令)。
客户端-----REST API----服务端之间交互过程
1、客户端使用命令传入的方式与rest API交互,例如
docker images (作用:传入命令和展示docker-server返回的结果)
2、rest API再交于服务端
3、服务端daemon整合docker images返回
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qixRqH0J-1642349143324)(D:\桌面\容器\图片\Snipaste_2022-01-10_19-37-06.png)]
4、Docker的架构(Docker architecture)
Docker使用客户端-服务器架构。Docker 客户端与Docker守护进程进行对话,该守护进程完成了构建,运行和分发Docker容器的繁重工作。
Docker 区别于传统的虚拟化,不需要虚拟硬件资源,直接使用容器引擎、所以速度快
Docker Client:客户端
Docker客户端(docker)是许多Docker用户与Docker交互的主要方式。当您使用诸如之类的命令时docker run,客户端会将这些命令发送到dockerd,以执行这些命令。该docker命令使用Docker APlo Docker客户端可以与多个守护程序通信。
Docker daemon:守护进程
Docker守护程序( dockerd)侦听Docker API请求并管理Docker对象,例如图像,容器,网络和卷。守护程序还可以与其他守护程序通信以管理Docker服务。
Docker images:镜像
Docker container:容器
Docker registry:镜像仓库
存储镜像的地方,默认在公共的Docker Hub 上查找,可以搞个人仓库。
5、docker原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dVbu5NGH-1642349143325)(D:\桌面\容器\图片\Snipaste_2022-01-10_19-53-31.png)]
原理:
命令由客户端传入到docker daemon,然后
搜所本地images,如果没有去registry公共仓库找
找到后返回本地images,然后解析成容器containers
6、名称空间(Namespaces)
Docker使用一种称为namespaces提供容器的隔离工作区的技术。运
行容器时,Docker会为该容器创建一组名称空间。
这些名称空间提供了一层隔离。容器的每个方面都在单独的名称空间中运行,并且其访问仅限于该名称空间。
Docker Engine在 Linux上使用以下名称空间:
cgroup资源控制与namespaces结合控制管理了6个名称空间资源:
(1)mount文件系统,挂载点
一个文件系统内,不能重复挂载一个指定目录,例如:/mnt
(2)user:操作进程的用户和用户组
(3)pid:进程编号
(4)uts:主机名和主机域
(5)ipc:信号量、消息队列,共享内存(理解:不同的应用调用内存资源的时候应该使用不同的内存空间)
(6)net:网络设备、网络协议栈、端口等
7、控制组(Control groups)
Linux上的 Docker引擎还依赖于另一种称为控制组(cgroups)的技术。cgroup将应用程序限制为一组特定的资源。控制组允许Docker Engine将可用的硬件资源共享给容器,并有选择地实施限制和约束。例如,您可以限制特定容器可用的内存。
注意:cgroup资源控制和namespaces名称空间两者构成了docker底层原理
总结:基于操作系统,要想两个应用之间完全隔离,必须将6个名称空间隔离
Dcoker是基于容器技术的轻量级虚拟化解决方案docker把linux的cgroup、namespaces等容器底层技术进行完美的封装、并抽象为用户提供创建和管理容器的便捷界面(命令行cli、api等) c/ s
企业中,开发——》运维整体流程
1、首先由开发进行代码研发,研发好之后进行编译、打包
PS:打包:一般会使用maven工具打war包或者jar包
2、打完包之后,放置对应的运行时环境中,进行试运行
PS:这里的运行时环境指:例如tomcat (java环境) php (php环境)等
3、中间会加上一些测试过程,测试代码的有效性、可用性和可执行性
4、以上测试完成,运维会将这个软件包拉过来,运行在实际生产的运行时环境中
问题:在以上的第2点中,不同开发语言的运行时环境混淆在一起运行会有很大的隐患,以及不便
传统中,所谓的运行时环境,例如tomcat (java环境) php (php环境)等
容器中,所谓的运行时环境,指的试"容器"内部
在此之前,容器—》是一个运行时环境,构成容器的组件是image镜像(一个运行时环境的模板)
三、container和vm不同点
不同点 | container | VM |
---|---|---|
启动速度 | 秒级 | 分钟级 |
运行性能 | 接近原生(直接在内核中运行) | 50%左右损失 |
磁盘占用 | MB | GB |
数量 | 成百上千 | 一般几十台 |
隔离性 | 进程级别 | 系统级别(更彻底) |
操作系统 | 主要支持Linux | 几乎所有 |
封装程度 | 只打包项目代码和依赖关系,共享宿主机内核 | 完整的操作系统,与宿主机隔离 |
四、扩展内容仓库
高阶重要三个内容:名称空间、隔离、资源分配
拓展的内容:
yum仓库 rpm包
包括:公共仓库和本地yum仓库
docker仓库同yum类似:
公共仓库:docker hub :lnmp lnmp-nginx docker 镜像
本地仓库:docker-harbor 上传下载方便、安全
公共代码仓库:github: github 网络404延迟
以下是本地代码仓库:
gitlab
svn
gitee
码云
语雀
五、部署20版的docker
#环境配置
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
vim /etc/selinux/config
SELINUX=disabled
安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2
设置阿里云镜像源
cd /etc/yum.repos.d/
以下两种下载源都可以使用:
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
docker-1.13(统一版本、开源)——》分类型1.15-1.17过程种分成两种,(1)开源社区docker-ce (2)企业版(收钱)docker-ee
#安装docker-ce社区版
yum install -y docker-ce
systemctl start docker
systemctl enable docker
---设置镜像加速--
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://ckexajko.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload 重新加载配置文件
systemctl restart docker
##控制docker server端的配置文件是 daemon.json
cat /etc/docker/daemon.json
#镜像加速注册地址
https://help.aliyun.com/ document_detail/60750.html
----------—―网络优化--------
vim /etc/sysctl.conf
net.ipv4.ip_forward=1
sysctl -p
意义:这里的网络优化在于加速流量转发
面试题(生产经验)
#docker-server端配置文件daemon .json
{
"graph" : " /data/ docker" , 数据目录/var/ lib/ docker
"storage-driver" : "overlay2 ", 存储引擎
早期的时候存储引擎使用的是aufs—》overlay2存储引擎
"insecure-registries": [ "registry.access.redhat.com" , "quary.io"] 私有仓库
"registry-mirrors" :[ "https:llq"] 镜像加速
"bip": "172.7.5.1/24", ☆☆☆ ☆ docker网络
"exec-opts":["native.cgroupdriver=systemd"],启动时候的额外参数(驱动,k8s使用)
"live-restore" : true
当docker容器引擎挂掉的时候,使用docker跑起来的容器还能运行(分离)
}
以上是建议的配置项
docker容器网络生产经验
docker 的网络建议和宿主机的iP"对照”
比如宿主机10.2.5.6容器的地址就可以修改为172.5.6.1,这样方便在故障发生时,更容易定位故障节点位置
六、docker镜像操作
docker ps 查看已经运行的docker容器
docker ps -a 查看所有的docker容器及状态
docker images 查看拥有的镜像
docker info 会显示容器统计信息,可以用shell脚本去过滤统计有用信息
docker version 查看docker客户端server端等版本信息
systemctl status docker
docker run hello-world
run :
pull docker hub仓库中项目/库/镜像start hello-world-image
1、docker client 客户端连接到了服务端(服务端是以一个守护进程的形式跑在操作系统里面的) restful api典型的c/s架构
2、由docker服务端的守护进程从docker hub上下载了镜像(PS:服务端会先检查本地系统是否有这个镜像)
3、服务端创建了一个新的容器,然后从拉去的这个镜像启动了一个容器,
容器执行了脚本/可执行程序让我们可以
查看/使用( client )
4、docker服务端把这些信息流(传递)返回到客户端并展示出来,(展示在终端上)
docker client可以是多种形式,比如"docker"命令工具所在的终端
yum仓库,如何开启缓存,软件包保存在哪
linux系统中的命令记10条(cd ls pwd mv cp )docker 十条管理命令(运维常用的命令)
#查询docker 版本
docker version && docker info
docker search 镜像名 在仓库里搜索镜像
#下载镜像(默认是从docker hub)
docker pull 镜像名
docker pull nginx 下载镜像
docker inspect nginx:latest 查看镜像详细信息
镜像名称:版本
docker inspect 605c77e624dd
镜像ID
[
{
"Id": "sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85",
"RepoTags": [
"nginx:latest"
],
"RepoDigests": [
"nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31"
],
"Parent": "",
"Comment": "",
"Created": "2021-12-29T19:28:29.892199479Z",
"Container": "ca3e48389f7160bc9d9a892d316fcbba459344ee3679998739b1c3cd8e56f7da", ##容器层的ID
#容器配置文件 "ContainerConfig": {
#容器名称 "Hostname": "ca3e48389f71",
#域名 "Domainname": "",
"User": "",
#标准输入关闭 "AttachStdin": false,
#标准输出关闭 "AttachStdout": false,
#标准错误输出关闭 "AttachStderr": false,
#暴露端口 "ExposedPorts": {
#映射出80端口 这里还映射出(空的) "80/tcp": {}
},
#终端关闭(无法登陆容器) "Tty": false,
#标准打开关闭 "OpenStdin": false,
#临时打开关闭 "StdinOnce": false,
#坏境 "Env": [
#坏境变量 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
#nginx版本 "NGINX_VERSION=1.21.5",
"NJS_VERSION=0.7.1",
"PKG_RELEASE=1~bullseye"
],
#传入命令 "Cmd": [
#开启进程 "/bin/sh",
#command命令 "-c",
"#(nop) ",
#传入命令启动nginx "CMD [\"nginx\" \"-g\" \"daemon off;\"]"
],
"Image":"sha256:82941edee2f4d17c55563bb926387c3ae39fa1a99777f088bc9d3db885192209",
#挂载 没有 "Volumes": null,
#指定工作目录 "WorkingDir": "",
#启动系统 "Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
#标签 "Labels": {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
#发送信息号停止 "StopSignal": "SIGQUIT"
},
#docker版本 "DockerVersion": "20.10.7",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.21.5",
"NJS_VERSION=0.7.1",
"PKG_RELEASE=1~bullseye"
],
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
"Image": "sha256:82941edee2f4d17c55563bb926387c3ae39fa1a99777f088bc9d3db885192209",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
"StopSignal": "SIGQUIT"
},
#64位 "Architecture": "amd64",
#操作系统 "Os": "linux",
#大小 "Size": 141479488,
#虚拟大小 "VirtualSize": 141479488,
#数据引擎 "GraphDriver": {
#数据 "Data": {
#数据保存四种类型 "LowerDir": "/var/lib/docker/overlay2/ce125c15a240b0782f686cfe578b55b02237fedc0be80c6cadf6b18bfc240fb8/diff:/var/lib/docker/overlay2/fd1c4bb501718725be4f3a091f1e0b2dbac14aeccb050498336c369a2be3b9df/diff:/var/lib/docker/overlay2/e2c5eda4323d3c65caac95d757725c8ffe6ab760ed92449ce343e03461ff92a7/diff:/var/lib/docker/overlay2/6542522d629751fade707de2d884212a02d54aeb8526f2d7430355280e839f8c/diff:/var/lib/docker/overlay2/e49a563b8ceb1d538c587e9773db538c4d0d75e28b54b7a07c8891082c1a3fda/diff",
"MergedDir": "/var/lib/docker/overlay2/726c03d40d29a7359fd70b796e0e49ac57371d3f09676c8a3ccdec925ef80a06/merged",
"UpperDir": "/var/lib/docker/overlay2/726c03d40d29a7359fd70b796e0e49ac57371d3f09676c8a3ccdec925ef80a06/diff",
"WorkDir": "/var/lib/docker/overlay2/726c03d40d29a7359fd70b796e0e49ac57371d3f09676c8a3ccdec925ef80a06/work"
},
"Name": "overlay2"
},
#系统里唯一的格式 "RootFS": {
"Type": "layers",
"Layers": [
"sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f",
"sha256:e379e8aedd4d72bb4c529a4ca07a4e4d230b5a1d3f7a61bc80179e8f02421ad8",
"sha256:b8d6e692a25e11b0d32c5c3dd544b71b1085ddc1fddad08e68cbd7fda7f70221",
"sha256:f1db227348d0a5e0b99b15a096d930d1a69db7474a1847acbc31f05e4ef8df8c",
"sha256:32ce5f6a5106cc637d09a98289782edf47c32cb082dc475dd47cbf19a4f866da",
"sha256:d874fd2bc83bb3322b566df739681fbd2248c58d3369cb25908d68e7ed6040a6"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
###overlay2 存储引擎
镜像包括四层:LowerDir
MergedDir
UpperDir
WorkDir
#添加镜像标签 //添加的镜像标签类似于软连接,共用同一个镜像数据
docker tag nginx:latest nginx:lnmp
需要加标签的镜像 加标签后的镜像名
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 2 weeks ago 141MB
[root@docker ~]# docker tag nginx:latest nginx:lnmp
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 2 weeks ago 141MB
nginx lnmp 605c77e624dd 2 weeks ago 141MB
##加标签后,镜像ID跟原来的一样
#删除镜像
docker rmi 镜像名称:镜像标签
docker rmi 镜像ID
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 2 weeks ago 141MB
nginx lnmp 605c77e624dd 2 weeks ago 141MB
[root@docker ~]# docker rmi nginx:lnmp
Untagged: nginx:lnmp
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 2 weeks ago 141MB
##Untagged: nginx:lnmp 信息显示只删除了标签,验证上面的添加镜像标签
##添加的镜像标签,因为跟原来的镜像有同样的镜像ID,所以不能用镜像ID删除,要用镜像标签
docker images -q 查看所有镜像ID
docker rmi `docker images -q` 基于镜像ID删除,所以用来批量删除镜像
#镜像导出
docker save -o 文件名 镜像名
示例:
docker save -o nginx_docker nginx:latest
#镜像导入
docker load < nginx
使用场景,有的生产环境,企业不直接使用docker私有仓库,而是存放在一个ftp服务器中,按需上传下载
#查询容器
docker ps -a
#创建容器
docker create -it nginx:latest /bin/bash
-i 让容器的标准输入保持打开
-t 分配一个伪终端
-d 后台守护进程的方式运行
-i 跟前面的标准输入对应,用于打开容器进行输入
-t 同样的代表终端Tty,用于给予一个伪终端,进行登录容器
/bin/bash 用于创建一个/bin/bash坏境去运行容器
##开启创建的容器
docker start 243d4571f78c
容器ID
#停止容器
docker stop 容器ID
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 2 weeks ago 141MB
centos 7 eeb6ee3f44bd 4 months ago 204MB
[root@docker ~]# docker create -it nginx:latest /bin/bash
243d4571f78ce2fe4b95b116962c859a4336faa918d6cb7066ae3d97c30f8285
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
243d4571f78c nginx:latest "/docker-entrypoint.…" 14 seconds ago Created sleepy_johnson
##status状态信息显示创建create代表创建成功
##开启创建的容器
docker start 243d4571f78c
[root@docker ~]# docker start 243d4571f78c
243d4571f78c
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
243d4571f78c nginx:latest "/docker-entrypoint.…" 8 minutes ago Up About a minute 80/tcp sleepy_johnson
##status显示Up About a minute说明容器开启成功,也代表在运行
#创建并启动容器(一次性执行)
docker run centos:7 /usr/bin/bash -c ls /
指定命令 根目录
[root@docker ~]# docker run centos:7 /usr/bin/bash -c ls /
anaconda-post.log
bin
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a617a6f76e72 centos:7 "/usr/bin/bash -c ls…" About a minute ago Exited (0) About a minute ago suspicious_einstein
##status显示容器是Exited (0) About退出状态,说明只是一次性启动,退出后就关闭了,此时容器并没有运行
##进入容器
docker run -it centos:7 /bin/bash
##每一秒执行一次“docker ps -a”并输出到终端上
watch -n 1 docker ps -a
周期
##退出容器
exit
Ctrl+d
##查看容器信息
docker inspect 容器名/容器ID
##进入容器(已经运行的容器),跟上面的区别在于退出后,容器还在运行
docker exec -it dccfdf64fca9 /bin/bash
exec(容器必须为开启状态)
Ps:
docker run -it 会创建前台进程,但是会在输入exit后终止进程。
docker attach 会通过连接stdin,连接到容器内输入输出流,会在输入exit后终止容器进程.
docker exec -it 会连接到容器,可以像sSH一样进入容器内部,进行操作,可以通过exit退出容器,不影响容器运行。
##持续后台运行
docker run -d centos:7 /bin/bash -c "while true;do echo hello;done"
##不加死循环不能持续后台运行,必须有一个任务,才能持续后台运行
docker run -d --name test centos:7 /bin/bash
后台 命名 指定的名字
#容器导出
docker export 容器ID >文件名
示例:
docker export 容器工D > nginx_a
#容器导入(生成镜像)
docker import 导出的文件名(容器) 指定镜像名称
示例:
docker import nginx_a nginx:latest
##删除容器
docker rm 容器ID
##强制删除运行的容器
docker rm -f 容器ID
##批量删除容器
docker rm `docker ps -aq`
##强制批量删除容器
docker rm -f `docker ps -aq`
##查看运行的容器ID
docker ps -q
##查看所有容器ID
docker ps -aq
#批量册删除容器(正则匹配)
docker ps -a | awk '{print "docker rm" $1}' | bash
#批量删除"exit"状态(指定状态)的容器
for i in `docker ps -a | grep -i exit | awk '{print $1}'`; do docker rm -f $i; done
##查询所有运行容器资源消耗信息
docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
c612adcbb85f inspiring_austin 0.00% 652KiB / 1.938GiB 0.03% 648B / 0B 549kB/0B
42221a1a55c7 unruffled_einstein 0.00% 496KiB / 1.938GiB 0.02% 648B / 0B 0B/0B
PIDS
1
1
##MEM USAGE / LIMIT 已使用内存量/内存剩余最大使用上限
##MEM % 内存使用占比
##NET I/O 网络速率/I/O输入输出
##docker stats 主要用于查看资源使用情况和监控
##调用docker资源使用的一个组件cadvisor
七、docker容器网络
1、docker容器网通信过程
docker0 类似于一个容器,网卡名docker0
ens33 宿主机网卡
lo 环回网卡
veth1cf9842 veth对,是一对虚拟接口/端口,用于连接容器和docker0(用于连接两个不同名称空间)
virbr0 虚拟网卡
bridge 网桥,用于连接不同的名称空间
网桥在容器中 用于连接宿主机跟docker0
单网桥容器间通信:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8qc6Ttka-1642349143326)(D:\桌面\容器\图片\Snipaste_2022-01-15_19-53-23.png)]
双网桥或多个网桥之间通信模式:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6KhElj1g-1642349143326)(D:\桌面\容器\图片\Snipaste_2022-01-15_20-09-41.png)]
docker容器的IP地址是由docker0分配的,同时也会承担作为一组docker容器的网关
docker0会以映射的方式映射出容器内nginx的端口80-----8080
默认是docker0
如果想自定义容器网段及IP,手动创建一个docker1(网桥),就可以自定义创建容器网段及IP
网桥与网桥之间通过物理网卡连接通信
docker inspect 镜像ID 可以查看到容器IP地址
2、docker容器网络模式
##几种网络模式
bridge: 网桥
host: 主机
ipvlan: ip方式划分vlan
macvlan: mac二层划分vlan
null: 没有
overlay: 叠加
2.1 Host网络模式
Host :与宿主机共享网络名称空间/网络协议栈,IP共享、端口范围共享
host容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是 docker host上已经使用的端口就不能再用了,网络的隔离性不好。
2.2 container网络模式
Container:多个容器之间共享一个network namespaces,多个容器公用一个IP和端口范围
二、container创建的容器不会创建自己的网卡、设置IP等,而是和一个指定地容器共享IP、端口范围
这个模式指定新创建的容器和已经存在的一个容器共享一个network namespace,而不是和宿主机共享,新创建的容器不会创建自己的网卡,配置自己的Ip,而是和一个指定地容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表还是隔离的。(★☆两个容器的进程可以通过 loo网卡设备通信)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pN4OuEV7-1642349143327)(D:\桌面\容器\图片\Snipaste_2022-01-15_22-24-55.png)]
2.3 None 网络模式(该模式关闭了容器的网络功能)
none没有任何网络连接 none模式可以在容器创建时通过 -network=none参数指定
这种类型的网络无法联网,但是封闭的网络能很好的保证容器的安全性
##none网络模式有两种用法:
1、可以当做一个私有仓库,存储镜像。
2、当作一个存储空间,挂载到另一个有网容器上,例如,将这种none封闭模式的容器挂载到nginx服务器。
2.4 Bridge网络模式
Bridge:此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0 网桥及iptables.的 nat表配置与宿主机通信
当Docker进程启动时,会在主机上创建一个名为dockero的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
从dockerO子网中分配一个IP给容器使用,并设置docker0的地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair 设备,Docker将 veth pair 设备的一端放在新创建的容器中,并命名为etho(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到dockero 网桥中。可以通过 brctl show命令查看。
总结:容器通过veth对跟docker0连接,docker0内通过iptables的规则,将ip及端口以映射的方式,映射给宿主机网卡,再通过宿主机网卡连接外网
2.5 小结:
注意:host模式和container模式,在k8s中也有对应的模式(原理相同)
docker 0 :容器的网关,绑定物理网卡,负责做NAT地址转换、端口映射
docker 0:本身也是一种容器
容器内的网卡是eth0,就是veth对
四种网络模式
--host模式 -net=host 容器和宿主机共享Network namespace。
container模式 -net=container:NAME or ID 多个谷器共旱一个Network namespaceo
none模式 -net=none 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。
bridge模式 -net=bridge (默认为i该模式)
以上不需要动手配置,真正需要配置的是自定义网络
2.6 查看网络模式列表
[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
4baec400f197 bridge bridge local
af302cfc44e3 host host local
1a4fe24e8198 none null local
2.7 自定义网络IP(创建一个docker0,可以给它任意指定IP地址网段)
##创建docker0,自定义ip命令
[root@docker ~]# docker network create --subnet=172.18.0.0/16 mynetwork
b0bd26fc40988b99a92e1e84fc713058f3c38963d480beab9466163151be9efe
##docker默认是bridge模式,所以这条命令里面可以加上 --network bridge
##创建docker0网卡成功后,用下列命令可以查看到
[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
4baec400f197 bridge bridge local
af302cfc44e3 host host local
b0bd26fc4098 mynetwork bridge local
1a4fe24e8198 none null local
##用ifconfig可以看到创建的新的容器网卡
[root@docker ~]# ifconfig
br-b0bd26fc4098: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.18.0.1 netmask 255.255.0.0 broadcast 172.18.255.255
ether 02:42:e1:41:e5:b9 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
##网卡创建成功后,用此网卡运行一个容器
[root@docker ~]# docker run -itd --name test01 --net mynetwork --ip 172.18.0.100 centos:7 /bin/bash 指定容器名称 指定容器网卡 指定容器ip
0f53832249563491495af3619082089841d7ae855665251727b939a897310c52
##查看是否创建成功
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0f5383224956 centos:7 "/bin/bash" 13 seconds ago Up 12 seconds test01
##查看test01这个容器,IP地址是不是自定义的
[root@docker ~]# docker inspect test01
........省略部分内容......
"Gateway": "172.18.0.1",
"IPAddress": "172.18.0.100",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:12:00:64",
"DriverOpts": null
2.8 暴露docker容器端口
#暴露端口
-p 自定义端口 (宿主机端口:容器内端口)
-P随机端口 ( -P 49153起始49153到65535)
docker run -itd -p 333:80 nginx /bin/bash 用的是(docker 0)网卡
docker run -itd -P nginx /bin/bash
#在宿主机环境执行容器内命令
docker exec -it 容器ID /bin/bash -c 'nginx'
自定义端口
##以映射的方式(333:80),将nginx的80端口暴露出去
[root@docker ~]# docker run -itd -p 333:80 nginx:latest /bin/bash
自定义端口
e34d2fe38f34ba9252d76dba987b2556f1bee329a91e0a5517c340178bc87103
##查看端口态(0.0.0.0:333->80/tctcp)
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e34d2fe38f34 nginx:latest "/docker-entrypoint.…" 40 seconds ago Up 40 seconds 0.0.0.0:333->80/tctcp practical_nobel
0f5383224956 centos:7 "/bin/bash" 29 minutes ago Up 29 minutes test01
##尝试访问nginx80端口映射暴露出的宿主机端口333
[root@docker ~]# curl 192.168.111.51:333
curl: (7) Failed connect to 192.168.111.51:333; 拒绝连接
##拒绝连接说明nginx进程没开启,nginx是一个命令,可以不进入容器开启nginx进程
##不进入容器开启nginx进程
[root@docker ~]# docker exec -it e34d2fe38f34 /bin/bash -c nginx
2022/01/15 16:27:55 [notice] 7#7: using the "epoll" event method
2022/01/15 16:27:55 [notice] 7#7: nginx/1.21.5
2022/01/15 16:27:55 [notice] 7#7: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2022/01/15 16:27:55 [notice] 7#7: OS: Linux 3.10.0-693.el7.x86_64
2022/01/15 16:27:55 [notice] 7#7: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2022/01/15 16:27:55 [notice] 13#13: start worker processes
2022/01/15 16:27:55 [notice] 13#13: start worker process 14
2022/01/15 16:27:55 [notice] 13#13: start worker process 15
##再次访问宿主机333端口(实质上是访问nginx80端口)
[root@docker ~]# curl 192.168.111.51:333
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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>
随机端口
##使用-P暴露映射nginx80端口----随机的一个映射端口
[root@docker ~]# docker run -itd -P --name nginx01 nginx:latest /bin/bash
480a1175100a92b488550530c4e497824cf52bf887b5abaff098719eecbbdc19
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
480a1175100a nginx:latest "/docker-entrypoint.…" 16 seconds ago Up 16 seconds 0.0.0.0:49153->80/tcp, :::49153->80/tcp nginx01
e34d2fe38f34 nginx:latest "/docker-entrypoint.…" 32 minutes ago Up 32 minutes 0.0.0.0:333->80/tcp, :::333->80/tcp practical_nobel
0f5383224956 centos:7 "/bin/bash" About an hour ago Up About an hour test01
八、将宿主机里的文件传到docker容器中
[root@docker opt]# docker cp /opt/1.txt 0f5383224956:/opt/
宿主机目录路径 容器ID 容器目录路径
##在容器里查看,是否复制成功
[root@0f5383224956 opt]# ls
1.txt
九、将docker容器内的文件传到宿主机
[root@docker opt]# docker cp 0f5383224956:/opt/2.txt /opt/
容器ID 容器目录路径 宿主机目录路径
##查看宿主机/opt目录
[root@docker opt]# ls
2.txt containerd rh
注意:宿主机与容器传输文件,命令是输入在宿主机上
十、授权给容器使用宿主机的命令
##授权容器使用宿主机的命令
[root@docker opt]# docker run -itd --name centos01 --privileged=true centos:7 /sbin/init
授权 使用的镜像 init初始化
31dac396556d53e5998322a47d1cd3e5cf4098f52f8a129135263a9583e7ff14
##查看
[root@docker opt]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
31dac396556d centos:7 "/sbin/init" 14 seconds ago Up 13 seconds centos01
##进入容器
[root@docker opt]# docker exec -it 31dac396556d /bin/bash
##安装http
[root@31dac396556d /]# yum install -y httpd
##验证用systemctl开启http
[root@31dac396556d /]# systemctl start httpd
十一、如何给已经运行的容器添加端口
#面试题:
docker中,假设,我运行了一个业务容器,需要暴露3个端口,启动之后发现自己少加了一个端口,那么,如何动态添加端口(如何对己运行的容器,添加/修改端口):
我们可以修改/var/lib/docker/container/[container_id]/中的两个文件
第一个文件:hostconfig.json portbinding:{}修改端口或添加端口
第二个文件:修改config.v2.json 文件,修改对应的Ports{} 来添加/修改端口
最后,重载守护进程
十二、数据卷和数据卷容器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wEMueOOD-1642349143328)(D:\桌面\容器\图片\Snipaste_2022-01-16_19-26-32.png)]
1、数据卷
数据卷:将宿主机的目录与容器内的指定目录进行挂载
作用:
(1)方便在宿主机上直接修改容器内的服务的配置文件(不用进入容器,就可以在宿主机上修改)
(2)可以将容器内数据将进行备份,在容器挂掉后,进行恢复
(3)传入变量挂载到宿主机在宿主机上添加变量内容,将变量放入共享目录,在容器中/etc/profile直接加载就可以export xxdir=/data/ data1/ xx.
##将宿主机目录与容器的目录进行挂载
[root@docker opt]# docker run -it -v /var/www:/data1 --name centos02 centos:7 /bin/bash
挂载 宿主机目录 容器目录
##验证(宿主机)
[root@docker ~]# cd /var/www/
[root@docker www]# ls
[root@docker www]# touch 1.txt
[root@docker www]# ls
1.txt
##在宿主机上创建文件容器内也会有
[root@c64d9925b03b /]# cd /data1
[root@c64d9925b03b data1]# ls
[root@c64d9925b03b data1]# ls
1.txt
2、数据卷容器
数据卷容器:将两个容器互相进行挂载,实现通讯
##新创建一个容器,暴露两个挂载点,使得另一个容器能够挂载连接
[root@docker ~]# docker run -it --name centos01 -v /data1 -v data2 centos:7 /bin/bash
暴露挂载点 暴露挂载点
##查看
[root@eb34b8a27116 /]# ls
anaconda-post.log data1 dev home lib64 mnt proc run srv tmp var
bin data2 etc lib media opt root sbin sys usr
##连接上面暴露出来的两个挂载点
[root@docker ~]# docker run -it --volumes-from centos01 --name centos02 centos:7 /bin/bash 指定挂载点来自centos01
##查看
[root@eb23dc8b2afe /]# ls
anaconda-post.log data1 dev home lib64 mnt proc run srv tmp var
bin data2 etc lib media opt root sbin sys usr
注意:只有挂载的目录,才能实现互相通讯
十三、容器互联
--容器互联(使用centos镜像)
docker run -itd -P --name web1 centos /bin/bash //创建并运行容器取名web1,端口号自动映射
docker run -itd -P --name web2 --link web1:web1 centos /bin/bash
//创建并运行容器取名web2,链接到web1和其通信
进web2容器ping web1
哨兵—》监控redis
哨兵和redis包括哨兵和哨兵之间相互监控,会使用ping命令
十四、容器挂载的实验
##小实验:
使用自定义配置启动redis
mkdir -p / data/redismkdir /etc/ redis
cd /data/redis/ && echo "appendonly yes" >>/data/redis/redis.conf
需求1:自定义挂载配置文件、自定义配置数据目录
docker run -v /data/redis/redis.conf:/etc/redis/redis.conf \-v / data/redis / data : / data \
-d --name myredis l
-p 6379:6379 \l
redis:latest redis-server letc/redis/redis.conf
使用redisDesktop Manager测试redis 连接
登陆——》connect to redis server
##配置账号密码
echo "requirepass abc123" >> letc/redis/redis.conf
##重启docker
docker restart myredis
#重新使用工具连接redis———》测试auth
##Redis desktop是redis可视化的一个windows工具