Docker教程(超全总结)_docker教程

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

写在前面

推荐一个不错的Docker讲解视频链接https://www.bilibili.com/video/BV1og4y1q7M4

【狂神说Java】Docker最新超详细版教程通俗易懂

概述

官网: https://docs.docker.com/

Docker Hub 网站: https://hub.docker.com/

容器较为官方的解释

一句话概括容器容器就是将软件打包成标准化单元以用于开发、交付和部署。

  • 容器镜像是轻量的、可执行的独立软件包 包含软件运行所需的所有内容代码、运行时环境、系统工具、系统库和设置。
  • 容器化软件适用于基于 Linux 和 Windows 的应用在任何环境中都能够始终如一地运行。
  • 容器赋予了软件独立性使其免受外在环境差异例如开发和预演环境的差异的影响从而有助于减少团队间在相同基础设施上运行不同软件时的冲突。

容器较为通俗的解释

如果需要通俗地描述容器的话我觉得容器就是一个存放东西的地方就像书包可以装各种文具、衣柜可以放各种衣服、鞋架可以放各种鞋子一样。我们现在所说的容器存放的东西可能更偏向于应用比如网站、程序甚至是系统环境。

在这里插入图片描述

虚拟化技术和容器化技术

虚拟化技术

首先Docker 容器虚拟化技术为基础的软件那么什么是虚拟化技术呢

简单点来说虚拟化技术可以这样定义

虚拟化技术是一种资源管理技术是将计算机的各种实体资源CPU内存磁盘空间网络适配器等予以抽象、转换后呈现出来并可供分割、组合为一个或多个电脑配置环境。由此打破实体结构间的不可切割的障碍使用户可以比原本的配置更好的方式来应用这些电脑硬件资源。这些资源的新虚拟部分是不受现有资源的架设方式地域或物理配置所限制。一般所指的虚拟化资源包括计算能力和数据存储。

Docker 基于 LXC 虚拟容器技术

Docker 技术是基于 LXCLinux container- Linux 容器虚拟容器技术的。

LXC其名称来自 Linux 软件容器Linux Containers的缩写一种操作系统层虚拟化Operating system–level virtualization技术为 Linux 内核容器功能的一个用户空间接口。它将应用软件系统打包成一个软件容器Container内含应用软件本身的代码以及所需要的操作系统核心和库。通过统一的名字空间和共用 API 来分配不同软件容器的可用硬件资源创造出应用程序的独立沙箱运行环境使得 Linux 用户可以容易的创建和管理系统或应用容器。

LXC 技术主要是借助 Linux 内核中提供的 CGroup 功能和 name space 来实现的通过 LXC 可以为软件提供一个独立的操作系统运行环境。

cgroup 和 namespace 介绍

  • namespace 是 Linux 内核用来隔离内核资源的方式。 通过 namespace 可以让一些进程只能看到与自己相关的一部分资源而另外一些进程也只能看到与它们自己相关的资源这两拨进程根本就感觉不到对方的存在。具体的实现方式是把一个或多个进程的相关资源指定在同一个 namespace 中。Linux namespaces 是对全局系统资源的一种封装隔离使得处于不同 namespace 的进程拥有独立的全局系统资源改变一个 namespace 中的系统资源只会影响当前 namespace 里的进程对其他 namespace 中的进程没有影响。

    以上关于 namespace 介绍内容来自https://www.cnblogs.com/sparkdev/p/9365405.html 更多关于 namespace 的呢内容可以查看这篇文章 。

  • CGroup 是 Control Groups 的缩写是 Linux 内核提供的一种可以限制、记录、隔离进程组 (process groups) 所使用的物力资源 (如 cpu memory i/o 等等) 的机制。

    以上关于 CGroup 介绍内容来自 https://www.ibm.com/developerworks/cn/linux/1506_cgroup/index.html 更多关于 CGroup 的呢内容可以查看这篇文章 。

cgroup 和 namespace 两者对比

两者都是将进程进行分组但是两者的作用还是有本质区别。namespace 是为了隔离进程组之间的资源而 cgroup 是为了对一组进程进行统一的资源监控和限制。

Docker基本组成

Docker 中有非常重要的三个基本概念理解了这三个概念就理解了 Docker 的整个生命周期。

  • 镜像Image
  • 容器Container
  • 仓库Repository

理解了这三个概念就理解了 Docker 的整个生命周期

在这里插入图片描述

Docker安装

查看系统内核和系统信息

命令

uname -r     #查看系统内核版本
cat /etc/os-release  #查看系统版本

示例

[root]# uname -r
4.18.0-348.7.1.el8_5.x86_64

[root]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="8 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="CentOS Linux 8 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:8"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

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

开始安装Docker

卸载旧版本

命令

yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

示例

[root@iZ1608aqb7ntn9Z /]# yum remove docker \
>                   docker-client \
>                   docker-client-latest \
>                   docker-common \
>                   docker-latest \
>                   docker-latest-logrotate \
>                   docker-logrotate \
>                   docker-engine
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
没有软件包需要移除。
依赖关系解决。
无需任何处理。
完毕

下载依赖安装包

yum install -y yum-utils

配置镜像仓库

#国外的地址
yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo  
    
# 设置阿里云的Docker镜像仓库
yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

示例

[root]# yum-config-manager \
>     --add-repo \
>     https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
添加仓库自https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

更新yum软件包

yum makecache fast 
#更新索引的时候出错即centos8没有该参数解决办法为去掉fast参数

下载docker

yum install docker-ce docker-ce-cli containerd.io   # 安装社区版
yum install docker-ee docker-ee-cli containerd.io   # 安装企业版

一般情况下安装社区版

启动Docker

命令

systemctl start docker   # 启动Docker
docker version           # 查看当前版本号是否启动成功
systemctl enable docker  # 设置开机自启动

示例

$ systemctl start docker

$ docker version
Client: Docker Engine - Community
 Version:           20.10.14
 API version:       1.41
 Go version:        go1.16.15
 Git commit:        a224086
 Built:             Thu Mar 24 01:47:44 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.14
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.16.15
  Git commit:       87a90dc
  Built:            Thu Mar 24 01:46:10 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.5.11
  GitCommit:        3df54a852345ae127d1fa3092b95168e4a88e2f8
 runc:
  Version:          1.0.3
  GitCommit:        v1.0.3-0-gf46b6ba
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Docker的HelloWorld

命令

docker run hello-world

示例

$ docker run hello-world
Unable to find image 'hello-world:latest' locally  # 本地没有
latest: Pulling from library/hello-world           # pull一个最新版
2db29710123e: Pull complete                        # pull成功
Digest: sha256:10d7d58d5ebd2a652f4d93fdd86da8f265f5318c6a73cc5b6a9798ff6d2b2e67
Status: Downloaded newer image for hello-world:latest

Hello from Docker!                                 # 运行结果
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

Docker卸载

yum remove docker-ce docker-ce-cli containerd.io  # 卸载依赖
rm -rf /var/lib/docker    # 删除资源  . /var/lib/docker是docker的默认工作路径

配置阿里云镜像

进入阿里云官网搜索容器镜像服务

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dikPDByc-1628378213410)(Docker学习笔记.assets/image-20210803135001995.png)]

执行命令

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://axvfsf7e.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

Docker运行流程和原理

在这里插入图片描述

启动流程

在这里插入图片描述

运行原理

在这里插入图片描述

Docker整体架构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p5ZfnhrM-1628378213415)(Docker学习笔记.assets/image-20210803134704395.png)]

Docker常用命令

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

管理镜像常用命令
在这里插入图片描述

创建容器

容器限制

基本命令

命令

docker version          #查看docker的版本信息
docker info             #查看docker的系统信息,包括镜像和容器的数量
docker 命令 --help       #帮助命令(可查看可选的参数)
docker COMMAND --help

示例

$ docker info
Client:
 Context:    default
 Debug Mode: false
 Plugins:
  app: Docker App (Docker Inc., v0.9.1-beta3)
  buildx: Docker Buildx (Docker Inc., v0.8.1-docker)
  scan: Docker Scan (Docker Inc., v0.17.0)

Server:
 Containers: 1
  Running: 0
  Paused: 0
  Stopped: 1
 Images: 1
 Server Version: 20.10.14
......

镜像命令

docker images 查看本地主机的所有镜像

示例

$ docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    feb5d9fea6a5   6 months ago   13.3kB

列表参数介绍

# 解释:
1.REPOSITORY  镜像的仓库源
2.TAG  镜像的标签
3.IMAGE ID 镜像的id
4.CREATED 镜像的创建时间
5.SIZE 镜像的大小

# 可选参数
-a/--all 列出所有镜像
-q/--quiet 只显示镜像的id

docker search 搜索镜像

示例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CzY36m6U-1628378213417)(Docker学习笔记.assets/image-20210803143107721.png)]

#可选参数
Search the Docker Hub for images
Options:
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print search using a Go template
      --limit int       Max number of search results (default 25)
      --no-trunc        Don\'t truncate output
          

#搜索收藏数大于3000的镜像

$ docker search mysql --filter=STARS=3000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   12427     [OK]
mariadb   MariaDB Server is a high performing open sou…   4787      [OK]

docker pull 镜像名[:tag] 下载镜像

示例

$ docker pull mysql:5.7
5.7: Pulling from library/mysql
72a69066d2fe: Pull complete
93619dbc5b36: Pull complete
99da31dd6142: Pull complete
626033c43d70: Pull complete
37d5d7efb64e: Pull complete
ac563158d721: Pull complete
d2ba16033dad: Pull complete
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 rmi 删除镜像

#1.删除指定的镜像id
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker rmi -f  镜像id

#2.删除多个镜像id
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker rmi -f  镜像id 镜像id 镜像id

#3.删除全部的镜像id
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker rmi -f  $(docker images -aq)

容器命令

docker run [可选参数] image 运行容器

docker run [可选参数] image

#参数说明
--name="名字"           指定容器名字
-d                     后台方式运行
-it                    使用交互方式运行,进入容器查看内容
-p                     指定容器的端口
( -p ip:主机端口:容器端口  配置主机端口映射到容器端口
  -p 主机端口:容器端口
  -p 容器端口)
-P                     随机指定端口(大写的P)

示例

$ docker run c20987f18b13
2022-04-18 07:07:31+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2022-04-18 07:07:31+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2022-04-18 07:07:31+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.36-1debian10 started.
2022-04-18 07:07:31+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
    You need to specify one of the following:
    - MYSQL_ROOT_PASSWORD
    - MYSQL_ALLOW_EMPTY_PASSWORD
    - MYSQL_RANDOM_ROOT_PASSWORD

进入容器

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -it [容器ID] /bin/bash

exit 退出容器

#exit 停止并退出容器后台方式运行则仅退出
#Ctrl+P+Q  不停止容器退出
[root@bd1b8900c547 /]# exit
exit
[root@iZwz99sm8v95sckz8bd2c4Z ~]#

docker ps列出容器

#docker ps 
     # 列出当前正在运行的容器
-a   # 列出所有容器的运行记录
-n=? # 显示最近创建的n个容器 (default -1)
-q   # 只显示容器的编号
-s   # 显示总文件大小


$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

$ docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS                      PORTS     NAMES
703fad61eccb   c20987f18b13   "docker-entrypoint.s…"   2 minutes ago    Exited (0) 2 minutes ago              inspiring_feistel
2e6f020d0299   c20987f18b13   "docker-entrypoint.s…"   3 minutes ago    Exited (1) 3 minutes ago              angry_stonebraker
a4889b27716f   hello-world    "/hello"                 14 minutes ago   Exited (0) 14 minutes ago             trusting_mcclintock

docker rm删除容器

# 选项
-f   # 移除正在运行的容器使用SIGKILL
-l   # 移除容器间的网络连接而非容器本身
-v   # 删除与容器关联的卷

docker rm 容器id                     # 删除指定的容器,不能删除正在运行的容器,强制删除使用 rm -f
docker rm -f $(docker ps -aq)       # 删除所有的容器
docker ps -a -q | xargs docker rm   # 删除所有的容器

启动和重启容器命令

docker start 容器id          #启动容器
docker restart 容器id        #重启容器
docker stop 容器id           #停止当前运行的容器
docker kill 容器id           #强制停止当前容器

其他命令

后台启动容器

#命令 docker run -d 镜像名
$ docker run -d ubuntu                                                   
c21cd5dd2594ec109dfb7e8eeba6bd129291de1f1095389c9b31492e98360947

#问题docker ps发现ubuntu停止了

#常见的坑docker容器使用后台运行就必须要有一个前台进程docker发现没有应用了就会自动停止
#nginx容器启动后发现自己没有提供服务就会立刻停止就是没有程序了

查看日志

$ docker logs --help

Usage:  docker logs [OPTIONS] CONTAINER

Fetch the logs of a container

Options:
-f       # 跟踪日志输出
--since  # 显示某个开始时间的所有日志
-t       # 显示时间戳
-n      # 仅列出最新N条容器日志默认为“全部”

常用
docker logs -tf 容器id
docker logs --tail number 容器id #num为要显示的日志条数
docker logs -n number 容器id     #num为要显示的日志条数

#docker容器后台运行必须要有一个前台的进程否则会自动停止
#编写shell脚本循环执行使得centos容器保持运行状态
$ docker run -d centos /bin/sh -c "while true;do echo hi;sleep 5;done"
f51f3cbb27511b49d85c98fa62691a1a19397d4a272a8cc7d4769d3d6ec41f2a

$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS         PORTS     NAMES
f51f3cbb2751   centos    "/bin/sh -c 'while t…"   10 seconds ago   Up 9 seconds             busy_ride

$ docker logs -tf --tail 10 f51f3cbb2751
2022-04-18T07:24:27.364628955Z hi
2022-04-18T07:24:32.365938530Z hi
2022-04-18T07:24:37.367324268Z hi
2022-04-18T07:24:42.368615239Z hi
2022-04-18T07:24:47.369976390Z hi
2022-04-18T07:24:52.371426169Z hi
2022-04-18T07:24:57.372834380Z hi
2022-04-18T07:25:02.374156939Z hi
2022-04-18T07:25:07.375425598Z hi

查看容器中进程信息

# 命令 docker top 容器id
$ docker top f51f3cbb2751
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                17874               17853               0                   15:24               ?                   00:00:00            /bin/sh -c while true;do echo hi;sleep 5;done
root                18164               17874               0                   15:25               ?                   00:00:00            /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 5

查看镜像的元数据

$ docker inspect 容器id

#docker inspect : 获取容器/镜像的元数据。

#语法
docker inspect [OPTIONS] NAME|ID [NAME|ID...]

#OPTIONS说明
-f :指定返回值的模板文件。
-s :显示总的文件大小。
--type :为指定类型返回JSON。

进入当前正在运行的容器

方式一



# 我们通常容器使用后台方式运行的 需要进入容器修改一些配置
 
# 命令
docker exec -it 容器id /bin/bash
 
# 测试
$ docker exec -it df358bc06b17 /bin/bash
[root@df358bc06b17 /]# ls       
bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr
[root@df358bc06b17 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Aug11 pts/0    00:00:00 /bin/bash
root        29     0  0 01:06 pts/1    00:00:00 /bin/bash
root        43    29  0 01:06 pts/1    00:00:00 ps -ef
 
# 方式二
docker attach 容器id
 
# docker exec       # 进入容器后开启一个新的终端可以在里面操作
# docker attach     # 进入容器正在执行的终端不会启动新的进程
#语法
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

#OPTIONS说明
-d :分离模式: 在后台运行
-i :即使没有附加也保持STDIN 打开
-t :分配一个伪终端

拷贝容器文件到主机

拷贝容器的文件到主机中

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

#进入容器中

$ docker cp 8b84603c410a:/home/test.java /home


$ ls
alex  arod  hello.java  neos  test.java

#拷贝只是一个手动功能未来我们使用 -v 卷的技术可以实现自动同步

常用命令小结

在这里插入图片描述

Docker图形化管理工具

Docker UI

命令

docker search dockerui
docker pull abh1nav/dockerui
docker run -d --privileged --name dockerui -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock abh1nav/dockerui  
#放开物理机的9000端口对应Docker容器的9000端口

示例

$ docker search dockerui
NAME                           DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
abh1nav/dockerui               An updated version of crosbymichael/dockerui…   99                   [OK]
kevan/dockerui                 Deprecated: Use  uifd/ui-for-docker             15                   [OK]
......

$ docker pull abh1nav/dockerui
Using default tag: latest
latest: Pulling from abh1nav/dockerui
Image docker.io/abh1nav/dockerui:latest uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/
a3ed95caeb02: Pull complete
5d3df020ecd3: Pull complete
bebf5a3b4dfb: Pull complete
e4452c0fe72b: Pull complete
6167d9726b07: Pull complete
53ebae19a314: Pull complete
Digest: sha256:a9c6c5393f561a0f42f41cfa80572b666e745d9b419569c42bac1e5cf9ceda32
Status: Downloaded newer image for abh1nav/dockerui:latest
docker.io/abh1nav/dockerui:latest

$ docker run -d --privileged --name dockerui -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock abh1nav/dockerui
959047ff6deba1e5d31017024a41b611e48f416a6f87f2cad4f528801a260c52

使用

访问http://ip地址:9000

会出现如下的界面

Shipyard

镜像下载

[docker@docker ~]$ docker pull alpine
[docker@docker ~]$ docker pull library/rethinkdb
[docker@docker ~]$ docker pull microbox/etcd
[docker@docker ~]$ docker pull shipyard/docker-proxy
[docker@docker ~]$ docker pull swarm
[docker@docker ~]$ docker pull shipyard/shipyard   #英文版

脚本安装shipyard

#安装shipyard中文版

curl http://dockerclub.net/deploy | bash -s

Portainer

命令

docker search portainer
docker pull portainer/portainer
docker run -d --name portainerUI -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer

示例

$ docker search portainer
NAME                                   DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
portainer/portainer                    This Repo is now deprecated, use portainer/p…   2201
portainer/portainer-ce                 Portainer CE - a lightweight service deliver…   1100
......                  

$ docker pull portainer/portainer
Using default tag: latest
latest: Pulling from portainer/portainer
94cfa856b2b1: Pull complete
49d59ee0881a: Pull complete
a2300fd28637: Pull complete
Digest: sha256:fb45b43738646048a0a0cc74fcee2865b69efde857e710126084ee5de9be0f3f
Status: Downloaded newer image for portainer/portainer:latest
docker.io/portainer/portainer:latest

$ docker run -d --name portainerUI -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
abbf483bd3df0e30eaeb3a0dd708776a6fbbf055e2c87bcb84177df7e86c8ac2

使用

访问http://ip地址:9000

常见容器部署Nginx, Tomcat, es + kibana

Nginx

命令

# 1. 查找镜像, 建议去docker官网搜索可以看到帮助文档 https://registry.hub.docker.com/
docker search nginx

# 2. 下载镜像 pull
docker pull nginx

# 3. 运行测试
docker images

# 4.

docker run -d --name nginx -p 3344:80 nginx   # 启动
curl localhost:3344  # 本机测试访问
# 备注
# -d 后台运行
# --name 给容器命名
# -p 3334:80 将宿主机的端口3334映射到该容器的80端口


# 进入容器
$ docker exec -it nginx /bin/bash
root@c70636684cd8:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@c70636684cd8:/# cd /etc/nginx/
root@c70636684cd8:/etc/nginx# ls
conf.d  fastcgi_params  mime.types  modules  nginx.conf  scgi_params  uwsgi_params

# 关闭容器
$ docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED             STATUS             PORTS                                       NAMES
c70636684cd8   nginx              "/docker-entrypoint.…"   11 minutes ago      Up 11 minutes      0.0.0.0:3344->80/tcp, :::3344->80/tcp       nginx
959047ff6deb   abh1nav/dockerui   "./dockerui"             About an hour ago   Up About an hour   0.0.0.0:9000->9000/tcp, :::9000->9000/tcp   dockerui
f51f3cbb2751   centos             "/bin/sh -c 'while t…"   About an hour ago   Up About an hour                                               busy_ride

$ docker stop c70636684cd8
c70636684cd8
# 发现访问不了此网站

测试访问

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Aqvif9AC-1628378213420)(Docker学习笔记.assets/image-20210804143438878.png)]

Tomcat

命令

# 官方的使用
docker run -it --rm tomcat:9.0
# 我们之前的启动都是后台的停止了容器之后 容器还是可以查到docker run -it --rm 一般用来测试用完就删

# 下载再启动
docker pull tomcat

# 启动运行
docker run -d -p 3355:8080 --name tomcat01 tomcat

# 测试访问没有问题

# 进入容器
docker exec -it tomcat01 /bin/bash

# 发现问题1.linux命令少了 2. webapps下内容为空阿里云默认是最小的镜像所有不必要的都剔除了
# 保证最小可运行环境即可

root@fd58d9c477e4:/usr/local/tomcat# cp -r webapps.dist/* webapps
## 网站恢复访问

测试访问

es + kibana

添加 ’-e ES_JAVA_OPTS=“-Xms128m -Xmx512m” ‘ 配置ElasticSearch的虚拟机占用的内存大小。

docker stats 查看资源占用情况

# es 暴露的端口很多
# es 十分的耗内存
# es 的数据一般需要放置到安全目录 挂载
# --net somenetwork ?  网络配置
 
# 启动elasticsearch
docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
 
$ docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
a920894a940b354d3c867079efada13d96cf9138712c76c8dea58fabd9c7e96f
 
# 启动了linux就卡住了docker stats 查看cpu状态
 
# 测试一下es成功了
$ curl localhost:9200
{
  "name" : "a920894a940b",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "bxE1TJMEThKgwmk7Aa3fHQ",
  "version" : {
    "number" : "7.6.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
    "build_date" : "2020-03-26T06:34:37.794943Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}
 
 
# 增加内存限制修改配置文件 -e 环境配置修改
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2

$ docker stats

端口暴露的原理

[外链图片转存中...(img-wrWtj9Ol-1628378213423)]

可视化

  • portainer先用这个
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
 
# 测试
$ curl localhost:8088
<!DOCTYPE html
><html lang="en" ng-app="portainer">
......
    ><!-- End Page Wrapper -->
  <script type="text/javascript" src="vendor.50213a000e42f5c05bcc.js"></script><script type="text/javascript" src="main.50213a000e42f5c05bcc.js"></script></body></html
>

# 外网访问 http://ip:8088

  • Rancher(CI/CD再用)

Docker镜像讲解

镜像是什么

Docker镜像是一种轻量级、可执行的独立软件包用来打包软件运行环境和基于运行环境开发的软件它包含某个软件所需的所有内容包括代码、库、环境变量、配置文件、运行时环境等。
所有的应用直接打包成Docker镜像然后通过镜像创建出容器然后就可以直接跑起来。

如何得到镜像

  • 从远程仓库下载比如docker hub、阿里云的镜像仓库等。
  • 朋友拷贝给你。
  • 自己制作一个镜像DockerFile。

通过对原有的镜像创建的容器进行一些修改也可以不修改然后通过Commit命令提交一个新的镜像。

UnionFS联合文件系统

  • 联合文件系统UnionFS是一种分层、轻量级并且高性能的文件系统它支持对文件系统的修改作为一次提交来一层层的叠加同时可以将不同目录挂载到同一个虚拟文件系统下。联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承基于基础镜像没有父镜像可以制作各种具体的应用镜像。

  • 特性一次同时加载多个文件系统但从外面看起来只能看到一个文件系统。联合加载会把各层文件系统叠加起来这样最终的文件系统会包含所有底层的文件和目录。

Docker镜像加载原理

docker镜像实际上是由一层层的文件系统组成这种层级文件系统就是联合文件系统。

  • bootfsboot file system主要包含BootLoader和kernelBootLoader主要负责引导加载kernelLinux刚启动时会加载bootfs文件系统来引导内核的加载Docker镜像的最底层就是bootfs。这一层与我们典型的unix系统是一样的包含boot引导器和内核当boot加载完成后整个内核就在内存中了此时内存的使用权已经由bootfs转交给内核此时系统会卸载bootfs。

  • rootfsroot file system包含典型Linux系统中的/dev/proc/bin/etc等标准目录和文件。rootfs就是各种不同Unix操作系统发行版UbuntuCentos等。因为底层直接用Host的kernelrootfs只包含最基本的命令工具和程序就可以了。

我们平时安装的虚拟机centos镜像好几个GDocker安装的才200多M因为对于一个精简的OSrootfs可以很小只需包含最基本的命令工具和程序库就行了因为底层直接使用宿主机的内核自己只需提供rootfs相当于操作内核的客户端就可以由此可见不同发行版的bootfs基本是一致的roorfs有差别因此不同的发行版可以公有bootfs。虚拟机是分钟级别容器是秒级。

第一个图仅仅是bootfs+rootfs然后如果要制作一个emacs环境的镜像就在这个基础上新加一层emacs镜像如图二。如果要在添加一个Apache环境那就再图二基础上加一个apache镜像。如图三。图中的每一层镜像都能进行复用。

分层理解

分层的镜像

image-20210521222350269

比如上面的redis镜像。使用docker inspect redis镜像的ID 命令查看镜像的元信息找到layer信息。

image-20210521222535031

由上图可以看到下载的redis镜像是由6个镜像一层层组成的。

19-4

这些镜像都是一个个独立可复用的镜像如果下载其他镜像是某一层镜像是已经存在本地的了就不用在下载直接复用该镜像节省空间。比如上面下载redis镜像时提示某个镜像已经存在。

注意
Docker镜像都是只读的用镜像创建容器启动时实际上是在原本的镜像上新建了一层可写层到原本镜像的顶部这一层我们叫作容器层容器层之下的叫作镜像层。

在这里插入图片描述

如上图使用Tomcat镜像创建容器后会在Tomcat镜像的基础上新建一个可写层容器的写入是在可写层进行记录然后使用commit命令把该容器创建一个新的镜像实际上新的镜像是tomcat镜像+可写层镜像以tomcat镜像为基础。通过下面介绍使用容器构建镜像可以更好地理解。

commit镜像

命令

docker commit 提交容器成为一个新的副本
docker commit -m="描述信息类似git提交的信息" -a="作者" 容器id  目标镜像名:[TAG]$ 编辑容器后提交容器成为一个新镜像a

实战测试

#1.启动一个默认的tomcat
docker run -it -p 8080:8080 tomcat
#2.发现这个默认的tomcat是没有webapps的应用镜像的原因官方的镜像默认webapps下面是没有文件的

#3.自己拷贝进去基本的文件
cp -r webapps.dist/* webapps

#4.将修改后的容器通过commit提交为新的镜像~我们以后就使用我们自己制作的镜像了
docker commit =a="lixingze" -m="add webapps app" 容器ID tomcat02:1.0

image-20210521224755933

容器数据卷

什么是容器数据卷

为了实现数据持久化使容器之间可以共享数据。可以将容器内的目录挂载到宿主机上或其他容器内实现同步和共享的操作。即使将容器删除挂载到本地的数据卷也不会丢失。

docker的理念回顾

将应用和环境打包成一个镜像

数据如果都在容器中那么我们容器一旦删除数据就会丢失 需求数据可以持久化

MySQL容器删了删库跑路 需求MySQL数据可以存储在本地

容器之间可以有一个数据共享的技术Docker容器中产生的数据同步到本地

这就是卷技术目录的挂载将我们容器内的目录挂载到Linux上面

容器的持久化和同步操作容器间也是可以做数据共享的

使用数据卷

方式一直接使用命令来挂载 -v

docker run -it -v 主机目录容器内目录

#测试
$ docker run -it -v /home/ceshi:/home centos /bin/bash

#启动后查看挂载情况
$ docker inspect 990046eb50f5

在这里插入图片描述

测试文件的同步在主机上改动观察容器变化

在这里插入图片描述

再来测试测试通过

  1. 停止容器

  2. 主机上修改文件

  3. 启动容器

  4. 容器内的数据依旧是同步的

好处我们以后只要在本地进行修改即可不需要每次都进入容器内部都能实现自动同步

实战安装MySQL

思考MySQL的数据持久化的问题

#获取镜像
$ docker pull mysql

#运行容器需要做数据挂载 
#安装启动mysql需要配置密码注意
#官方测试docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

#启动自己的
-d 后台运行
-p 端口映射
-e 环境配置
--name 容器名字

$ 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=[password] --name mysql01 mysql

#启动成功之后在本地用数据库连接工具测试连接我使用的Navicat Premium

#sql可视化工具连接到服务器的3310 ---- 3310 和容器内的3306映射成功连接

#在本地测试创建一个数据库发现mysql/data 中增加了数据库数据

image-20210524213345565

假设删除了docker镜像

发现挂载到本地的数据卷依然没有丢失这实现了容器数据持久化功能

具名和匿名挂载

#匿名挂载
-v 容器内挂载
docker run -d -P --name nginx01 -v /etc/nginx nginx    $ -P 随机指定端口

#查看所有的volume的情况
$ docker volume ls
DRIVER    VOLUME NAME
local     8026aa409bf4851f9056cc3092e27493db1ee654b461b1ea05c3bedfafed3e32
#这里发现这种就是匿名挂载我们在 -v 只写了容器内的路径没有写容器外的路径

#具名挂载

$ docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
72bf479b190b74d53256311e626bab459630af2028b9c9e1a83064c2ff745d9e

$ docker volume ls
$ docker volume ls
DRIVER    VOLUME NAME
local     8026aa409bf4851f9056cc3092e27493db1ee654b461b1ea05c3bedfafed3e32
local     04862392ad0fcff6ecabd65989ae57e109a9963de0d517f4e8b305b44700795a
local     d7111fd00a6d3704ec4bd5419eee07ba6c4bac699abe227b908f6d385188c472
local     jumping-nginx


# 通过-v 卷名容器内的路径
# 查看一下这个卷
# docker volume inspect juming-nginx
 
$ docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2022-04-19T14:52:24+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
        "Name": "jumping-nginx",
        "Options": null,
        "Scope": "local"
    }
]

所有docker容器内的卷没有指定目录的情况下都是在/var/lib/docker/volumes/xxxxx/_data

我们通过具名挂载可以方便找到我们的一个卷大多数情况都使用具名挂载

#如何确定是具名挂载还是匿名挂载还是指定路径挂载
-v 容器内路径 		 #匿名挂载
-v 卷名:容器内路径	    #具名挂载
-v /宿主机路径::容器内路径  #指定路径挂载

拓展

#通过-v容器内路径ro rw改变读写权限
ro		read only #只读
rw		read write #可读可写

#一旦这个设置了容器权限容器对我们挂载出来的内容就有限定了
$ docker run -d -P --name nginx02 -v jumping-nginx:/etc/nginx:ro nginx  
$ docker run -d -P --name nginx02 -v jumping-nginx:/etc/nginx:rw nginx  

#ro 只要看到ro就说明这个路径是只能通过宿主机来操作容器内部是无法操作

初识DockerFile

Dockerfile就是用来构建docker镜像的构建文件也就是命令脚本

通过这个脚本可以生成一个镜像镜像是一层一层的脚本一个个的命令对应层数

#创建一个dockerfile文件名字可以随意建议Dockerfile
#文件中的内容 指令大写 参数
FROM centos

VOLUME ["volume01","volume02"]

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

#这里的每个命令就是镜像的一层

部署容器

1

启动自己的容器

2

这个卷和外部一定有一个同步的目录

3

在目录下新建一个测试用的文件

3-1

查看卷挂载的路径

4

测试一下刚才的文件是否同步到主机上了

5

成功。

这种方式我们未来使用的十分多 因为我们通常会构建自己的镜像

假设构建镜像时候没有挂载卷要手动镜像挂载 -v 卷名:容器内路径

数据卷容器

多个mysql同步数据

6

#启动三个容器通过我们自己写的镜像启动

7

CTRL+p+q 退出当前的docker01通过docker01挂载docker02

8

同理创建一个docker03在数据卷上新建的文件也会在其它容器上同步

#只要通过 --volumes-from 我们就可以实现容器间的数据共享

#当删除了docker01时docker02和docker03经测试依然可以访问建立的文件

多个mysql实现数据共享

$ 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=[password] --name mysql01 mysql

$ docker run -d -p 3311:3306 -e MYSQL_ROOT_PASSWORD=[password] --name mysql02 --volumes-from mysql01 mysql

#这个时候可以实现两个容器数据同步

结论

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

但是一旦持久化到了本地这个时候本地的数据是不会被删除的。

DockerFile

DockerFile介绍

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

构建步骤

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

查看一下官方是怎么做的

9

10

很多官方镜像都是基础包我们通常会自己搭建自己的镜像。

官方既然可以制作镜像那我们也可以自己构建。

DockerFile构建过程

基础知识

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

  2. 执行顺序从上到下

  3. #表示注释

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

Docker镜像原理

Dockerfile概念及作用

Dockerfile 关键字

关键字作用备注
FROM指定父镜像指定dockerfile基于那个image构建
MAINTAINER作者信息用来标明这个dockerfile谁写的
LABEL标签用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看
RUN执行命令执行一段命令 默认是/bin/sh 格式: RUN command 或者 RUN [“command” , “param1”,“param2”]
CMD容器启动命令提供启动容器时候的默认命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD [“command” , “param1”,“param2”]
ENTRYPOINT入口一般在制作一些执行就关闭的容器中会使用
COPY复制文件build的时候复制文件到image中
ADD添加文件build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务
ENV环境变量指定build时候的环境变量 可以在启动的容器的时候 通过-e覆盖 格式ENV name=value
ARG构建参数构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数
VOLUME定义外部可以挂载的数据卷指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME [“目录”]
EXPOSE暴露端口定义容器运行的时候监听的端口 启动容器的使用-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp
WORKDIR工作目录指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径
USER指定执行用户指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户
HEALTHCHECK健康检查指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制
ONBUILD触发器当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大
STOPSIGNAL发送信号量到宿主机该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。
SHELL指定执行脚本的shell指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell

Dockerfile 案例

dockerfile是面向开发的我们以后要发布项目做镜像就需要编写dockerfile文件这个文件十分简单。

步骤开发、部署、上线运维

Dockerfile构建文件定义了一切的步骤源代码

Dockerimage通过Dockerfile构建生成的镜像最终发布和运行的产品

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

DockerFile指令

以前的时候我们是使用别人的现在我们尝试用dockerfile构建一个自己的镜像

FROM 		#基础镜像一切从这里开始构建
MAINTAINER	#镜像是谁写的姓名+邮箱
RUN			#镜像构建时需要运行的命令
ADD			#步骤tomcat镜像这个tomcat压缩包添加内容
WORKDIR		#镜像工作目录
VOLUME		#挂载的目录
EXPOSE		#暴露端口配置
CMD			#指定这个容器启动的时候要运行的命令,只有最后一个会生效可被替代
ENTRYPOINT	#指定这个容器启动的时候要运行的命令可以追加命令
ONBUILD		#当构建一个被继承DockerFile 这个时候就会运行 ONBUILD 的指令触发指令
COPY		#类似ADD,将我们的文件拷贝至镜像中
ENV			#构建的时候设置环境变量

11

实战测试

DockerHub中99%的镜像都是从基础镜像过来的 FROM scratch然后配置需要的软件和配置来进行构建

12

创建一个自己的centos

#1.编写DockerFile的文件

$ cat mydockerfile-centos 
FROM centos:7
MAINTAINER lixingze<lixingzee@gmail.com>

ENV MYPATH /user/local
WORKDIR $MYPATH

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

EXPOSE 80

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

#2.通过这个文件构建镜像
#命令 docker build -f dockerfile文件路径 -t 镜像名:[tag]

$ docker build -f mydockerfile-centos -t mycentos:0.1 .

Successfully built c8310c185c21
Successfully tagged mycentos:0.1

#3.测试运行

对比之前原生的centos增加之后的镜像默认进入了工作目录且可以使用vim

13

我们可以列出本地进行的变更历史

14

我们平时拿到一个镜像可以研究一下它是如何构建的了。

CMD 和 ENTRYPOINT 区别

CMD			#指定这个容器启动的时候要运行的命令,只有最后一个会生效可被替代
ENTRYPOINT	#指定这个容器启动的时候要运行的命令可以追加命令

测试CMD

#1.编写dockerfile文件

$ cat dockerfile-cmd-test
FROM centos:7
CMD ["ls","-a"]

#2.构建镜像

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

#3.启动容器

$ docker run 608fe2c633ee
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

#想追加一个命令 -ls -al

$ docker run 608fe2c633ee -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.

#cmd的清理下 -l替换了["ls","-a"]命令-l不是命令所以报错 

测试ENTRYPOINT

# 1. 编写dockerfile文件
$ vim dockerfile-entrypoint-test 
FROM centos
ENTRYPOINT ["ls", "-a"]
 
# 2. 构建文件
$ docker build -f dockerfile-entrypoint-test -t entrypoint-test .
 
# 3. run运行 发现我们的ls -a 命令同样生效
$ docker run entrypoint-test
.
..
.dockerenv
bin
dev
etc
home
lib
 
# 4. 我们的追加命令 是直接拼接到ENTRYPOINT命令的后面的
$ docker run entrypoint-test -l
total 56
drwxr-xr-x  1 root root 4096 Aug 13 07:52 .
drwxr-xr-x  1 root root 4096 Aug 13 07:52 ..
-rwxr-xr-x  1 root root    0 Aug 13 07:52 .dockerenv
lrwxrwxrwx  1 root root    7 May 11  2019 bin -> usr/bin
drwxr-xr-x  5 root root  340 Aug 13 07:52 dev
drwxr-xr-x  1 root root 4096 Aug 13 07:52 etc
drwxr-xr-x  2 root root 4096 May 11  2019 home
lrwxrwxrwx  1 root root    7 May 11  2019 lib -> usr/lib
lrwxrwxrwx  1 root root    9 May 11  2019 lib64 -> usr/lib64
drwx------  2 root root 4096 Aug  9 21:40 lost+found
 

DockerFile中很多命令都十分相似我们需要了解他们的区别最好的学习方式就是测试并对比效果

实战Tomcat镜像

  1. 准备镜像文件 tomcat 压缩包

15

  1. 编写dockerfile文件官方命名Dockerfilebuild会自动寻找这个文件就不需要 -f 进行指定了
$ cat Dockerfile
FROM centos:7
MAINTAINER lixingze<lixingzee@gmail.com>

COPY README.txt /user/local/README.txt

ADD jdk-8u202-linux-x64.tar.gz /usr/local
ADD apache-tomcat-10.0.20.tar.gz /usr/local

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_202
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-10.0.20
ENV CATALINA_BASH /usr/local/apache-tomcat-10.0.20
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-10.0.20/bin/startup.sh && tail -F /usr/local/apache-tomcat-10.0.20/bin/logs/catalina.out
  1. 构建镜像
#docker build -t diytomcat .
  1. 启动镜像
$ docker run -d -p 9090:8080 --name lxztomcat -v /home/lxz/build/tomcat/test:/usr/local/apache-tomcat-10.0.20/webapps/test -v /home/lxz/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-10.0.20/logs diytomcat
f8fcb1d5565c7a00a46ff95ee7effb3b19a58931bb47b385cf6b11fe06cc4676
  1. 访问测试
#本地测试
curl localhost:9090

访问网站

16

  1. 发布项目由于做了卷挂载我们直接在本地编写项目就可以发布了

在tomcat的test文件夹下建立文件夹WEB-INF 在其中创建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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>FirstWebFontEnd</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

在test文件夹下创建index.jsp文件

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>首页</title>
<style>
    *{
    padding:0;
    margin:0;
    font-family:"微软雅黑";
}
.header{
    height:72px;
    background:#458fce ;
}
.header .logo{
    color:#fff ;
    line-height:70px;
    font-size:30px;
    margin-left:20px;
    display:inline-block;
    text-align:center;

}
a {
    color: #fff ;
    text-decoration: none ;
}
.header .login{
    float:right;
    color:#fff ;
    line-height:72px;
    margin-right:2px;
    display:inline-block;
}
.banner{
    height:380px;
    overflow:hidden;
    background: #ddd;
}
</style>
</head>
<body>
    <div class="header">
        <div class="logo">web实践</div>
        <div class ="login">
            <a href ="javascript:void(0)">登录</a>
            <span>|</span> 
            <a href ="javascript:void(0)">故事</a>
        </div>
    </div>
Hello World!<br/>
My blog is lxz9.com!<br/>
</body>
</html>

发现项目部署成功可以正常访问页面http://IP地址:9090/test/

17

以后开发的步骤需要掌握Dockerfile的编写我们之后的一切都是使用docker镜像来进行

发布自己的镜像

DockerHub

  1. 地址https://hub.docker.com/ 注册自己的账号

  2. 确定这个账号可以登录

  3. 在我们的服务器上提交自己的镜像

$ docker login --help

Usage:  docker login [OPTIONS] [SERVER]

Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.

Options:
  -p, --password string   Password
      --password-stdin    Take the password from stdin
  -u, --username string   Username
  1. 登录完毕后就可以提交镜像了 docker push
$ docker login -u xingzeli
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

5.提交镜像

#如果报错可以更改镜像名称试试 尽量带上版本号
$ docker tag diytomcat xingzeli/tomcat:1.0  

$ docker push xingzeli/tomcat:1.0
The push refers to repository [docker.io/xingzeli/tomcat]
85d10e85e1ff: Pushed
d3da19ae481a: Pushed
533ab4087ebb: Pushed
e7d29c8e7b5a: Pushed
174f56854903: Mounted from library/centos
1.0: digest: sha256:dff3c979a270967f2bc1b1e18170bb515c0e67938ee38f0971c1ecc7d58f06ac size: 1373

提交的时候也是按照镜像层级来进行提交的

阿里云镜像服务

  1. 登录阿里云

  2. 找到容器镜像服务

  3. 创建命名空间

  4. 创建容器镜像

  5. 浏览阿里云

18

小结

19

Docker 网络

理解Docker0

清空所有环境

# 1.列出所有的容器 ID:
docker ps -aq

# 2.停止所有的容器:
docker stop $(docker ps -aq)

# 3.删除所有的容器:
docker rm $(docker ps -aq)

# 4.删除所有的镜像
docker rmi $(docker images -q)

20

三个网络

#问题 docker是如何处理容器网络访问的

21

Docker在官网下载Tomcat镜像里面没有ip addr等命令解决

$ docker exec -it tomcat01 ip addr
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ip": executable file not found in $PATH: unknown
#容器里执行ip addr 显示 ip command not found 与tomcat镜像有关最新版的镜像阉割了很多命令连最基本的yum命令都没有了如果容器内有yum可以用 yum install net-tools 之后用ifconfig也一样如果没有yum 则进入容器 cat /etc/hosts

解决方案

  1. 进入上面你利用Tomcat镜像运行的容器。
root 16:50:34 ~
$ docker exec -it tomcat01 /bin/bash
  1. 执行下面两个命令
root@7cc13e6f0963:/usr/local/tomca$ apt update
root@7cc13e6f0963:/usr/local/tomca$ apt install -y iproute2

#apt install -y net-tools
#apt install -y iproute2
#apt install -y iputils-ping
  1. 成功
$ docker run -d -P --name tomcat01 tomcat

$ docker exec -it tomcat01 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
70: eth0@if71: <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
#查看容器的内部ip地址  ip addr ,  发现容器启动的时候会得到一个 eth0@if71 ip地址这是由docker分配的


#思考linux能不能 ping 通容器内部
$ ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.028 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.013 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.014 ms

#linux可以 ping 通docker容器内部

原理

  1. 我们每启动一个docker容器docker就会给docker容器分配一个id我们只要安装了docker就会有一个网卡docker0

桥接模式使用的技术是veth-pair技术

再次测试 ip addr

20-1

  1. 再启动一个容器测试发现又多了一对网卡

20-2

#我们发现这个容器带来的网卡都是一对一对的
#veth-pair 就是一对的虚拟设备接口他们都是成对出现的一段连着协议一段彼此相连可以通信
#正因为有这个特性 veth-pair 充当一个桥梁连接各种虚拟网络设备的
#OpenstacDocker容器之间的连接OVS的连接都是使用veth-pair技术
  1. 我们来测试下tomcat01和tomcat02是否可以ping通

20-3

$ docker exec -it tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.078 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.032 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.021 ms

#结论容器和容器之间是可以互相ping通的

绘制一个网络模型图

22

结论tomcat01 和tomcat02 是共用的一个路由器docker0。

所有的容器不指定网络的情况下都是docker0路由的docker会给我们的容器分配一个默认的可用IP

小结

docker使用的是Linux的桥接宿主机中是一个docker容器的网桥 docker0

23

docker中所有网络接口都是虚拟的虚拟的转发效率高内网传递文件

只要容器删除对应网桥一对就没了

20-4

–link

思考一个场景我们编写一个微服务database url=ip: 项目不重启数据库ip换掉了我们希望可以处理这个问题可以用名字来访问容器

$ docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
 
# 如何可以解决呢
# 通过--link既可以解决网络连通问题
$ docker run -d -P  --name tomcat03 --link tomcat02 tomcat
24fe246a54f3e169b18db73e71f17694ffbe95900b885a4653a232023ad0635b

$ docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED              STATUS              PORTS                                         NAMES
24fe246a54f3   tomcat    "catalina.sh run"   About a minute ago   Up About a minute   0.0.0.0:49160->8080/tcp, :::49160->8080/tcp   tomcat03
56140c84bab0   tomcat    "catalina.sh run"   33 minutes ago       Up 33 minutes       0.0.0.0:49159->8080/tcp, :::49159->8080/tcp   tomcat02
7cc13e6f0963   tomcat    "catalina.sh run"   3 hours ago          Up 3 hours          0.0.0.0:49158->8080/tcp, :::49158->8080/tcp   tomcat01

$ docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.129 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.100 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.110 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=4 ttl=64 time=0.107 ms
 
# 反向可以ping通吗
$ docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known


$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
be0679d23977   bridge    bridge    local
d334b9fee722   host      host      local
e56141257cf7   none      null      local

$ docker network inspect be0679d23977
# 探究inspect

20-5

其实这个tomcat03就是在本地配置了tomcat02的配置

$ docker exec -it tomcat03 cat /etc/hosts
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3  tomcat02 56140c84bab0
172.17.0.4  24fe246a54f3

本质探究–link 就是我们在hosts配置中增加了一个172.17.0.3 tomcat02 56140c84bab0

我们现在玩Docker已经不建议使用–link了

自定义网络不使用Docker0

Docker0的问题它不支持容器名链接访问

自定义网络

查看所有的docker网络

$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
be0679d23977   bridge    bridge    local
d334b9fee722   host      host      local
e56141257cf7   none      null      local

网络模式

bridge 桥接模式桥接 docker 默认自己创建的也是用brdge模式

none 不配置网络

host 和宿主机共享网络

container容器网络连通用的少 局限很大

  • 测试
# 我们直接启动的命令默认有一个 --net bridge而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat
 
# docker0特点默认容器名不能访问 --link可以打通连接
# 我们可以自定义一个网络
# --driver bridge
# --subnet 192.168.0.0/16 可以支持255*255个网络 192.168.0.2 ~ 192.168.255.254
# --gateway 192.168.0.1
$ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
340bd988f751b88da07e0213fc3941068eb5eb19dcd563b9fc9f4b952b1bc8db

$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
be0679d23977   bridge    bridge    local
d334b9fee722   host      host      local
340bd988f751   mynet     bridge    local
e56141257cf7   none      null      local

我们自己的网络就创建好了

20-6-1

在自己创建的网络里面启动两个容器

$ docker run -d -P --name tomcat-net-01 --net mynet tomcat
a3aa944c9cba8b72a540fa58d914f098282be89dd81e7f29f9cef91249898749

$ docker run -d -P --name tomcat-net-02 --net mynet tomcat
93210c62a4f513800aa3cf00310eab710427f2f5d0e95a9e177a5e13fe06fe7a

$ docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "340bd988f751b88da07e0213fc3941068eb5eb19dcd563b9fc9f4b952b1bc8db",
        "Created": "2022-04-20T20:37:39.632971496+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "93210c62a4f513800aa3cf00310eab710427f2f5d0e95a9e177a5e13fe06fe7a": {
                "Name": "tomcat-net-02",
                "EndpointID": "b1aaabbb9c8c27797a3577fdb1563ac6a0a9a3c57c9533fdd49965a7a75315a9",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "a3aa944c9cba8b72a540fa58d914f098282be89dd81e7f29f9cef91249898749": {
                "Name": "tomcat-net-01",
                "EndpointID": "52395f6049507e7128621beffe1a2b96a7de9086af5540868fff62cfaa73e266",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
 
# 再次拼连接
$ docker exec -it tomcat-net-01 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.113 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.093 ms

# 现在不使用 --link也可以ping名字了
$ docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.068 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.096 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.094 ms

我们自定义的网络docker都已经帮我们维护好了对应的关系推荐我们平时这样使用网络

好处

redis - 不同的集群使用不同的网络保证集群时安全和健康的

mysql - 不同的集群使用不同的网络保证集群时安全和健康的

网络连通

测试打通tomcat01 和 mynet

20-6

$ docker network connect  mynet tomcat01
 
# 连通之后就是讲tomcat01 放到了mynet网路下
# 一个容器两个ip地址
# 阿里云服务器公网ip私网ip
# 连通ok
$ docker exec -it tomcat01 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.100 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.085 ms

# 02依旧无法连通因为没有connect
$ docker exec -it tomcat02 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known

实战 部署Redis集群

20-7

20-8

# 创建网卡
docker network create redis --subnet 172.38.0.0/16
 
# 通过脚本创建六个redis配置
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

# 脚本创建六个节点
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf


# 创建结点1
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
#创建结点2
docker run -p 6372:6379 -p 16372:16379 --name redis-2 \
-v /mydata/redis/node-2/data:/data \
-v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点3
docker run -p 6373:6379 -p 16373:16379 --name redis-3 \
-v /mydata/redis/node-3/data:/data \
-v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点4
docker run -p 6374:6379 -p 16374:16379 --name redis-4 \
-v /mydata/redis/node-4/data:/data \
-v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点5
docker run -p 6375:6379 -p 16375:16379 --name redis-5 \
-v /mydata/redis/node-5/data:/data \
-v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点6
docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
-v /mydata/redis/node-6/data:/data \
-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
 
# 创建集群
$ docker exec -it redis-1 /bin/sh
/data # ls
appendonly.aof  nodes.conf
/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: 541b7d237b641ac2ffc94d17c6ab96b18b26a638 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
M: a89c1f1245b264e4a402a3cf99766bcb6138dbca 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: 259e804d6df74e67a72e4206d7db691a300c775e 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: 9b19170eea3ea1b92c58ad18c0b5522633a9e271 172.38.0.14:6379
   replicates 259e804d6df74e67a72e4206d7db691a300c775e
S: 061a9d38f22910aaf0ba1dbd21bf1d8f57bcb7d5 172.38.0.15:6379
   replicates 541b7d237b641ac2ffc94d17c6ab96b18b26a638
S: 7a16b9bbb0615ec95fc978fa62fc054df60536f0 172.38.0.16:6379
   replicates a89c1f1245b264e4a402a3cf99766bcb6138dbca
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: 541b7d237b641ac2ffc94d17c6ab96b18b26a638 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: a89c1f1245b264e4a402a3cf99766bcb6138dbca 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 7a16b9bbb0615ec95fc978fa62fc054df60536f0 172.38.0.16:6379
   slots: (0 slots) slave
   replicates a89c1f1245b264e4a402a3cf99766bcb6138dbca
S: 061a9d38f22910aaf0ba1dbd21bf1d8f57bcb7d5 172.38.0.15:6379
   slots: (0 slots) slave
   replicates 541b7d237b641ac2ffc94d17c6ab96b18b26a638
M: 259e804d6df74e67a72e4206d7db691a300c775e 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 9b19170eea3ea1b92c58ad18c0b5522633a9e271 172.38.0.14:6379
   slots: (0 slots) slave
   replicates 259e804d6df74e67a72e4206d7db691a300c775e
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.


docker搭建redis集群完成

在这里插入图片描述

SpringBoot微服务打包Docker镜像

  1. 构建springboot项目

  2. 打包应用

FROM java:8
 
COPY *.jar /app.jar
 
CMD ["--server.port=8080"]
 
EXPOSE 8080
 
ENTRYPOINT ["java", "-jar", "/app.jar"]
  1. 编写Dockerfile

  2. 构建镜像

  3. 发布运行

# 把打好的jar包和Dockerfile上传到linux
$ ll
total 16140
-rw-r--r-- 1 root root 16519871 Aug 14 17:38 demo-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root      122 Aug 14 17:38 Dockerfile
 
# 构建镜像不要忘了最后有一个点
$ docker build -t lixingze .
Sending build context to Docker daemon  16.52MB
Step 1/5 : FROM java:8
8: Pulling from library/java
5040bd298390: Pull complete 
fce5728aad85: Pull complete 
76610ec20bf5: Pull complete 
60170fec2151: Pull complete 
e98f73de8f0d: Pull complete 
11f7af24ed9c: Pull complete 
49e2d6393f32: Pull complete 
bb9cdec9c7f3: Pull complete 
Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d
Status: Downloaded newer image for java:8
 ---> d23bdf5b1b1b
Step 2/5 : COPY *.jar /app.jar
 ---> d4de8837ebf9
Step 3/5 : CMD ["--server.port=8080"]
 ---> Running in e3abc66303f0
Removing intermediate container e3abc66303f0
 ---> 131bb3917fea
Step 4/5 : EXPOSE 8080
 ---> Running in fa2f25977db7
Removing intermediate container fa2f25977db7
 ---> d98147377951
Step 5/5 : ENTRYPOINT ["java", "-jar", "/app.jar"]
 ---> Running in e1885e23773b
Removing intermediate container e1885e23773b
 ---> afb6b5f28a32
Successfully built afb6b5f28a32
Successfully tagged lixingze:latest
 
# 查看镜像
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
lixingze          latest              afb6b5f28a32        14 seconds ago      660MB
tomcat              latest              2ae23eb477aa        8 days ago          647MB
redis               5.0.9-alpine3.11    3661c84ee9d0        3 months ago        29.8MB
java                8                   d23bdf5b1b1b        3 years ago         643MB
 
# 运行容器
$ docker run -d -P --name xiaofan-springboot-web lixingze
fd9a353a80bfd61f6930c16cd92204532bfd734e003f3f9983b5128a27b0375e
# 查看运行起来的容器端口因为我们启动的时候没有指定
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
fd9a353a80bf        lixingze          "java -jar /app.jar …"   9 seconds ago       Up 8 seconds        0.0.0.0:32779->8080/tcp   xiaofan-springboot-web
# 本地访问1
$ curl localhost:32779
{"timestamp":"2020-08-14T09:42:57.371+00:00","status":404,"error":"Not Found","message":"","path":"/"}
# 本地访问2
$ $ curl localhost:32779/hello
hello, xiaofan
# 远程访问开启阿里云上的安全组哦

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Docker

“Docker教程(超全总结)_docker教程” 的相关文章