尚硅谷 Docker核心技术(基础篇)
李阳
网站:docker-cn.com
hub.docker.com
文章连接:
http://dockone.io/article/9209 // Docker 基础知识
前提知识:Linux 命令,Maven / Git 相关知识
Maven:?
(JAVA 工程师)常用的开源软件:Nginx, Jetty, ActiveMQ, Kafka, Redis, RabbitMQ, Memcached等
直接对口方向:云计算,且应该掌握 Golang // Docker 底层是用GO语言写的
Docker相关技术:Swarm, Compose, Machine, mesos, k8s ---- CD / CI, jenkinds整合
相关课程:区块链有涉及
镜像:
容器:
容器虚拟化技术与虚拟机的区别
虚拟机技术:Virtual Machine
对于应用软件来讲,虚拟机和正常机器一样,无差别
对于底层系统来讲,虚拟机就是一个普通文件,删除后对其他文件没有任何影响。
这类虚拟机完美地运行了另一套系统,能够使应用程序、操作系统和硬件三者之间的逻辑关系不变
缺点:占用资源多,荣誉步骤多,启动慢
容器虚拟化技术:Linux容器(Linux Containers 缩写 LXC)
并非模拟一个完整的操作系统,只需要软件工作所需的库资源和设置,系统因此变得轻量高效并保证在任何环境中的软件都能运行
主要区别: 1. 硬件差别
前者虚拟出一套硬件,运行一个完整的操作系统,在其上再运行所需应用进程
后者的应用程序直接运行于宿主机的内核,容器没有自己的内核,也没有进行硬件模拟,因此容器比传统虚拟机更轻便
2. 独立性
每个容器之间相互隔离,有自己的文件系统,容器之间进程不会相互影响,能区分计算资源
??区分计算资源??
此性质的应用
3. 速度
前者分钟级,后者秒级
Docker file, cmd, entrypoint 的区别
痛点:环境不同,开发与运维环境不同
运维产品上线面对的困境:互联网高并发,大流量,集群分布的特点
弹性云扩容时,用镜像文件跟方便快捷
集群分布:?
高并发:?
弹性云扩容:?
Docker的解决办法:“软件带环境安装” ,一次构建,处处运行
包含两方面技术:1. 镜像技术
打破“程序及应用”,自系统环境自底向上打包应用,形成镜像。“镜像及应用”
内核,操作系统,运行依赖包,运行环境,配置环境,可执行文件
2.
war包是什么?
弹幕解决方案:打包成 jar 包,嵌入jetty ?
target: build, ship and run any app, anywhere.
通过对应用组件的 封装、分发、部署、运行 的生命周期的管理,使用户的APP(WEB应用或是数据库应用等)及其运行环境做到“一次封装,到处运行”
“集装箱”的理解
Docker 三要素
仓库:?
镜像:?
容器:?
开发/运维 (DevOps)
快速应用交付与部署:安装配置再镜像内已内置好,节约部署配置及测试验证时间
便捷的升级与扩缩容
简单的系统运维
高效的计算资源的利用
存储:系统盘aufs/dm/overlayfs
数据盘volume
网络:宿主机网络,NS隔离(?)
分层的存储与包管理?? devops 理念??
支持增量分发,易于部署
易于构建,良好的REST API, 也适合自动化测试和持续集成
JAVA 三个特性————继承、封装、多态 ???
gav---- group_id, artifact_id, version ???
P6 安装Docker & P34
官方文档
检查网络
https://www.jianshu.com/p/94d9135edb91
1. 以命令 cd /etc/sysconfig/network-scripts/ 进入network-scripts目录下,找到文件ifcfg-ens33(具体名字可能因系统不同而各异,如eth0、eth33…),对该文件进行配置网卡信息
2. 以命令 vi ifcfg-ens33 打开网络配置文件,【INS】键进入编辑输入模式,在文件末尾加上(根据需要添加or变更,非必须)
3. onboot = yes
结尾加上(非必须):
# 指定DNS服务器的IP地址,使其可正常解析域名,从而访问外网
DNS1=8.8.8.8
DNS2=4.2.2.2
4. ping www.baidu.com 检查 CTRL + C 终止操作
docker 查看版本命令
docker version
阿里云镜像加速器
专属加速器地址 https://pydv1gb4.mirror.aliyuncs.com
您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-‘EOF’ // -tee 追加写
-------------------------------------------------------------
{
“registry-mirrors”: [“https://pydv1gb4.mirror.aliyuncs.com”]
}
-------------------------------------------------------------
EOF
sudo systemctl daemon-reload //重载配置文件
sudo systemctl restart docker // 重载docker服务
docker配置文件docker-daemon.json详解:
https://www.cnblogs.com/golinux/p/12759674.html
https://blog.csdn.net/lanshen110119/article/details/104671442/
Linux 新建文件: https://linux.cn/article-10549-1.html
docker info 显示镜像
检查配置是否成功 ps -ef | grep docker
docker run hello-world // 本地没有,会自动从docker hub上 pull 下来
docker 镜像 (IMAGE)是一个 只读 模板。镜像可以用来创建Docker容器,一个镜像可以创建多个容器。
类比
Docker 面向对象
容器 对象
镜像 类
C / S 结构, Client-Server
Docker 守护进程运行在主机上,通过 Socket 连接从客户端访问,守护进程从客户端接收命令并管理运行在主机上的容器。
容器,是一个运行时环境,就是“集装箱”
docker 为什么快?
1. docker 有更少的
docker version // 版本
docker info // 信息
docker --help
镜像命令 |
---|
docker images // 本地镜像
-a 本地所有镜像,含中间映像层 // a -> ALL
中间映像层??
-q 只显示镜像ID
-digests 摘要
-no-trunc 显示完整信息
类比:镜像是一层套一层
docker search …
-s 50 // 收藏 50 以上的
–automated // 只列出 automated build 类型的镜像
-no-trunc
docker pull …
docker rmi … // 删除镜像
docker rmi -f $(docker images -qa) // 删除全部
git::
docker commit ??
docker push ??
???tomcat???
容器命令 |
---|
容器可以被看作一个简易版的 Linux 环境(包括ROOT用户使用权限、进程空间、用户空间和网络空间等) 和运行在其中的应用程序。
容器定义和镜像几乎一模一样,也是一堆层(???)的统一视角,唯一区别在于容器最上面那一层是 可读可写
docker run [OPTIONS] image [COMMAND] [ARG…]
–name=“容器的新名字”
-d 后台运行,并返回ID,也即启动守护式容器
用 docker ps -a 查看,发现容器已经退出
docker 容器后台运行,就必须有一个前台进程
容器如果运行的不是 一直挂起的命令(比如 top, tail ),就会自动退出
docker 机制:前台没有应用,会使 docker 后台容器自杀
最佳解决方案:以前台程序运行
测试: docker run -d /bin/sh -c "while true; do echo hello world; sleep 2; done"
// 每两秒 打印 hello world, 前端有相应,后端就会一直运行
查看容器日志: docker logs -tf 容器名 或 ID
-i 以交互模式运行容器,与 -t 配合使用
-t 为容器重新分配一个伪输入终端
-P 随即接口映射 ??
-p 指定端口映射,有四种格式
ip::hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort
// tomcat 与 -p , -P 有关
ps -ef ?? // 查看进程
docker ps // 运行的容器
-a 列出当前正在运行 以及 历史运行过的全部容器
-l 显示最近创建的容器
-n 显示最近 n 个创建的容器
-q 静默模式,只显示容器编号
–no-trunc
退出容器:
exit 容器停止退出
ctrl + P + Q 容器不停止退出
启动容器
docker start 容器名或 ID
停止
docker stop 容器名或 ID
docker kill 容器名或 ID // 强制停止
删除已停止的容器
docker rm -f 容器名或 ID // rm 删除容器 rmi 删除镜像
docker rm -f $(docker ps -aq) 或 docker ps -aq | xargs docker rm
查看容器日志
docker logs -f -t --tail
-f //跟随最新日志dayin
-t // 时间戳
–tail 5 // 显示最后5条记录
查看容器内的进程
docker top 荣启铭 或 ID
查看容器内部的细节
docker inspect ID
// docker 是一层套一层
进入正在运行的容器并以命令行交互
docker attach ID //重新进入后台容器
docker exec -t ID [COMMAND] // 在容器外面执行
比如 docker exec -t 32jk123h ls -l /tmp
从容器内拷贝文件到主机
docker cp ID: 文件路径 目标路径
是什么
轻量级、可执行的独立软件包,用来打包 软件运行环境 和 基于运行环境开发的软件
UnionFS (联合文件系统)
分层、轻量级、高性能文件系统
支持修改作为一次提交来一层层叠加,同时可以将不同目录挂载到同一虚拟文件系统下(unite several directions into a single virtual filesystem)
UnionFS 是 Docker 镜像的基础。镜像可以通过分层来继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像
特性:一次同时加载多个文件系统,但从外面看,只能看到一个文件系统,联合加载会将各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
多层文件原理
kernel 内核???
为什么采用分层结构
最大好处————共享资源
如多个镜像都从相同的 BASE 镜像构建而来,宿主机只需在磁盘上保存一份 BASE 镜像,同时内存中也只需加载一份 BASE 镜像,就可为所有容器服务,且每一层都可以被共享
补充命令 : docker commit
提交副本使之成为一个新的镜像
docker commit -m = “描述信息” -a = “author” ID 要创建的镜像名:[标签名]
实例演示:从hub上下载 tomcat 到本地并成功运行
1. docker run -it -p 8888:8080 tomcat
或 docker run -it -P tomcat
-p 主机端口:docker 容器端口
-P 随机分配端口
i // 交互 t // 终端
docker 的端口 8888
// 404 ———— 可能因为 tomcat 容器中 webapps 文件夹中没有这个欢迎页,可以自己上传一个欢迎页???
2. docker exec -it ID /bin/bash
webapps/docs 删除后就找不到 docs 的页面
后台访问
docker run -d -p 6666:8080 tomcat
需求:运行产生的数据持久化,容器间可以共享数据 , 就像是一个U盘
类似于 Redis 里面的 rbd 和 aof 文件
特点:
1. 数据卷可在容器之间共享或重用数据
2. 卷中的更改可以直接生效
3. 数据卷中的更改不会包含在镜像的更新中
4. 数据卷的生命周期一直持续到没有容器使用它为止
容器内添加
直接命令添加
1. docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
如: docker run -it -v /myDataVolume:/dataVolume centos // 可以自动生成相应文件夹
2. 查看数据是否挂载成功
docker inspect ID
3. 容器与宿主之间数据共享
两边同时修改,添加,都同步
即使容器关闭后,主机在修改,容器打开后也会同步
4. 容器写保护(带权限)
docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名 // ro ---- read only 在容器中不能 新建也不能修改 只允许主机单方向输出
DockerFile添加
docker file 用来描述 image
docker file 内部有自己的很多模块描述诸如端口一类的信息
自己写一个 dockerfile :
FROM centos
VOLUME ["/dataVolume01","/dataVolume02"] // 能添加多个路径
CMD echo “finished, --------successs01”
CMD /bin/bash
大致相当于 docker run -it -v /主机路径:/dataVolume01 -v /主机路径:/dataVolume02 centos /bin/bash
但是 dockerfile 不支持写主机路径,为了增强自身的可迁移性
补充:运行镜像时,只会执行最后一个 CMD, 且如果启动时指定参数,所有 CMD 命令都会被覆盖
第二步,通过 docker build 生成一个镜像
docker builf -f /mydocker/dockerfile01 -t alexisabel/centos . // "." 表示打包当前目录, 新镜像名字叫做 alexisabel/centos
查找主机对应默认地址:docker inspect ID
如果出现 cannot open dictionary. : Permission denied
在挂载目录最后添加多一个 --priviledged = true
原理???
P21 数据卷容器
命名的容器称为挂载数据卷,其他容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,成为数据卷容器。
理解:“在第一层活动硬盘下面有多个二层活动硬盘,它们之间实现数据共享” 是个树形结构
实例
1. docker run -it --name dc01 alexisabel/centos
2. cd dataVolume02
3. touch dc01_add.txt
4. ctrl+p+q 退出
*** 继承:
docker run -it --name dc02 --volumes-from dc01 alexisabel/centos
dc01, dc02 之间数据均可共享
备注
是什么:用来构建 Docker 镜像的构建文件,是由一系列命令和参数构成的脚本。
可以在官网上查到文件 docker hub
形式如:
FROM scratch // scratch 元镜像
MAINTAINER The Centos Project [email protected]
ADD
LABEL
#Default command
CMD
基础知识:
1. 每条指令以大写保留字开头且后面至少跟随一个参数
2. 每条指令都会创建一个新的镜像层,并对镜像进行提交
3. 由上到下,逐一执行
执行流程:
1. 从基础镜像运行一个容器
2. 执行一条指令并对容器进行修改
3. 执行类似 docker commit的操作提交一个新的镜像层
4. docker 再基于刚提交的镜像运行一个新容器
5. 执行 docker file 中下一条指令直到所有指令都执行完成
从应用软件来看,
dockerfile 原材料,面向开发
镜像 交付品,成为交付标准
容器 软件的运行状态,设计运维和部署
dockerfile ---> docker images ----> docker container
build run
dockerfile: 定义了进程需要的一切东西,包括执行代码或是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程等
当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计 namespace 的权限控制
FROM
基于的父镜像,最基础的是元镜像 scratch
MAINTAINER
开发者邮箱等信息
RUN
容器构建时需要运行的命令
EXPOSE
当前容器对外暴露的端口
WORKDIR
指定再创建容器后,终端默认登陆进来的工作目录,类比停车场的车位
ENV
环境变量 可以在后续任何 RUN 指令中使用,如同在命令前制定了环境变量前缀一样
也可以在其他指令中直接使用这些环境变量
如:
ENV MY_PATH /usr/mytest
WORKDIR $MY_PATH // $ 表示引用
ADD
拷贝并且会解压缩和自动处理URL
COPY
拷贝
两种写法 COPY src dest
COPY ["src", "dest"]
VOLUME
容器卷
CMD
容器启动时要运行的命令
可以有多个 CMD 指令,但是只有最后一个会生效,CMD 会被 docker run 之后的参数替换
ENTRYPOINT
容器启动时要运行的命令
和 CMD 目的一样,不同在于 ENTRYPOINT 是追加指令,不会被覆盖
ONBUILD
当构建一个被继承的 Dockerfile 时运行命令,父镜像在被子镜像继承后父镜像的 onbuild 被触发 (*被动技能*,可以搞点事情)
弹幕:“关系如同 > >> " ???
案例1:
原始 centos 默认路径为根目录
没有 vim 编辑器
无法使用 ifconfig 命令
Dockerfile2 内容
---------
FROM centos
MAINTAINER alexisabel
ENV MY_PATH /tmp
WORKDIR $MY_PATH
RUN yum -y install vim
RUN yum -y install net-tools // 用 & 能不能将两个 RUN 命令连接起来???
EXPOSE 80
CMD echo $MY_PATH
CMD echo "success------------"
CMD /bin/bash
----------
执行 docker build -f /mydocker/Dockerfile2 -t mycentos:1.3 . // 文件路径 /mydocker/Dockerfile2, 名字叫 mycentos,版本号1.3
列出镜像变更历史,可以看出命令操作的流程
docker history ID
案例2:CMD 与 ENTRYPOINT 的演示
entrypoint:docker run 之后的参数会被当作参数传递给 ENTRYPOINT,之后形成新的命令组合
curl http://www.baidu.com // 下载命令,会返回表单,测试端口???
Dockerfile03
--------
FROM centos
RUN yum -y curl
CMD ["curl", "s", "http://ip.cn"]
// https 可能不行???
// curl cip.pp ? ? ?
--------
docker build -f /mydocker/dockerfile03 -t myip .
如果要看 http 的报头信息,需要加参数 -i,可是这样就很大程度上改变了功能,不然还需要修改 dockerfile, 再重新构建。故使用 entrypoint 命令达到追加效果
Dockerfile04
-------
FROM centos
RUN yum -y curl
ENTRYPOINT ["curl", "s", "http://ip.cn"]
-----
docker build -f /mydocker/dockerfile04 -t myip2 .
docker run myip2 -i
// 可以成功执行
案例3 综合案例:自定义 tomcat
P31 docker 常用安装
P33 docker 发布到阿里云