Docker学习笔记
一.Docker概念?
1.为什么使用Docker容器技术?
传统的项目上线方式: jar包+服务器部署redis,tomcat等环境,缺点:
1.项目有多套环境,每套环境都要重新安装,jdk,redis等软件,
2.软件环境升级麻烦,
3.运维需要按照开发给出的文档安装环境部署
docker优点:核心思想:容器隔离
1.将**运行环境和项目打包成镜像**(jar+环境),安装镜像直接部署使用,开发运维一体化;
2.(redis+jdk+tomcat等)镜像内服务一键升级
3.**端口隔离**
2.docker与vmware的比较
1.两者都是容器技术
2.虚拟机通过镜像,虚拟出来多台电脑,不仅虚拟出内核,还虚拟出硬件,每台电脑都有linux内核;
容器没有内核,可直接运行在宿主机的内核,且有自己的文件系统,容器相互隔离;
3.容器体积小,环境启动快;虚拟机本身就是一个虚拟电脑,占内存,启动慢
4.容器极大的压榨宿主机的内存以及性能
3.docker资料
官网:https://www.docker.com
仓库:https://hub.docker.com
文档:https://docs.docker.com
其他: http://www.dockerinfo.net/dockerfile%E4%BB%8B%E7%BB%8D
二.docker 命令
查看docker 信息: docker version
查看docker 详细信息 : docker info
docker帮助命令: docker [命令] --help
1.镜像命令
-
运行镜像:docker run 镜像
docker run -it centos /bin/bash 后面的 bin/bash的作用
首先,docker run -it centos 的意思是,为centos这个镜像创建一个容器, -i和-t这两个参数的作用是,为该docker创建一个伪终端,这样就可以进入到容器的交互模式?(也就是直接进入到容器里面)后面的/bin/bash的作用是表示载入容器后运行bash ,docker中必须要保持一个进程的运行,要不然整个容器启动后就会马上kill itself,这样当你使用docker ps 查看启动的容器时,就会发现你刚刚创建的那个容器并不在已启动的容器队列中。这个/bin/bash就表示启动容器后启动bash,但是有些镜像不适合bash shell风格,会报错。
-
拉取镜像:docker pull 镜像
-
查看本机所有镜像:docker images
-a 查看所有镜像
-q 只显示容器id
-
搜索镜像: docker search 镜像名字
-
删除镜像:docker rmi 镜像 1 镜像 1
-
删除所有镜像: docker rmi -f $(docker images)
2.容器命令
-
新建容器 设置端口 名字 并启动: docker run -it --name tomcat01 -p 8080:8080 tomcat /bin/bash
-it 后台交互启动,进入dcoker容器 (相当于打开一个终端)
-d 后台启动 (只有第一次启动容器的时候容器会成功,如果启动已经创建的容器 失败)
-p 宿主机ip:端口:容器端口 宿主端口:容器 端口 容器端口
-P 随机指定端口
/bin/bash 打开一个伪终端(但是有些镜像不适合bash shell风格,会报错)
-
删除容器 :docker rm 容器id
-f 强制删除
-
启动容器: docker start 容器id
-
重启:docker restart 容器id
-
停止正在运行容器: docker stop 容器id
-
强制停止容器: docker kill 容器id
-
**查看正在运行的容器 😗*docker ps
-
历史运行容器: docker ps -a
-
退出容器的两种方式: exit 直接退出 CTRL+P+Q 不停止退出
3.常用命令
-
后台运行容器 : docker run -d centos
问题:docker ps. 发现centos 停止了
常见的坑,docker容器使用后台运行,就必须要有要一个前台进程,docker发现没有应用,就会 自动停止 nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
-
查看容器查看日志
#显示日志
-tf #显示日志信息(一直更新)
--tail number #需要显示日志条数 docker logs -t --tail number 容器id #查看n行日志
docker logs -ft 容器id #跟着日志
-
查看容器中进程信息:docker top 容器id
-
查看镜像元数据:docker inspect 容器id
-
进入当前正在运行容器的两种方式
docker exec -it 容器id bashshell #进入当前容器后开启一个新的终端,可以在里面操作。(常 用)
docker attach 容器id # 进入容器正在执行的终端
-
从容器内拷贝文件到主机 : docker cp 容器id:容器文件 宿主机ip:目录
3.docker命令作业
-
安装nginx
-
安装tomcat
问题:无法访问tomcat主页?
copy webapp.dist 到 webapps 文件
-
安装es
消耗内存 过大 -e 设置最小,最大占用内存
docker运行交互示意图: client,server,宿主交互
docker 端口暴露示意图 : 外网->阿里云开放的端口->本机系统开放端口(例如:centos防火墙开放端口)->映射到docker 容器端口
docker,vm 架构示意图
docker 内部容器连接示意图
docker stats 查看docker 容器消耗内存情况
注意:当使用 curl localhost:port 访问本机开启的服务时,要确定本机的防火墙开启了port
-
查看主机监听端口:netstat -tlunp
-
查看防火墙开放端口:iptables-save
-
开启防火墙:systemctl start firewalld.service
-
查看防火墙状态: systemctl status firewalld
-
防火墙的管理命令firewalld-cmd,例如我要开发80端口: firewall-cmd --zone=public --add-port=80/tcp --permanent firewall-cmd --reload
-
防火墙放行 IP 地址转发:firewall-cmd --add-masquerade --permanent firewall-cmd --reload
4. 安装docker后无法访问 端口
https://blog.csdn.net/alphr/article/details/107969190
https://ld246.com/article/1585805255477
5.docker命令小结
docker 帮助文档
attach Attach local standard input, output, and error streams to a running container
#当前shell下 attach连接指定运行的镜像
build Build an image from a Dockerfile # 通过Dockerfile定制镜像
commit Create a new image from a container's changes #提交当前容器为新的镜像
cp Copy files/folders between a container and the local filesystem #拷贝文件
create Create a new container #创建一个新的容器
diff Inspect changes to files or directories on a container's filesystem #查看docker容器的变化
events Get real time events from the server # 从服务获取容器实时时间
exec Run a command in a running container # 在运行中的容器上运行命令
export Export a container's filesystem as a tar archive #导出容器文件系统作为一个tar归档文件[对应import]
history Show the history of an image # 展示一个镜像形成历史
images List images #列出系统当前的镜像
import Import the contents from a tarball to create a filesystem image #从tar包中导入内容创建一个文件系统镜像
info Display system-wide information # 显示全系统信息
inspect Return low-level information on Docker objects #查看容器详细信息
kill Kill one or more running containers # kill指定docker容器
load Load an image from a tar archive or STDIN #从一个tar包或标准输入中加载一个镜像[对应save]
login Log in to a Docker registry #
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
三. 镜像
1.镜像加载原理
1.UnionFS联合文件系统
Union文件系统(UnionFs)是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下( unite several directories into a single virtual filesystem)。Union文件系统是 Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
过程:docker 中的镜像是分层级的,拉取一个镜像(例如redis)的时候,这个镜像可能是由多个镜像文件叠加组成,拉取redis会发现分6层,有六个镜像文件,一个接着一个的拉取这些镜像文件,当本地有这些镜像文件会显示已存在;
好处:镜像分层,可以资源共享,轻量级,高性能。
查看某个镜像有哪些分层: docker image inspect 镜像名(例如:redis)
2.docker镜像加载原理
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs 文件系统:包含系统文件加载器bootloader和内核kernel;bootloader主要引导加载kernel,当机器启动时,先加载bootfs,bootloader加载内核kernel到内存(电脑从黑屏到亮屏),加载完成后内存的使用权由bootfs转换到 kernel,最后会卸载bootfs。
rootfs文件系统:bootfs之上是rootfs。包含的就是典型 Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。 rootfs就是各种不同的操作系统发行版,比如 Ubuntu, Centos等等。
3.深入理解
当下载这个大镜像redis6的时候,可能这个镜像所需的分层文件来自 镜像a的文件1,2,3,镜像b的文件4,5,6,一共六个layer(文件)。当要更新到redis7的时候只需要把文件7替换文件5就行。
**另外:我们下载的镜像是 只读 的,例如:我们run 镜像redis7 ,生成一个容器,那么我们的操作就会在redis7 上再加一层镜像层layer 保存我们的操作;之后我们打包dockerfile后,会把只读的redis7和 我们的操作 打包成新的镜像,发布出去。 **
2.commit 镜像
与git提交相似
docker commit -m=“描述” -a=“作者” 容器id 新的镜像名:[TAG]
四.数据卷
1.概念
当我们修改tomcat配置文件的时候需要 进入容器内部 修改文件,操作麻烦,我们能不能在宿主机linux 系统新建一个文件,通过修改这个文件,修改tomcat配置文件?
当mysql容器被删除,是不是 数据也被删除,当我们要把保存数据到本地,删除容器不删除数据,该怎么办?
mysql集群搭建,怎么做到数据共享?
于是,就有了数据卷;我们可以将 容器文件挂载到本地 ,修改本地数据会自动同步容器修改,删除容器,本地数据不会被删除,集群时可以保证数据共享;
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!
2. 使用数据卷
-
查看所有挂载情况: docker volume ls
-
目录挂载
-v 宿主机目录:容器需要挂载目录 (目录挂载:docker volume ls 是查看不到的)
-e 环境配置
-
具名挂载和匿名挂载
匿名挂载:-v 容器内路径!
docker run -d -P --name nginx01 -v /etc/nginx nginx具名挂载: -v 卷名:容器需要挂载目录
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxx(卷名)/_data
下
3. dockerfile 构建镜像的时候自动挂载卷
# 创建一个dockerfile文件,名字可以随便 建议Dockerfile
# 文件中的内容 指令(大写) 参数
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
#这里的每个命令,就是镜像的一层!
构建自己的镜像:docker build -f 创建的dockerfile的路径 -t tjh/centos2 .
-f 运行的dockerifle路径
-t 自定义镜像名病指定标签
. 当前目录 (一般在dockerfile所在目录)
docker inspect 容器id 可以看到启动的容器自动挂载到volume01,volume02
我们通常会构建自己的镜像,可以在构建镜像的时候自动挂载卷,也不可以不配置volume,通过 -v 手动挂载卷
4.数据卷容器
–volumes-from 容器id
docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
注意:若mysql01已经挂载,此时mysql01为数据卷容器,也是父容器;mysql01,mysql02挂载的volume01,volume02目录共享
五.dockerfile
1.dockerfile构建过程
- 新建dockerfile文件 (作为构建镜像的源文件)
- docker build 构建镜像
- docker run 测试修改
- dokcer push发布镜像
2.dockerfile文件命令详解
1.dockerfile配置
# DockerFile常用指令
FROM # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的, 姓名+邮箱 (已经遗弃,被LABEL代替)
LABEL # 为镜像添加元数据,元数以键值对的形式指定:LABEL version="1.0" description="这 是一个Web服务器" by="IT笔录"
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤,tomcat镜像,这个tomcat压缩包!添加内容 添加同目录
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 暴露端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承 DockerFile 这个时候就会运行ONBUILD的指令,触发指令。
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量!
2.测试
注:命令必须大写
FROM centos (FROM指定基础镜像)
MAINTAINER 姓名<邮箱>
RUN yum -y install vim 执行shell命令
RUN yum -y install net-tools 执行shell命令
ADD 宿主机JDK所在目录/jdk-8u231-linux-x64.tar.gz /usr/local #复制文件,/usr/local为复制到镜像
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV 环境变量设置
ENV JAVA_HOME /usr/local/jdk1.8.0_231 #设置环境变量
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.35 #设置环境变量
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib #设置环境变量 分隔符是:
VOLUME ["volume01","volume02"] 自定义挂载目录
WORKDIR 工作目录(即,启动容器时进入的目录)
EXPOSE 8080 #设置暴露的端口
CMD /usr/local/apache-tomcat-9.0.35/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.35/logs/catalina.out # 设置默认命令(此处表示启动容器时开启tomcat,并查看日志)
ENTRYPOINT 指定这个容器启动的时候要运行的命令,可以追加命令
CMD ["ls" "-a"] 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
CMD和ENTRYPOINT的区别
CMD指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT 指定这个容器启动的时候要运行的命令,可以追加命令
3. 新建自定义image
docker build -f 构建镜像所依赖的源文件 -t 自定义镜像名:标签 构建目录(为 . 代表当前目录)
注意:当 源文件命名为Dockerfile不用 -f 指定源文件 自定义镜像不能以"/"开头
4. 查看镜像构建历史
docker history 镜像ID
查看镜像构建历史,可以看见 image构建过程
5.给镜像重新命名或加tag
docker tag 镜像id image-name:tag
3.镜像发布
-
发布到dockerhub
docker login -u -p (登陆dockerhub)
docker push 镜像 (镜像名字:dockerhub账号名/镜像,例如:qiaokelitangdocker/mytomcat:tjh)
docker logout
-
发布到阿里云
容器镜像服务
创建 命名空间
创建自己的 镜像仓库
按阿里云提示在本机 登陆阿里云,push镜像
4.docker镜像操作流程
六. docker网络
1.docker 网络原理
docker 安装启动成功就会生成一个 网卡接口docker0 ,他在整个docker网络起到了 类似 网络路由的 作用。
假设docker 0 路由地址为172.17.0.1/16(16代表ip前缀为16位,即2个"."前一样的ip在同一网段),每当docker run 一个容器时,docker0会为 这个docker容器分配一个 IP地址,并且 会运用 veth-pair技术 生成一对 虚拟网络设备,一端连接网络协议栈,一端彼此相连。
2.命令
查看当前容器 网络ip信息: docker exec -it 容器id ip addr
查看当前容器 ip地址: docker exec -it 容器id cat /etc/hosts
容器之间互ping :docker exec -it 容器id ping ip地址
docker network : docker 网络命令
docker network ls 查看所有网络信息
docker network inspect 网络id
思考一个场景:我们编写了一个微服务,database url=ip: 项目不重启,数据ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器?
解决方式一:–link 绑定 指定容器, 会在当前容器的/etc/hosts 文件 加上指定容器名,然后直接ping 指定容器名
解决方式二:自定义网络,弥补docker0 无法ping 容器名 等 缺陷
3. --link
原理:就是给当前容器设置域名,类似linux 修改/etc/hosts文件
docker run -d -P --name tomcat03 --link tomcat01 tomcat:8
docker inspect tomcat03 可以看到相关links
然后可以直接 ping tomcat01 就能ping 通
4.自定义网络
我们run 一个容器时,默认使用网卡docker0,使用 --net bridge 桥接网
docker network create 自定义一个自己的网络
docker network create --driver bridge --subnet 192.168.0.0/16 – gateway 192.168.0.1 network-nginx (创建一个名为 network-nginx的网卡)
docker run 的时候指定 --net network-nginx 就会由network-nginx分配相同网段ip给容器,且这些容器之间可以直接通过 ping 容器名 的方式连通
5.网络互连
docker network connect 自定义网卡2 网卡1中容器container1
那么就把 container1 连接到网卡2 ,container1可以直接ping· 网卡2中容器
那么container1 单个容器就有两个ip
好处:网络隔离,高可用
例如:有redis集群使用网卡1,nginx集群使用网卡2,当 网络断时,不会导致所有服务死掉
七. docker compose
1.为什么使用docker-compose
当我们使用微服务或者集群的时候,使用Dokcerfile + Run 形式需要一个一个打包镜像,启动容器,且配置网络;
使用docker-compose 容器编排技术,帮助我们一键部署微服务,集群应用,且每个service内部的所有容器使用同一个网络,docker-compose 就是来管理我们的容器的;
2.docker-compose GET STARTED
docker compose 安装
使用国内下载地址:curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-uname -s
-uname -m
> /usr/local/bin/docker-compose
相关安装步骤看官网
使用步骤:
-
定义/打包 程序文件
-
为程序编写 Dockerfile文件
-
编写yaml文件
-
docker-compose up 运行docker-compose
如果启动失败 docker-compose up --build 重新构建
docker-compose 核心标签:services(每个service 其实对应一个容器,子标签对应容器的操作命令)
docker-compose up 最终生成一个project ,多个services,默认构建一个网络, 当前project的services公用这个网络
docker compose容器编排就是来管理这些services的
3. yaml文件详解
官方文档:https://docs.docker.com/compose/compose-file/
大概分成三层:
-
version: 与docker-compose相对应
-
services: 代表了多个service(子标签对应容器命令)
-
其他全局配置
八.docker swarm
1.docker 集群命令
docker swarm 命令
Commands:
ca Display and rotate the root CA
init Initialize a swarm
join Join a swarm as a node and/or manager
join-token Manage join tokens
leave Leave the swarm
unlock Unlock swarm
unlock-key Manage the unlock key
update Update the swarm
2. Raft协议
保证一个集群中至少有两个主节点可用
3.实践
-
初始化集群并添加节点到集群
docker swarm init --advertise-addr 172.17.55.130 在 172.17.55.130机器初始化一个集群
docker swarm join-token worker 为当前集群生成一个可加入worker的 token
docker swarm join-token manager 为当前集群生成一个可加入manager 的 token
docker node ls 查看集群内 节点状态信息
-
docker swarm 可以进行service 的扩缩容
docker service create --name swarm-nginx -p 8001:80 nginx 这个swarm-nginx服务会被随机分配在集群中的一台机器
docker service update --replicas 2 swarm-nginx 扩容swarm-ngixn服务为2个
docker service scale swarm-nginx=3 扩容swarm-nginx 服务为3个
docker service ps swarm-nginx 查看当前集群中的swarm-nginx服务
九.其他
docker scompose 单机版构建应用
docker stack 集群版构建 应用
docker secret
docker config