目录

  1. 一、Docker 简介
  2. 二、Docker 概述和常用命令
    1. 1. Docker 整体理解
    2. 2. 辅助命令及学习网站
    3. 3. 镜像命令
    4. 4. 容器命令
    5. 5 常用命令汇总
    6. 6 Docker 镜像理解
    7. 7 commit镜像
  3. 三、Docker 进阶
    1. 0 可视化管理docker
    2. 1. 容器数据卷
    3. 2. DockerFile 构建镜像
      1. 数据卷容器
      2. DockerFile
      3. DockerFile 构建过程及指令
        1. CMD 和 ENTRYPOINT 的区别
    4. 3.Docker 网络原理
      1. Docker0
      2. 容器互联
        1. –link (入门互联 通过名字ping通两个容器)
        2. 自定义网络(高级互联)
          1. 网络模式
          2. 默认网络
          3. 自定义网络
        3. 网络连通
    5. 4.IDEA 整合 Docker
    6. 5.Docker Compose 集群管理
    7. 6. Docker Swarm 容器编排
    8. 7.CI/CD jenkins
  4. 四、深入理解Docker
    1. 读文档
  • 五、项目练习
    1. 1 Docker 部署Nginx
    2. 2 使用docker来装一个tomcat
    3. 3 部署 es + kibana
    4. 4 安装并挂载mysql
    5. 5 DockerFile 构建镜像
    6. 6 tomcat 镜像
    7. 7 redis集群部署
  • 一、Docker 简介

    根据百度百科的介绍:

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。

    Docker采用的是Go语言编写的,该语言一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言,常用于Web程序开发,并且具有成熟的Web开发框架,如Beego、Gin、Iris等等。

    Go语言描述

    Go的语法接近C语言,但对于变量的声明有所不同。Go支持垃圾回收功能。

    二、Docker 概述和常用命令

    1. Docker 整体理解

    576507-docker1.png

    docker解决问题:项目带上环境安装打包,可以跨平台(windows–>Linux)

    Docker和VM对比

    Vmware,虚拟电脑,很笨重,属于虚拟化技术

    ​ dockers容器技术也是一种虚拟化技术

    docker:隔离,镜像(最核心的环境)十分小巧

    • 传统虚拟机,虚拟出一套硬件,运行一个完整的操作系统,然后在这个操作系统上安装和运行软件
    • 容器内的应用直接运行在宿主机的内核上,容器没有自己的内核,也没有虚拟硬件,因此更为轻便。每个容器之间是互相隔离的,每个容器内都有一个属于自己的文件系统,且互不影响

    Docker有着比虚拟机更少的抽象层。

    1676711860958

    Docker利用的是宿主机的内核,VM用的是Guest OS,因此,新建容器时,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导。VM是分钟级的,docker是秒级的

    1676712052236

    学习路径:先学会传统虚拟机上如何部署环境,再学习Docker

    概述:基于Go语言开发,开源

    docker基本组成

    镜像(Image):镜像是一个原始模板,通过模板来创建容器

    容器(container):容器是来提供服务的。启动,停止,删除等等

    仓库(repository):仓库是用来存放镜像的地方,类似与github、gitee等等,分为共有私有。docker hub 在国外,需要配置国内的镜像加速。

    **安装基本步骤(cnetos8)**:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    1. 卸载旧版本
    sudo yum remove docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine

    2. 安装相关依赖
    sudo yum install -y yum-utils

    3. 设置国内yum镜像源
    国外源:sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    阿里云国内源安装docker:sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo


    4. 更新yum软件包索引
    centos8 无fast参数:yum makecache
    yum makecache fast

    5. 安装docker
    最新版的安装方式(2023/2/18):docker-ce社区版;docker-ee企业版
    sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

    一路按 y

    6. 启动docker
    sudo systemctl start docker

    7. 验证安装成功
    docker version

    8. 通过启动镜像验证安装成功
    sudo docker run hello-world

    9. 查看镜像是否已经被下载
    docker images

    10. 卸载docker
    a. 卸载依赖
    sudo yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
    b. 删除资源
    sudo rm -rf /var/lib/docker
    sudo rm -rf /var/lib/containerd

    11. 设置阿里云docker镜像加速
    登录阿里云官方,找到“容器镜像服务”--> 镜像工具 --> 镜像加速器
    选择所使用的操作系统,按照步骤来配置,下面的命令依次敲:
    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
    "registry-mirrors": ["https://自己的仓库地址,你猜.mirror.aliyuncs.com"]
    }
    EOF
    sudo systemctl daemon-reload
    sudo systemctl restart docker

    Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上通过Socket从客户端访问。DockerServer接收到Docker-Client的指令就会执行。容器内的端口映射到宿主机的端口。

    1676711593560

    2. 辅助命令及学习网站

    docker官网

    docker hub 仓库地址

    1
    2
    3
    4
    5
    6
    # 查看操作系统的发行版号
    uname -r
    # 显示系统名、节点名称、操作系统的发行版号、内核版本等等
    uname -a
    # 查看虚拟机系统版本信息
    cat /etc/os-release

    帮助命令:

    1
    2
    3
    4
    5
    6
    # 显示docker的版本信息
    docker version
    # 显示docker系统信息,包括镜像和容器的数量
    docker info
    # 帮助万能命令
    docker 命令 --help

    docker命令帮助文档地址:https://docs.docker.com/reference/

    菜鸟教程中文地址:Docker 命令大全 | 菜鸟教程 (runoob.com)

    3. 镜像命令

    docker images 查看镜像

    1
    2
    3
    4
    docker images
    # 常用参数
    -a, --all Show all images (default hides intermediate images)
    -q, --quiet Only show image IDs

    a. 通过官方文档来学习命令:https://docs.docker.com/engine/reference/commandline/images/

    b. 通过help来学习docker images --help

    1
    2
    3
    4
    # 相当于在docker hub上搜索
    docker search mysql
    # 过滤出收藏量大于3000的,且展示详细信息
    docker search mysql --filter=STARS=3000 --no-trunc
    1
    2
    # 列出images完整id
    docker images --no-trunc

    docker pull 下载镜像

    1
    docker pull 镜像名:tag

    不写tag默认下载最新版本,docker images 分层下载,是image的核心,联合文件系统。

    pull中的design是签名,最后一行为真实地址

    1
    2
    3
    # pull mysql等价于从真实地址去拉取
    docker pull mysql
    docker pull docker.io/library/mysql:latest

    docker rmi 删除镜像

    1
    2
    3
    4
    docker rmi -f 镜像id
    docker rmi repository:tag
    # 删除所有镜像
    docker rmi -f $(docker images -aq)

    4. 容器命令

    前提,先pull一个镜像

    1
    docker pull centos

    docker run 启动容器

    docker run | Docker Documentation

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
    # 如果没有下载启动时会自动下载,默认下载最新版本
    # 常用参数
    --name 给容器命名
    -d 后台方式启动(后台运行时如果没有前台进程,docker发现没有应用就会自动停止)
    -i 交互式操作
    -t 终端
    -p 指定容器的端口,将容器端口映射到主机 -p 8080:8080
    -p 主机端口:容器端口 (最常用的一种方式)
    -p 容器端口
    容器端口
    ip ip:主机端口:容器端口
    -P 大写的P是随机指定端口

    启动一个容器:

    1
    docker run -it centos /bin/bash

    非后台启动,退出命令为:exit

    1
    2
    3
    4
    5
    6
    # 列出正在运行的容器
    docker ps
    # 常用参数
    -a 列出所有,包括历史曾运行过的容器
    -n=1 只显示最近的一个
    -q 只显示容器的编号

    退出容器

    1
    2
    3
    4
    # 直接停止并退出
    exit
    # 容器不停止退出
    Ctrl + P + Q

    删除容器

    1
    2
    3
    4
    5
    6
    # 删除指定容器
    docker rm 容器id
    # 删除所有的容器
    docker rm -f $(docker ps -aq)
    # 通过管道符过滤删除
    docker ps -a -q|xargs docker rm

    启动容器

    1
    2
    3
    4
    5
    6
    7
    8
    # 启动容器
    docker start 容器id
    # 重启容器
    docker restart 容器id
    # 停止当前正在运行的容器
    docker stop 容器id
    # 强制停止当前容器
    docker kill 容器id

    5 常用命令汇总

    查看日志

    docker logs | Docker Documentation

    1
    2
    3
    4
    5
    docker logs 容器id
    # 常用参数
    -f : 跟踪日志输出,持续输出日志内容
    -t : 显示时间戳
    --tail/-n :仅列出最新N条容器日志 -n 15
    1
    2
    3
    4
    5
    6
    # shell 脚本
    "while true;do echo docker;sleep 1;done"
    # 重新启动一个容器,运行shell脚本,使其不断打印,产生日志
    docker run -d centos /bin/sh -c "while true;do echo docker;sleep 1;done"
    # 查看容器日志
    docker logs -t -f -n 10 71f8b56ac14e

    查看容器中的进程信息

    1
    2
    3
    4
    5
    docker top 容器id
    # 显示
    UID 用户ID
    PID 父ID
    PPID 进程ID

    查看镜像的元数据

    1
    docker inspect 容器id

    进入当前正在运行的容器

    1
    2
    3
    4
    5
    # 进入容器后开启新终端(常用)
    docker exec -it 容器id/name bashShell

    # 例:
    docker exec -it 71f8b56ac14e /bin/bash
    1
    2
    3
    # 进入容器正在执行的终端,不会启动新的进程
    docker attach 容器id
    # Attach local standard input, output, and error streams to a running container

    从容器内拷贝文件到主机

    1
    2
    3
    docker cp 容器id:容器内路径 目的的主机路径

    docker cp 9d140e95797a:/home/a.txt /home

    官方图:

    1676816820100

    6 Docker 镜像理解

    镜像是独立的软件包

    Docker镜像加载原理为**UnionFS (联合文件系统)**,镜像可以通过分层来进行继承,基于基础镜像,制作复制具体的应用镜像。

    docker的镜像实际上有一层一层的文件系统组成,这种层级的文件系统就是UnionFS。

    bootfs(boot file system) linux刚启动时会加载bootfs文件系统,Dcker也是一样的,加载完成后整个内核就在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs

    rootfs(root file system) ,在bootfs之上。包含的就是典型Linux系统中的 /dev, /proc, /bin, /etc 等标准目录和文件,rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等

    为什么Docker中的centos很小?

    因为rootfs中只包含了最基本的命令、工具和程序库,直接用的是主机的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。

    分层

    分层进行复用。

    Docker的镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层就是我们说的容器层,容器之下只读,无法改变的部分都叫做镜像层。

    7 commit镜像

    1
    2
    3
    docker commit 提交容器成为一个新的副本

    docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
    1
    2
    3
    4
    5
    6
    项目练习2 拷贝tomcat基本镜像

    docker commit -a="Abilish" -m="add webapps app" 236dffd55cf1 tomcat02:1.0

    # 查看自己提交的镜像
    docker images

    三、Docker 进阶

    0 可视化管理docker

    portainer

    1
    docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

    设置登录密码,选择本地(local)

    Rancher(CI/CD)

    1
    待补充

    挂载分为使用命令挂载,以及用DockerFile挂载两种方式。

    1. 容器数据卷

    产生原因:数据和容器分离,数据单独独立,持久化保存。

    MySQL数据可以存储在本地。容器之间可以有一个数据共享的技术。Docker 容器中产生的数据剋同步到本地,因此产生了目录挂载目录挂载就是容器内和容器外连接的目录是同步更新的。

    方式一:使用命令挂载

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    docker run -it -v 主机目录:容器目录

    docker run -it -v /home/test:/home centos /bin/bash
    # 可以查看到容器的挂载信息
    docker inspect 容器id
    ......
    "Mounts": [
    {
    "Type": "bind",
    "Source": "/home/test",
    "Destination": "/home",
    "Mode": "",
    "RW": true,
    "Propagation": "rprivate"
    }
    ......
    # 容器删除,本机上挂载的数据依旧存在

    具名挂载和匿名挂载

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    # 匿名挂载:只写容器内名字不写容器外名字
    -v 容器内路径
    docker run -d -P --name nginx01 -v /etc/nginx nginx
    # 查看本地所有的卷的情况,显示的是没有名字的这就是匿名挂载
    docker volume ls


    # 具名挂载
    docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
    docker volume ls
    # 可以看到挂载的名字为 juming-nginx
    # 查看这个卷的位置
    docker volume inspect juming-nginx

    {
    "CreatedAt": "2023-02-22T22:48:38+08:00",
    "Driver": "local",
    "Labels": null,
    "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data", # 此参数为挂载的目录位置
    "Name": "juming-nginx",
    "Options": null,
    "Scope": "local"
    }

    # 在没有指定目录的情况下,基本所有的卷都在这个位置 /var/lib/docker/volumes/卷名/_data

    docker volume –help

    总结:挂载的方式总共分为三种,指定路径挂载、匿名挂载、具名挂载

    其他:

    1
    2
    3
    4
    5
    6
    7
    8
    # 挂载目录后面加上 ro 或者 rw
    # ro 表示 read only 只读
    # rw 表示 read write 可读可写

    # 默认为 rw
    # 设置的容器权限。如果是 ro ,那么在容器内部是只读的,无法改变,只能通过宿主机改变
    docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
    docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx

    2. DockerFile 构建镜像

    挂载方式二

    Dockerfile 就是用来构建 docker 镜像的构建文件,是命令脚本,通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个一个命令,每个命令都是一层。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    # 1 新建一个dockerfile01文件,编辑,写入如下的命令:

    FROM centos

    VOLUME ["volume01","volume02"]

    CMD echo "----end----"
    CMD /bin/bash

    # 文件中的内容,或者指令都是大写的

    # 2 docker build 命令构建镜像
    docker build -f dockerfile01 -t abilish/centos:1.0 .

    # 常用参数
    -f file文件名
    -t 生成的镜像及标签名 Name and optionally a tag in the name:tag format

    # 3 执行后可以看到成功生成的镜像
    docker images

    # 4 启动镜像
    docker run -it afa669b6bce7 /bin/bash
    ls
    # 可以看到其中的两个目录:volume01、volume02,这两个目录就是刚刚挂载的目录
    docker inspect 容器id
    # 可以查到主机中挂载的位置

    如果在构建镜像时没有设置挂载,那么需要在启动镜像时设置 -v 挂载参数

    数据卷容器

    多个容器之间实现数据同步

    被挂载的叫做父容器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    --volumes-from 

    docker run -it --name docker01 abilish/centos:1.0
    # 启动第二个镜像并进行挂载
    docker run -it --name docker02 --volumes-from docker01 abilish/centos:1.0
    # volume01、volume02 镜像之间会同步更新
    docker run -it --name docker03 --volumes-from docker01 abilish/centos:1.0

    # 停止父容器,在其他容器中(docker02、docker03)挂载目录依旧同步,
    # 其他的容器中之前创建的文件不会消失

    # 删除父容器,docker02、docker03 之间挂载目录的数据依旧时同步的
    docker rm -f docker01

    问题(待解决):如果两个容器有不同数量的挂载目录呢?如果挂载之前每个容器中有不同的数据,能合并吗?

    同理,mysql中也就可以实现数据同步了

    容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止

    但是一但持久化到了本地,就可以持久化保存了

    DockerFile

    概念:dockerfile 是用来构建docker镜像的文件,命令参数脚本

    构建步骤:

    1、编写一个 dockerfile 文件

    2、docker build 构建成为一个镜像

    3、docker run 运行镜像

    4、docker push 发布镜像(DockerHub或者阿里云镜像库)

    centos为例:

    sig-cloud-instance-images/Dockerfile at b2d195220e1c5b181427c3172829c23ab9cd27eb · CentOS/sig-cloud-instance-images (github.com)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    FROM scratch
    ADD centos-7-x86_64-docker.tar.xz /

    LABEL \
    org.label-schema.schema-version="1.0" \
    org.label-schema.name="CentOS Base Image" \
    org.label-schema.vendor="CentOS" \
    org.label-schema.license="GPLv2" \
    org.label-schema.build-date="20201113" \
    org.opencontainers.image.title="CentOS Base Image" \
    org.opencontainers.image.vendor="CentOS" \
    org.opencontainers.image.licenses="GPL-2.0-only" \
    org.opencontainers.image.created="2020-11-13 00:00:00+00:00"

    CMD ["/bin/bash"]

    大多数官方的镜像都是基础包,用户需要自定义搭建镜像

    DockerFile 构建过程及指令

    基础知识:

    1、每个保留关键字(指令)都必须是大写字母

    2、执行从上到下顺序执行

    3、# 表示注释

    4、每一个指令都会创建提交一个新的镜像层

    DockerFile 是面向开发的,用来发布项目,做镜像

    指令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    FROM        # 基础镜像
    MAINTAINER # 镜像是谁写的,维护者信息,姓名+邮箱
    RUN # 镜像构建的时候需要运行的命令
    ADD # 步骤,tomcat镜像,上传压缩包,会自动解压
    WORKDIR # 镜像的工作目录
    VOLUME # 挂载的目录
    EXPOSE # 指定端口,这里写了就不用指定 -p 了
    CMD # 指定这个容器启动的时候要运行的命令,是替换命令行中的命令
    ENTRYPOINT # 指定这个容器启动的时候要运行的命令,是在命令行命令后追加命令
    ONBUILD # 当构建一个被继承 DockerFile 这个时候就会运行 ONBUILD 的指令,触发指令。
    COPY # 类似 ADD ,将我们文件拷贝到镜像中
    ENV # 构建的时候设置环境变量
    1
    2
    # 查看构建历史
    docker history 镜像id

    CMD 和 ENTRYPOINT 的区别

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    CMD         # 指定这个容器启动的时候要运行的命令,是替换命令行中的命令
    ENTRYPOINT # 指定这个容器启动的时候要运行的命令,是在命令行命令后追加命令


    vim dockerfile-cmd-test

    FROM centos
    CMD ["ls", "-a"]

    docker build -f dockerfile-cmd-test -t cmdtest .

    # run 这个容器后会输出当前目录,这是因为DockerFile中增加了CMD命令
    docker run cmdtest

    # 如果在run时增加-l参数,-l会替换 CMD ["ls", "-a"] 命令,-l不是命令所以会报错
    docker run cmdtest -l
    # 正确的方式为:
    docker run cmdtest ls -al



    vim dockerfile-cmd-entrypoint

    FROM centos
    ENTRYPOINT ["ls", "-a"]

    docker build -f dockerfile-cmd-entrypoint -t entorypoint-test .
    # 可以执行成功,并且输出 ls -al 的结果
    docker run b40785390900 -l

    DockerFile :构建文件,定义了一切的步骤,源代码

    DockerImages :通过 DockerFile 构建生成的镜像,最终发布和运行的产品

    Docker容器 :容器是镜像运行起来提供服务的

    3.Docker 网络原理

    Docker0

    1
    2
    3
    4
    5
    6
    # 查看网卡
    ip addr
    结果:
    lo 本机回环地址
    eth0 内网地址
    docker0 docker网卡地址,桥接模式,使用的技术是 veth-pair 技术

    Docker 中的网络访问

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    docker exec -it tomcat_net ip addr

    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    valid_lft forever preferred_lft forever
    76: eth0@if77: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
    valid_lft forever preferred_lft forever

    # 可以看到容器启动的时候会得到一个 eth0@ 的ip地址,这是dockers分配的ip地址。
    ping 172.17.0.2
    # Linux是可以ping通docker容器内部的
    容器带来的网卡都是成对出现的,veth-pair 技术,是一对的虚拟设备接口,一端连着协议,一端彼此相连。veth-pair 充当一个桥梁,连接各种虚拟网络设备的。
    # 不同容器之前是可以互相ping通的
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # docker0 相当于是路由器,转发消息,不同容器共用一个路由器
    # 所有的容器不指定网络的情况下,都是 docker0 路由的,docker会给我们的容器分配一个默认的可用 IP
    # 只要容器删除,对应的网桥就没了

    255.255.0.1/16

    正常的地址:00000000.00000000.00000000.00000000
    十进制:255.255.255.255
    一个路由下:255.255.0.0 255*255-0.0.0.0(回环地址)-255.255.255.255(最终地址)=65535

    255.255.0.1/24 域 局域网,一般小教室是24,公司是16

    1677513000633

    容器互联

    启动两个tomcat:

    1
    2
    docker run -d -P --name tomcat01 tomcat
    docker run -d -P --name tomcat02 tomcat

    直接通过名字ping是无法ping通的

    1
    2
    docker exec -it tomcat02 ping tomcat01
    OCI runtime exec failed: exec failed: unable to start container process: exec: "ping": executable file not found in $PATH: unknown

    创建容器时通过 –link 参数来 link 另一个容器

    1
    docker run -d -P --name tomcat03 --link tomcat02 tomcat

    通过 --link 参数建立连接后,只能从03的方向ping 02,反过来是ping不通的

    1
    docker exec -it tomcat03 ping tomcat02

    如果在容器启动时进行了link,但被link的容器删除掉,即使再创建一个同名的容器也是无法ping通的

    docker network 命令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    docker network -help
    docker network ls
    NETWORK ID NAME DRIVER SCOPE
    d50b0dcbbc57 bridge bridge local
    eeea9a40175b host host local
    8460731336c8 none null local
    # 查看网络信息
    docker network inspect d50b0dcbbc57
    # 使用下面的命令可以找到 "Links" 参数,存放了link的信息
    docker inspect 容器id
    # 或者通过第二种方式查看,在hosts文件中增加了一个映射
    docker exec -it tomcat03 cat /etc/hosts
    ...
    172.17.0.5 tomcat02 606ae16ac1bd
    ...

    自定义网络(高级互联)

    查看所有的网络

    1
    docker network ls
    网络模式

    1678017716675

    **bridge(桥接模式)**:搭桥,通过 0.1 可以访问 0.2 和 0.3 ,0.1起到转发的作用。docker默认使用桥接模式,自己创建的网络也使用桥接模式

    none(不配置网络)

    **host(主机模式)**:和宿主机共享网络

    container(容器内网络连通):用的较少,局限很大

    默认网络

    直接启动时时可以指定参数,bridge 就是docker0的网络

    1
    docker run -d -P --name tomcat01 --net bridge diytomcat

    docker0的特点:

    1. –net 默认走docker0
    2. 域名不能访问,–link可以打通连接
    自定义网络
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
    # 常用参数
    --driver: 指定网络模式,bridge 桥接模式
    --subnet:子网,192.168.0.0/16,16时65535个子网,如果为24,那么只能创建255个
    --gateway:指定网关,从哪里出去

    # ls查看一下,即可看到创建的网络 mynet
    docker network ls
    2e4276da5434 mynet bridge local

    # 启动一个使用自定义网络的容器
    docker run -d -P --name tomcat-net-01 --net mynet diytomcat
    docker run -d -P --name tomcat-net-02 --net mynet diytomcat
    # 查看网络状态
    docker network inspect mynet
    # 使用自定义的网络是可以 ping 通的
    docker exec -it tomcat-net-01 ping tomcat-net-02
    docker exec -it tomcat-net-02 ping tomcat-net-01

    自定义的网络docker0已经维护好了对应的关系,功能更加完善,无需指定–link参数。

    不同的集群使用不同的网络,保证集群是安全和健康的

    网络连通

    docker0网络中启动两个容器

    1
    2
    docker run -d -P --name tomcat1 diytomcat
    docker run -d -P --name tomcat2 diytomcat

    连接容器tomcat1到网络mynet

    1
    docker network connect mynet tomcat1

    此时,两个方向来ping是可以ping通的了

    实际上,tomcat1是被加入到了mynet网络中,这就是一个容器两个ip地址

    1
    docker network inspect mynet

    4.IDEA 整合 Docker

    5.Docker Compose 集群管理

    6. Docker Swarm 容器编排

    7.CI/CD jenkins

    四、深入理解Docker

    读文档

    1、

    1674740418153

    docker layer 是什么?

    What is docker layer? importance of docker layer while creating Dockerfile (naiveskill.com)

    看完这篇文章后我的简单理解:docker layer 是 dockerfiles 创建时的每一层,每一层对应完成fockerfiles的一个动作,dockerfiles总的来看分成了两个动作:base image基于base image的layers

    1674740633100

    层数越多,所占用的空间就越多,因此可以通过减少层数来降低所占用的空间

    五、项目练习

    1 Docker 部署Nginx

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # 1 搜索nginx: a.docker search   b.到 docker hub 上搜索
    https://hub.docker.com/_/nginx
    docker pull nginx
    # 服务器开放3344端口,容器内在80端口,通过公网3344可以访问到容器内部
    docker run -d --name nginx01 -p 3344:80 nginx
    # 运行测试
    curl localhost:3344
    # 进入容器
    docker exec -it nginx01 /bin/bash
    # 找nginx的配置文件位置(有很多,都是做什么的呢?)
    whereis nginx
    cd /etc/nginx
    # 其中 nginx.conf 使nginx的配置文件

    问题:每次改动nginx配置文件都一定需要进入容器吗?—>数据卷

    2 使用docker来装一个tomcat

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    docker run -it --rm tomcat:9.0
    # --rm参数,用完即删

    docker pull tomcat
    docker run -d -p 8080:8080 tomcat:latest
    # 指定开放的端口后,外网可以访问到,但提示404,因为官方所给的tomcat不是完整版
    # 进入容器
    docker exec -it b9b74f7a705d /bin/bash
    # 发现问题:1 Linux命令少了 2 没有webapps
    # 阿里云镜像原因,默认为最小镜像,所有不必要的都剔除掉
    # 将webapps.dist 复制过去就可以访问了
    cp -r webapps.dist/* webapps

    3 部署 es + kibana

    elasticsearch - Official Image | Docker Hub

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    # es 暴露的端口很多
    # es 十分耗内存
    # es 的数据一般要放在安全目录,挂载
    # --net somenetwork 网络配置

    # 启动
    完整版命令:docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:tag

    docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:8.6.1

    # 验证安装成功
    curl localhost:9200

    # 查看cpu状态
    docker stats

    # 过于占用内存,直接卡死了,修改配置文件,-e修改环境
    docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:8.6.1

    4 安装并挂载mysql

    mysql - Official Image | Docker Hub

    1
    2
    3
    4
    5
    6
    7
    8
    # 1 拉取镜像
    docker pull mysql:5.7
    # 2 挂载镜像,注意mysql需要设置密码
    docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
    # 增加多个挂载版本的命令
    docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
    # 启动成功后即可访问
    # 容器删除,本机上挂载的数据依旧存在

    5 DockerFile 构建镜像

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    # 创建一个文件夹
    mkdir dockerfile
    cd dockerfile
    vim mydockerfile-centos

    # 填写构建镜像内容
    # 基础镜像centos,设置环境变量和工作路径,开放80端口,安装vim。net工具
    # 因为centos已经停止维护了,所以运行到 yum install 这里会卡住,需要加上修改镜像源的命令,yum makecache这一步会很慢,我更了大概有4分钟多,需要耐心等待。
    # 但是会自动更新版本!最后构建出来的镜像特别大,正在找解决方法(待解决)

    FROM centos
    MAINTAINER abilish<[email protected]>

    ENV MYPATH /usr/local
    WORKDIR $MYPATH

    RUN cd /etc/yum.repos.d/
    RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
    RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
    RUN yum makecache
    RUN yum update -y


    RUN yum -y install vim
    RUN yum -y install net-tools

    EXPOSE 80

    CMD echo $MYPATH
    CMD echo "----end----"
    CMD /bin/bash

    # build 构建
    docker build -f mydockerfile-centos -t mycentos:1.0 .
    # 查看构建好的镜像
    docker images
    # 运行
    docker -it mycentos:1.0
    # 查看构建变更历史
    docker history

    问题待解决,镜像换源后如何不自动更新

    6 tomcat 镜像

    1、准备镜像文件 tomcat压缩包,jdk的压缩包

    jdk-8u151-linux-x64.tar.gz

    apache-tomcat-9.0.72.tar.gz

    链接:https://pan.baidu.com/s/1Zbe2JcOVYX-b1YPQhL3cgw?pwd=8888
    提取码:8888

    1
    touch readme.txt

    2、编写dockerfile文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    # Dockerfile 是官方命名,build时会自动找这个名字的文件,不用指定-f参数了
    vim Dockerfile

    # Dockerfile 文件中的内容,ADD后会自动解压文件
    FROM centos
    MAINTAINER abilish<[email protected]>

    COPY readme.txt /usr/local/readme.txt

    ADD jdk-8u151-linux-x64.tar.gz /usr/local/
    ADD apache-tomcat-9.0.72.tar.gz /usr/local/

    RUN cd /etc/yum.repos.d/
    RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
    RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
    RUN yum makecache
    RUN yum update -y

    RUN yum -y install vim

    ENV MYPATH /usr/local
    WORKDIR $MYPATH

    ENV JAVA_HOME /usr/local/jdk1.8.0_151
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.72
    ENV CATALINE_BASE /usr/local/apache-tomcat-9.0.72
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

    EXPOSE 8080

    CMD /usr/local/apache-tomcat-9.0.72/bin/startup.sh && tail -F /url/local/apache-tomcat-9.0.72/bin/logs/catal
    ina.out

    # 构建镜像
    docker build -t diytomcat .

    # 运行镜像
    # 挂载目录是上面存放jdk、apache等文件目录下的目录
    docker run -d -p 9090:8080 --name abilishtomcat -v /home/tomcat-jdk/test:/usr/local/apache-tomcat-9.0.72/webapps/test -v /home/tomcat-jdk/tomcatlogs/:/usr/local/apache-tomcat-9.0.72/logs diytomcat

    # 进入容器
    docker exec -it 镜像id /bin/bash

    # 访问 ip:9090

    # 发布项目(由于做了卷挂载,直接在本地编写项目就可以发布了)
    cd /home/tomcat-jdk/test
    mkdir WEB-INF
    cd WEB-INF
    vim web.xml

    # 写入
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">

    </web-app>

    # cd 到上一层目录
    cd ..

    vim index.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>啦啦啦啦啦</title>
    </head>
    <body>
    Hello World!<br/>
    <%
    System.out.println("---my test web log---");
    %>
    </body>
    </html>

    # 访问 ip地址:9090/test/

    # 查看日志是否打印出来了
    cd ..
    cat catalina.out
    # 可以看到输出的 ---my test web log--- 日志


    # 项目部署成功并且能成功访问

    # 发布镜像

    # 发布到官方镜像库中
    1 注册自己的账号:https://hub.docker.com/
    2 确定账号可以登录
    3 在服务器上提交镜像
    docker login --help
    # 常用参数
    -u 指定昵称
    -p 指定密码

    4 登录后 docker push
    docker tag 镜像id 用户名(账号名)/仓库名:版本号
    docker tag diytomcat xxx/diytomcat:version1.0

    docker push 用户名(账号名)/仓库名:版本号
    docker push xxx/diytomcat:version1.0

    # 发布到阿里云镜像库中
    登录阿里云,找到容器镜像服务,创建个人实例后,找到命名空间,创建一个命名空间;创建容器镜像,仓库信息选择本地仓库

    退出登录刚刚登录的账号:docker logout
    按照阿里云镜像下面的步骤来登录push即可

    7 redis集群部署

    特点:分片、高可用、负载均衡

    当r-m3 挂了,备份 r-s3 会进行替代

    1678065538739

    准备:移除所有容器,防止卡顿

    1
    docker rm -f $(docker ps -aq)

    自定义一个网络

    1
    docker network create redis --subnet 172.38.0.0/16

    通过脚本来创建六个redis配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    for port in $(seq 1 6); \
    do \
    mkdir -p /mydata/redis/node-${port}/conf
    touch /mydata/redis/node-${port}/conf/redis.conf
    cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
    port 6379
    bind 0.0.0.0
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    cluster-announce-ip 172.38.0.1${port}
    cluster-announce-port 6379
    cluster-announce-bus-port 16379
    appendonly yes
    EOF
    done
    1
    cd /mydata/

    启动容器

    1
    2
    3
    4
    docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
    -v /mydata/redis/node-1/data:/data \
    -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf