狂神说_Docker教程

本文最后更新于:2025年6月25日 晚上

前言

Docker学习

  • Docker概述
  • Docker安装
  • Docker命令
    • 镜像命令
    • 容器命令
    • 操作命令
    • ……
  • Docker镜像!
  • 容器数据卷
  • DockerFile
  • Docker网络原理
  • IDEA整合Docker
  • CI/CD
  • Kubernetes

Docker概述

Docker为什么会出现

debug…..

传统虚拟机与容器化技术的对比

传统虚拟机的方式

传统虚拟机

缺点:

  1. 资源占用十分多
  2. 冗余步骤多
  3. 启动慢

容器化技术

容器化技术

比较Docker 和 虚拟机技术的不同 :

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

Docker的历史

2010年,几个搞IT的年轻人,就在美国成立了一家公司dotcloud

做一些 pass 的云计算服务! LXC 有关的容器技术!

他们将自己的技术(容器化技术) 命名 就是 Docker !

Docker 刚刚诞生的时候,没有引起行业的注意! dotCloud,就活不下去!

开源

开发源代码!

2013年,Docker开源!

Docker越来越多的人发现了docker的优点!火了,Docker 每个月都会更新一个版本!

2014年4月9日,Docker1.0发布!

Docker为什么这么火?十分的轻巧!

在容器技术出来之前,我们都是使用虚拟机技术!

虚拟机:在window中装一个Vmware,通过这个软件我们可以虚拟出来一台或者多台电脑!笨重!

虚拟机也是属于虚拟化技术,Docker容器技术,也是一种虚拟化技术!

Docker官网

Docker基于Go语言开发的开源项目

官网:Docker官网

文档地址:Docker官方文档

Docker文档位置

仓库文档地址:Docker Hub

Docker的基本组成

Docker基本组成

Docker名词解释

  • 镜像(Image)

    docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像==> run => tomcat

  • 容器(Container)

    Docker利用容器技术,独立运行一个或者一个组应用,通过镜像来创建的。

    启动,停止,删除,基本命令!

    目前就可以把这个容器理解为就是一个简易的linux系统

  • 仓库(Repository)

    仓库就是存放镜像的地方。仓库分为公有仓库私有仓库
    Docker Hub(默认是国外的)
    阿里云….都有容器服务器(配置镜像加速!)

Docker安装

安装Docker

环境

# 系统内核需要 3.10 以上
[root@VM-0-5-centos ~]# uname -r
3.10.0-1160.88.1.el7.x86_64

# 系统版本
[root@VM-0-5-centos ~]# cat  /etc/os-release 
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

[root@VM-0-5-centos ~]# 

安装

文档地址:[Install Docker Engine on CentOS](Install Docker Engine on CentOS | Docker Documentation)

  1. 卸载旧版本的Docker

    # 卸载旧版本的Docker
    [root@VM-0-5-centos ~]# sudo yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-engine
    
    Repository epel is listed more than once in the configuration
    No Match for argument: docker
    No Match for argument: docker-client
    No Match for argument: docker-client-latest
    No Match for argument: docker-common
    No Match for argument: docker-latest
    No Match for argument: docker-latest-logrotate
    No Match for argument: docker-logrotate
    No Match for argument: docker-engine
    No Packages marked for removal
  2. 安装需要的安装包

    # 安装需要的安装包
    [root@VM-0-5-centos ~]# yum install -y yum-utils
  3. 设置镜像源,一般不选择默认的Docker官方镜像源,速度比较慢,设置为阿里云的镜像源

    # 设置【官方】镜像源
    [root@VM-0-5-centos ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    
    # 设置【阿里云】镜像源
    [root@VM-0-5-centos ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  4. 更新软件包索引

    # 更新软件包索引
    [root@VM-0-5-centos ~]# yum makecache fast
  5. 安装docker docker-ce docker-ce-cli containerd.io

    # 安装
    [root@VM-0-5-centos ~]# yum install docker-ce docker-ce-cli containerd.io
  6. 查看版本,检测是否安装成功

    [root@VM-0-5-centos ~]# docker version
    Client: Docker Engine - Community
     Version:           24.0.4
     API version:       1.43
     Go version:        go1.20.5
     Git commit:        3713ee1
     Built:             Fri Jul  7 14:54:21 2023
     OS/Arch:           linux/amd64
     Context:           default
    
    Server: Docker Engine - Community
     Engine:
      Version:          24.0.4
      API version:      1.43 (minimum version 1.12)
      Go version:       go1.20.5
      Git commit:       4ffc614
      Built:            Fri Jul  7 14:53:26 2023
      OS/Arch:          linux/amd64
      Experimental:     false
     containerd:
      Version:          1.6.21
      GitCommit:        3dce8eb055cbb6872793272b4f20ed16117344f8
     runc:
      Version:          1.1.7
      GitCommit:        v1.1.7-0-g860f061
     docker-init:
      Version:          0.19.0
      GitCommit:        de40ad0
  7. 启动docker

    [root@VM-0-5-centos ~]# systemctl start docker
  8. 运行hello-world

    [root@VM-0-5-centos ~]# docker run hello-world

    Unable to find image ‘hello-world:latest’ locally
    latest: Pulling from library/hello-world
    719385e32844: Pull complete
    Digest: sha256:926fac19d22aa2d60f1a276b66a20eb765fbeea2db5dbdaafeb456ad8ce81598
    Status: Downloaded newer image for hello-world:latest

    Hello from Docker!

    ……

    大概流程:

    st=>start: 开始
    run=>operation: docker run hello-world
      >cond1=>condition: 本地镜像库中是否存在此镜像?
    noExistAtLocal=>operation: 访问远程仓库
    cond2=>condition: DockeHub中否存在?
      >ExistInOrign=>operation: 拉取DockeHub中的镜像到本地仓库
    error=>operation: 报错
    app=>operation: 运行
      >e=>end: 结束
    
    st(right)->run(right)->cond1->cond2>e
      >cond1(yes,right)->app->e
     cond1(no)->noExistAtLocal->cond2
      >cond2(yes)->ExistInOrign->app->e
    cond2(no)->error->e
  9. 查看下载的镜像

    # 查看下载的镜像
    [root@VM-0-5-centos ~]# docker images
    REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
    hello-world   latest    9c7a54a9a43c   2 months ago   13.3kB 

卸载Docker

  1. 卸载依赖

    # 卸载依赖
    [root@VM-0-5-centos ~]# yum remove docker-ce docker-ce-cli containerd.io
  2. 删除容器

    # 删除容器
    [root@VM-0-5-centos ~]# rm -rf /var/lib/containerd
  3. 删除默认工作目录

    # 删除默认工作目录
    [root@VM-0-5-centos ~]# rm -rf /var/lib/docker

配置阿里云镜像加速

  1. 进入阿里云官网,登录进入控制台

  2. 搜索容器镜像服务

  3. 选择镜像加速器/CentOS

    容器镜像服务

  4. 配置到服务器上

    # 创建文件夹
    [root@VM-0-5-centos ~]# mkdir -p /etc/docker
    
    # 编写daemon.json脚本
    [root@VM-0-5-centos ~]# tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["https://04tctgkm.mirror.aliyuncs.com"]
    }
    EOF
    
    # 加载新的unit配置文件 
    [root@VM-0-5-centos ~]# systemctl daemon-reload
    
    # 重启docker
    [root@VM-0-5-centos ~]# systemctl restart docker

Docker常用命令

Docker帮助命令

docker version			# 显示docker版本信息
docker info				# 显示docker系统信息,包括镜像和容器的数量
docker 命令 --help 	   # 帮助命令 

Docker镜像命令

  • docker images 查看本机镜像

    [root@VM-0-5-centos ~]# docker images
    REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
    hello-world   latest    9c7a54a9a43c   2 months ago   13.3kB

    REPOSITORY 镜像仓库源

    TAG 镜像标签

    IMAGE ID 镜像ID

    CREATED 镜像创建时间

    SIZE 镜像大小

    可选项

    - a, –all # 列出所有

    - q, –quiet # 只显示镜像ID

  • docker search 镜像名 搜索镜像

    [root@VM-0-5-centos ~]# docker search mysql
    NAME                            DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    mysql                           MySQL is a widely used, open-source relation…   14321     [OK]       
    mariadb                         MariaDB Server is a high performing open sou…   5467      [OK]       
    percona                         Percona Server is a fork of the MySQL relati…   617       [OK]       
    phpmyadmin                      phpMyAdmin - A web interface for MySQL and M…   836       [OK]       

    可选项

    –filter=stars=5000 # 根据star数量 大于等于5000的 进行过滤

    [root@VM-0-5-centos ~]# docker search mysql --filter=stars=5000
    NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    mysql     MySQL is a widely used, open-source relation…   14328     [OK]       
    mariadb   MariaDB Server is a high performing open sou…   5469      [OK]       
  • dcoker pull 镜像名 下载镜像

    [root@VM-0-5-centos ~]# docker pull mysql
    Using default tag: latest		# 不指定版本,默认下载最新版本
    latest: Pulling from library/mysql
    72a69066d2fe: Pull complete 	# 分层下载,docker images的核心 联合文件系统
    93619dbc5b36: Pull complete 
    99da31dd6142: Pull complete 
    626033c43d70: Pull complete 
    37d5d7efb64e: Pull complete 
    ac563158d721: Pull complete 
    d2ba16033dad: Pull complete 
    688ba7d5c01a: Pull complete 
    00e060b6d11d: Pull complete 
    1c04857f594f: Pull complete 
    4d7cfa90e6ea: Pull complete 
    e0431212d27d: Pull complete 
    Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709	# 签名
    Status: Downloaded newer image for mysql:latest
    docker.io/library/mysql:latest	# 真实地址 

    默认下载是最新版本,可以使用docker pull xxx:[tag] 来下载指定的版本,如下载mysql5.7的版本

    [root@VM-0-5-centos ~]# docker pull mysql:5.7
    5.7: Pulling from library/mysql
    72a69066d2fe: Already exists 		# 已经存在是因为上面已经下载过一些文件,直接跳过,极大的较少了内存和时间的占用
    93619dbc5b36: Already exists 
    99da31dd6142: Already exists 
    626033c43d70: Already exists 
    37d5d7efb64e: Already exists 
    ac563158d721: Already exists 
    d2ba16033dad: Already exists 
    0ceb82207cd7: Pull complete 
    37f2405cae96: Pull complete 
    e2482e017e53: Pull complete 
    70deed891d42: Pull complete 
    Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94
    Status: Downloaded newer image for mysql:5.7
    docker.io/library/mysql:5.7		# docker pull mysql:5.7 等价于 docker pull docker.io/library/mysql:5.7
    [root@VM-0-5-centos ~]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
    mysql        5.7       c20987f18b13   19 months ago   448MB
    mysql        latest    3218b38490ce   19 months ago   516MB
  • docker rmi 镜像ID1 镜像ID2 删除镜像,可以删除单个或多个

    [root@VM-0-5-centos ~]# docker rmi c20987f18b13
    Untagged: mysql:5.7
    Untagged: mysql@sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94
    Deleted: sha256:c20987f18b130f9d144c9828df630417e2a9523148930dc3963e9d0dab302a76
    Deleted: sha256:6567396b065ee734fb2dbb80c8923324a778426dfd01969f091f1ab2d52c7989
    Deleted: sha256:0910f12649d514b471f1583a16f672ab67e3d29d9833a15dc2df50dd5536e40f
    Deleted: sha256:6682af2fb40555c448b84711c7302d0f86fc716bbe9c7dc7dbd739ef9d757150
    Deleted: sha256:5c062c3ac20f576d24454e74781511a5f96739f289edaadf2de934d06e910b92

    docker rmi $(docker images -aq) 删除所有镜像

    注意:镜像ID只要能唯一标识一个镜像就行,可以不用显示出来的全部

Docker容器命令

说明:使用容器命令的前提是要有镜像存在!!!为了学习,下载一个centos镜像来练习。禁忌:不要把docker当作虚拟机使用,这里只是为了学习

[root@VM-0-5-centos ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
a1d0c7532777: Pull complete 
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
  • docker run [可选参数] 镜像ID 运行容器

    参数说明:

    –name=”Name” 容器名字 tomcat01,tomcat02,用来区分容器

    -d 后台运行方式(有坑,当不给设置前台进程时,会直接退出)

    -it 使用交互方式运行,进入容器查看内容

    -p 指定容器的端口 -p 8080:8080

    ​ -p ip:主机端口号:容器端口

    ​ -p 主机端口号:容器端口(常用)

    ​ -p 容器端口

    -P 随机指定端口

    # 以交互方式运行docker里面的centos
    [root@VM-0-5-centos ~]# docker run -it centos /bin/bash
    
    # docker中centos的ls命令,注意看:root@后面
    [root@c12f3268e2b4 /]# ls
    bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    # 退出当前容器
    [root@c12f3268e2b4 /]# exit		
    exit
    
    # 服务器真实的ls命令
    [root@VM-0-5-centos ~]# ls
    sa_recovery.log  sa_recovery.log.bak  Steam
    [root@VM-0-5-centos ~]# 
  • dcoker ps 列出正在运行的容器

    参数说明:

    -a 列出历史运行过的所有的容器

    -n=? 显示最近创建的几个容器

    -q 只显示容器的编号

    # 列出正在运行的容器 
    [root@VM-0-5-centos ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
    
    # 列出历史运行过的所有的容器
    [root@VM-0-5-centos ~]# docker ps -a
    CONTAINER ID   IMAGE     COMMAND       CREATED        STATUS                    PORTS     NAMES
    c12f3268e2b4   centos    "/bin/bash"   16 hours ago   Exited (0) 16 hours ago             elegant_lovelace
    
    # 列出历史运行过的所有的容器,只显示编号
    [root@VM-0-5-centos ~]# docker ps -aq
    c12f3268e2b4
  • exit 退出当前容器并停止运行

  • Ctrl + P + Q 退出当前容器不停止运行

  • docker rm 容器Id 删除容器

    # 删除所有容器1
    [root@VM-0-5-centos ~]# docker rm $(docker ps -qa)
    
    # 删除所有容器2
    [root@VM-0-5-centos ~]# docker ps -aq | xargs docker rm
  • docker start 容器id 启动容器

  • docker restart 容器id 重启容器

  • docker stop 容器id 停止容器

  • docker kill 容器id 强制停止容器

Docker常用其他命令

  • docker tag 镜像id 版本 重命名镜像版本

  • docker run -d 镜像名 后台启动容器

    # 后台启动centos
    [root@VM-0-5-centos ~]# docker run -d centos
    26b6bff63675488bfd24ee8edfe11d41db3d6829e6ca0c5a280edd96fcb2f655
    
    # 查看正在运行的容器
    [root@VM-0-5-centos ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

    哎?我刚刚后台启动的centos呢??

    常见的坑:

    docker容器使用后台运行,就必须要有要一个前台进程,docker发现没有应用,就会自动停止。nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了,所以访问是不生效的

  • docker logs -tf --tail ? 显示最近的?条日志

    参数说明

    -f 跟随最新日志滚动输出

    -t 显示时间戳

    -- tail ? 显示多少条日志

    [root@VM-0-5-centos ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND     CREATED              STATUS              PORTS     NAMES
    45a9c4dab4e4   centos    "/bin/sh"   About a minute ago   Up About a minute             adoring_wilbur
    
    # 显示 45a9c4dab4e4 中的5条日志 并显示时间戳
    [root@VM-0-5-centos ~]# docker logs -tf --tail 5 45a9c4dab4e4
    2023-07-22T02:16:41.919509791Z bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    2023-07-22T02:16:42.909968273Z sh-4.4# clear
    2023-07-22T02:16:42.910167308Z sh: clear: command not found
    2023-07-22T02:16:44.003014063Z sh-4.4# ls
    2023-07-22T02:16:44.004496012Z bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

    要是没有日志,可以敲几个或者使用脚本方式自己编写打印日志:

    docker run -d centos /bin/sh -c "while true;do echo 我是日志...... ;sleep 1;done"
  • docker top 容器id 查看容器中的进程信息

    [root@VM-0-5-centos ~]# docker top 45a9c4dab4e4
    UID		PID		PPID		C		STIM		TTY		TIME 		CMD
    root 	1281	1255		0 		10:16		pts/0 	00:00:00 	/bin/sh
    [root@VM-0-5-centos ~]# 
    
  • docker inspect 容器id 查看容器的元数据

    # 查看 4eb302c01941 容器的配置信息(下面贴出来的部分省略)
    [root@VM-0-5-centos ~]# docker inspect 4eb302c01941
    [
        {
            "Id": "4eb302c01941dd5d1d87390e606c823277892e78146cbf98326ef68c1e3b9d1a",
            "Created": "2023-07-22T02:28:43.722770778Z",
            "Path": "/bin/bash",
            "Args": [
                "-c",
                "while true;do echo 我是日志...... ;sleep 1;done"
            ],
            "State": {
                "Status": "running",
                "Running": true,
                "Paused": false,
                "Restarting": false,
                "OOMKilled": false,
                "Dead": false,
                "Pid": 14848,
                "ExitCode": 0,
                "Error": "",
                "StartedAt": "2023-07-22T03:30:35.879820821Z",
                "FinishedAt": "2023-07-22T02:29:41.643196662Z"
            },
            "Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
    ...
            "NetworkSettings": {
                "Bridge": "",
                "SandboxID": "ced489be2a1766c79e4e8dd1bb05dc7fee08d925ca23b78d4d486f443d688690",
                "HairpinMode": false,
                "LinkLocalIPv6Address": "",
                "LinkLocalIPv6PrefixLen": 0,
                "Ports": {},
                "SandboxKey": "/var/run/docker/netns/ced489be2a17",
                "SecondaryIPAddresses": null,
                "SecondaryIPv6Addresses": null,
                "EndpointID": "dca9cd9f5a5103c02fcb29a7bc15cd3bb67d94da20a0cc7ceffc1fa97f3d8346",
                "Gateway": "172.17.0.1",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "IPAddress": "172.17.0.3",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "MacAddress": "02:42:ac:11:00:03",
                "Networks": {
                    "bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "NetworkID": "e7ef1665d7a01dda73a28ba88c3a9bffa56b051c84f158c8b044859779b9b4c4",
                        "EndpointID": "dca9cd9f5a5103c02fcb29a7bc15cd3bb67d94da20a0cc7ceffc1fa97f3d8346",
                        "Gateway": "172.17.0.1",
                        "IPAddress": "172.17.0.3",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "MacAddress": "02:42:ac:11:00:03",
                        "DriverOpts": null
                    }
                }
            }
        }
    ]
  • dcoker exec -it 容器id 进入正在运行的容器内(开启一个新的终端执行命令)

    [root@VM-0-5-centos ~]# docker ps 
    CONTAINER ID   IMAGE     COMMAND
    4eb302c01941   centos    "/bin/bash -c 'while…"
    45a9c4dab4e4   centos    "/bin/sh"
    
    # 进入容器 4eb302c01941 里面
    [root@VM-0-5-centos ~]# docker exec -it 4eb302c01941 /bin/bash
    [root@4eb302c01941 /]# ps -ef
    UID        PID  PPID  C STIME TTY          TIME CMD
    root         1     0  0 03:30 ?        00:00:00 /bin/bash -c while true;do echo ????????????...... ;sleep 1;done
    root       404     0  0 03:37 pts/0    00:00:00 /bin/bash
    root       507     0  0 03:38 pts/1    00:00:00 /bin/bash
    root       523     1  0 03:38 ?        00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
    root       524   507  0 03:38 pts/1    00:00:00 ps -ef
  • docker attach 容器id 进入正在运行的容器内(执行原来启动这个容器时的终端)

  • docker cp 容器id:dir1/a dir2 复制容器iddir1目录中的a文件服务器的dir2目录

    [root@VM-0-5-centos ~]# docker ps 
    CONTAINER ID   IMAGE     COMMAND
    4eb302c01941   centos    "/bin/bash -c 'while…"
    
    # 进入容器,新开一个终端
    [root@VM-0-5-centos ~]# docker exec -it 4eb302c01941 /bin/bash
    [root@4eb302c01941 /]# cd /home
    [root@4eb302c01941 home]# ls
    
    # 在容器centos内部创建一个`test.txt`文件,输入内容:Hello,My name is test.....
    [root@4eb302c01941 home]# vi test.txt
    [root@4eb302c01941 home]# cat test.txt 
    Hello,My name is test.....
    # 退出容器
    [root@4eb302c01941 home]# exit
    exit
    [root@VM-0-5-centos ~]# docker ps 
    CONTAINER ID   IMAGE     COMMAND  
    4eb302c01941   centos    "/bin/bash -c 'while…" 
    
    # 复制容器centos内部刚刚创建的那个`test.txt`文件到服务器的当前目录
    [root@VM-0-5-centos ~]# docker cp 4eb302c01941:/home/test.txt ./
                                                   Successfully copied 2.05kB to /root/./
                                                   
    # 查看当前目录,存在test.txt,并且内容就是刚刚在容器内部的创建的那个文件内容
    [root@VM-0-5-centos ~]# ls
    sa_recovery.log  sa_recovery.log.bak  Steam  test.txt
    [root@VM-0-5-centos ~]# cat test.txt 
    Hello,My name is test.....

    复制文件不用容器运行。也可以复制历史运行过的容器,只要容器还在

    如果需要把服务器的文件复制到容器内部:docker cp dir3/test.txt 容器id:dir4,把当前目录的test.txt复制到容器的dir4目录

Docker命令小结

Docker命令小结

Docker命令练习

部署Nginx

# 以后台方式运行nginx,取名为nginx01,外部端口8080映射到容器内部80
[root@VM-0-5-centos ~]# docker run -d --name nginx01 -p 8080:80 nginx
fd046b30b032ccf9f4fb0d7971878972b4cd37c9c6219b7205583480663bf4d3

[root@VM-0-5-centos ~]# docker ps
CONTAINER ID   IMAGE     COMMAND	CREATED			PORTS  								   NAMES
fd046b30b032   nginx     "/docker-entrypoint.…"   0.0.0.0:8080->80/tcp, :::8080->80/tcp   nginx01

# 使用curl测试访问8080端口,看能不能显示nginx主页
[root@VM-0-5-centos ~]# curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@VM-0-5-centos ~]#

部署Tomcat

# 拉取9.0的镜像
[root@VM-0-5-centos ~]# docker pull tomcat:9.0
9.0: Pulling from library/tomcat
0e29546d541c: Pull complete 
......
b93639122cb4: Pull complete 
Digest: sha256:cd96d4f7d3f5fc4d3bc1622ec678207087b8215d55021a607ecaefba80b403ea
Status: Downloaded newer image for tomcat:9.0
docker.io/library/tomcat:9.0

# 运行tomcat容器,以8080端口映射到容器内的8080端口
[root@VM-0-5-centos ~]# docker run --name tomcat01 -p 8080:8080 tomcat

# 访问公网pi:8080,发现能进去,但是为404界面,进入容器 复制默认网站到webapp目录
[root@VM-0-5-centos ~]# docker exec -it  f1e6a444bd05 /bin/bash
root@f1e6a444bd05:/usr/local/tomcat# pwd
/usr/local/tomcat
root@f1e6a444bd05:/usr/local/tomcat# ls
BUILDING.txt  CONTRIBUTING.md  LICENSE  NOTICE  README.md  RELEASE-NOTES  RUNNING.txt  bin  conf  lib  logs  native-jni-lib  temp  webapps  webapps.dist  work

root@f1e6a444bd05:/usr/local/tomcat# cp -r  webapps.dist/* ./
#再次访问公网ip:8080 端口就看到了tomcat的网站

部署ES+Kibaba

[root@VM-0-5-centos ~]# docker run -d --name elasticsearch -p 8080:9200 -p 8081:9300 -e "discovery.type=single-node" elasticsearch:7.17.10

# 访问容器的9200端口
[root@VM-0-5-centos ~]# curl localhost:8080
{
  "name" : "70db009be7f3",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "3Bnp55RgRxq7kZmwPwvm2A",
  "version" : {
    "number" : "7.17.10",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "fecd68e3150eda0c307ab9a9d7557f5d5fd71349",
    "build_date" : "2023-04-23T05:33:18.138275597Z",
    "build_snapshot" : false,
    "lucene_version" : "8.11.1",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

# 查看docker状态,发现elasticsearch占了大半内存
[root@VM-0-5-centos ~]# docker stats
CONTAINER ID   NAME            CPU %     MEM USAGE / LIMIT     MEM %     NET I/O          BLOCK I/O       PIDS
70db009be7f3   elasticsearch   0.29%     1.161GiB / 1.794GiB   64.69%    1.18kB / 1.3kB   141MB / 688kB   55

按照默认模式启动,会非常消耗内存,因此,需要通过参数限制其内存,增加参数-e ES_JAVA_OPTS="-Xms64m,-Xmx512m"

[root@VM-0-5-centos ~]# docker images
REPOSITORY      TAG       IMAGE ID       CREATED         SIZE
elasticsearch   7.17.10   a305059888ba   3 months ago    622MB

[root@VM-0-5-centos ~]# docker run -d --name es -p 8080:9200 -p 8081:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms50m -Xmx512m" a305059888ba

[root@VM-0-5-centos ~]# docker stats
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O         PIDS
4c3bf1a8d612   es        0.21%     558.7MiB / 1.794GiB   30.40%    44.2MB / 1.72MB   65.3MB / 92.2MB   57
[root@VM-0-5-centos ~]# docker run -d  --name kibana -p 5601:5601 kibana:7.17.10
Unable to find image 'kibana:7.17.10' locally
7.17.10: Pulling from library/kibana
99803d4b97f3: Already exists 
1b833df53080: Pull complete 
3f550a4d40b2: Pull complete 
9db648d59d34: Pull complete 
dcb1f897f694: Pull complete 
4f4fb700ef54: Pull complete 
f75409cbb707: Pull complete 
43502892358b: Pull complete 
056fa2eee2ce: Pull complete 
77aff48366b1: Pull complete 
d5e7789a1859: Pull complete 
a01160071b90: Pull complete 
f342da3964c7: Pull complete 
48487d0402f9: Pull complete 
Digest: sha256:85f56231725dfb4a2663388fa8343926de043e5ce05e787e6fbc965eac0c3b3f
Status: Downloaded newer image for kibana:7.17.10
51298c3c7ef659100a2adb77f854106b61274c2a29dbc8dd7b51fd81327993e2

Dockers可视化界面

Portainer

安装

# 安装 portainer 
[root@VM-0-5-centos ~]# docker run -d -p 8080:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

访问:公网ip:8080

创建用户,并选择Local

测试访问Portainer

选择Local

Portainer主界面

Docker镜像讲解

镜像是什么

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。浅显的讲类似于手机上的一个应用安装包(apk)

从哪儿获得镜像

  • 远程仓库下载
  • 别处拷贝
  • 自己制作DockerFile

Docker镜像加载原理

UnionFS(联合文件系统)

Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system),在bootfs之上。包含的就是典型Linux 系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,CentOS等等

为什么Docker的镜像CentOS大小只有200M,但是真正安装的iso镜像却有几个G?

因为Docker中的CentOS镜像底层库使用的是服务器原来的,底层使用的是Host的Kernel,自己只需要提供rootfs就可以了,精简过的镜像rootfs也可以很小,只需要基本的命令(像ps,pwd等)、工具和程序库就可以。由此可见,针对于不同Linux的发行版,bootfs基本一致,rootfs会有差别,所以不同系统可以公用bootfs。

[root@VM-0-5-centos ~]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
a2abf6c4d29d: Already exists 		# 已经下载过的,直接拿过来用
c7a4e4382001: Pull complete 
4044b9ba67c9: Pull complete 
c8388a79482f: Pull complete 
413c8bb60be2: Pull complete 
1abfd3011519: Pull complete 
Digest: sha256:db485f2e245b5b3329fdc7eff4eb00f913e09d8feb9ca720788059fdc2ed8339
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest
[root@VM-0-5-centos ~]# 

提交自己的镜像

  1. 启动一个默认的tomcat

  2. 修改tomcat

  3. docker commit 提交,-m 修改的备注 -a 作者 tomcat_hh_1.0 版本号
    docker commit -m=”xxxxx” -a=”xx” 容器id 镜像名:版本号

  4. 查看镜像列表(docker images)

[root@VM-0-5-centos ~]# docker ps 
CONTAINER ID   IMAGE			PORTS                                    NAMES
9316cde12d4d   tomcat:8.5   0.0.0.0:8081->8080/tcp, :::8081->8080/tcp   tomcat01

[root@VM-0-5-centos ~]# docker commit -m "初始化tomcat界面" -a "hhu" 9316cde12d4d tomcat_hhu:1.0
sha256:8fcc6c1f0ad9e3d74adab15e89fc72df47a383eff2fadd439665179873290c96

[root@VM-0-5-centos ~]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
tomcat_hhu            1.0       8fcc6c1f0ad9   4 seconds ago   683MB
tomcat                8.5       2d2bccf89f53   19 months ago   678MB

Docker数据卷

问题:删除容器之后,容器内的数据一并删除了,有时候需要保留数据,所以就需要使用数据卷技术,使用容器的持久化和同步操作

它们类似共享文件占用一块存储,不会存两份;

挂载就是主机往容器挂的,源是主机,挂载就是将宿主机的一部分空间共享给容器一起用(因此数据卷也可以用来做扩容!!)宿主机和容器都可以数据共享。

即使容器被停止,在宿主机操作的挂载目录下的文件,还是能映射进容器内的。

方式1:直接使用命令 -v 源目录(主机目录)xxx:容器内目录xxx 路径挂载

还有另外两种:具名挂载、匿名挂载

具名挂载:docker -v xxx:dir1 xxx挂载的数据卷的名字

匿名挂载:docker -v dir1 随机生成一个哈希值的名字

docker run -it -v /var/share/mysql:/var/mysql

方式2:使用DockerFile

卷的其他命令:

查看所有卷信息:docker volume ls

查看卷的具体挂载路径:docker volume inspect 卷名或者卷Id

具名挂载/匿名挂载

[root@VM-0-5-centos home]# docker volume ls
DRIVER    VOLUME NAME
local     69bf15b9adf3bfbc18d5c518f023d3291a5193f42abc924f6b4d7b8997778c33
# 具名挂载(mysql01)
[root@VM-0-5-centos home]# docker run -d -v mysql01:/etc/mysql/conf/conf.d -p 8080:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.12
316e4a49f78be6045382636271928514a313e4ae4f24ca09978df42cdd73fc49
[root@VM-0-5-centos home]# docker volume ls
DRIVER    VOLUME NAME
local     mysql01
[root@VM-0-5-centos home]# docker volume inspect mysql01
[
    {
        "CreatedAt": "2023-07-28T10:34:05+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/mysql01/_data",		# 实际路径
        "Name": "mysql01",
        "Options": null,
        "Scope": "local"
    }
]
# 匿名挂载
[root@VM-0-5-centos home]# docker run -d -v /etc/mysql/conf/conf.d -p 8081:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.12
ac0ca411a06468ee42c1918d3bf1fd5df9f823770aa9e2d03ac7aeb59fce373f
[root@VM-0-5-centos home]# docker volume ls
DRIVER    VOLUME NAME
local     781640e41dd83c31b0c96041a111f3d87c8527cf522a31f7e5788a0f4baee2c1
local     e5984bfcaa862a65103fa2c593c4afc9b33973085c996dd6246d9aa5809ebf43
local     mysql01

[root@VM-0-5-centos home]# docker ps
CONTAINER ID   IMAGE          COMMAND    ...
ac0ca411a064   mysql:8.0.12   "docker-entrypoint.s…"   ...

# 这样找起来非常麻烦
[root@VM-0-5-centos home]# docker inspect ac0ca411a064
......
        "Mounts": [
            {
                "Type": "volume",
                "Name": "e5984bfcaa862a65103fa2c593c4afc9b33973085c996dd6246d9aa5809ebf43",
                "Source": "/var/lib/docker/volumes/e5984bfcaa862a65103fa2c593c4afc9b33973085c996dd6246d9aa5809ebf43/_data", #真实路径
                "Destination": "/var/lib/mysql",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "781640e41dd83c31b0c96041a111f3d87c8527cf522a31f7e5788a0f4baee2c1",
                "Source": "/var/lib/docker/volumes/781640e41dd83c31b0c96041a111f3d87c8527cf522a31f7e5788a0f4baee2c1/_data", #真实路径
                "Destination": "/etc/mysql/conf/conf.d",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
......
[root@VM-0-5-centos home]# 

可以看出不管是具名挂载还是匿名挂载,实际的路径都是挂载在/var/lib/docker/volumes下的,只不过具名挂载会生成定义的那个名字的文件夹,匿名会是一些哈希值的文件夹。

方式1:实战——MySQL数据卷测试

当前目录(/root)下没有mysql
[root@VM-0-5-centos ~]# ls
-  sa_recovery.log  sa_recovery.log.bak  Steam

# 以后台方式
[root@VM-0-5-centos ~]# docker run -d --name=mysql -p 8080:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data/:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.12
1859371ac66e8d286ac7c7e15a5e12e1d16f3ca02df648f3a88185f2afb45b7e
[root@VM-0-5-centos ~]# [root@VM-0-5-centos ~]# docker inspect 1859371ac66e
......
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/root/mysql/conf",
                "Destination": "/etc/mysql/conf.d",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/root/mysql/data",
                "Destination": "/var/lib/mysql",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ]
......

[root@VM-0-5-centos data]# pwd
/root/mysql/data
[root@VM-0-5-centos data]# ls
auto.cnf       binlog.index  client-cert.pem  ibdata1      ibtmp1     performance_schema  server-cert.pem  undo_001
binlog.000001  ca-key.pem    client-key.pem   ib_logfile0  mysql      private_key.pem     server-key.pem   undo_002
binlog.000002  ca.pem        ib_buffer_pool   ib_logfile1  mysql.ibd  public_key.pem      sys
[root@VM-0-5-centos data]# 

在Windows上通过Navicat连接连接数据库:

主机:服务器公网IP

端口:8080(上面暴露给外面的端口)

用户名:root

密码:上面参数中的123456(-e MYSQL_ROOT_PASSWORD=123456)

创建一个test数据库,在服务器上查看目录内是否有新建的数据库

[root@VM-0-5-centos data]# ls
auto.cnf       ......  test  # 这个就是刚才在navicat中创建的test数据库  ......  undo_002

# 现在我们停掉容器,删除容器,看数据库信息是否还在
[root@VM-0-5-centos data]# docker kill 1859371ac66e
3476c8674a61
[root@VM-0-5-centos data]# docker rm 1859371ac66e
3476c8674a61
[root@VM-0-5-centos data]# ls
auto.cnf       ......  test  # 这个就是刚才在navicat中创建的test数据库  ......   undo_002

[root@VM-0-5-centos data]# docker ps -a
CONTAINER ID   IMAGE            COMMAND           CREATED      STATUS                PORTS     NAMES

拓展:

使用 docker -v 容器内路径:ro/rw 来改变容器内目录的读写权限

ro - readonly - 只读

rw - readwrite - 可读可写(默认)

# 容器内只读
[root@VM-0-5-centos ~]# docker run -it --name centos01 -v centos01:/home/test:ro centos /bin/bash
[root@8e47b81c532d /]# cd /home/test/
[root@8e47b81c532d test]# ls
[root@8e47b81c532d test]# touch aa.txt
# 可以看到是不可以创建文件的
touch: cannot touch 'aa.txt': Read-only file system

# 宿主机上操作
[root@VM-0-5-centos ~]# docker volume ls
DRIVER    VOLUME NAME
local     centos01
[root@VM-0-5-centos ~]# docker volume inspect centos01 
[
    {
        "CreatedAt": "2023-07-28T13:36:28+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/centos01/_data",
        "Name": "centos01",
        "Options": null,
        "Scope": "local"
    }
]
[root@VM-0-5-centos ~]# cd /var/lib/docker/volumes/centos01/_data
[root@VM-0-5-centos _data]# touch test1.txt
[root@VM-0-5-centos _data]# ll
total 0
-rw-r--r-- 1 root root 0 Jul 28 13:38 test1.txt

[root@VM-0-5-centos _data]# docker attach 8e47b81c532d
[root@8e47b81c532d test]# ls
test1.txt

方式2:初尝DockerFile

Dockerfile就是用来构建docker镜像的构建文件的命令脚本!先体验一下!

使用docker build 命令来打包

部分参数列表:

- f 指定要使用的Dockerfile路径

- t 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签

一个简单的DockerFile文件内容如下所示:

FROM centos
VOLUME ["volume01","volume02"]
CMD ECHO "------ END ------"
CMD /bin/bash

测试:

# 创建一个文件(没有后缀)
[root@VM-0-5-centos ~]# touch testDockerFile
[root@VM-0-5-centos ~]# vi testDockerFile 
# 编写如下内容
[root@VM-0-5-centos ~]# cat testDockerFile 
CMD ECHO "------ START ------"
FROM centos
VOLUME ["volume01","volume02"]
CMD ECHO "------ END ------"
CMD /bin/bash

# 最后这有个.,一定要注意
[root@VM-0-5-centos ~]# docker build -f /root/testDockerFile -t hhu_centos:1.0 .
[+] Building 0.1s (5/5) FINISHED                    						docker:default
 => [internal] load build definition from testDockerFile          			0.0s
 => => transferring dockerfile: 127B                        				0.0s
 => [internal] load .dockerignore        									0.0s
 => => transferring context: 2B   											0.0s
 => [internal] load metadata for docker.io/library/centos:latest  			0.0s
 => CACHED [1/1] FROM docker.io/library/centos   							0.0s
 => exporting to image   													0.0s
 => => exporting layers    													0.0s
 => => writing image sha256:90b92c4cee5f64154b91707603f7df4fadfab490411f9390169a32dd776b6749         0.0s
 => => naming to docker.io/library/hhu_centos:1.0     						0.0s

[root@VM-0-5-centos ~]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
hhu_centos            1.0       90b92c4cee5f   22 months ago   231MB
centos                latest    5d0da3dc9764   22 months ago   231MB

[root@VM-0-5-centos ~]# docker run -it hhu_centos:1.0 
[root@5fba373aa532 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  volume01  volume02
[root@VM-0-5-centos ~]# docker inspect 5fba373aa532
......
        "Mounts": [
            {
                "Type": "volume",
                "Name": "ea053221628118cb291e160a0d9c045c593086eac1015810590d61f91fb58e09",
                "Source": "/var/lib/docker/volumes/ea053221628118cb291e160a0d9c045c593086eac1015810590d61f91fb58e09/_data",
                "Destination": "volume01",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "0cb130b25673485bc7d3994a41abcf3f42867ae6a5420addd1917fcb7a34f8f9",
                "Source": "/var/lib/docker/volumes/0cb130b25673485bc7d3994a41abcf3f42867ae6a5420addd1917fcb7a34f8f9/_data",
                "Destination": "volume02",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
......

封装在docker里的volume01volume02已经自动挂载了,启动的时候没有 添加 -v 参数。

假如构建dockerFile的时候没有挂载卷,需要在启动容器的时候加入-v参数手动挂载

父子容器数据共享

如果用户需要在多个容器之间共享一些持续更新的数据,最简单的方式是使用父子容器数据共享。 父子容器对应的目录数据共享,各容器修改、添加数据等都是同步共享的。数据卷的生命周期一直持续到没有容器使用它为止。

命令:docker run xxx --volumes-from 父容器

# 启动dockerFile生成的镜像,取名centos01,是有自动挂载的volume01、volume02
[root@VM-0-5-centos ~]# docker run -it --name centos01 hhu_centos:1.0
[root@784e9fa7a162 /]# ls
bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var       volume02
dev  home  lib64  media       opt  root  sbin  sys  usr  volume01

# 启动dockerFile生成的镜像,取名centos02,从centos01同步,也是有自动挂载的volume01、volume02
[root@VM-0-5-centos ~]# [root@VM-0-5-centos ~]# docker run -it --volumes-from centos01 --name centos02  hhu_centos:1.0

[root@VM-0-5-centos ~]# docker attach centos01 
[root@784e9fa7a162 /]# cd volume01/
# 在centos01的volume01目录下创建ttttest文件
[root@784e9fa7a162 volume01]# touch ttttest
[root@784e9fa7a162 volume01]# ls
ttttest

# Ctrl+P+Q退出centos01,进入centos02
[root@VM-0-5-centos ~]# docker attach centos02 
[root@40cbfd2ea133 /]# cd volume01/
# 可以看到是同步过来的
[root@40cbfd2ea133 volume01]# ls
ttttest

[root@40cbfd2ea133 /]# [root@VM-0-5-centos ~]# docker ps
[root@VM-0-5-centos ~]# docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED         STATUS         PORTS     NAMES
41cdd3f95ef3   hhu_centos:1.0   "/bin/sh -c /bin/bash"   6 minutes ago   Up 6 minutes             centos03
40cbfd2ea133   hhu_centos:1.0   "/bin/sh -c /bin/bash"   30 hours ago    Up 30 hours              centos02
784e9fa7a162   hhu_centos:1.0   "/bin/sh -c /bin/bash"   30 hours ago    Up 30 hours              centos01

# 启动dockerFile生成的镜像,取名centos03,从centos01同步,也是有自动挂载的volume01、volume02,并且volume01中已经有centos01创建的文件了
[root@VM-0-5-centos ~]# docker run -it --volumes-from centos01 --name centos03 hhu_centos:1.0
[root@41cdd3f95ef3 /]# cd volume01/
[root@41cdd3f95ef3 volume01]# ls
ttttest

# 删掉centos01
[root@VM-0-5-centos ~]# docker kill 784e9fa7a162
784e9fa7a162
[root@VM-0-5-centos ~]# docker rm 784e9fa7a162
784e9fa7a162

[root@VM-0-5-centos ~]# docker ps -a
CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS          PORTS     NAMES
41cdd3f95ef3   hhu_centos:1.0   "/bin/sh -c /bin/bash"   13 minutes ago   Up 13 minutes             centos03
40cbfd2ea133   hhu_centos:1.0   "/bin/sh -c /bin/bash"   30 hours ago     Up 30 hours               centos02
# 进入centos03创建文件,看centos02是否会有同步
[root@VM-0-5-centos ~]# docker attach centos03
[root@41cdd3f95ef3 volume01]# touch test
[root@41cdd3f95ef3 volume01]# ls
test  ttttest

# Ctrl+P+Q退出centos03,进入centos02,看也有centos03创建的文件
[root@VM-0-5-centos ~]# docker attach centos02 
[root@40cbfd2ea133 volume01]# ls
test  ttttest

# 查看centos02和centos03,发现他们挂载的都是同一个路径
[root@VM-0-5-centos ~]# docker inspect centos02
......
        "Mounts": [
            {
                "Type": "volume",
                "Name": "c7c43116b57172e865ae6c648ae9f7be59e4aab2a6bf2eb62b85712c1ab4118f",
                "Source": "/var/lib/docker/volumes/c7c43116b57172e865ae6c648ae9f7be59e4aab2a6bf2eb62b85712c1ab4118f/_data",
                "Destination": "volume02",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "7b26b93df60335e29d880bd7c5bafe5a93bed42228b3175c6667317081f690fc",
                "Source": "/var/lib/docker/volumes/7b26b93df60335e29d880bd7c5bafe5a93bed42228b3175c6667317081f690fc/_data",
                "Destination": "volume01",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
......

DockerFile

DockerFile介绍

DockerFile是用来构建docker镜像的文件,命令参数脚本。

构建步骤:

  1. 编写一个dockerfile文件
  2. docker build构建成一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(DockerHub,阿里云镜像仓库)

DockerHub中CentOS的DockerFile文件

FROM scratch
MAINTAINER The CentOS Project <cloud-ops@centos.org>
ADD c7-docker.tar.xz /
LABEL name="CentOS Base Image" \
    vendor="CentOS" \
    license="GPLv2" \
    build-date="2016-03-04"

# Volumes for systemd
# VOLUME ["/run", "/tmp"]

# Environment for systemd
# ENV container=docker

# For systemd usage this changes to /usr/sbin/init
# Keeping it as /bin/bash for compatability with previous
CMD ["/bin/bash"]

DockerFIle构建过程

  1. 保留关键字必须大写
  2. 执行顺序从上到下
  3. # 为注释
  4. 每一个指定都会往上创建提交一个新的镜像层,并提交

DockerFile指令详解

  • FROM <image>:<digest> 指定基础镜像,并且必须是第一条指令,digest参数可选

    如果不以任何镜像为基础,那么写法为:FROM scratch。同时意味着接下来所写的指令将作为镜像的第一层开始

  • LABEL标签 LABEL <key1>=<value1> <key2>=<value2> <key3>=<value3>

    LABEL “com.example.vendor”=”ACME Incorporated”
    LABEL com.example.label-with-value=”foo”
    LABEL version=”1.0”

    如太长需要换行的话则使用\符号

    LABEL description=”This text illustrates
    that label-values can span multiple lines.”

    说明:LABEL会继承基础镜像种的LABEL,如遇到key相同,则值覆盖

  • ADD ["<src>",... "<dest>"] 复制命令,把文件复制到镜像中

    • 路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径,推荐写成绝对路径
    • 可以是一个本地文件或者是一个本地压缩文件,还可以是一个url
    • 如果把写成一个url,那么ADD就类似于wget命令

    注意事项

    • src为一个目录的时候,会自动把目录下的文件复制过去,目录本身不会复制
    • 如果src为多个文件,dest一定要是一个目录
  • COPY ["<src>",... "<dest>"] COPY的只能是本地文件,其他用法一致

  • EXPOSE <port>/<tcp/udp> 功能为暴漏容器运行时的监听端口给外部,但是EXPOSE并不会使容器访问主机的端口。如果想使得容器与主机的端口有映射关系,必须在容器启动的时候加上 -p 参数

  • ENV 一次设置多个

    ENV一次设置一个

    ENV=… 一次设置多个

    在Dockerfile中使用变量的方式

    • $varname
    • ${varname}
    • ${varname:-default value} 当变量不存在使用-号后面的值
    • $(varname:+default value} 当变量存在时使用+号后面的值(当然不存在也是使用后面的值)
  • RUN 运行指定的命令,有两种格式

    RUN在linux操作系统上默认 /bin/sh -c;在windows操作系统上默认 cmd /S /C

    RUN [“executable”, “param1”, “param2”] 可将executable理解成为可执行文件,后面就是两个参数。

    换行使用\,多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层。多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错。

  • CMD 容器启动时默认命令或参数,语法有三种写法

    第一种就是shell这种执行方式和写法
    CMD command param1 param2

    第二种是可执行文件加上参数的形式(推荐)
    CMD [“executable”,”param1”,”param2”]

    该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
    CMD [““,”“,…]

    举例说明两种写法:

    CMD [ "sh", "-c", "echo $HOME" 
    CMD [ "echo", "$HOME" ]

    这里边包括参数的一定要用双引号,就是”,不能是单引号。千万不能写成单引号。原因是参数传递后,docker解析的是一个JSON array

    不要把RUN和CMD搞混了

    RUN是构件容器时就运行的命令以及提交运行结果

    CMD是容器启动时执行的命令,在构件时并不运行,构件时紧紧指定了这个命令到底是个什么样子

  • ENTRYPOINT 容器启动时运行得启动命令

    ENTRYPOINT command param1 param2					可执行文件加参数(EXEC调用,可在docker run启动时传递参数)
    ENTRYPOINT ["executable", "param1", "param2"]		写shell (shell执行)

    CMD比较说明(这俩命令太像了,而且还可以配合使用):

    相同点:

    • 只能写一条,如果写了多条,那么只有最后一条生效
    • 容器启动时才运行,运行时机相同

    不同点:

    • ENTRYPOINT不会被运行的command覆盖,而CMD则会被覆盖
    • 如果我们在Dockerfile种同时写了ENTRYPOINT和CMD,并且CMD指令不是一个完整的可执行命令,那么CMD指定的内容将会作为ENTRYPOINT的参数
  • VOLUME ["/data"] 挂载功能,可以将宿主机目录挂载到容器中

  • USER 设置启动容器的用户,可以是用户名或UID

    USER daemo
    USER UID

    注意:

    如果设置了容器以daemon用户去运行,那么RUN, CMD 和 ENTRYPOINT 都会以这个用户去运行,
    使用这个命令一定要确认容器中拥有这个用户,并且拥有足够权限

  • WORKDIR /path/to/workdir 设置工作目录,对RUN,CMD,ENTRYPOINT,COPY,ADD生效。如果不存在则会创建,也可以设置多次。

    WORKDIR /a
    WORKDIR b
    WORKDIR c
    RUN pwd

    pwd执行的结果是/a/b/c

    WORKDIR也可以解析环境变量,如:

    ENV DIRPATH /path
    WORKDIR $DIRPATH/$DIRNAME
    RUN pwd

    pwd的执行结果是/path/$DIRNAME

  • ARG <name>[=<default value>] 设置变量命令

    设置变量命令,ARG命令定义了一个变量,在docker build创建镜像的时候,使用 –build-arg = 来指定参数

    如果用户在build镜像时指定了一个参数没有定义在Dockerfile中,那么将有一个Warning:

    [Warning] One or more build-args [foo] were not consumed.

    我们可以定义一个或多个参数,如下:

    FROM busybox
    ARG user1
    ARG buildno

    也可以给参数一个默认值,当build镜像时没有指定参数值,将会使用这个默认值

    FROM busybox
    ARG user1=someuser
    ARG buildno=1
  • STOPSIGNAL signal 当容器停止时给系统发送什么样的指令,默认是15

  • HEALTHCHECK 容器健康状况检查命令

    HEALTHCHECK [OPTIONS] CMD command				容器内部运行一个命令来检查容器的健康状况
    HEALTHCHECK NONE								基础镜像中取消健康检查命令

    [OPTIONS]的选项支持以下三中选项:

    –interval=DURATION 两次检查默认的时间间隔为30秒

    –timeout=DURATION 健康检查命令运行超时时长,默认30秒

    –retries=N 当连续失败指定次数后,则容器被认为是不健康的,状态为unhealthy,默认次数是3

    注意:

    HEALTHCHECK命令只能出现一次,如果出现了多次,只有最后一个生效。

    CMD后边的命令的返回值决定了本次健康检查是否成功,具体的返回值如下:

    0: success - 表示容器是健康的

    1: unhealthy - 表示容器已经不能工作了

    2: reserved - 保留值

    举个例子:

    HEALTHCHECK --interval=5m --timeout=3s \
    CMD curl -f http://localhost/ || exit 1

    健康检查命令是:curl -f http://localhost/ || exit 1

    两次检查的间隔时间是5秒

    命令超时时间为3秒

DockerFile实战——构建自己的CentOS镜像

需求:基础镜像:centos7,拓展vim命令、ifconfig命令、设置工作路径为 /usr/local,对外开放80端口

FROM centos:7
MAINTAINER hhu<1247857703@qq.com>
ENV DIRPATH /usr/local/docker/src
WORKDIR $DIRPATH
RUN yum -y install vim
RUN yum -y install  net-tools
EXPOSE 80
CMD echo $DIRPATH
CMD echo "------ END ------"
CMD /bin/bash
docker build -f /root/dockerFileTest -t hhu_centos .

DockerFile实战——构建自己的Tomcat

下载jdk-8u381-linux-x64.tar.gzapache-tomcat-9.0.78.tar.gz,上传到与Dockerfile同目录。

需求:以centos7为基础镜像,安装vim命令,添加jdk1.8,tomcat,开放8080端口

FROM centos:7
MAINTAINER hhu<1247857703@qq.com>

ENV LOCAL /usr/local
WORKDIR $LOCAL

RUN yum -y install vim

COPY readme.md $LOCAL/readme.md
ADD jdk-8u381-linux-x64.tar.gz $LOCAL
ADD apache-tomcat-9.0.78.tar.gz $LOCAL

ENV JAVA_HOME $LOCAL/jdk1.8.0_381
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME $LOCAL/apache-tomcat-9.0.78
ENV CATALINA_BASE $LOCAL/apache-tomcat-9.0.78
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD $CATALINA_HOME/bin/startup.sh && tail -F $CATALINA_HOME/logs/catalina.out
[root@VM-0-5-centos docker]# docker build -t hhu_tomcat .
[+] Building 181.5s (11/11) FINISHED                                                                          docker:default
 => [internal] load .dockerignore    							0.0s
 => => transferring context: 2B      							0.0s
 => [internal] load build definition from Dockerfile        	0.0s
 => => transferring dockerfile: 608B                        	0.0s
 => [internal] load metadata for docker.io/library/centos:7  	1.7s
 => [1/6] FROM docker.io/library/centos:7@sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4       0.0s
 => [internal] load build context              					1.3s
 => => transferring context: 150.99MB        					1.2s
 => CACHED [2/6] WORKDIR /USR/LOCAL/      						0.0s
 => [3/6] RUN yum -y install vim      							173.5s
 => [4/6] COPY readme.md /usr/local//readme.md      			0.1s
 => [5/6] ADD jdk-8u381-linux-x64.tar.gz /usr/local/    		3.3s 
 => [6/6] ADD apache-tomcat-9.0.78.tar.gz /usr/local/          	0.3s 
 => exporting to image             								2.5s 
 => => exporting layers         								2.5s 
 => => writing image sha256:2aa52cbbd4007ca8296221fccead04a89569723f8c1c70d98632a753fb4cbd8d    		 0.0s 
 => => naming to docker.io/library/hhu_tomcat 
 
[root@VM-0-5-centos docker]#  docker run -d -p 8080:8080 --name hhu_tomcat -v /home/docker/hhu_tomcat/webapps:/usr/local/apache-tomcat-9.0.78/webapps -v /home/docker/hhu_tomcat/logs:/usr/local/apache-tomcat-9.0.78/logs hhu_tomcat

发布自己的镜像

发布到DockerHub

  1. 在DockerHub注册账号

  2. 服务器上登录

    [root@VM-0-5-centos docker]# docker login -u 用户名 -p 密码
    WARNING! Using --password via the CLI is insecure. Use --password-stdin.
    WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    
    Login Succeeded
    [root@VM-0-5-centos docker]# 
  3. 推送(直接推送是不允许的,没有指定用户会推送到dockerhub,这样是不允许的)

    [root@VM-0-5-centos docker]# docker push hhu_tomcat
    .....
    denied: requested access to the resource is denied
    
    [root@VM-0-5-centos docker]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
    hhu_tomcat   latest    0c76a9570958   23 hours ago   832MB
    [root@VM-0-5-centos docker]# docker tag 0c76a9570958 hhudockerhub/diytomcat
    [root@VM-0-5-centos docker]# docker images
    REPOSITORY               TAG       IMAGE ID       CREATED        SIZE
    hhudockerhub/diytomcat   latest    0c76a9570958   23 hours ago   832MB
    hhu_tomcat               latest    0c76a9570958   23 hours ago   832MB
    
    [root@VM-0-5-centos docker]# docker push hhudockerhub/diytomcat
    Using default tag: latest
    The push refers to repository [docker.io/hhudockerhub/diytomcat]
    477a9c7b6ee8: Pushed 
    5742cc94ee8c: Pushed 
    314a5ed20d51: Pushed 
    66f82c1d6412: Pushed 
    5f70bf18a086: Pushed 
    174f56854903: Pushed 
    latest: digest: sha256:d88d3d28f4868f1e765a96917a49fc486bde6444e9c64955991eb62a4fbdeb6e size: 1579
  4. 查看

    登录DockerHub账号,点击右上角头像,选择My Profile,就可以看到刚刚推送的镜像了

    push的镜像

发布到腾讯云镜像服务上

  1. 注册腾讯云控制台账号,进入控制台

  2. 搜索容器镜像云服务

    控制台容器镜像云服务
  3. 创建一个命名空间

  4. 创建一个镜像仓库

    创建好的仓库

  5. 点击上图中的快捷指令,都有提示的。

    [root@VM-0-5-centos docker]# docker login ccr.ccs.tencentyun.com --username=100024928731
    Password: 
    WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    Login Succeeded
    
    # 查看镜像Id
    [root@VM-0-5-centos docker]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
    diytomcat    latest    0c76a9570958   24 hours ago   832MB
    
    # 增加一个版本,为了传到腾讯云的仓库下,而不是dockerhub下
    [root@VM-0-5-centos docker]# docker tag 0c76a9570958 ccr.ccs.tencentyun.com/hhu_docker/docker:1.0.0
    [root@VM-0-5-centos docker]# docker images
    REPOSITORY                                 TAG       IMAGE ID       CREATED        SIZE
    ccr.ccs.tencentyun.com/hhu_docker/docker   1.0.0     0c76a9570958   24 hours ago   832MB
    diytomcat                                  latest    0c76a9570958   24 hours ago   832MB
    
    # 推送创建的那个新版本的到腾讯云仓库
    [root@VM-0-5-centos docker]# docker push ccr.ccs.tencentyun.com/hhu_docker/docker:1.0.0 
    The push refers to repository [ccr.ccs.tencentyun.com/hhu_docker/docker]
    477a9c7b6ee8: Mounted from hhu_docker/hhu_dockerhub 
    5742cc94ee8c: Mounted from hhu_docker/hhu_dockerhub 
    314a5ed20d51: Mounted from hhu_docker/hhu_dockerhub 
    66f82c1d6412: Mounted from hhu_docker/hhu_dockerhub 
    5f70bf18a086: Mounted from hhu_docker/hhu_dockerhub 
    174f56854903: Mounted from hhu_docker/hhu_dockerhub 
    1.0.0: digest: sha256:d88d3d28f4868f1e765a96917a49fc486bde6444e9c64955991eb62a4fbdeb6e size: 1579
  6. 查看

    查看推送的docker镜像

Docker网络

理解Docker网络

debug……

docker网络模式详解

[root@VM-0-5-centos ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
21a6d8f8fa1e   bridge    bridge    local
980732ce125d   host      host      local
cf2d2fe63e33   none      null      local

bridge:桥接模式,默认为该模式,此模式会为每一个容器分配,设置IP等,并将容器连接到一个docker0的虚拟网桥,通过docker0网桥以及iptables nat表配置与宿主机通信。

host:和宿主机共享网络,容器将不会虚拟出自己的网卡,配置自己的IP

null:该模式关闭了网络功能,主要用于测试

container:创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP,端口范围;用的少,局限大

bridge模式

当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方

式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将

veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络

设备加入到docker0网桥中。可以通过brctl show命令查看。

bridge模式是docker的默认网络模式,不写–net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规

则,实现端口转发功能。可以使用iptables -t nat -vnL查看。

host模式

使用 –net=host模式指定,相当于VMware中的桥接模式,与宿主机在同一个网络中,但没有独立的IP地址。

Docker 使用了Linux的Namespace技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace

隔离网络等。一个Network Namespace提供了一份独立的网络环境,包括网卡,路由,iptables 规则等都与其他Network Namespace隔离。

一个Docker容器一般会分配一个独立的Network Namespace。但是如果启动容器的时候使用host模式,name这个容器将不会获得一个独立的

Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和

端口范围。此时容器不再拥有隔离的、独立的网格栈,不拥有所有的端口资源。

none模式

加上后面的参数就行了 --net=none

none模式没有IP地址,无法连接外网,等于就是断网的状态,作用就是用于测试,生产环境一般不会用到这种。

container模式

这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信

Docker自定义网络

# 创建一个自定义网络,使用桥接模式
[root@VM-0-5-centos ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
a5e2f577f6232a83f7af794ee90ef47a1a63411a79c0a478f348b29508d8cfd5
[root@VM-0-5-centos ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
21a6d8f8fa1e   bridge    bridge    local
980732ce125d   host      host      local
a5e2f577f623   mynet     bridge    local
cf2d2fe63e33   none      null      local

# 启动两个自定义tomcat,使用上述创建好的自定义网络mynet,另外两个使用默认的docker0分发的ip
[root@VM-0-5-centos ~]# docker run -d -P --name tomcat01-mynet  --network mynet diytomcat
[root@VM-0-5-centos ~]# docker run -d -P --name tomcat02-mynet  --network mynet diytomcat
[root@VM-0-5-centos ~]# docker run -d -P --name tomcat01 diytomcat
[root@VM-0-5-centos ~]# docker run -d -P --name tomcat02 diytomcat

[root@VM-0-5-centos ~]# docker ps
[root@VM-0-5-centos ~]# docker ps
CONTAINER ID   COMMAND     				PORTS                             			  NAMES
c1713e35de5d   "/bin/sh -c '$CATALI…"   0.0.0.0:32771->8080/tcp, :::32771->8080/tcp   tomcat01
f8c2a4e33180   "/bin/sh -c '$CATALI…"   0.0.0.0:32772->8080/tcp, :::32772->8080/tcp   tomcat02
cdbbaa8e245a   "/bin/sh -c '$CATALI…"   0.0.0.0:32768->8080/tcp, :::32768->8080/tcp   tomcat01-mynet
dd15cf1b5cf5   "/bin/sh -c '$CATALI…"   0.0.0.0:32769->8080/tcp, :::32769->8080/tcp   tomcat02-mynet

# 看一下mynet的详细使用情况,可以看到tomcat01-mynet用的是192.168.0.2,tomcat02-mynet用的是192.168.0.3
[root@VM-0-5-centos ~]# docker network inspect mynet 
[
    {
        "Name": "mynet",
        "Id": "a5e2f577f6232a83f7af794ee90ef47a1a63411a79c0a478f348b29508d8cfd5",
        "Created": "2023-08-03T15:28:16.495919428+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
......
        "Containers": {
            "cdbbaa8e245adf1cd028e6927c2df42076bf7f2f03b405e8645f35029dc1f179": {
                "Name": "tomcat01",
                "EndpointID": "11d76112814b389f0b42394f3faf93e70b18b8b2799887f3749ecea61d4e51bb",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "dd15cf1b5cf547e66dd24cc80455362917a0f800d002f12579e64fe28343d28c": {
                "Name": "tomcat02",
                "EndpointID": "9d236a4decbc9d1835e2fe463bf61a55dd2238a749440dee40175b5faa3a8b9f",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

# 使用mynet的容器内是可以ping通的
[root@VM-0-5-centos ~]# docker exec -it dd15cf1b5cf5 ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.043 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.038 ms
64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.029 ms
^C
--- 192.168.0.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.029/0.036/0.043/0.009 ms

# 使用docker0的tomcat01就ping不通使用mynet的tomcat01-mynet
[root@VM-0-5-centos ~]# docker exec -it tomcat01 ping 192.168.0.2
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
^C
--- 192.168.0.3 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 1999ms

网络连通

使用命令docker network connect 网络名 容器名

[root@VM-0-5-centos ~]# docker network inspect bridge 
......
        "Containers": {
            "c1713e35de5d858c5e43fac8434fd0415e0735f73355becd1632e08a2425894e": {
                "Name": "tomcat01",
                "EndpointID": "5c20c973c0d93260650222fd0022e058d112e2484062c53037d1905b252f83ec",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            },
            "f8c2a4e33180bc66d66e17d57468f8144c090b992a0c57b32c28b230ccbe3bb7": {
                "Name": "tomcat02",
                "EndpointID": "1bfe12bae694c6959149dae195d1d5099afce73f6561f6c0fa842f4d8b72d771",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            }
        },
......
[root@VM-0-5-centos ~]# docker network inspect mynet 
......
        "Containers": {
            "cdbbaa8e245adf1cd028e6927c2df42076bf7f2f03b405e8645f35029dc1f179": {
                "Name": "tomcat01-mynet",
                "EndpointID": "11d76112814b389f0b42394f3faf93e70b18b8b2799887f3749ecea61d4e51bb",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "dd15cf1b5cf547e66dd24cc80455362917a0f800d002f12579e64fe28343d28c": {
                "Name": "tomcat02-mynet",
                "EndpointID": "9d236a4decbc9d1835e2fe463bf61a55dd2238a749440dee40175b5faa3a8b9f",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
......

# 把tomcat01(原来使用的是docker0)和mynet连接起来
[root@VM-0-5-centos ~]# docker network connect mynet  tomcat01

# 发现mynet里面多了一个tomcat01
[root@VM-0-5-centos ~]# docker network inspect mynet 
......
        "Containers": {
            "c1713e35de5d858c5e43fac8434fd0415e0735f73355becd1632e08a2425894e": {
                "Name": "tomcat01",
                "EndpointID": "f1ff92a5bc4b206ffa787bb4663091b69309fbc4021eb97b47787ef0e8d7e9fb",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
            },        
            "cdbbaa8e245adf1cd028e6927c2df42076bf7f2f03b405e8645f35029dc1f179": {
                "Name": "tomcat01-mynet",
                "EndpointID": "11d76112814b389f0b42394f3faf93e70b18b8b2799887f3749ecea61d4e51bb",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "dd15cf1b5cf547e66dd24cc80455362917a0f800d002f12579e64fe28343d28c": {
                "Name": "tomcat02-mynet",
                "EndpointID": "9d236a4decbc9d1835e2fe463bf61a55dd2238a749440dee40175b5faa3a8b9f",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
......

# 发现可以ping通了
[root@VM-0-5-centos ~]# docker exec -it tomcat01 ping tomcat02-mynet 
PING tomcat02-mynet (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat02-mynet.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.045 ms
64 bytes from tomcat02-mynet.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.046 ms

Docker网络实战——Redis集群

# 创建一个自定义网络
[root@VM-0-5-centos ~]# docker network create redis-net  --driver  bridge --subnet 172.38.0.0/16 

# 通过脚本创建6个redis配置
for port in $(seq 1 6); \
do \
mkdir -p /home/docker/redis/node-${port}/conf
touch /home/docker/redis/node-${port}/conf/reids.conf
cat << EOF > /home/docker/redis/node-${port}/conf/reids.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

# 启动redis-1
[root@VM-0-5-centos ~]# docker run -d --name redis-1 -p 6371:6379 -p 16371:16379 --net redis-net --ip 172.38.0.11 -v /home/docker/redis/node-1/data:/data -v  /home/docker/redis/node-1/conf/reids.conf:/etc/redis/redis.conf redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 启动redis-2,同理,redis-3,redis-4,redis-5,redis-6
[root@VM-0-5-centos ~]# docker run -d --name redis-2 -p 6372:6379 -p 16372:16379 --net redis-net --ip 172.38.0.12 -v /home/docker/redis/node-2/data:/data -v  /home/docker/redis/node-2/conf/reids.conf:/etc/redis/redis.conf redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 创建redis集群, --cluster-replicas 1 执行集群中一个主节点的从节点个数(当前总结是6,1主1从,最终为3主,3从)
/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379  172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.38.0.15:6379 to 172.38.0.11:6379
Adding replica 172.38.0.16:6379 to 172.38.0.12:6379
Adding replica 172.38.0.14:6379 to 172.38.0.13:6379
M: e0bab02a0d11bfdb119f67815931ef978f8d9f9d 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
M: baed99ebdfbad1cc24866979b854df63b119bdc8 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: b8feb6045100f187b7ee30eda7da7503fa05712a 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: 56e61f301385a97e42982e632292428175d049ca 172.38.0.14:6379
   replicates b8feb6045100f187b7ee30eda7da7503fa05712a
S: 5899877df5a8c585cc3bc27668fe9975a8eea396 172.38.0.15:6379
   replicates e0bab02a0d11bfdb119f67815931ef978f8d9f9d
S: 3e72cdcdae0dccad967340b85f98d616e0aeaa7b 172.38.0.16:6379
   replicates baed99ebdfbad1cc24866979b854df63b119bdc8
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
..
>>> Performing Cluster Check (using node 172.38.0.11:6379)
M: e0bab02a0d11bfdb119f67815931ef978f8d9f9d 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: baed99ebdfbad1cc24866979b854df63b119bdc8 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 5899877df5a8c585cc3bc27668fe9975a8eea396 172.38.0.15:6379
   slots: (0 slots) slave
   replicates e0bab02a0d11bfdb119f67815931ef978f8d9f9d
M: b8feb6045100f187b7ee30eda7da7503fa05712a 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 56e61f301385a97e42982e632292428175d049ca 172.38.0.14:6379
   slots: (0 slots) slave
   replicates b8feb6045100f187b7ee30eda7da7503fa05712a
S: 3e72cdcdae0dccad967340b85f98d616e0aeaa7b 172.38.0.16:6379
   slots: (0 slots) slave
   replicates baed99ebdfbad1cc24866979b854df63b119bdc8
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

# 以集群方式启动redis客户端
/data # redis-cli -c
127.0.0.1:6379> CLUSTER nodes
baed99ebdfbad1cc24866979b854df63b119bdc8 172.38.0.12:6379@16379 master - 0 1691133749107 2 connected 5461-10922
e0bab02a0d11bfdb119f67815931ef978f8d9f9d 172.38.0.11:6379@16379 myself,master - 0 1691133748000 1 connected 0-5460
5899877df5a8c585cc3bc27668fe9975a8eea396 172.38.0.15:6379@16379 slave e0bab02a0d11bfdb119f67815931ef978f8d9f9d 0 1691133748105 5 connected
b8feb6045100f187b7ee30eda7da7503fa05712a 172.38.0.13:6379@16379 master - 0 1691133749006 3 connected 10923-16383
56e61f301385a97e42982e632292428175d049ca 172.38.0.14:6379@16379 slave b8feb6045100f187b7ee30eda7da7503fa05712a 0 1691133749000 4 connected
3e72cdcdae0dccad967340b85f98d616e0aeaa7b 172.38.0.16:6379@16379 slave baed99ebdfbad1cc24866979b854df63b119bdc8 0 1691133749000 6 connected

SpringBoot微服务打包docker镜像

  1. 初始化一个springboot项目

  2. 随便写一个接口

    package com.example.demo.controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class HelloController {
        @RequestMapping("/hello")
        public String hello(){
            return "<h1>Hello,World</h1>";
        }
    }
  3. 点击idea的package,打包项目

  4. 编写Dockerfile文件

    FROM java:8
    LABEL authors="hhu"
    CMD "------ SERVER.PORT:8080 ------"
    COPY *.jar /app.jar
    EXPOSE 8080
    ENTRYPOINT ["java", "-jar","/app.jar"]
  5. 使用FTP客户端把上图中打包出来的demo-0.0.1-SNAPSHOT.jarDockerfile文件上传到服务器

  6. docker build -t xxx . 使用上传的Dockerfile构建项目

  7. docker run -d -p 8080:8080 xxx运行项目

  8. 访问 公网ip:8080/hello

Tag标签测试

tag行标签

我是测试文本

tag行内标签

我是一段文字,我是行内标签,好看吧!!

测试组图


狂神说_Docker教程
https://codeofhh.cn/2023/07/20/狂神说_Docker教程/
作者
hhu
发布于
2023年7月20日
许可协议