docker的思想来自集装箱,通过隔离机制,将服务器利用到极致
本质:所有的技术都是因为出一些问题才去解决才去学习
虚拟机与真实的电脑相似,相互隔离,但是比较笨重
虚拟机与docker相似都是虚拟化技术
docker基于go语言开发,开源项目
docker官网: https://www.docker.com
Doker能干什么
虚拟机技术模拟的不是一个完整的操作系统:
1、虚拟机技术资源占用多
2、冗余步骤多
比较docker和虚拟机的不同:
传统虚拟机,虚拟出一条硬件,允许一个完整的操作系统,然后在这个系统上安装和运行软件
容器直接运行在宿主机中,容器没有自己的内核,也没有虚拟我们的硬件,所以很轻便
容器之间相互隔离,每个容器都有自己的文件系统,互不影响
Docker安装
docker的基本组成
镜像 (image):
相当于一个模板,利用这个模板来创建容器,可以创建多个容器
容器 (container):
docker利用容器,独立运行一个或者一组应用,通过镜像来创建的,可以吧容器理解为建议的liunx系统
仓库 (repository):
存放镜像的地方,仓库分为共有仓库和私有仓库
1.安装docker
docker官网: https://www.docker.com
# 1.卸载旧的版本 sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine #2. 安装需要的安装包 yum install -y yum-utils #3. 设置镜像仓库 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo #默认国外的,非常慢(下面是阿里云地址) yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #4. 安装docker相关的 dcoer-ce 社区版 ee yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin #5. 启动服务 systemctl enable docker --now #6. 检测是否安装成功 docker version #7.测试hello word docker run hello-world #8.查看镜像 docker images
了解:卸载docker
#卸载安装的组件 yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras #删除目录 rm -rf /var/lib/docker #docker默认的路径 rm -rf /var/lib/containerd
阿里云镜像加速
cat /etc/docker/daemon.json tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors" : ["https://uy35zvn6.mirror.aliyuncs.com"] } EOF systemctl daemon-reload systemctl restart docker
底层原理
docker是如何工作的
docker是一个clent-server结构的系统,docker的守护进程运行在宿主机,通过socke从客户端访问
dockerServer接收到dcoker-Client的指令,就会执行这个命令!
docker为什么比虚拟机快
docker有比虚拟机更少的抽象层
常用命令
docker version #查看docker版本 docker info #查看docker信息 docke 命令 --help
帮助文档地址: (https://docs.docker.com/engine/reference/commandline/docker/)
1.镜像命令
docker images 查看本地主机所有的镜像
REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest d2c94e258dcb 9 months ago 13.3kB # 解释 REPOSITORY 镜像仓库源 TAG 镜像的标签 IMAGE ID 镜像的ID CREATED 镜像创建时间 SIZE 大小 #可选项 docker image -a #显示所有镜像 docker image -q #只显示ID
docker search 搜索镜像
docker search mysql #镜像名称
docker pull 下载镜像
docker pull 镜像名称 Using default tag: latest latest: Pulling from library/mysql 72a69066d2fe: Pull complete #分层下载是docker images核心 联合文件系统 93619dbc5b36: Pull complete 99da31dd6142: Pull complete 626033c43d70: Pull complete 37d5d7efb64e: Pull complete ac563158d721: Pull complete d2ba16033dad: Pull complete 688ba7d5c01a: Pull complete 00e060b6d11d: Pull complete 1c04857f594f: Pull complete 4d7cfa90e6ea: Pull complete e0431212d27d: Pull complete Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709 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
docker rmi 镜像id
dockers rmi -f 镜像id
2.容器命令
新建容器并启动
docker run [可选参数] image #参数说明 --name="Name" 容器名称tomcat01 tomcat02,用来区分容器 -d 后台方式运行 -it 使用交互方式运行,进入容器查看内容 -p 指定容器端口 -p主机端口:容器端口 -p 容器端口 容器端口 -P 随机指定容器端口 #启动并且进入容器 docker run -it centos /bin/bash #退出容器 exit #直接退出容器并停止运行 ctrl + p + Q #容器不停止退出
列出容器
docker ps -a #列出当前正在运行的容器+带出历史运行的容器 -n=? #显示最近创建的容器 -aq #只显示容器的的编号
删除容器
docker rm 容器id #指定删除容器,不能删除正在运行的容器,如果要强制删除 rm -f docker rm -f $(docker ps -aq) #删除所有的容器
启动和停止容器操作
docker start 容器id #启动容器 docker restart $(docker ps -a) #重启所有容器 docker stop 容器id #停止容器 docker stop $(docker ps) #停止所有容器 docker kill 容器id #杀死容器
3. 常用其他容器
后台启动容器
# 命令docker run -d 镜像名! #问题docker ps 发现centos停止了 常见的坑,docker 容器使用后台运行必须要有一个前台进程,docker发现没有应用就会自动停止
查看日志
docker logs -tf --tail 容器 # 显示日志 -tf #显示日志 --tail number #要显示日志条数
查看日志中的进程
docker top 容器id
查看镜像元数据
docker inspect 容器id
进入当前正运行的容器
#方式一 (打开新的终端) docker exec -it 容器id /bin/bash #方式二 (使用正在运行的命令行) docker attach 容器id
从容器中拷贝文件到宿主机
docker cp 容器id:容器内路径 目的地主机路径
小作业
1.使用docker部署nginx
#1. 拉取官放nginx镜像 docker pull nginx #2. 启动nginx docker run -d --name nginx01 -p 80:80 nginx
2.使用docker部署tomcat
#1.拉取tomcat 镜像 docker pull tomcat #2.启动 docker run -d --name tomcat01 -p 8080:8080 tomcat
3.部署es+kibana
#启动es docker run -d --name elasticsearch01 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx521m" elasticsearch:8.3.3
Docker可视化管理
-
portainer
docker图像化界面管理工具!提供一个后台面板供我们操作
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:latest
访问测试 (平时不会使用到,有兴趣可以自行测试)
192.168.32.128:9000
Docker 镜像详解
镜像是什么
镜像是一种轻量级,可执行的独立软件包,用来打包软件环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件
如何得到镜像:
-
从远程仓库下载
-
朋友获取
-
自己制作一个镜像使用
docker镜像的加载原理
UFS(联合文件系统)
是一种分层、轻量级并且高性能的文件系统,它支持文件系统的修改作为一次提交来一层层叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,联合文件系统是docker镜像的基础,镜像可以通过分层来继承,基于基础镜像可以制作各种具体的应用镜像
dokcer镜像加载原理
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统Uniofs.
bootfs主要包含bootloader和kernel,bootloader主要是引导加载kernel,liunx刚启动时会加载bootfs文件系统,在doker镜像的最底层是bootfs
为什么一个镜像很大,在docker里几百MB不到
对于一个精简的OS,rootfs可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用hos的kernel,自己只需要提供rootfs。
分层理解
思考:为什么docker镜像要采用这种分层的结构呢?
最大的好处莫过于资源共享,比如由很多个镜像都从相同的Base镜像构建而来,那么宿主机著需要在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层偶可以被共享。
#分层命令 docker image inspect redis:latest
理解:
所有的docker镜像都起始于一个基础镜像层,当进行修改或增加时,就会在当前镜像层之上,创建新的镜像层
特点:
Docker的镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层就是我们通常说的容器层,容器之下都叫镜像层
commit镜像
提交一个自己的镜像
docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名] #例子: docker commit -m="elasticsearch" -a="anzijun" e12bf1c234da elasticsearch:1.0 #### 提交完成后使用docker images 查看 # 创建成功后相当于打了一个虚拟机快照,保存了当前系统的状态
容器数据卷
1. 什么是容器数据卷
docker的理念回顾
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么容器删除,数据就会丢失 需求:数据可持久化
Mysql,容器删掉,删库跑路! 需要:mysql数据可以存储在本地!
容器之间可以有一个数据共享的技术! Docker容器中产生的数据,同步到本地
这就是卷技术! 目录的挂载,将我们容器内的目录挂载到liunx上面!
总结:容器的持久化和同步操作!容器之间可以数据共享!
2.使用数据卷
方式一:直接使用命令来挂载 -v
#目录映射,主机的目录和容器中的目录会进行同步 dokcer run -it -v 主机目录:容器内目录
3. 实战:安装MYSQL
思考:mysql的数据持久化的问题
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=asb#1234 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -d mysql
4.匿名挂载
#匿名挂载 -v 容器内路径! docker run -d -p --name nginx01 -v /etc/nginx nginx #查看所有的volume的情况,也就是查看匿名挂载的情况 docker volume ls [root@cloud-01 ~]# docker volume ls DRIVER VOLUME NAME local 047ccaae850bf36a6000488f3d9709761e92e868c82d894eae4fc9631f00e55a #这里发现,这种就是匿名挂载,我们在-vhi写了容器内的路径,没有写容器内的路径 #具名挂载 docker run -d -P --name nginx02 -v an-nginx:/etc/nginx nginx [root@cloud-01 ~]# docker volume ls DRIVER VOLUME NAME local an-nginx # 通过-v 卷名容器内路径 # 查看具体挂载路径 [root@cloud-01 ~]# docker inspect volume an-nginx [ { "CreatedAt": "2024-02-21T14:59:51+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/an-nginx/_data", "Name": "an-nginx", "Options": null, "Scope": "local" } ]
没有指定目录的情况下,去挂载容器内部的路径一般都会在这个路径下
/var/lib/docker/volumes/****/_data
通过具命挂载
可以方便找到卷
#如何确定是剧名挂载还是匿名挂载,还是指定路径挂载 -v 容器内路径 #匿名挂载 -v 卷名:容器内路径 #具命挂载 -v 宿主机:容器内路径 #指定路径挂载
Dockerfile
1.初识dockerfile
Dockerfile 就是用来构建 docker 镜像的构建文件!命令脚本!先体验一下!
通过这个脚本可以生成一个镜像,镜像是一层一层的,脚本是一个一个的命令,每个命令都是一层
#新建目录 mkdir -p /home/docker-test-volume cd docker-test-volume pwd vim dockerfile1 FORM centos VOLUME ["vloume01","vloume02"] CMD echo "---end---" CMD /bin/bash #这里的每个命令,就是镜像的一层 docker build -f ./dockerfile1 -t anzijun/cnetos:1.0 .
2.数据卷容器
多个mysql 同步数据,两个容器之间相互挂载,原容器删除后,共享目录数据不会丢失
--volumes-from
#命令行 docker01的共享目录同步至docker02,docker01就可以称作数据卷容器 docker run -it --name docker02 --volumes-from docker01 镜像id
------------------------------------备份机制---------------------------------------------------------
容器之间配置信息的传递,数据的生命周期,一直到没有容器使用为止
3.Dockerfile介绍
dockerfile是用来构建docker镜像的文件,说白了就是命令参数脚本
1、编写一个dockerfile文件
2、docker build构建一个镜像
3、docker run 运行镜像
4、docker push 发布镜像 (dockerhub、阿里云镜像)
很多官方得到镜像都是基础包,很多功能没有,我们通常会自己搭建镜像
4.Dokerfile构建
基础知识:
1、每个保留关键字(指令)都必须是大写字母
2、执行从上到下顺序执行
3、 # 表示注释
4、每一个指令都会被当做一层提交
dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件十分简单!
Dokcer镜像逐渐成为企业交付的标准,必须要掌握 !
Dockerfile: 构建文件,定义了一切的步骤,源代码
Dokerimages: 通过Dockerfile构建生成的镜像,最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供服务
5.Dcokerfile的指令
FROM #基础镜像 Centos unbatu,一切从这里开始 MAINTAI #镜像是谁写的,姓名+邮箱 RUN #镜像构建时需要运行的命令 ADD #步骤,tomcat镜像,这个TOMCAT 压缩包! 添加内容 WORKDIR #镜像的工作目录 VOLUME #挂载目录 EXPOSE #暴露端口配置 ls -a docker run CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代 ONBUILD # 当构建一个被继承dockerfile 这个时候就会运行 COPY # 类似ADD,将我们的文件拷贝到镜像 ENV # 构建时设置环境变量!
6.实战测试
Dcoker hub中99%镜像都是从这个基础镜像过来的FROM scratch,然后配置需要的软件和配置来进行构建
创建一个自己的Centos
# 1. 编写Dokerfile的文件 FROM centos:7 MAINTAINER anzijun<2447225967@qq.com> ENV MYPATH /usr/local WORKDIR $MYPATH RUN yum -y install vim EXPOSE 22 CMD echo $MYPATH CMD echo "----end----" CMD /bin/bash #通过文件构建镜像 docker build -f mydockerfile-centos -t mycentos:0.1 . #测试运行 docker run -it mycentos:0.1 /bin/bash #工作目录在/usr/local #有vim命令
我们可以列出本地镜像变更的历史
docker history 镜像id
7.CMD 和ENTRYPOINT区别
CMD 在容器run的时候会执行这条命令,追加的命令会替换原先的命令 而ENTRPOINT会进行追加不会替换
了解以上内容后,docker使用没有任何问题,以下内容为运维进阶
Docker 网络
1. 理解docker0
ip a 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:df:90:30:06 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是如何处理网络访问的
1、我们每启动一个容器,docker就会给容器分配一个ip 2、我们只要安装了docker,就会有一个网卡docker0 # 这个docker0 默认为桥接模式,使用的技术是evth-pair技术,我们发现容器带来的网卡都是一对一对的,说白了就是一对虚拟的设备接口,他门都是成对出现的,一端连着协议,一端彼此相连 # 正因为有这个特性,我们会充当一个桥梁,专门连接各种虚拟设备
经过测试,容器与容器之间是可以相互ping通的,以下是容器之间的网络结构图
结论:tomcat01和tomcat02是公用一个路由器docker0
所有容器不指定网络的情况下,都是docker0路由,docker会给我们的容器分配一个默认的可用ip
docker 使用的是Linux的桥接,删除容器默认的一对网卡就会消失
2. --link(新手使用)
#容器中直接去ping另一个容器是不通的,如何解决这个问题呢? #使用--link docker run -d -P --name tomcat03 --link tomcat02 tomcat
本质
--link参数会将tomcat03容器中/etc/hosts文件里直接写死tomcat02容器的ip地址和主机名,这种方式是不推荐使用的!
我们追求的是自定义网络,不适用docker0!
3.自定义网络 (推荐)
查看所有的docker网络
网络模式
bridge: 桥接模式 在docker中搭桥
none:不配置网络
host: 主机模式,与宿主机共享网络
container:容器网络连接!(用的少)
测试
#我们直接启动的命令--net bridge,而这个就是我们的docker0 docker run -d -P --name tomcat01 -net bridge tomcat #docker0特点:默认,域名不能访问,--link可以打通连接! #我们可以自定义一个网络 docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet # 查看一下新建的网络 [root@cloud-01 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 368b6f8dbcff bridge bridge local 763531b46bc7 host host local a74e10aef4f3 mynet bridge local 9c3c566f9afe none null local #根据自己创建的网络去创建容器 docker run -d -P --name tomcat-net-01 -net mynet tomcat docker run -d -P --name tomcat-net-02 -net mynet tomcat #按照以上方法创建出的容器,容器与容器之间可以ping通,容器之间使用容器名称也可以ping通
推荐平时这样使用网络
好处:
不通集群之间使用不同的网络,保证集群是安全和健康的
4.网络联通
每个docker容器集群之间网络相互打通,连接一个网络到一个容器
#测试打通 tomcat01 -mynet docker network connect mynet tomcat01 #联通之后 tomcat01容器就加入到了mynet配置当中,放到了mynet网络下 #实际就是一个容器两个网卡,简单粗暴
至此,doker 入门完结