文章目录
要求版本
- 要求运行在CentOs 7(64位上),内核版本为3.8以上
- 用 cat /etc/redhat-release 和 uname -r 查看
三要素
- 镜像:类似java的class文件
- 容器:类似通过class new出来的对象,也是简易版本的linux运行环境,应用运行在这个环境上
- 仓库:存放镜像的地方
Client:用户客户端
Docker_host:linux运行环境
Docker daemon:安装在linux上的docker服务
Registry:dock镜像仓库
流程:客户端 在 安装了docker服务的linux上 找到镜像images(找不到就去仓库找),然后运行一个个的容器Containers
安装步骤
https://docs.docker.com/engine/install/centos/
1.卸载旧版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2.安装gcc相关
yum -y install gcc
yum -y install gcc-c++
3.安装相关软件包
yum install -y yum-utils
4.配置stable镜像仓库(国内)
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
5.重建yum索引
yum makecache fast
6.安装docker CE
yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
7.启动docker服务
systemctl start docker
8.hello world 测试
docker run hello-world
9.卸载
配置阿里云镜像以及加速
- 登录https://www.aliyun.com/
- 点击
- 获取镜像加速器地址
- 执行镜像配置
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["上面赋值的地址"]
}
EOF
systemctl daemon-reload
systemctl restart docker
命令
帮助命令
镜像命令
docker images 列出本地上的镜像 -a:列出本地所有的镜像(含历史堆叠) -q:只显示镜像id
docker search xxx 查找远程仓库中有没有对应镜像 --limit 5 前五个
docker pull xxx:[tag版本号] 下载镜像,不加tag默认最新
docker system df 查看镜像/容器/数据卷所占空间
docker rmi xxx 删除某个镜像名 -f 强制删除
docker rmi xxx xxx xxx 删除多个
docker rmi -f $(docker images -qa) 删除全部镜像
容器命令
启动容器
docker run [OPTIONS]IMAGE[COMMAND][ARG...]
常用 OPTIONS:
--name="容器新名字" 为容器指定一个新名字
-d: 后台运行容器并返回容器id,守护线程
-i: 以交互模式运行容器,通常与-t一起使用
-t:为容器重新分配一个伪输入终端 与-i同时使用
-P:随机端口映射 -p 6379:6379 docker容器的6379映射容器内服务的6379端口
-p:指定端口映射
测试
docker run -it ubuntu /bin/bash 以交互模式启动乌班图系统
exit 退出容器
罗列出所有正在运行的容器
docker ps
常用 OPTIONS:
-a:列出所有运行的容器和历史上运行过的容器
-l:显示最近创建的容器
-n xx:显示最近n个创建的容器
-q:只罗列容器id
退出容器
exit 交互模式中退出容器,会停止容器
ctrl+p+q:交互模式中退出容器,不会停止容器
启动容器,重启容器,停止容器,强制停止容器,删除已停止容器,重新进入容器
docker start 容器Id或者容器名字
docker restart 容器id或者服务名
docker stop 容器id或者服务名
docker kill 容器id或者服务名
#删除已停止容器
docker rm 容器id
# 强制删除容器
docker rm -f 容器id
# 删除所有容器
docker rm -f ${docker ps -a -q}
docker ps -a -q | xargs docker rm 把|前的结果放在xargs
# 重新进入容器
docker attach 容器id 不推荐,进入redis这种后台进程会直接卡死,退出后自动停止容器
docker exec -it 容器id /bin/bash 推荐 退出后容器不会停止
从容器中拷贝文件到本地,从本地拷贝到容器
#容器-》主机
docker cp 容器id:容器内地址 主机地址
docker cp 4364abb49dc4:/data/dump.rdb /root/foo/dump.rdb
#主机-》容器
docker cp 主机地址 容器id:容器内地址
docker cp /root/foo/a.txt 4364abb49dc4:/data/a.txt
导出导入容器
导出
docker export 容器id>文件名.tar
docker export 9d3e3a6d4514>a.tar
导入(为镜像)
cat 文件名.tar | docker import -镜像用户/镜像名:镜像版本号
cat a.tar | docker import - cyz/redis:6.29
守护式容器启动
ubuntu centos这种镜像生成的容器,一般需要进行交互,docker run -it ubuntu
redis 类似的镜像生成的容器,一般要作为后台使用 -d
使用镜像ubuntu以后台模式启动一个容器
docker run -d ubuntu
然后通过
docker ps -a发现,容器已经退出,docker机制就是容器后台运行,就必须有一个前台的进程,容器运行的命令如果不是那些一直挂起的命令top,tail等,就是会自动退出
前后台测试redis
前台交互(一旦ctrl+c 容器就自动停止了)
docker run -it redis:6.0.8
后台守护启动(可以一直存在)
docker run -d redis:6.0.8
为什么ubuntu会退出而redis不会退出。猜想应该是因为ubuntu没有执行挂起的命令了,认为这个已经没用了,所以停止,而redis会有tcp持续等待接收类似while(TRUE)所以-d后不会退出
查看容器的日志,查看容器内运行的进程,查看容器内部细节
#查看容器的日志
docker logs 容器id
#查看容器内运行的进程
docker top 容器id
#查看容器内部细节
docker inspect 容器id
镜像详解
- 镜像的分层
在pull一个镜像时都是一层一层进行下载
-
UnionFs 联合文件系统
是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。 -
镜像加载原理
bootfs:加载linux系统的引导程序
kernel:linux内核
rootfs:linux文件系统:类似乌班图,centos
加载时先根据bootfs引导kernel的加载,然后层层加载rootfs,因为bootfs基本一致,所以可以通用,只是rootfs有所差别
- 为什么docker要采用这种分层结构
最主要的就是共享资源,进行复用。就类似java的Object类。可以在其中扩展中一个Person类。
将Person打包成镜像,根据Person类又可以扩展出Man或者Women。Man或者Women又可以扩展出自己的子类,这就和联合文件系统思想类似。
*重点理解
Docker镜像层都是只读的,容器层是可写的
类似java中封装的概念,Container容器,就像是jdk提供的一些功能类。你可以继承这个类进行功能扩展。
而不能直接修改他的源码。也可以在你扩展这个类后打成jar包(commit 镜像)给他人使用,别人也只能继承你这个类扩展,而不能直接修改你的源码,层层堆叠。
发布自己的镜像
commit镜像
例:在默认下载的Ubuntu的操作系统是没有vim指令。现在要扩展这个指令并打包成自己的镜像。后面每一次生成容器就会自带vim的指令
#启动最基础的ubuntu的容器
docker run -it ubuntu /bin/bash
#接通外网下载vim指令(ubuntu容器中操作)
apt-get update
apt-get install vim
# commit提交自己的容器
docker commit -m="提交的信息" -a="作者" 容器Id 要创建的目标镜像名:[标签名]
docker commit -m="add vim" -a="ck" c0cab8aff270 cyz/myubuntu:0.69
大小已经发生改变,生成镜像成功
镜像发布
发布到阿里云
1.创建命名空间
2.创建镜像仓库
创建后有教程提示
# 登录远程阿里仓库
docker login --username=账号 registry.cn-hangzhou.aliyuncs.com
# 从Registry中拉取镜像(具体地址要看自己)
docker pull registry.cn-hangzhou.aliyuncs.com/cyzimages/cyz:[镜像版本号]
# 重命名镜像的名字
docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/cyzimages/cyz:[镜像版本号]
docker tag 86d92847ba9f registry.cn-hangzhou.aliyuncs.com/cyzimages/cyz:6.29
# 将镜像推送到Registry
docker push registry.cn-hangzhou.aliyuncs.com/cyzimages/cyz:[镜像版本号]
docker push registry.cn-hangzhou.aliyuncs.com/cyzimages/cyz:6.29
发布到私有库
# 拉取镜像
docker pull registry
# 启动 -v是容器卷相关命令 默认情况仓库被创建在/var/lib/registry目录下,建议自行用容器卷映射,方便联调
docker run -d -p 5000:5000 -v /cyz/myregistry/:/tmp/registry --privileged=true registry
# 查看私有库中有哪些镜像
ip add show 先查看自己的ip:eth0
curl -XGET http://192.168.0.xxx:5000/v2/_catalog
# docker默认不支持http 需要修改配置
vim /etc/docker/daemon.json 加上 ,[ip:端口] 如下图
# 重启(切记修改配置文件daemon.json不能出错,不然启动不起来)
systemctl status docker
#tag 自己的镜像名,要符合提交仓库的命名
docker tag 容器id 192.168.0.226:5000/ubuntu:0.01
#提交push到本地仓库
docker push 192.168.0.226:5000/ubuntu:0.01
#再次查看
curl -XGET http://192.168.0.xxx:5000/v2/_catalog
#拉到本地
docker pull 192.168.0.226:5000/ubuntu:0.01
容器数据卷
作用:将容器内的一些重要文件和宿主机文件进行绑定,做数据的持久化。类似redis的aof和rdb
命令格式 :docker run -it –privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名
privileged=true 为权限最好都要加,就算容器挂了,启动时也会同步最新数据
可以查看容器详细信息 来查看挂载关系
docker inspect 容器id
容器卷只读规则
只能在宿主机写入,容器内的目录只能读取
docker run -it ==--privileged=true== -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
容器卷之间的继承
作用:宿主机同步数据到容器1,容器1再可以同步到容器2
docker run -it --privileged=true --volumes-from 父类容器id 镜像id
docker run -it --privileged=true --volumes-from 3fd99d622192 ba6acccedd29
就算某个服务挂了,依然不会影响子类。再次上线后自动同步新数据
dockerFile
通过文件一条条命令来构建镜像。
1.每条保留字指令都必须为大写字母且后面要跟随至少一个参数
2.指令从上到下,顺序执行
3.#表示注解
4.每条指令都会创建一个新的镜像层并对镜像进行提交
保留字
FROM 基础镜像,当前新镜像是基于哪个镜像的,指定一个已存在的镜像,第一条必须是FROM
MAINTAINER 镜像的维护者 和 邮箱
RUN 容器构建时执行的命令 在build指令时执行的命令
#构建时在容器里安装vim(shell脚本形式)
RUN yum -y install vim
#exec形式
#RUN ["可执行文件","参数一","参数二"]
RUN ["./test.php","dev","offline"] 等价于 RUN ./test.php dev offline
EXPOSE 对外端口的映射
WORKDIR 容器启动后操控终端的落脚点
USER 指定什么用户能操作,不写默认root(一般不写)
ENV构建镜像过程中设置环境变量
#类似设置变量,在跳转落脚点,可以直接落在/usr/mytest
ENV MY_PATH /usr/mytest
WORKDIR $MY_PATH
ADD
类似COPY+解压,将宿主机上的文件拷贝到容器中,自动处理url或者tar解压
COPY
拷贝文件和目录到镜像中
COPY src dest
src=源文件
dest=目标地址(不用新建)
VOLUME 容器卷配置
CMD
指定容器启动后要做的事情,可以有多个CMD但是只会有最后一行的生效,CMD会被docker run后的参数替代,
上图是tomcat镜像dockerfile的最后一行,表示最后执行命令catalina.sh启动tomcat
# 对应指令,这样会默认执行catalina.sh
docker run -it -p 8080:8080 tomcat
# 覆盖指令,不会启动tomcat,等于加上了CMD["/bin/bash","run"]
docker run -it -p 8080:8080 tomcat /bin/bash
ENTRYPOINT
也是类似于CMD,但是不会被run命令后的指令替代,而且run后的指令会作为参数传给ENTRYPOINT
下面例子ENTRYPOINT等同于一定会执行的命令 nainx -c ,如果run后面不加别的 就执行CMD 加了就会替换CMD
根据dockerfile自定义一个镜像
# 编写dockerfile文件
# docker build -t 新镜像名字:TAG . <-(有一个点)
# docker run -it 新镜像名字:TAG
FROM ubuntu
MAINTAINER cyz<553490664@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN apt-get update
RUN apt-get install vim -y
RUN apt-get install net-tools -y
EXPOSE 80
CMD echo $MYPATH
CMD echo "hello,seccess~~~~~~~~~~~"
CMD /bin/bash
虚悬镜像
repositort 和 tag都为空的镜像,最好都删除
#找到所有虚悬镜像
docker image ls -f dangling=true
# 删除
docker image prune
Docker网络
主要作用就是docker容器和容器直接的相互沟通
启动docker后会出现一个虚拟网桥
四种网络模式的解释
- bridge 拥有自己的独立的网络,就好像一个人有一台手机
- host 都是用宿主机的
- none 基本不用,要自己配置
- container 蹭其他容器的网络配置
常用命令
docker network ls #查看网络
docker network create 网络名 #增加一个网络
docker network rm 网络名 #删除一个网络
docker network inspect 网络名 #查看一个网络细节
run容器的时候
beidge模式
docker0也相当于一个路由器,每个容器都连在这个路由器上,所以他们可以互相根据ip访问。
host模式
如果直接使用主机相同,端口映射将会无效。没有意义
none模式
只有一个localhost 其他网卡 ip啥都没有
container模式
偷别人的,要是端口映射相同。如果两个tomcat都是8080就会报错。而且如果主机停止了,从机也寄了
自定义网络
作用:默认docker0只能通过ip来进行容器间的互通,自定义网络可以用服务名来进行交互
#第一步先自定义自己的网络
docker network create cyz
# 第二步启动容器并且放在自己的网络上
docker run -it --network cyz --name cyz1 cyzubt:0.01
docker run -it --network cyz --name cyz2 cyzubt:0.01
# 测试ping容器的服务名 发现可以ping同 默认的哇docker0是不可以的
在cyz1中ping cyz2
Docker-composer
作用:容器太多的情况下,控制他们的先后启动顺序,复用,类似启动java项目之前,必须要先启动mysql或者redis。
下载安装
官网(docker version查看版本,要对应版本下载)
https://docs.docker.com/compose/compose-file/compose-file-v3/
下载地址:https://docs.docker.com/compose/install/
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version
常用命令
docker-compose.yml
version: "3"
services:
microService:
image: zzyy_docker:1.6
container_name: ms01
ports:
- "6001:6001"
volumes:
- /app/microService:/data
networks:
- atguigu_net
depends_on:
- redis
- mysql
# 没有command因为在docker file构建容器中已经添加启动命令
redis:
image: redis:6.0.8
ports:
- "6379:6379"
volumes:
- /app/redis/redis.conf:/etc/redis/redis.conf
- /app/redis/data:/data
networks:
- atguigu_net
command: redis-server /etc/redis/redis.conf
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: '123456'
MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
MYSQL_DATABASE: 'db2021'
MYSQL_USER: 'zzyy'
MYSQL_PASSWORD: 'zzyy123'
ports:
- "3306:3306"
volumes:
- /app/mysql/db:/var/lib/mysql
- /app/mysql/conf/my.cnf:/etc/my.cnf
- /app/mysql/init:/docker-entrypoint-initdb.d
networks:
- atguigu_net
command: --default-authentication-plugin=mysql_native_password #解决外部无法访问
networks:
atguigu_net:
自定义了网络所以服务中配置文件可以用服务名来
spring.datasource.url=jdbc:mysql://mysql:3306/db2021?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.redis.host=redis