docker

Docker为什么会出现

开发-上线,两套环境

而环境配置是十分麻烦的,实现开发即运维,将环境直接打包在一起,这样就不需要重新配置环境

类比软件安装:java - apk - 发布(应用商店) - 下载安装 - 使用apk

Docker使用:java - jar(环境) - 打包项目带上环境(镜像) - (Docker仓库:商店) - 下载镜像 - 直接运行即可!


Docker的思想来自于集装箱!

JRE - 多个应用(端口冲突) - 原来都是交叉的!

隔离:Docker核心思想!打包装箱!每个箱子都是隔离的

比如:水果和生化武器

Docker通过隔离机制,可以将服务器利用到极致!


与虚拟机区别

虚拟机:在window中装一个Wmware,通过这个软件我们可以虚拟化出来一台或者多台电脑!笨重!

虚拟机缺点:资源占用十分多;冗余步骤多;启动很慢;

虚拟机也是属于虚拟化技术,Docker容器技术,也是一种虚拟化技术!

容器化技术不是模拟一个完整的操作系统,Docker镜像小巧,且秒级启动


比较Docker和虚拟机:

  • 传统虚拟机,虚拟出一种硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
  • 容器 是将应用直接运行在宿主机的内核上,没有自己的内核,也没有虚拟硬件,所以更加轻便
  • 每个容器间是相互隔离的,每个容器内都有一个属于自己的文件系统,互不影响

DevOps(开发、运维)

  1. 应用更快速的交付和部署

    传统:一堆帮助文档,安装程序

    Docker:打包镜像发布测试,一键运行

  2. 更便捷的升级和扩缩容

    使用Docker后,我们部署应用就和搭积木一样

  3. 更简单的系统运维

  4. 更高效的计算资源利用

    一个物理机上可以运行很多的容器实例


Docker基本组成

镜像(image):好比一个模板,可以通过这个模板创建容器

容器(container):在容器上可以独立运行一个或者一组应用

仓库(repository):存放镜像的地方!分为公有仓库和私有仓库


安装

Docker Documentation 官方文档非常详细!

docker run hello-world
  1. 在本机寻找hello-world镜象
  2. 本机没找到就从doker hub上下载
  3. 下载镜像到本地进行运行

Docker是怎么工作的?

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

DockerServer接收到Docker-Client的指令,就会执行这个命令


Docker常用命令

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

帮助文档的地址:https://docs.docker.com/engine/reference/run/


镜像命令

docker images:查看镜像,-aq:只显示所有镜像的镜像id

docker search 镜像名:搜索镜像,相当于在docker hub上搜索,--filter=STARS=3000:搜索STARS大于等于3000的

docker pull 镜像名:下载镜像,默认下载最新版,可以通过docker pull 镜像名[:tag]指定下载版本

docker rmi -f 镜像id:通过镜像id删除某个镜像

docker rmi -f 镜像id 镜像id 镜像id:通过镜像id删除多个镜像

docker rmi -f $(docker images -aq):删除全部镜像


容器命令

说明:有了镜像才可以创建容器,所以首先需要下载一个centos镜像

docker pull centos

新建容器并启动

docker run [可选参数] image

# 参数说明
# --name="name":容器名字,用来区分容器
# -d :后台方式运行
# -it:使用交互方式运行,进入容器查看内容,/bin/bash,内部很多内容都是不完善的
# -p:指定容器的端口,如8080:8080
# -P:随机指定端口

查看容器

docker ps     # 查看正在运行的容器
docker ps -a  # 查看运行过的所有容器
docker ps -aq # 查看运行过的所有容器id
docker ps -n=1  # 查看最近创建的一个容器

退出容器

exit # 停止容器并退出
Ctrl + P + Q # 不停止容器并退出

删除容器

docker rm 容器id 	   # 通过容器id删除指定容器,不能删除正在运行的容器
docker rm -f 容器id  # 强制删除正在运行的容器
docker rm -f $(docker ps -aq)  # 删除所有容器

启动和停止容器

docker start 容器id	# 启动容器
docker reatart 容器id	# 重启容器
docker stop 容器id	# 停止容器
docker kill 容器id	# 强制停止容器

一些其他常用命令

后台启动容器

docker run -d 镜像名

问题:通过 docker run -d 镜像名 来启动容器后,然后发现容器停止了

docker容器要通过使用后台运行,就必须要有一个前台进程!因为如果docker发现容器中没有正在运行的应用,就会自动停止容器


查看日志

docker logs -f -t --tail 10 容器id

查看容器中的进程信息

docker top 容器id

查看容器的元数据

docker inspect 容器id

进入当前正在运行的容器

docker exec -it 容器id /bin/bash	# 进入容器后开启新的终端(常用)
docker attach 容器id				# 进入容器正在执行的终端,不会启动新的进程

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

docker cp 容器id:容器内路径 目的主机路径

只要容器在,容器内的文件就存在,与容器正在运行与否无关!

拷贝是一个手动过程,可以使用 -v 卷的技术实现自动同步


Docker镜像加载原理

联合文件系统(UnionFS)

UnionFS是一种分层、轻量级并且高性能的文件系统,它支持 对文件系统的修改 作为一次提交来一层层叠加,同时可以挂载到同一个虚拟文件系统下

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,UnionFS会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

  • bootfs(boot file system) 主要包含bootloader和kernel,bootloader主要用来引导加载kernel,加载完成后,内存的使用权交给内核,此时系统也会卸载bootfs

  • rootfs(root file system),在bootfs之上,就是典型的Linux系统目录(/dev,/etc等)

对于一个精简的OS,rootfs可以很小,只需要包含最基本的命令,工具和程序库,因为底层直接用Host的kernel,自己只需要提供rootfs


容器数据卷

什么是容器数据卷?

如果数据都在容器中,那么容器删除,数据就会丢失!

需求:数据可以持久化

需要容器之间有一个数据共享的技术!Docker容器中产生的数据,同步到本地!这就是卷技术,将容器内的目录挂载到Linux

总结:为了容器的持久化和同步操作,容器间也是可以数据共享的


使用数据卷

方式一:直接使用命令来挂载 -v

1)同时指定主机目录和容器目录

docker run -it -v 主机目录:容器内目录 容器id /bin/bash

挂载后通过docker inspect 容器id可以查看挂载信息,具体地,“Mounts”中“Source”为主机内地址,“Destination”为容器内地址

2)不指定主机目录,具名挂载和匿名挂载

docker run -it -v 容器内目录 容器id /bin/bash		 # 匿名挂载
docker run -it -v 卷名:容器内目录 容器id /bin/bash  	# 具名挂载

docker volume ls  # 查看所有的卷,没有名字的就叫做匿名卷,即匿名挂载

docker volume inspect 卷名  # 查看卷的详细信息,发现挂载目录默认为"/var/lib/docker/volume/卷名/_data"

平时主要使用具名挂载,一般不使用匿名挂载

# 如何判断是具名挂载还是匿名挂载,还是指定路径挂载
-v 容器内路径		# 匿名挂载
-v 卷名:容器内路径	   # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载

拓展:

# 通过 -v 容器内路径:ro/rw 改变读写权限
# ro(readonly):只读,只能通过宿主机操作,容器内部是无法操作的
# rw(readwrite):可读可写
docker run -it -v 主机目录:容器内目录:ro/rw 容器id /bin/bash

方式二:通过Dockerfile挂载

VOLUME ["volume01","volume02"]  # 两个"volume01","volume02"匿名挂载卷

然后通过docker inspect 容器id就可以查看挂载信息

这种方式使用的非常多,因为我们通常会构建自己的镜像,如果没有在构建镜像时挂载,就需要手动使用-v命令挂载


数据卷容器

实现容器间的数据共享:--volumes-from 数据卷容器

删除容器,但是只要存在一个容器,数据就不会丢失,这类似一种备份机制

  • 容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止
  • 但是一旦持久化了本地,这个时候,本地的数据是不会删除的

Dockerfile

Dockerfile就是用来构建docker镜像的命令脚本

镜像是一层一层的,脚本是一个一个的命令,每个命令都是一层

脚本文件名建议为Dockerfile

构建步骤

  1. 编写一个Dockerfile文件
  2. docker build 构建一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(DockerHub、阿里云镜像仓库)

官方镜像很多都是基础包,很多功能没有,我们通常会自己搭建自己的镜像

基础知识

  1. 每个保留关键字(指令)都必须是大写字母
  2. 从上到下顺序执行
  3. #表示注释
  4. 每一个指令都会创建 提交一个新的镜像层
FROM		# 基础镜像,一切从这里开始
MAINTAINER	# 镜像是谁写的,姓名+邮箱
RUN			# 镜像构建的时候需要运行的命令
ADD			# 添加内容
WORKDIR		# 镜像的工作目录
VOLUME		# 挂载的目录
EXPOSE		# 保留端口配置
CMD			# 指定容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT	# 指定容器启动的时候要运行的命令,可以追加命令
ONBUILD		# 当构建一个被继承 Dockerfile 时运行,是一个触法指令,了解即可
COPY		# 类似ADD,将文件拷贝到镜像中
ENV			# 构建时设置环境变量

网络

docker0

宿主机 是能 ping 通容器的


容器间公用一个路由器 docker0(宿主机),所有容器不指定网络的情况下,都是 docker0 路由的,docker会给容器分配一个默认的可用IP

  • Docker使用的是Linux的桥接,宿主机 docker0是Docker容器的网桥

  • Docker中所有的网络接口都是虚拟的,这样转发效率高(内网传递文件)

  • 只要容器删除,对应的一对网桥就没了


--link:容器间使用 服务名替代IP 来解决网络连通问题,注意这个是单向的,反向也需要配置

--link操作其实是在hosts配置文件中增加了相应容器服务的配置

现在已经不建议使用--link了,高手都是自定义网络!

docker0存在的问题:它不支持容器名连接访问


自定义网络

通过docker network ls查看所有的Docker网络

网络模式

  • bridge:桥接,Docker(默认,就是上边说的docker0的方式,自定义网络也使用bridge模式)

  • none:不配置网络

  • host:和宿主机共享网络

  • container:容器网络连通(用得少!局限很大)

    docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
    

我们自定义的网络Docker都已经帮我们维护好了对应关系,推荐这样使用网络

好处:不同的集群使用不同的网络,保证集群是安全和健康的


网络连通

两个网络下的容器之间是不可以 ping 通的,因为是在两个网段下

docker network connect:连接一个容器到一个网络

连通后就是把容器放到了网络下

原理:一个容器两个ip,比如阿里云服务的公网ip和私网ip都可以访问

结论:假设要跨网络操作别人,就需要使用connect进行连通

posted @ 2022-11-12 19:12  黄一洋  阅读(30)  评论(0)    收藏  举报