1 三要素

docker本身是一个容器运行载体或称之为管理引擎。我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个运行环境就是image镜像我呢见。只有通过这个镜像文件才能生成Docker容器实例;

image文件可以看作是容器的模板。Docker根据image文件生成容器的实例。同一个image文件,可以生成多个同时运行的容器实例。

  • 镜像:镜像中包含应用/服务运行所必需的操作系统和应用文件,一个镜像可以启动多个容器
  • 容器:run 镜像
  • 仓库:集中存放镜像,仓库分为公库和私库

    1.1 docker镜像分层

    就以pull tomacat为基础看,一看就是一层一层的下载,镜像是分层的,docker的每一层的都是可以被共享的; 因此我们只需要保存一份base镜像,其他镜像在base镜像上累加就行了;docker镜像层都是只读的,容器层是可写的;一般来说,最外层的是容器层,容器曾下面都是镜像层
    image.png

    1.1.1 UnionFS(联合文件系统)

    Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层一层的叠加镜像可以通过分层来进行继承

    2 安装docker

    环境:centos7,官方文档
  1. 卸载旧版本

    1. sudo yum remove docker \
    2. docker-client \
    3. docker-client-latest \
    4. docker-common \
    5. docker-latest \
    6. docker-latest-logrotate \
    7. docker-logrotate \
    8. docker-engine
  2. 设置镜像仓库,这里建议给阿里云的镜像环境

    $ sudo yum install -y yum-utils
    $ sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
  3. 安装Docker引擎

    $  sudo yum install docker-ce docker-ce-cli containerd.io
    
  4. 启动docker

    $  sudo systemctl start docker
    
  5. 启动一个helloword

    $  sudo docker run hello-world
    
  6. 查看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
image.png
在自己的虚拟机直接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

image.png
然后直接登录就行了。

3 docker命令

3.1 帮助启动类

启动docker:systemctl start docker
停止docker:systemctl stop docker
重启docker: systemctl restart docker
查看dockers状态:systemctl status docker
image.png
image.png

开机启动:systemctl enable docker
查看docker概要信息: docker info
查看docker总体帮助文档: docker —help
查看docker命令帮助文档: docker 具体命令 —help

3.2 镜像 命令

  1. 查看docker中所有镜像:docker images

image.png
REPOSITORY:镜像仓库源
TAG: 镜像的标签版本号
IMAGE ID:镜像id
CREATED:镜像创建时间
SIZE:镜像大小

  • -a 列出所有本地的镜像
  • -q 只显示镜像id
  1. 查询镜像 docker search [镜像名]
    1. —limit 只列出限制条数
  2. docker pull [镜像名字:TAG] 这里的TAG可以省略的
  3. 查看镜像/容器/数据卷所占的空间 docker system df
  4. 删除某个xxx镜像名字id dockers rmi
    1. -f 强制删除
    2. 删除多个 docker rmi 镜像id1 镜像id2 ……
  5. 镜像重命名:docker tag [source_image] [targer_image]

    3.3 容器命令

  6. 容器启动命令:docker run [OPTIONS] IMAGE [COMMAND] [ARG…]

    • docker run -it ubuntu
      • -i 以交互模式运行容器,通常与-t同时使用
      • -t 为容器重新分配一个伪输入终端

image.png

  - -p 端口映射 docker run -p 6380:6379 redis

说一下这个端口映射:下面的redis是放在容器内部的,redis默认端口给的是6379,但是我们访问这个redis的时候还需要再访问一下这个容器,才能进一步访问这个redis image.png

  - --name 指定容器的名称
  1. 查看所有的运行容器:docker ps
    • 查看所有容器包括历史启动:docker ps -a
    • -l 显示最近创建的容器 docker ps -l
    • -n 显示最近n个创建的容器 docker ps -n 2
    • -q:静默模式,只显示容器id
  2. 容器退出
    1. 使用 CTRL+P+Q 容器后台运行
    2. exit 容器退出,并且停止运行
  3. 启动已经停止的容器 docker start [容器id或者容器名字]
  4. 重启容器 docker restart [容器id或者容器名字]
  5. 停止容器 docker stop [容器id或者容器名字]
  6. 强制停止容器 docker kill [容器id或者容器名字]
  7. 删除已经停止的容器 docker rm [容器id或者容器名字]
    1. docker rm -f 强制删除,也就是说可以删除正在运行的容器
  8. 守护式容器,后台启动 docker run -d redis
  9. 查看启动日志 docker logs [容器id]
  10. 查看容器内部的进程 docker top [容器id]
  11. 查看容器内部信息 docker inspect [容器id]
  12. 进入正在运行的容器,并可以操作命令行 docker exec -it [容器id] /bin/bash
  13. 备份容器中的文件 : docker cp [容器id]:[文件地址] 主机地址
  14. 导出镜像:docker export [容器id] > 主机地址
  15. kill指定容器:docker kill [容器id]
  16. 容器自启动: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

image.png

  • 如果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

image.png

5.2 有啥用

容器数据卷的方式可以完成数据的持久化,docker容器中的数据保存到宿主主机中;
image.png

5.3 容器卷之间的继承

docker run -it —volumes-from u2 —name u1 ubuntu u1继承u2
u2:父容器 ;
两个容器的文件是相通的,借助主机文件映射;

6 DockerFile

6.1 什么是DockerFile

DockerFile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需要的指令和参数构成的脚本;

6.2 基本内容

  1. 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
  2. 指令从上到下顺序执行
  3. 表示注释

  4. 每条指令都会创建一个镜像层,并且进行提交

    6.3 保留字指令

  5. FROM:基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板

  6. MAINTAINER:镜像维护者的姓名和邮箱地址
  7. RUN:容器构建时需要运行的命令,RUN是在docker build的时候运行
  8. EXPOSE:当前容器开放的端口
  9. WORKDIR:指定容器创建后,终端默认登录的进来工作目录
  10. USER:指定该镜像以什么样的用户去执行,如果不指定,默认是root
  11. ENV:用来构建镜像的时候创建环境变量
  12. VOLUME:容器数据卷,用于数据保存和持久化工作
  13. ADD:将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包
  14. COPY:将宿主机目录文件拷贝进镜像中
  15. CMD:
    1. 指定容器启动后需要做的事情
    2. DockerFile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换
  16. 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 虚玄镜像

在我们创建镜像的时候可能会出现:
00285df0df87 5 days ago 342 MB
REPOSITORY TAG均为none,这个东西最好是别出现在容器里面,因此需要将其删除

$ docker images -f dangling=true
$ docker rmi $(docker images -q -f dangling=true)

7 docker 网络

image.png

7.1 常用命令

  1. 查看所有网络 :docker network ls

image.png

  1. 创建一个网络:docker network create aa_network

image.png

  1. docker network rm aa_network

image.png

  1. 查看docker网络的命令 docker network inspect bridge;可以看到跟宿主机的桥接名字”docker0”

image.png

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会改变,因此在使用的时候最好使用容器名

  1. 创建一个自己的网络

    docker network create zx_network
    
  2. 容器启动指定网络,c1是我自定义的镜像

    docker run -it --network zx_network --name zz1 c1
    docker run -it --network zx_network --name zz2 c1
    
  3. 尝试在zz1中ping zz2

    ping zz2
    

    image.png

    8 docker compose容器编排

    可以管理多个docker容器组成一个应用

    8.1 安装docker compose

    https://docs.docker.com/…

  4. 安装

    $ 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
    
  5. 赋权

    $ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
    
  6. 检查是否安装成功

    $ docker-compose --version
    

    8.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: