1 三要素
docker本身是一个容器运行载体或称之为管理引擎。我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个运行环境就是image镜像我呢见。只有通过这个镜像文件才能生成Docker容器实例;
image文件可以看作是容器的模板。Docker根据image文件生成容器的实例。同一个image文件,可以生成多个同时运行的容器实例。
- 镜像:镜像中包含应用/服务运行所必需的操作系统和应用文件,一个镜像可以启动多个容器
- 容器:run 镜像
- 仓库:集中存放镜像,仓库分为公库和私库
1.1 docker镜像分层
就以pull tomacat为基础看,一看就是一层一层的下载,镜像是分层的,docker的每一层的都是可以被共享的; 因此我们只需要保存一份base镜像,其他镜像在base镜像上累加就行了;docker镜像层都是只读的,容器层是可写的;一般来说,最外层的是容器层,容器曾下面都是镜像层
1.1.1 UnionFS(联合文件系统)
Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层一层的叠加;镜像可以通过分层来进行继承。2 安装docker
环境:centos7,官方文档
卸载旧版本
sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine
设置镜像仓库,这里建议给阿里云的镜像环境
$ sudo yum install -y yum-utils $ sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo安装Docker引擎
$ sudo yum install docker-ce docker-ce-cli containerd.io启动docker
$ sudo systemctl start docker启动一个helloword
$ sudo docker run hello-world查看docker版本
$ docker version在这里可以看到docker有个客户端以及守护进程 ```shell Client: Docker Engine - Community Version: 20.10.12 API version: 1.41 Go version: go1.16.12 Git commit: e91ed57 Built: Mon Dec 13 11:45:41 2021 OS/Arch: linux/amd64 Context: default Experimental: true
Server: Docker Engine - Community Engine: Version: 20.10.12 API version: 1.41 (minimum version 1.12) Go version: go1.16.12 Git commit: 459d0df Built: Mon Dec 13 11:44:05 2021 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.4.12 GitCommit: 7b11cfaabd73bb80907dd23182b9347b4245eb5d runc: Version: 1.0.2 GitCommit: v1.0.2-0-g52b36a2 docker-init: Version: 0.19.0 GitCommit: de40ad0
出现以上就代表安装成功了。。。。
7. 卸载docker
```shell
// 如果启动了docker需要将其关闭
$ systemctl stop docker
// 卸载docker
$ sudo yum remove docker-ce docker-ce-cli containerd.io
// 删除本地文件
$ sudo rm -rf /var/lib/docker
$ sudo rm -rf /var/lib/containerd
2.1 配置阿里云镜像加速器
https://juejin.cn/post/6902255510469214222
在自己的虚拟机直接cv操作就行了,但是在拉取镜像的时候可能会出错:
Error response from daemon: pull access denied for tomacat, repository does not exist or may require ‘docker login’: denied: requested access to the resource is denied
3 docker命令
3.1 帮助启动类
启动docker:systemctl start docker
停止docker:systemctl stop docker
重启docker: systemctl restart docker
查看dockers状态:systemctl status docker

开机启动:systemctl enable docker
查看docker概要信息: docker info
查看docker总体帮助文档: docker —help
查看docker命令帮助文档: docker 具体命令 —help
3.2 镜像 命令
- 查看docker中所有镜像:docker images

REPOSITORY:镜像仓库源
TAG: 镜像的标签版本号
IMAGE ID:镜像id
CREATED:镜像创建时间
SIZE:镜像大小
- -a 列出所有本地的镜像
- -q 只显示镜像id
- 查询镜像 docker search [镜像名]
- —limit 只列出限制条数
- docker pull [镜像名字:TAG] 这里的TAG可以省略的
- 查看镜像/容器/数据卷所占的空间 docker system df
- 删除某个xxx镜像名字id dockers rmi
- -f 强制删除
- 删除多个 docker rmi 镜像id1 镜像id2 ……
镜像重命名:
docker tag [source_image] [targer_image]3.3 容器命令
容器启动命令:docker run [OPTIONS] IMAGE [COMMAND] [ARG…]
- docker run -it ubuntu
- -i 以交互模式运行容器,通常与-t同时使用
- -t 为容器重新分配一个伪输入终端
- docker run -it ubuntu

- -p 端口映射 docker run -p 6380:6379 redis
说一下这个端口映射:下面的redis是放在容器内部的,redis默认端口给的是6379,但是我们访问这个redis的时候还需要再访问一下这个容器,才能进一步访问这个redis
- --name 指定容器的名称
- 查看所有的运行容器:docker ps
- 查看所有容器包括历史启动:docker ps -a
- -l 显示最近创建的容器 docker ps -l
- -n 显示最近n个创建的容器 docker ps -n 2
- -q:静默模式,只显示容器id
- 容器退出
- 使用 CTRL+P+Q 容器后台运行
- exit 容器退出,并且停止运行
- 启动已经停止的容器 docker start [容器id或者容器名字]
- 重启容器 docker restart [容器id或者容器名字]
- 停止容器 docker stop [容器id或者容器名字]
- 强制停止容器 docker kill [容器id或者容器名字]
- 删除已经停止的容器 docker rm [容器id或者容器名字]
- docker rm -f 强制删除,也就是说可以删除正在运行的容器
- 守护式容器,后台启动 docker run -d redis
- 查看启动日志 docker logs [容器id]
- 查看容器内部的进程 docker top [容器id]
- 查看容器内部信息 docker inspect [容器id]
- 进入正在运行的容器,并可以操作命令行 docker exec -it [容器id] /bin/bash
- 备份容器中的文件 : docker cp [容器id]:[文件地址] 主机地址
- 导出镜像:docker export [容器id] > 主机地址
- kill指定容器:docker kill [容器id]
- 容器自启动:docker update —restart=always [容器id]
4 发布镜像
修改原有的镜像,生成一个新的镜像。
4.1 发布到阿里云
修改一个镜像后,直接commit本地一个新的镜像
docker commit -m=”add vim cmd” -a=”zx” [容器id] zhang/ubuntu:1.1
docker login —username=[用户id] registry.cn-hangzhou.aliyuncs.com
- docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/zhangrep/xixihaha:[镜像版本号]
docker push registry.cn-hangzhou.aliyuncs.com/zhangrep/xixihaha:[镜像版本号]
4.2 私库
先拉一个本地的镜像仓库 docker pull registry
- 启动仓库 : docker run -d -p 5000:5000 -v /zhang/myrefistry/:/tmp/registry —privileged=true registry
- 查看仓库中的镜像:curl -XGET http://192.168.233.128:5000/v2/_catalog

如果docker不支持http方式推送镜像==> vi /etc/docker/daemon.json
“insecure-registries”: [“192.168.233.128:5000”]
拉取镜像:docker pull 192.168.233.128:5000/redis1:1.0
5 容器数据卷
5.0 解决权限问题
docker挂载主机访问如果出现cannot open directory .: Permission denied,
解决方法:在挂载目录后多加一个—privileged=true参数即可
5.1 操作命令
docker run -d -p 5000:5000 -v /zhang/myrefistry/:/tmp/registry —privileged=true registry/zhang/myrefistry/:/tmp/registry:左边的是宿主机文件,右边的是容器内部文件
这就意味着宿主机上的 /zhang/myrefistry/目录中有的文件,容器中在/tmp/registry目录中也存在着,做了映射就算容器关闭,重新启动后仍然会存在。
现在不让使用者在容器内修改映射文件,因此将容器里面的权限设置为只读:容器目录:ro(read only)
docker run -it -v /zhang/u2:/tmp/u2:ro —name=u2 ubuntu

5.2 有啥用
容器数据卷的方式可以完成数据的持久化,docker容器中的数据保存到宿主主机中;
5.3 容器卷之间的继承
docker run -it —volumes-from u2 —name u1 ubuntu u1继承u2
u2:父容器 ;
两个容器的文件是相通的,借助主机文件映射;
6 DockerFile
6.1 什么是DockerFile
DockerFile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需要的指令和参数构成的脚本;
6.2 基本内容
- 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
- 指令从上到下顺序执行
表示注释
-
6.3 保留字指令
FROM:基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板
- MAINTAINER:镜像维护者的姓名和邮箱地址
- RUN:容器构建时需要运行的命令,RUN是在docker build的时候运行
- EXPOSE:当前容器开放的端口
- WORKDIR:指定容器创建后,终端默认登录的进来工作目录
- USER:指定该镜像以什么样的用户去执行,如果不指定,默认是root
- ENV:用来构建镜像的时候创建环境变量
- VOLUME:容器数据卷,用于数据保存和持久化工作
- ADD:将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包
- COPY:将宿主机目录文件拷贝进镜像中
- CMD:
- 指定容器启动后需要做的事情
- DockerFile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换
- ENTRYPOINT:可以和CMD一起用,一般是变参才会使用CMD,这里的CMD等于是在给ENTRYPOINT传参。
6.4 自定义centos
一个原本的centos安装了jdk8,vim,network
FROM centos
MAINTAINER zhangxun<zhangxun_a@si-tech.com.cn>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
RUN mkdir /docker-java-home
COPY ./jdk-8u301-linux-x64.tar.gz /docker-java-home
RUN mkdir /docker-java-home/jdk8
RUN tar -zxvf /docker-java-home/jdk-8u301-linux-x64.tar.gz -C /docker-java-home/jdk8
ENV JAVA_HOME /docker-java-home/jdk8/jdk1.8.0_301
ENV JAVA_VERSION 8u171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/libtools.jar:$JAVA_HOME/lib:$JAVA_HOME
ENV PATH $JAVA_HOME/bin:$PATH
6.5 虚玄镜像
在我们创建镜像的时候可能会出现:
REPOSITORY TAG均为none,这个东西最好是别出现在容器里面,因此需要将其删除
$ docker images -f dangling=true
$ docker rmi $(docker images -q -f dangling=true)
7 docker 网络
7.1 常用命令
- 查看所有网络 :docker network ls

- 创建一个网络:docker network create aa_network

- docker network rm aa_network

- 查看docker网络的命令 docker network inspect bridge;可以看到跟宿主机的桥接名字”docker0”
7.2 网络模式
| 网络模式 | 简介 | 命令 |
|---|---|---|
| bridge | 为每一个容器分配、设置ip等,并将容器连接到一个docker0虚拟网桥,默认为该模式 |
docker |
| host | 容器将不会自己虚拟出网卡、配置自己的ip等,而是使用宿主机的IP和端口 | |
| none | 容器有独立的Network namespace,但是并没有对其进行任何网络设置,如分配veth pair和网桥连接,ip等 | |
| container | 新创建的容器不会创建自己的=网卡和配置自己的IP,而是和一个指定的容器共享IP、端口范围等 |
7.2.1 bridge
Docker服务默认会创建一个docker0网桥(其上有一个docker0内部接口),该网桥的名称为docker0,它在内核层连通了其他的物理或虚拟网卡,这将所有的容器和本地主机都放在同一个物理网络。Docker默认指定了docker0接口的IP地址和子网掩码,让主机和容器之间可以通过网桥相互通信。
点击查看【processon】
可以从上图看到每一个容器都是并列的,之间并没有什么交互,容器之间所有的交互都需要通过docker0(网桥)去相连。宿主机跟docker也是通过网桥;
7.2.2 docker自定义网络
为了容器的分类;因为镜像每次启动的时候可能ip会改变,因此在使用的时候最好使用容器名
创建一个自己的网络
docker network create zx_network容器启动指定网络,c1是我自定义的镜像
docker run -it --network zx_network --name zz1 c1 docker run -it --network zx_network --name zz2 c1尝试在zz1中ping zz2
ping zz28 docker compose容器编排
8.1 安装docker compose
安装
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose赋权
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose检查是否安装成功
$ docker-compose --version8.2 核心概念
一个文件:docker-compose.yml
服务(service):一个个应用容器实例,比如订单微服务、库存微服务、mysql容器
工程(project):由一组关联的应用容器组成的一个完整业务的单元,在docker-compose.yml文件中定义
8.3 文件分析
version: "3"
services:
microService: # 自定义一个service,microService自己取名字
image: ms01 # 镜像名称
container_name: dm # 启动后的容器名称
ports: # 开放的端口
- "8080:8080"
volumes: # 容器卷
- /app/microService:/data
networks: # 指定网络,可以看到最后一行的 networks
- atguigu_net
depends_on: # 依赖启动
- redis
- mysql
redis:
image: redis
ports:
- "6379:6379"
volumes:
- /root/redis/config/redis/redis.conf:/etc/redis/redis.conf
- /app/redis/data:/data
networks:
- atguigu_net
command: redis-server /etc/redis/redis.conf # 就跟咱们的cmd一样
mysql:
image: mysql:5.7.36
environment: # 环境变量
MYSQL_ROOT_PASSWORD: 'root'
MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
MYSQL_DATABASE: 'test'
MYSQL_USER: 'zz'
MYSQL_PASSWORD: 'root'
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:


