目录
一、docker
1、背景
以Linux而言,Linux操作系统会有一个主进程pid=1,派生出其他进程来控制不同服务,比方说三
个服务运行时会互相影响,使用者期望将这三个不同的服务,跑往不同的运行时的环境中实现相互
不影响,同事不会增加服务器成本延伸出,能否将这三种服务分别封装起来,利用kvm虚拟化技
术,实现了一个操作系统模拟多个操作系统、不同的运行随着技术发展,虚拟化技术开销较大(例
如:只要运行一个python脚本,想要使用虚拟化方式实现,还需要安装一个安装操作系统很不方
便)
注:虚拟化层的抽象层(用户层)剥离,使用docker egine来代替(来宾操作系统去除),只要通过引擎就可以直接连接到宿主机操作系统中,极大减小了开销。
docker 与虚拟机区别之一(资源利用率/损耗)
2、名称空间
如何实现应用与应用之间隔离
应用和应用的隔离,如何进行判断以操作系统维度
应用A与应用B隔离,在操作系统中,是通过namespaces(名称空间、命名空间)实现的,只要实现
以下6个空间隔离,才能认为两个应用实现了完全/完整隔离容器隔离了6个名称空间(namespace
资源隔离-用容器化技术封装)mount文件系统,挂载点 一个文件系统内,不能重复挂载一个指定
目录,例如:/mntuser操作进程的用户和用户组
pid命名空间 | 进程隔离(PID:进程ID) |
net命名空间 | 管理网络接口(NET网络) |
ipc命名空间 | 管理访问IPC资源(IPC:进程间通信) |
mnt命名空间 | 管理文件系统挂载点(MNT:mount) |
uts命名空间 | 隔离内核和版本表示符(UTS:Unix时间共享) |
user命名空间 | 操作进程的用户和用户组 |
3、使用docker的意义和使用场景
(1)docker引擎统一了基础设施环境-docker容器环境(引擎)
(2)docker引擎统一了程序打包(装箱)方式-docker镜像
(3)docker引擎统一了程序部署(运行)方式-docker 容器
镜像(封装的某一个时刻的服务/应用状态)(容器使应用跑起来的状态(正常提供服务的状态-运行时))
打包应用程序简单部署
可脱离底层硬件任意迁移(实现了应用的隔离,将应用拆分并进行解耦),例如:服务器从腾讯云
迁移到阿里云,持续集成和持续交付(CI/CD):开发到测试发布,部署微服务
提供PAAS产品(平台即服务){OpenStack_的云主机类似于阿里云的ECs,属于IAAS、Docker
(K8S)属于PAAS}
4、Docker引擎(Docker engine)
docker engine 诗句有以下主要主键的客户端—服务器应用程序:服务器是一种长期运行的程序,称为守护进程(docker 命令)
REST API,他指定程序可以用来与守护进程进行通讯并指示其操作的接口(命令行界面cli 客户端docker命令)
docker三大组件:
1、Docker images:镜像
2、Docker container:容器
3、Docker registry:镜像仓库
5、docker的镜像运行过程
6、container和VM的区别
不同点 | container | VM |
启动速度 | 秒级 | 分钟级 |
运行性能 | 接近原生(直接在内核中运行) | 50%左右损失 |
磁盘占用 | MB | GB |
数量 | 成百上千 | 几十台 |
隔离性 | 进程级别 | 系统级别(更彻底) |
操作系统 | 主要支持Linux | 几乎所有 |
封装程度 | 只有包项目和依赖关系,共享宿主机关系 | 完整的操作系统,与宿主机隔离 |
二、Docker基本命令及操作
①docker client客户端连接到了服务端(服务端是以一个守护进程的形式跑在操作系统里面的)restful api典型的c/s架构
②由docker服务端的守护进程从docker hub 上下载了镜像(PS:服务端会先检查本地系统是否有这个镜像)
③服务端创建了一个新的容器,然后从拉去的这个镜像启动了一个容器,容器执行了脚本/可执行程序让我们可以查看/使用(client)
④docker服务端把这些信息流(传递)返回到客户端并展示出来,(展示在终端上)docker client可以是多种形式,比如"docker"命令工具所在的终端
1、镜像操作
(1)搜索镜像
docker search nginx
(2) 查询docker 版本
docker version && docker info
(3)下载镜像(默认是从docker hub)
docker pull 镜像名称,例如:
docker pull centos
(4)查看镜像列表
docker images——查看当前docker下的下载镜像信息
(5)添加镜像标签(docker tag nginx:latest nginx:lnmp)
docker tag centos centos-httpd
(6)删除
docker rmi 镜像名称
docker rmi 镜像标签
运行中的 镜像无法删除 需要先删除容器 删除唯一性标签 才可以删除 强行删除名称需要加-f3
也可以通过镜像id镜像删除
docker images -q
(7) 镜像导出
docker save -o 文件名 镜像名
示例:
docker save centos:7-httpd > centos_7-httpd
(8) 镜像导入
docker load < nginx
使用场景,有的生产环境,企业不直接使用docker 私有仓库,而是存放在一个ftp服务器中,按需上传下载
2、容器操作
(1)查询容器
docker ps -a
(2)创建容器
docker create -it nginx:latest /bin/bash
-i 让容器的标准输入保持打开
-t 分配一个伪终端
-d 后台守护进程的方式运行
面试题:
容器状态有哪些,分别是什么场景
STATUS: 容器状态。 状态有7种: created(已创建) restarting(重启中) running(运行中) removing(迁移中) paused(暂停) exited(停止) dead(死亡)
(3)启动容器
docker start 容器id
(4)启动容器(一次性执行)
docker run nginx:latest /usr/bin/bash -c ls /
(5)停止容器(停止时比较慢)
docker stop 容器ID
(6)持续后台运行
docker run -d nginx:latest /bin/bash -c "while true;do echo hello;done"
(7)进入容器
① 使用run
docker run -it nginx:latest /bin/bash
状态
② exec(容器必须为开启状态)
docker exec -it 容器ID /bin/bash
exec 和shell 是两种运行模式
⭐⭐⭐docker三种模式
⭐docker run -it 会创建前台进程,但是会在输入exit后终止进程。(创建一个容器并进入)
⭐docker attach 会通过连接stdin,连接到容器内输入输出流,会在输入exit后终止容器进程.(连接一个容器 退出是容器会推出)
⭐docker exec -it 会连接到容器,可以像SSH一样进入容器内部,进行操作,可以通过exit退出容器,不影响容器运行。(进入up状态的容器 退出是不会影响到容器的运行状态 类似于ssh)
⭐⭐注:docker中的日志会保存两份 一分是docker中的 另一份是宿主机 而宿主机保存的相当于docker日志的映射
(8)容器导出
docker export 容器ID > 文件名
示例:
docker export 容器ID > nginx_a
(9)容器导入(生成镜像)
docker import 导出的文件名(容器) 指定镜像名称
示例:
docker import nginx_a nginx:latest
cat 文件名(容器) | docker import - nginx:latest
(10)删除容器
docker rm 容器ID
#强制删除容器(正在运行的)
还在写入
(11) 以上会遇到一个情况 就是基础资源问题 导致的磁盘空间被日志占满 (日志写入 不光只存放于docker中 宿主机也有其日志 docker logs查看的也是宿主机的日志)
宿主机日志存入位置
设置docker日志文件数量及每个日志大小 针对于日志做定期清理(也可以 提前备份需要的日志 然后再删除日志)
清除日志 脚本
收集docker日志 给予一个阈值 来收集日志 对daemon.json进行控制 再用elk的filebeat收集容器中挂载出来的日志
(12) 批量删除“exit”状态(指定状态)的容器
[root@apache ~]# docker ps -a | grep Created | awk '{print $1}' | docker rm -f
创建多个容器
(13)删除非up状态的 rm -f : 强制删除所有
docker rm `docker ps -q`
(14)批量删除“exit”状态(指定状态)的容器
for i in `docker ps -a | grep -i exit | awk '{print $1}'`; do docker rm -f $i;done
(15)容器打包为镜像(也可以为退出的容器打包 当然名字不能冲突)
docker run -it --name Nginx.01 nginx:latest /bin/bash
三、docker 网络模式
Docker四种网络模式(面试题:)
⭐⭐docker中有几种网络模式,分别提供哪些功能
Host、container、none、bridge
六种网络模式Docker info: bridge host ipvlan macvlan null overlay(必要了解)
①Host :与宿主机共享网络名称空间/网络协议栈,IP共享、端口范围共享
②Container:多个容器之间共享一个network namespaces,多个容器公用一个IP和端口范围
③None :自闭空间,无网卡,无需网络连接
④Bridge:桥接,默认模式,在不指定网络模式的情况下创建容器,默认使用此模式,通过Veth对连接容器与dockerO网桥,网桥分配给容器IP,同时docker O作为“局域网”内容器的网关,最后和宿主机网卡进行通讯,同时,通过IPtables规则将容器IP/port 映射出去,用于与宿主机网卡交互
①HOST和②container两种模式,在K8S中也有对应的模式(原理相同)
⭐⭐两个容器如何通讯
Docker 0
Loo0 (container模式)
一、HOST模式
host容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口如果启动容器的
时候使用host模式,那么这个容器将不会获得一个独立的NetworkNamespace,而是和宿主机共
用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机
的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。使用host模
式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端
口,不需要进行NAT,host最大的优势就是网络性能比较好,但是dockerhost上已经使用的端口
就不能再用了,网络的隔离性不好。(共享一个网络名称空间 共享一个宿主机ip范围但不可用同一个端口)
二、container
创建的容器不会创建自己的网卡、设置IP等,而是和一个指定地容器共享IP、端口范围
这个模式指定新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定地容器共享
IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表还是隔离的。(☆☆两个容器的进程可以通过lo 0/localhost网卡设备通信)
三、None
该模式关闭了容器的网络功能
这种模式下容器只有io会还网口,没有其他的网卡。none模式可以再容器创建时通过-network=non额参数指定,这种类型的网络无法联网,但是封闭的网络能很好的保证容器的安全性
四、Bridge
Bridge: [此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker虚拟网桥,通过
dockero网桥及iptables.的 nat,表配置与宿主机通信当Docker进程启动时,会在主机上创建一个名为
docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和
物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。从docker 0子网中
分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡
veth pair设备,Docker '将veth palr 设备的一段放在新创建的容器中,并命名为etho(容器的网
卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥
中。可以通过brctl show命令查看。bridge模式是docker的默认网络模式,不写-net参数,就是
bridge模式。使用dockerrun -p时, docker实际是在 iptables.,做了DNAT规则,实现端口转发功能。
可以使用jptables -t nat-vnL查看。
(1)查看网络列表
docker network ls
(2)查看容器信息(包含配置、环境、网关、挂载、cmd等等信息)
docker inspect 容器ID
(3) 指定分配容器IP地址
docker run -itd --name test1 --network bridge --ip 172.17.0.10 centos:latest /bin/bash
需要指定ip 否则会报错
自定义网络固定ip
docker network create --subnet=172.18.0.0/16 mynetwork
docker run -itd --name test2 --net mynetwork --ip 172.18.0.100 centos:latest /bin/bash
(4)暴露端口
-p 自定义端口 ( 宿主机端口:容器内端口)
-P 随机端口 (-P 49153起始 49153到65535)
docker run -itd -p 333:80 nginx /bin/bash (docker 0)
docker run -itd -P nginx /bin/bash
(5)在宿主机环境执行容器内命令
docker exec -it 容器ID /bin/bash -c 'nginx'
docker exec 容器ID/容器name 执行的命令
宿主机加端口 在网页可以看到服务
(6)进入容器没有systemctl 命令解决:添加--privileged=true (指定此容器是否为特权容器),使用此参数,则不能用attach
示例:
docker run -itd --name test3 --privileged=true centos /sbin/init
/sbin/init 内核启动时主动呼叫的第一个进程
可以使用docker inspect 容器ID
docker ps -a
docker exec -it 容器id /bin/bash
yum install httpd -y
systemctl status httpd
(7)Docker 数据卷
docker pull centos
//宿主机目录/var/www 挂载容器中的/data1
docker run -v /var/www:/data1 --name web1 -it nginx /bin/bash
[root@202dd484fd62 /]# cd /data1/
[root@202dd484fd62 data1]# touch test123
将docker数据卷挂载到宿主机中 创建一个test123 从宿主机中能看到 也创建了一个test123
//返回宿主机进行查看
[root@localhost ~]# ls /var/www/
原理:将容器内部的配置文件目录,挂载到宿主机指定目录下
作用:
① 修改配置文件例如,nginx.conf /usr/local/nginx/conf/nginx.conf ---> /container_nginx/conf/nginx.conf
② 容器内部产生的日志,如何收集 将容器内部存方日志文件的目录挂载到宿主机指定目录下/container_nginx/log/access_log/access_log
③ 传入变量 挂载到宿主机 在宿主机上添加变量内容,将变量放入共享目录,在容器中/etc/profile 直接加载就可以
export xxdir=/data/data1/xx.
(8)数据卷容器
数据卷容器
docker run --name web100 -v /data1 -v /data2 -it nginx /bin/bash
//新容器挂载数据卷容器web100
docker run -it --volumes-from web100 --name db1 nginx /bin/bash
原理:让两个容器实现数据共享
php ——》mysql 之间想要通讯 借助于socket 通讯文件
(9)端口映射
docker run -d -P httpd:centos
docker run -d -p 49280:80 httpd:centos
docker ps -a
6d461287c25d httpd:centos "/run.sh" 7 seconds ago Up 7 seconds 0.0.0.0:49280->80/tcp zen_swanson
(10)容器互联(使用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命令