Docker教程
*Docker
Docker为什么会出现?
一款产品:开发—上线 两套环境!应用环境,应用配置!
开发 —- 运维 问题:我在我的电脑上可以运行!版本更新,导致服务不可用!对于运维来说,考验就十分大?
开发即运维
环境配置十分麻烦,每一个机器都要部署环境(集群Redis,ES,Hadoop……),费时费力。
那么项目能不能带上环境一起安装呢
Docker通过隔离机制,可以将服务器利用到极致
本质:所有的技术因为出现了一些问题,我们需要去解决,才去学习。
Docker的历史
2010年,几个搞IT的年轻人,就在美国成立了一家公司 dotCloud
做一些pass的云计算服务!
我们将自己的技术(容器化技术)命名 就是docker!
Docker刚刚诞生的时候,没有引起行业的注意!
开源
开发源代码
2013年,Docker开源
Docker越来越多的人发现了Docker的优点,Docker每个月都会更新一个版本
2014年四月,Docker1.0发布
Docker为什么这么火呢,因为它相对于一个虚拟机来说,它非常轻。
- 在容器技术出来之前,我们都是使用的虚拟机技术。
- 虚拟机:创建一个操作系统非常的笨重 内存占用大
- Docker: 内存占用下 启动快 只需要运行一个软件即可
到现在,所有开发人员都必须会docker!
聊聊Docker
Docker是基于Go语言开发的·!开源项目!
Docker能干嘛
- 之前的虚拟机技术
- 1、 资源占用十分多
- 冗余步骤多
- 启动很慢
- 容器化技术
比较Docker和虚拟机技术的不同:
- 传统虚拟机。虚拟出一条硬件,运行一个完整的操作系统,憨厚在这个系统上安装和运行软件
- 容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了。
- 每个容器间时互相隔离,每个容器内都有一个属于自己的文件系统,互不影响。
Docker安装
Docker的基本组成
镜像 (Image):
docker镜像就好比是一个模板,开源通过这个模板来创建容器服务,romcat镜像—run—tomcat01容器(提供服务器),通过这个镜像可以创建多个容器。
容器(container):
Docker利用容器技术:独立运行一个或者一个组应用,通过镜像来创建的。
启动、停止、删除、基本命令!
目前可以把容器给i理解为就是一个简易的Linux系统
仓库 (repository):
仓库就是存放镜像的地方!
仓库分为共有仓库和私有仓库!
Docker Hub (默认是国外的)
阿里云..都有容器服务
安装Docker (网络源)
环境查看
系统内核要是3.0以上的 |
系统版本 |
安装
1、 卸载Docker的旧版本
sudo yum remove docker \ |
2、 安装基本环境
yum install -y yum-utils |
3、设置镜像的仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo |
4、更新yum源并安装docker-ce
yum update --allowerasing --nobest |
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y |
5、启动docker
[root@k8s ~]# systemctl start docker |
6、 查看docker version 查看是否安装成功
[root@k8s ~]# docker version |
7、 运行hello world
[root@k8s ~]# docker run hello-world |
8、 查看hello-world镜像
[root@k8s ~]# docker images |
了解:卸载docker
# 1、卸载依赖 |
配置阿里云加速
1、 执行命令、查看是否在dockrr.service文件中配置过镜像地址
systemctl cat docker | grep '\-\-registry\-mirror' |
2、 在/etc/docker/daemon.json中写入如下内容 (如果文件不存在请新建该文件)
{ |
一定要确保文件符合jssn规范,否则Docker将不能启动
3、重启docker服务
sudo systemctl daemon-reload |
回顾HelloWorld流程
run的运行流程图
底层原理
Docker是什么工作的?
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问!
Docker为什么比VM快?
- Docker有着比虚拟机更少的抽象层
- Docker利用的是宿主机的内核,VM需要是Guest OS。
所以说,新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导。虚拟机时加载Guest OS,分钟级别的,而Docker时利用宿主机的操作系统。
Docker的常用命令
帮助命令
docker version # 显示docker的版本信息 |
帮助文档地址:https://docker-practice.github.io/zh-cn/
镜像命令
- docker images 查看镜像
[root@k8s ~]# docker images |
- docker search 搜索镜像
[root@k8s ~]# docker search nginx |
- docker pull 下载镜像
下载镜像 docker pull 镜像名[:tag] |
- docker rm 删除镜像
[root@k8s ~]# docker rmi -f nginx:latest |
容器命令
说明: 我们有了镜像才可以创建容器、linux、下载一个centos来测试学习
docker pull centos |
新建容器并启动
docker run [可选参数] image |
列出运行中的容器
docker ps 命令 |
- 退出容器
exit # 停止容器并退出 |
- 删除容器
docker rm 容器id # 删除指定容器,不能删除正在运行的容器 如果要强制删除 rm -f |
- 启动和停止容器的操作
docker start 容器id # 启动容器 |
常用其它命令
后台启动容器
[root@k8s ~]# docker run -d centos //后台启动容器 |
利用死循环让容器有事可做
创建容器 并在其中编写一个shell脚本 |
查看日志
docker logs -f -t --tail 容器,没有日志 |
查看容器中的进程信息 ps
[root@k8s ~]# docker top bf139241a91b |
查看镜像源数据
[root@k8s ~]# docker inspect bf139241a91b |
进入当前正在运行的容器
我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置 |
从容器内拷贝文件到容器外
docker cp 容器id:容器内路径 目的的主机路径 |
exec会进入容器并开启一个新bash终端,exit时不会导致容器stop,attach退出时会导致容器stop
小结
attach Attach to a running container #当前shell下attach连接指定运行镜像 |
Docker安装Nginx
搜索镜像 下载镜像 |
思考问题:我们每次改动nginx配置文件,都需要进入容器内部?十分的麻烦,我要是可以再容器外部提供一个映射的路径,在容器修改文件,容器内部就可以自动修改?
-v 数据卷
docker安装tomcat
一、下载tomcat
docker pull tomcat |
二、检查镜像
[root@k8s ~]# docker images |
三、启动运行tomcat
[root@k8s ~]# docker run -d -p 8002:8080 --name tomcat01 tomcat |
四、测试访问tomcat
[root@k8s ~]# curl localhost:8002 |
发生404报错 说明缺少配置
五、进入tomcat容器
[root@k8s ~]# docker exec -it tomcat01 bash |
保存并退出容器 再次进行访问
网页就已经有内容了
思考问题:当每次部署服务时,每次都要进入容器是否十分麻烦?我要是可以在容器外部提供一个映射路径,webapps。我们在外部放置项目,就自动同步到内部就好了!
部署es+kibana
# es 暴露的端口很多 |
启动elasticsearch
docker run -d --name elasticsearch2 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" --memory="4g" -e "ES_JAVA_OPTS=-Xms1024m -Xmx2048m" --ulimit nofile=1024 elasticsearch |
docker stats查看cpu状态
docker stats |
访问测试9200端口
[root@k8s ~]# curl localhost:9200 |
可视化
- portainer
docker run -d -p 8088:9000 \ --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer |
- Rancher (CI/CD再用)
什么是portainer
一、 docker的图形化界面管理工具,提供一个后台面板供我们操作
docker run -d -p 8088:9000 \ --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer |
二、访问本地主机的8088端口
- 进入后的面板
可视化面板我们平时不会使用,大家测试玩玩即可
Docker镜像讲解
镜像是什么
镜像是一种轻量级、可执行的独立软件包、用来打包软件运行环境和基于运行环境开发的软件、包含运行某个软件所需的所有内容、包括代码、运行库、环境变量和配置文件
所用应用打包到docker镜像
如何得到镜像:
- 远程仓库下载
- 朋友拷给你
- 自己制作一个镜像dockerfile
Docker镜像加载原理
UnionFS (联合文件系统)
UnionFS(联合文件系统):Union文件系统是一种分层、轻量级并且高性能的文件系统、它支持对文件系统的修改作为一次提交来一层层的叠加、同时可以将不同目录挂载同一个虚拟文件系统下。Union文件系统时Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次他哦那个是加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终文件系统会包含所有底层的文件和目录。
Docker镜像加载原理
docker镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS
bootfs主要包含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镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层上面,创建新的镜像层。
举一个简单的例子,假如基于Ubuntu Linux创建一个新的镜像,这就是新镜像的第一层,如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层,如果继续添加一个安全补丁,就会创建第三个镜像层。
该镜像当前已经包含3个镜像层,如下图所示:
在添加额外的镜像层的同时,镜像始终保持时当前所有镜像的组合,下图中,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
上图中的镜像跟之前略有区别,便于展示文件。
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7时文件5的一个更新的版本。
这种情况下,上层镜像层中的文件覆盖了顶层镜像层中的文件,这样使得文件的更新版本作为一个新镜像层添加到镜像当中。
Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层的堆栈,并保证多镜像层对外展示统一的文件系统。
Linux上可用的村塾引擎由AUFS,Overlay2.故名思意,每种存储引擎都基于Linux中对应的文件一同或者块这杯技术。
Docker在Windows上仅支持windowsfilter一种存储引擎,该殷勤基于NTFS文件系统之上实现了分层
特点
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。
这一层就是我们常说的容器层,容器之下的都叫镜像层。
特点
Docker镜像都是只读的,当容器启动时 (run),一个新的可写层被加载到镜像的顶部!
这一层就是我们所说的容器层,容器之下的都叫镜像层(pull)
如何提交一个自己的镜像
commit镜像
docker commit 提交容器成为一个新的副本 |
实战测试
一、启动一个默认的tomcat
发现这个默认的tomcat 是没有webapps应用的 镜像的原因 官方的镜像默认webapps下面是没有文件的! |
容器数据卷
什么是容器数据卷
docker的理念回顾
将应用和环境打包成一个镜像
如果数据都在容器中,那么我们容器一删除,数据就会丢失。==需求:数据可以持久化==
使用数据卷
- 方式一:使用命令进行挂载
docker run -it -v 主机目录,容器目录 |
宿主机内创建的文件 容器内部也能看到
效果:
容器内部:
宿主机:
部署MySQL
获取镜像
[root@k8s home]# docker pull mysql:5.7 |
启动服务
[root@k8s home]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7 |
具名挂载和匿名挂载
匿名挂载 |
对应的路径
[root@k8s home]# docker volume inspect juming-nginx |
所有的docker容器内的卷,没有指定目录的情况下,都在/var/lib/docker/volumes/xxxx/_data
通过具名股灾可用方便的找到我们的一个卷 大多数情况在使用的是具名挂载
区分具名、匿名挂载
-v 容器内路径 # 匿名挂载 |
初识dockerfile
Dockerfile就是用来构建docker镜像的构建文件!
# 创建一个dockerfile文件,名字可用随机,建议使用Dockerfile |
使用构建的镜像创建容器
[root@k8s docker-test]# docker run -it bcb7b9d02259 bash |
测试目录同步
进入到volume2中 创建文件并保存
[root@k8s docker-test]# docker exec -it 65b097a207f6 bash |
查看容器信息 (查看宿主机默认的挂载目录)
[root@k8s _data]# docker inspect 65b097a207f6 |
进入默认挂载目录并查看目录内容
[root@k8s docker-test]# cd /var/lib/docker/volumes/2ad3dd80f2261dee63ddd333ccfe0057a890ded085d58e2c050fd141d40dafe2/_data |
数据卷容器
多个mysql同步数据 容器间的数据共享
# 启动三个容器 通过我们自己写的镜像启动 |
- docker01
- docker02
- docker03 同步
- docker01 同步
- docker02 同步
同步成功 这样我们就实现了容器间的数据共享
当我们在docker1上创建了文件时 宿主机、docker02、3都能接收到这个文件 说明了我们实现了容器间的数据共享
~
docker02、03时绑定的docker01 但是docker01容器被kill掉时 docker02、03的数据依旧不会消失 ~
因为他们三个都绑定到了宿主机上
只要宿主机上的文件还存在
那么volumes01、02目录的内容就不会消失~
实现多个mysql数据共享
一、创建两个mysql容器 mysqlB绑定到mysqlA上
[root@k8s ~]# docker run -d -p 3311:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysqlA mysql:5.7 |
二、在MysqlA上创建数据库mariadb 并查看宿主机上的挂载目录
三、在MysqlB上创建数据库postgresql并在宿主机上查看目录
这样就实现了多个mysql的数据共享
Dockerfile
dockerfile是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
1、编写一个dockerfile文件
2、docker build构建成一个镜像
3、docker run 运行镜像
4、 docker push 发布镜像
Docker构建过程
基础知识:
1、每个保留关键词(指令)都是必须大写字母
2、执行从上到下的顺序
3、 # 表示注释
4、 每一个指令都会创建提交一个新的镜像层并提交!
dockerfile是面向开发的,我们以后发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单
Docker镜像逐渐成为了企业交付的标准,必须要掌握。
Dockerfile:构建文件,定义了一切的步骤
DockerImages:通过dockerfile构建生成的一个镜像
Dockercontainer:容器就是镜像运行起来提供服务器
Dockerfile的指令
FROM # 基础镜像,一切从这里开始构建 |
创建一个自己的centos
[root@k8s centos]# cat Dockerfile |
通过文件构建镜像
[root@k8s centos]# docker build -f Dockerfile -t centos-yum:1.0 . |
测试运行
[root@k8s centos]# docker run -it --name centos01 centos-yum:1.0 |
测试vim和ifconfig命令
[root@075633642f19 local]# ifconfig |
查看镜像构建过程
Docker history
[root@k8s centos]# docker history centos-yum:1.0 |
CMD
Dockerfile中的CMD的运用技巧
创建一个Dockerfile 并在其中添加CMD参数命令 指定进入容器时 运行ls -a命令 |
ENTRYPORT
Dockerfile中ENTRYPOINT的运用技巧
创建容器 |
构建httpd镜像
一、创建文件夹并编辑Dockerfile文件
FROM rockylinux:9.1 |
构建镜像 |
查看镜像列表
root@k8s tomcat]# docker images |
创建容器
[root@k8s tomcat]# docker run -itd --name webA -p 8001:80 centos-web:1.0 |
访问8001端口
[root@k8s tomcat]# curl localhost:8001 |
Rocky容器内启动Apche Httpd服务
利用镜像创建容器
[root@k8s ~]# docker run -it --name web1 -p 1234:80 --privileged=true --restart=always rockylinux:9.1 bash |
配置好yum源
[root@daa98bede414 /]# cat /etc/yum.repos.d/yum.repo |
下载软件包并进行配置
下载软件包和vim工具 |
重启httpd
[root@daa98bede414 /]# /usr/sbin/httpd |
退出到宿主机并访问1234端口
[root@k8s ~]# curl localhost:1234 |