Docker学习笔记
docker概述
基于go语言开发的开源项目 解决环境问题——“在我的电脑上能跑”
传统开发一款产品 两套环境 开发和上线 环境配置麻烦 无法跨平台
传统:打jar包 交给运维
现在:开发打包部署上线(打包jar包+环境)
集装箱思想:环境镜像,打包装箱,每个箱子之间相互隔离
虚拟机:在windows中安装一个vmware,通过软件去虚拟化出一台或多台电脑 笨重 几分钟启动
容器:核心环境镜像(最核心环境+jdk+mysql…)同样是虚拟化技术 轻巧 秒级启动
官方文档:https://docs.docker.com
仓库地址:https://hub.docker.com 发布镜像
Docker能干什么?
虚拟机技术缺点:资源占用多;冗余步骤多;启动慢
容器化技术:并非模拟一个完整的操作系统
比较docker和传统虚拟机技术:
-
传统虚拟机会虚拟出一套硬件,模拟一个完整的操作系统,然后在此操作系统安装运行软件
-
容器内的应用程序直接运行在宿主机的内核,容器没有自己的内核,也没有虚拟硬件,所以更为轻便
-
每个容器相互隔离,有自己的一套文件系统,互不影响
DevOps(开发,运维)
应用更快速的交互和部署
传统:大量帮助文档,安装程序
Docker:打包镜像发布测试,一键运行
更便捷的升级和扩容
项目打包为一个镜像,可以以服务器为单位整体扩展
更简单的系统运维
容器化之后,开发测试环境变得高度一致
更高效的计算机资源利用率
Docker是内核级别的虚拟化,可以在一台物理机上运行很多容器实例
Docker安装
Docker的基本组成
客户端-服务器-远程仓库
镜像image :
docker镜像好比是一个模版,可以通过这个模版来创建容器服务,tomcat镜像->run->tomcat01容器(提供服务器),
通过这个镜像可以创建多个容器(最终服务或项目运行在容器当中)
容器cotainer :
Docker利用容器技术,独立运行一个或一组应用,通过镜像来创建。
启动 停止 删除 基本命令
简单看作一个简易版Linux系统
仓库repository:
仓库是用来存放镜像的地方,分为共有仓库和私有仓库
Docker Hub默认国外
阿里云等等(镜像加速)
安装Docker
环境准备CentOS7;Xshell远程连接
参考帮助文档
卸载旧版本-安装相关依赖包-设置镜像仓库-安装docker相关内容-启动docker——systemctl start docker
Run的流程和Docker原理
Docker run - 在本机寻找镜像-有则运行 没有就在仓库上下载-仓库有则下载到本地并运行 没有则返回报错
底层原理
Docker是怎么工作的?
Docker是一个client-server结构系统,Docker守护进程运行在主机上,客户端通过socket访问
docker-server接收到docker-client的指令后执行
Docker为什么比VM快?
- Docker有着比虚拟机更少的抽象层
- Docker使用的是宿主机的内核,VM需要Guest OS
所以docker启动时不需要重新加载一个操作系统的内核
Docker常用命令
帮助命令
docker version 显示当前docker版本信息
docker info 显示docker的系统信息 包括镜像和容器的数量
docker 命令 --help
镜像命令
docker images 查看所有本地主机上的镜像
可选项:-a 显示所有镜像 -q 仅显示镜像id
docker search mysql 搜素镜像
可选项:–filter stars=3000 #过滤查找收藏数大于3000的镜像结果
docker pull 镜像名 下载镜像
可指定版本下载 否则默认下载最新版本
docker rmi 删除镜像
docker rmi -f 镜像id #删除指定镜像
docker rmi -f $(docker images -aq) #删除全部镜像
容器命令
说明:有了镜像才可以创建容器
docker pull centos
新建容器并启动
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=? #显示最近创建的容器
-q #只显示容器的编号
删除容器
docker rm 容器id #删除指定容器,但无法删除正在运行的,强制删除则rm -f
docker rm -f $(docker ps -aq) #递归删除所有容器
docker ps -a -q|xargs docker rm #将所有容器逐个删除
启动和停止容器的操作
docker start 容器id #启动
docker restart 容器id #重启
docker stop 容器id #停止
docker kill 容器id #强制停止
常用的其他命令
后台启动容器
#命令 docker run -d 镜像名
docker run -d centos
#问题:发现输入docker ps,发现centos停止了
原因:docker容器使用后台运行时需要有至少一个前台进程#容器启动后,发现自己并没有提供服务,会立刻停止自身
查看日志
docker logs -t -f --tail 10 容器
#显示日志
-tf #f follow 跟踪日志实时输出;t timestamp 打印时间戳
--tail number #显示的日志条数
查看容器中的进程信息
#命令 docker top 容器id
查看容器的元数据
docker inspect 容器id
进入当前正在运行的容器
#容器通常采用后台方式运行,需要进入容器修改一些配置
#命令 exec——执行execute 交互
docker exec -it 容器id /bin/bash
#方式二
docker attach 容器id
#两者区别
docker exec——#进入容器后开启一个新的终端,可以在里面执行操作(常用)
docker attach——#进入容器正在执行的终端,不会启动新的进程
从容器内拷贝文件到主机
docker cp 容器id:容器内路径 目的主机路径
练习实例
使用docker安装nginx
#步骤:
#1、搜索镜像search 2、下载镜像 pull 3、运行测试
docker run -d --name nginx1 -p 1000:80 nginx
# -d 后台运行
# --name 给容器命名
# -p 宿主机端口:容器内部端口
端口暴露的概念
问题思考:每次改动nginx配置文件,都需要进入容器内部十分麻烦,能否在容器外部提供一个映射路径,达到在容器修改文件,容器内部就可以自动修改?-v 数据卷
使用docker安装tomcat
#官方文档
docer run -it --rm tomcat:9.0
#之前的方式是后台启动,停止容器后,容器还能被查到, docker run -it --rm 命令一般用于测试,容器使用完成后会被删除(一般不建议使用)
#下载
docker pull tomcat:9.0
#启动运行
docker run -d -p 1001:8080 --name tomcat1 tomcat
#进入容器
docker exec -it tomcat1 /bin/bash
#发现问题:linux命令变少了,同时webapps目录下为空——原因:阿里云镜像默认是最小的,剔除了多余的内容
可以将webapps.disk目录下的内容复制到webapps #cp -r webapps.dist/* webapps
思考:以后部署项目能否不进入容器内部,通过外部提供一个映射路径映射到webapps,在外部放置项目,自动同步?
可视化
-
portainer(暂时先用这个)
什么是portainer?
docker图形化界面管理工具 提供一个后台面板供我们操作
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
访问测试:8088端口
-
Rancher(CI/CD再用)
Docker镜像讲解
镜像——轻量级、可执行的独立软件包,包含了运行某个软件所需的所有内容,包括代码,运行环境变量,库,配置文件
所有的应用,直接打包docker镜像,就可以跑起来
如何得到镜像?
- 从远程仓库下载
- 通过他人的拷贝
- 自己制作一个镜像DockerFile
Docker镜像加载原理
UnionFS(联合文件系统)docker的镜像实际上是由一层一层的文件系统组成的
内核组成有bootfs(宿主机内核 公用)加rootfs(操作系统发行版的指令集 轻巧)
因此虚拟机启动需要分钟级别,而容器启动可以做到秒级
分层理解
每下载一个镜像就会加一层,可以理解为windws系统的安全补丁
docker镜像都是只读的,任何可写的操作都是基于容器层,被添加到镜像层的顶部,然后再一起打包成一个新的镜像提交
commit镜像
docker commit 提交容器成为一个新的副本
#命令与git原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
概念:等同于虚拟机VM的快照,保存当前容器的状态,通过commit提交,获得一个镜像
———入门———
容器数据卷
什么是容器数据卷
数据存储在哪里?如果数据存储在容器中,一旦容器被删除,数据就会丢失
需求:数据可以持久化,例如mysql数据存储到本地
容器之间有一个可以数据共享的技术——Docker容器中产生的数据同步到本地
卷技术——目录挂载,将容器的目录挂载到Linux上面
总结一句话:容器的持久化和同步操作,实现容器见的数据共享
使用数据卷
#方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器内目录
docker run -it -v /home/test:/home centos /bin/bash
#启动后可以通过docker inspect 容器id 来查看是否挂载成功 Source主机内地址:/home/test Destination容器内地址:/home
好处:以后修改只需在本地改动,容器内会自动同步
实战:安装MySQL
思考mysql持久化的问题?
#拉取镜像
docker pull mysql:5.7
#运行容器,对数据进行挂载
-d 后台运行
-p 端口映射
-v 数据卷绑定 可绑定多个
-e 配置环境
docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql1 myusql:5.7
具名挂载和匿名挂载
#匿名挂载
-v 容器内路径 (不指定宿主机路径)
docker run -d -P --name nginx1 -v /etc/nginx nginx
#查看所有volume的情况
docker volume ls
local 2l5k6jh23k45h63klg5l2kh5kl26ll
#具名挂载
docker run -d -P --name nignx2 -v named-nginx:/etc/nginx nginx
docker volume ls
local named-nginx
#通过-v 卷名:容器内路径进行具名挂载
所有docker容器内的卷,如果没有指定目录的情况下,都是在#/var/lib/docker/volumes/xxxx/_data
通过具名挂载可以方便的找到想要的卷,大多数情况下是用具名挂载
#区分具名挂载,匿名挂载,指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载
初识DockerFile
Dockerfile就是docker用来构建docker镜像的文件,命令脚本,通过这个脚本可以生成镜像
镜像是分层的,脚本的每一个命令都是一层
#创建一个dockerfile文件,名字随机 建议dockerfile
#文件中的内容 指令(大写)参数
FROM centos
VOLUME ['volume1','volume2'] #挂载数据卷的第二种方式
CMD echo "----end-----"
CMD /bin/bash
#以上的每一个命令就是镜像的一层
这种方式在构建自己的镜像时使用的较多,假设构建镜像时没有挂载卷,则需要手动挂载 -v 卷名:容器内路径
数据卷容器
容器之间的数据卷,多个mysql同步数据
docker run docker02 --volumes-from docker01
结论:
容器之间配置信息的传递,数据卷容器的生命周期会一直持续到没有容器使用为止(引用传递)
一旦持久化到了本地,即使删除容器,本地的数据也不会被删除
DockerFile
DockerFile介绍
dockerfile是用来构建docker镜像的文件,命令参数脚本
构建步骤:
- 编写一个dockerfile文件
- docker build构建成为一个镜像
- docker run 镜像
- docker push 发布镜像(dockerhub or 阿里云镜像仓库)
DockerFile构建过程
基础知识:
- 每个保留关键字(指令)都必须是大写字母
- 从上到下顺序执行
- #表示注释
- 每一个指令都会创建一个新的镜像层并提交
Docker镜像逐渐成为企业交付的标准
DockerFile是用来构建docker镜像的文件,命令参数脚本
DockerImage是通过DockerFile构建生成的镜像,是最终发布和运行的产品
Docker容器是镜像运行起来提供的服务器
DockerFile指令
在这里插入图片描述
FROM #基础镜像,一切从这里开始构建
MAINTAINER #镜像是谁写的,姓名+邮箱
RUN #镜像构建的时候需要运行的命令
ADD #步骤:添加的内容压缩包
WORKDIR #镜像的工作目录
VOLUME #挂载的目录
EXPOSE #暴露的端口号
CMD #指定这个容器启动的时候要运行的命令 替代
ENTRYPOINT #同CMD 追加
ONBUILD #当构建一个被继承的DockerFile时的触发指令
COPY #类似于ADD,将文件拷贝到镜像中
ENV #构建的时候设置环境变量
实战测试
自己写一个dockerfile
FROM centos
MAINTAINER kyle<12345678@qq.com>
ENV MYPATH /usr/local
WORKDIR MYPATH
RUN yum -y install vim #安装vim命令
RUN yum -y install net-tools #安装ifconf命令
EXPOSE 80
CMD echo $MYPATH
CMD echo "------end------"
CMD /bin/bash
#2、通过这个文件构建镜像
#-f dockerfile文件路径 -t target 镜像名:版本号
docker build -f mydockerfile-centos -t mycentos:1.0 .
#3、测试运行
可以通过docker history 镜像id 来查看镜像的构建过程和变更历史
CMD和ENTRYPOINT的区别
CMD——指定这个容器启动时要运行的命令,不可追加,会被替代
ENTRYPOINT——指定这个容器启动时要运行的命令,可以追加命令
实战:做一个tomcat镜像
- 准备镜像文件,tomcat压缩包,jdk的压缩包
- 编写dockerfile文件
FROM centos
MAINTAINER kyle<12345678@qq.com>
COPY readme.txt /usr/local/readme.txt #复制帮助文档
ADD jdk-8u11-linux-x64.tar.gz /usr/local/ #添加jdk和tomcat压缩包 会自动解压
ADD apache-tomcat-9.0.22.tar.gz /usr/laocal/
RUN yum -y install vim #安装vim工具
ENV MYPATH /usr/local
WORKDIR $MYPATH
#配置环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_11
ENV CALSSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PAHT:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080 #暴露端口
CMD /usr/local/apache-tomcat-9/0/22/bin/startup.sh && tail -F /usr/laocal/apache-tomcat-9.0.22/bin/logs/catlina.out
3、构建镜像
# docker build -t mytomcat
4、启动镜像,访问测试
5、发布项目(由于做了数据卷挂载,可以直接在本地编写项目发布)
需要掌握Dockerfile的编写
发布自己的的镜像到阿里云镜像服务
- 登陆阿里云,找到容器镜像服务,创建命名空间
- 创建容器镜像仓库
- 将容器推送到远程仓库