Docker

2023-10-26

参考资料

官方文档:Redirecting…

【官方文档超级详细】

仓库地址:Docker Hub

【发布到仓库,git pull push】

b站教程:【狂神说Java】Docker最新超详细版教程通俗易懂_哔哩哔哩_bilibili?

【这个教程非常简洁!且深入!基于企业应用场景!推荐!以下笔记都基于该课程】

前期基础

linux基本命令,类似cd,mkdir等

Docker概述

Docker为什么会出现

一款产品,开发和上线两套环境,应用环境配置费时费力,而且容易出问题

尤其对于机器学习和深度学习的库更是如此,很可能存在版本问题、底层依赖冲突问题

所以发布项目时,不只是一套代码过去,而是代码+环境整体打包过去

所谓开发即运维,保证系统稳定性,提高部署效率

使用Docker后的流程:

开发:建立模型--环境--打包带上环境,即镜像--放到Docker仓库

部署:下载Docker中的镜像,直接运行即可

Docker的思想来自于集装箱,集装箱,对环境进行隔离

Docker通过隔离机制,可以将服务器利用到极致。

Docker的历史

2010年,几个搞IT的人,在美国成立一家公司dotCloud

做一些pass的云计算服务

他们将自己的容器化技术命名为Docker

Docker基于Go语言开发

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

然后他们决定开源

2013年,创始人将Docker开源,不开则以,一开惊人,刚开源的时候,每个月都会更新一个版本

2014年4月9日,Docker 1.0发布

容器vs虚拟机

在容器技术出来之前,用的是虚拟机技术

虚拟机原理示意图

缺点:

  1. 资源占用多

  2. 冗余步骤多

  3. 启动很慢

容器化技术示意图

不是模拟的完整的操作系统

二者对比

比较虚拟机和Docker的不同

传统虚拟机 Docker
虚拟内容 硬件+完整的操作系统+软件 APP+LIB
大小 笨重,通常几个G 轻便几个M或KB
启动速度 慢,分钟级 快,秒级

Docker安装

Docker的基本组成

明确几个概念:

  1. 镜像(image):docker镜像好比一个模板,可以通过这个模板来创建容器(container),一个镜像可以创建多个容器,类似Python中的Class

  2. 容器(container):类似Python中通过Class创建的实例,Object;容器可以理解为一个简易的系统

  3. 仓库(repository):存放镜像的地方,

    分为共有仓库和私有仓库

    • Docker Hub:国外的

    • 阿里云:配置镜像加速

环境准备

我们要有一台服务器,并且可以操作它

  1. Linux命令基础,购买linux阿里云的服务器

  2. CentOS 7

  3. 使用Xshell链接远程服务器

安装xshell

下载CentOS7 CentOS 7镜像下载 - 简书

下载VMware 360软件管家下载

VMware配置虚拟机 VMware安装Centos7超详细过程(图文)_小七的玩偶的博客-CSDN博客_centos

xshell链接服务器 Xshell远程连接CentOS-7版的Linux_张侦毅的博客-CSDN博客_centos连接xshell

[root@192 ~]# cd /
[root@192 /]# pwd
/
[root@192 /]# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@192 /]# uname -r
3.10.0-1127.el7.x86_64

用户名

密码

查看ip:vmware里面输入,ip addIPr

视频书签,p602:20

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

Centos安装

Install Docker Engine on CentOS | Docker Documentation

卸载旧的版本

# 卸载旧的版本
$ sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
​

安装基本环境

# 安装基本的安装包
$ sudo yum install -y yum-utils

!

设置镜像的仓库

注意!!下载默认用国外的,太慢不要用!

用国内镜像,百度搜索,docker的阿里云镜像地址

# 不要用官网默认这个!
$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo # 默认是国外的
​
# 换成下面的
​
$ sudo yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 阿里云镜像

直接复制粘贴就OK了

更像软件包索引

yum makecache fast

没有问题的话就是可以用的

安装docker引擎

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

注意这里会有几个个y/n的判断

要看到Complet再收手!

启动Docker

systemctl start docker # 代表启动成功
docker version
Client: Docker Engine - Community
 Version:           19.03.11
 API version:       1.40
 Go version:        go1.13.10
 Git commit:        42e35e61f3
 Built:             Mon Jun  1 09:13:48 2020
 OS/Arch:           linux/amd64
 Experimental:      false
​
Server: Docker Engine - Community
 Engine:
  Version:          19.03.11
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.10
  Git commit:       42e35e61f3
  Built:            Mon Jun  1 09:12:26 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683
​
docker run hello-world

中间一堆是签名信息

run的运行流程图

查看下载的镜像

docker images

卸载Docker

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

阿里云镜像加速

支付宝扫码登录,短信验证,确认授权

我有两个问题

  1. 阿里云镜像加速必须配置嘛?

    哎呦我去: 加速快

    哎呦我去: 要是翻墙就无所谓了

  2. 这个阿里云必须要买嘛,买哪个,我看阿里云好多产品

    哎呦我去:不需要买

    哎呦我去:免费的

    哎呦我去:阿里云搜索容器服务

    哎呦我去:有一个镜像加速

  3. 这个地址是哪来的呀

操作

控制台搜索 容器镜像服务

找到加速地址

sudo mkdir -p /etc/docker # 创建一个陌路
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://uyfgafsw.mirror.aliyuncs.com"]
}
EOF # 编写配置文件
​
sudo systemctl daemon-reload # 重启服务
sudo systemctl restart docker # 重启docker

在线画图软件ProcessOn

服务器及购买相关介绍

底层原理

Docker是真么工作的?

Docker是一个Client-Server结构的系统,Docker的守护进程在主机上。通过Socket从客户端访问!

DockerServer接受到Docker-Client的指令,

Docker为什么比VM快?

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

  2. docker主要用的是宿主机的内核,vm需要Guest OS

所以说新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导

Docker命令

帮助命令

docker version # 显示docker的基本信息
docker info # 系统信息,镜像和容器的数量
docker 命令 --help # 全部信息

官网文档

镜像命令

docker images

查看所有本地主机上的镜像

[root@192 ~]# docker images
​

# 解释
REPOSITORY  # 镜像仓库源
TAG                 # 镜像的标签
IMAGE ID           # 镜像的ID
CREATED           # 镜像的创建时间
SIZE # 镜像的大小
--all , -a      Show all images (default hides intermediate images) # 显示所有
--digests       Show digests
--filter , -f       Filter output based on conditions provided
--format        Pretty-print images using a Go template
--no-trunc      Don’t truncate output
--quiet , -q        Only show numeric IDs # 只显示id

docker search

搜索仓库中的镜像,相当于网页搜索

网页搜索

mysql

docker search mysql

docker search --help

# 解释
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
​
docker search mysql --filter=STARS=3000 # 搜索出Stars大于3000的

docker pull

下载镜像

docker pull mysql # 下载mysql镜像,default tag,默认最新版latest
[root@192 ~]# sudo systemctl daemon-reload
[root@192 ~]# sudo systemctl restart docker
[root@192 ~]# docker pull mysql
Using default tag: latest # 不写tag默认最新版
latest: Pulling from library/mysql
8559a31e96f4: Pull complete  # layer 分层下载,docker image的核心 联合文件系统
d51ce1c2e575: Pull complete 
c2344adc4858: Pull complete 
fcf3ceff18fc: Pull complete 
16da0c38dc5b: Pull complete 
b905d1797e97: Pull complete 
4b50d1c6b05c: Pull complete 
c75914a65ca2: Pull complete 
1ae8042bdd09: Pull complete 
453ac13c00a3: Pull complete 
9e680cd72f08: Pull complete 
a6b5dc864b6c: Pull complete 
Digest: sha256:8b7b328a7ff6de46ef96bcf83af048cb00a1c86282bfca0cb119c84568b4caf6#签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址
​
# 即
docker pull mysql
# 等价于
docker pull docker.io/library/mysql:latest
​
​
# 指定版本下载 
docker pull mysql:5.7

版本来自于官网,版本库Docker Hub

docker images

此时查看镜像,可以看到新下载的两个

docker rmi

remove images

# 删除一个 可以通过名称 也可以指定id -f表示删除所有
docker rmi -f 9cfcce23593a
# 删除多个 用空格分隔id
docker rmi -f id id id
# 删除所有 
docker rmi -f $(docker images -aq) # images -aq就是查所有镜像id,从而递归删除

容器命令

说明:有了镜像才能创建容器,linux,下载一个centos镜像来测试学习

docker pull centos

新建容器并启动

docker run [可选参数] image
​
# 参数说明
--name=“Name” # 容器名字,用于区分容器
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口 如-p 8080::8080
    -p ip:主机端口:容器端口
    -p 主机端口:容器端口
    -p 容器端口
    
-p 随机指定端口

进入退出容器

# 进入
docker run -it centos /bin/bash 
# 查看目录
ls
# 退出
exit

注意这里面主机名,编程了centos的id

这里面就是一个容器,套娃啊

查看运行的容器

# 查看正在运行的容器
docker ps
# 查看曾经运行的容器
docker ps -a
# 显示最近创建的容器,设置显示个数
docker ps -a - n=? 
# 只显示容器的编号
docker ps -aq
[root@192 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@192 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
9939864fa2e6        centos              "bin/bash"          4 minutes ago       Exited (0) 4 minutes ago                       unruffled_knuth
5f42e9930435        centos              "/bin/bash"         8 minutes ago       Exited (0) 4 minutes ago                       lucid_cannon
a89ddb393d3d        bf756fb1ae65        "/hello"            19 hours ago        Exited (0) 19 hours ago                        gracious_bhabha
[root@192 ~]# docker ps -a -n=2
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
9939864fa2e6        centos              "bin/bash"          6 minutes ago       Exited (0) 6 minutes ago                       unruffled_knuth
5f42e9930435        centos              "/bin/bash"         10 minutes ago      Exited (0) 7 minutes ago 
[root@192 ~]# docker ps -aq
9939864fa2e6
5f42e9930435
a89ddb393d3d
​

退出容器

# 容器停止退出
exit
# 容器不停止退出 注意必须在英文输入法下,中文输入法不行
Ctrl + P + Q
[root@192 ~]# docker run -it centos /bin/bash
[root@bfcea13c40cd /]# [root@192 ~]# docker ps ##注意这里会自动给个命令,删掉
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
bfcea13c40cd        centos              "/bin/bash"         About a minute ago   Up About a minute                       stoic_wilson
edbd9366d959        centos              "/bin/bash"         7 minutes ago        Up 7 minutes                            affectionate_bartik
[root@192 ~]# docker exec -it edbd9366d959 /bin/bash ## 再次进入
[root@edbd9366d959 /]# exit ##停止并推出
exit
​

删除容器

# 删除指定容器 不能删除正在运行的容器,如果强制删除 rm -f
docker rm 容器id
# 删除所有容器
docker rm -f $(docker ps -aq)
# 删除所有容器
docker ps -a -q|xargs docker rm
[root@192 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
bfcea13c40cd        centos              "/bin/bash"         29 minutes ago      Up 29 minutes                                   stoic_wilson
edbd9366d959        centos              "/bin/bash"         35 minutes ago      Up 35 minutes                                   affectionate_bartik
9939864fa2e6        centos              "bin/bash"          48 minutes ago      Exited (0) 48 minutes ago                       unruffled_knuth
5f42e9930435        centos              "/bin/bash"         52 minutes ago      Exited (0) 49 minutes ago                       lucid_cannon
a89ddb393d3d        bf756fb1ae65        "/hello"            20 hours ago        Exited (0) 20 hours ago                         gracious_bhabha
[root@192 ~]# docker rm 5f42e9930435
5f42e9930435
[root@192 ~]# docker rm edbd9366d959      # 注意正在运行的容器不能删除
Error response from daemon: You cannot remove a running container edbd9366d9596c744dd449119269b04de2f2a494e7fc471f6396bcefd94c33fe. Stop the container before attempting removal or force remove
​
[root@192 ~]# docker ps -aq # 所有容器id
bfcea13c40cd
edbd9366d959
9939864fa2e6
a89ddb393d3d
[root@192 ~]# docker rm -f $(docker ps -aq) # 全部删除
bfcea13c40cd
edbd9366d959
9939864fa2e6
a89ddb393d3d
​

启动和停止容器的操作

docker start
docker restart
docker stop
docker kill
[root@192 ~]# docker run -it centos /bin/bash
[root@7b1a7dd10ea4 /]# exit
exit
[root@192 ~]# docker ps #查看正在运行的
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@192 ~]# docker ps -a # 查看历史运行过的
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
7b1a7dd10ea4        centos              "/bin/bash"         54 seconds ago      Exited (0) 42 seconds ago                       fervent_mirzakhani
[root@192 ~]# docker start 7b1a7dd10ea4 # 启动当前这个容器 container id 粘过 来
7b1a7dd10ea4
[root@192 ~]# docker ps # 查看当前运行容器 发现启动成功
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
7b1a7dd10ea4        centos              "/bin/bash"         2 minutes ago       Up 28 seconds                           fervent_mirzakhani
[root@192 ~]# docker stop 7b1a7dd10ea4 # 停止运行
7b1a7dd10ea4
[root@192 ~]# docker ps # 再次查看 没有这个容器了
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
​
​

常用其他命令

后台启动docker

docker run -d 镜像名
# 用docker ps 查看的时候 发现停止了
​
# 后台运行,docker发现前台没有,容器启动后,发现自己没有提供服务,会立刻停止
Last login: Wed Jun 17 19:47:35 2020
[root@192 ~]# systemctl start docker # 关机后重启了,需要启动docker
[root@192 ~]# docker run -d centos # 运行
8ce188e5fee31c2fac93c0a405ee1a95c38dbc50cb47c35b19c0039c27558ded
[root@192 ~]# docker ps -a # 查看正在运行的
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
8ce188e5fee3        centos              "/bin/bash"         19 seconds ago      Exited (0) 18 seconds ago                       tender_dirac
7b1a7dd10ea4        centos              "/bin/bash"         8 hours ago         Exited (0) 8 hours ago                          fervent_mirzakhani
​

查看日志

docker logs
docker logs -f -t --tail n 【id】
​

[root@192 ~]# docker logs --help
​
Usage:  docker logs [OPTIONS] CONTAINER
​
Fetch the logs of a container
​
Options:
      --details        Show extra details provided to logs
  -f, --follow         Follow log output
      --since string   Show logs since timestamp (e.g.
                       2013-01-02T13:23:37) or relative
                       (e.g. 42m for 42 minutes)
      --tail string    Number of lines to show from the
                       end of the logs (default "all")
  -t, --timestamps     Show timestamps # 时间戳
      --until string   Show logs before a timestamp (e.g.
                       2013-01-02T13:23:37) or relative
                       (e.g. 42m for 42 minutes)
​
whiel true;do echo shenzai;sleep 

# 运行一个
[root@192 ~]# docker run -it centos /bin/bash
​
[root@c2887d35c71d /]# [root@192 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
c2887d35c71d        centos              "/bin/bash"         57 seconds ago      Up 56 seconds                           vigorous_kare
​
# 查看日志,由于没有运行脚本,所以啥也没显示
[root@192 ~]# docker logs -f -t --tail 10 c2887d35c71d
^C # ctrl+c退出
​
# 运行centos里面加个脚本
[root@192 ~]# docker run -d centos /bin/sh -c "while true;do echo shenzai;sleep 1;done"
cb6d7fbc3f27a064137d58282de97b97365dea2705211ebfbad642079cc1b388
​
[root@192 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
cb6d7fbc3f27        centos              "/bin/sh -c 'while t…"   7 seconds ago       Up 6 seconds                            dreamy_almeida
c2887d35c71d        centos              "/bin/bash"              3 minutes ago       Up 3 minutes                            vigorous_kare
​
# 查看日志 发现隔一秒打印一条
[root@192 ~]# docker logs -f -t --tail 10 cb6d7fbc3f27
2020-06-17T12:02:11.293765084Z shenzai
2020-06-17T12:02:12.297675608Z shenzai
2020-06-17T12:02:13.301845582Z shenzai
2020-06-17T12:02:14.304800996Z shenzai
2020-06-17T12:02:15.307130238Z shenzai
2020-06-17T12:02:16.310574235Z shenzai
2020-06-17T12:02:17.312946923Z shenzai
2020-06-17T12:02:18.314841295Z shenzai
2020-06-17T12:02:19.317021705Z shenzai
2020-06-17T12:02:20.319670013Z shenzai
2020-06-17T12:02:21.322651649Z shenzai
2020-06-17T12:02:22.325466918Z shenzai
2020-06-17T12:02:23.327984704Z shenzai
2020-06-17T12:02:24.329656919Z shenzai
​

查看正在运行的容器信息

[root@192 ~]# docker inspect cb6d7fbc3f27
[
    {
        # 容器的完整id
        "Id": "cb6d7fbc3f27a064137d58282de97b97365dea2705211ebfbad642079cc1b388",
        
        # 创建时间
        "Created": "2020-06-17T12:00:50.706906186Z",
        
        # 脚本位置
        "Path": "/bin/sh",
        
        # 运行的脚本
        "Args": [
            "-c",
            "while true;do echo shenzai;sleep 1;done"
        ],
        "State": {
            "Status": "running", # 状态,正在运行
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 1909, # 父进程id
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2020-06-17T12:00:51.093617477Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        
        # 来源镜像
        "Image": "sha256:831691599b88ad6cc2a4abbd0e89661a121aff14cfa289ad840fd3946f274f1f",
        "ResolvConfPath": "/var/lib/docker/containers/cb6d7fbc3f27a064137d58282de97b97365dea2705211ebfbad642079cc1b388/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/cb6d7fbc3f27a064137d58282de97b97365dea2705211ebfbad642079cc1b388/hostname",
        "HostsPath": "/var/lib/docker/containers/cb6d7fbc3f27a064137d58282de97b97365dea2705211ebfbad642079cc1b388/hosts",
        "LogPath": "/var/lib/docker/containers/cb6d7fbc3f27a064137d58282de97b97365dea2705211ebfbad642079cc1b388/cb6d7fbc3f27a064137d58282de97b97365dea2705211ebfbad642079cc1b388-json.log",
        
        
        "Name": "/dreamy_almeida",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        
        # 主机配置
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Capabilities": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        
        # 其他配置
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/3675586ebbd79cd72d2562a90c9380627a331c563724c0dac091f92600af4907-init/diff:/var/lib/docker/overlay2/7f79322e0f58d651a84a555dadd83d92537788172525945d3f538dd95dce336c/diff",
                "MergedDir": "/var/lib/docker/overlay2/3675586ebbd79cd72d2562a90c9380627a331c563724c0dac091f92600af4907/merged",
                "UpperDir": "/var/lib/docker/overlay2/3675586ebbd79cd72d2562a90c9380627a331c563724c0dac091f92600af4907/diff",
                "WorkDir": "/var/lib/docker/overlay2/3675586ebbd79cd72d2562a90c9380627a331c563724c0dac091f92600af4907/work"
            },
            "Name": "overlay2"
        },
        
        "Mounts": [], # 挂载
        
        # 基本配置
        "Config": {
            "Hostname": "cb6d7fbc3f27",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ], # 基本环境变量,这里没有Java
            
            # 基本命令
            "Cmd": [
                "/bin/sh",
                "-c",
                "while true;do echo shenzai;sleep 1;done"
            ],
            "Image": "centos",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20200611",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        
        # 网卡,比如现在用的是桥接的网卡
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "4d701985d7e77aa153790b697b2f38a61e20555c224b7675e4bf650b82799882",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/4d701985d7e7",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "8a6c71e2bafb19ca7dfd85445ccc4bef6d17467360a243d624089e676a24a018",
            "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": "22b0fd2290ccbc4e066a75d3f01bd8bf32ee4352c5bbcfc9f911287219219571",
                    "EndpointID": "8a6c71e2bafb19ca7dfd85445ccc4bef6d17467360a243d624089e676a24a018",
                    "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
                }
            }
        }
    }
]
​

# 停止正在疯狂输出的那个容器
[root@192 ~]# docker stop cb6d7fbc3f27
cb6d7fbc3f27

进入当前正在运行的容器

# 我们通常容器都是使用后台方式运行的e
​
docker exec -it 容器id bashSHELL
​
# 测试
[root@192 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
c2887d35c71d        centos              "/bin/bash"         35 minutes ago      Up 35 minutes                           vigorous_kare
[root@192 ~]# docker exec -it c2887d35c71d /bin/bash
[root@c2887d35c71d /]# ls
bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr
[root@c2887d35c71d /]# ps -ef
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 11:57 pts/0    00:00:00 /bin/bash
root         14      0  0 12:32 pts/1    00:00:00 /bin/bash
root         28     14  0 12:32 pts/1    00:00:00 ps -ef
[root@c2887d35c71d /]# c2887d35c71d
[root@c2887d35c71d /]# exit
exit
​
# 方式二
[root@192 ~]# docker attach c2887d35c71d
[root@c2887d35c71d /]# 
​
# 区别
# docker exec # 进入容器后开启一个新的终端,可以在里面操作(常用)
# docker attach 进入容器正在执行的终端,不会启动新的进程
​

从容器内拷贝文件到主机上

# 运行
[root@192 ~]# docker run -it centos
# ctrl P Q 不关闭退出,查看
[root@0569081aa89c /]# [root@192 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
0569081aa89c        centos              "/bin/bash"         19 seconds ago      Up 19 seconds    
hopeful_chebyshev
​
# 查看主机home下无文件
[root@192 ~]# cd /home
[root@192 home]# ls
​
# 进入正在运行的容器
[root@192 home]# docker attach 0569081aa89c
​
# 进入容器home目录
[root@0569081aa89c /]# cd /home
​
# 在目录中创建java文件
[root@0569081aa89c home]# touch test.java
​
# 退出并停止容器
[root@0569081aa89c home]# exit
exit
​
# 查看现在运行的容器
[root@192 home]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
​
# 容器虽然被停止,但是数据都会保留
[root@192 home]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                         PORTS               NAMES
0569081aa89c        centos              "/bin/bash"              3 minutes ago       Exited (0) 8 seconds ago                           hopeful_chebyshev
f589e5684a01        centos              "/bin/bash"              44 minutes ago      Exited (0) 44 minutes ago                          cranky_easley
cb6d7fbc3f27        centos              "/bin/sh -c 'while t…"   54 minutes ago      Exited (137) 42 minutes ago                        dreamy_almeida
c2887d35c71d        centos              "/bin/bash"              58 minutes ago      Exited (127) 16 minutes ago                        vigorous_kare
8ce188e5fee3        centos              "/bin/bash"              About an hour ago   Exited (0) About an hour ago                       tender_dirac
7b1a7dd10ea4        centos              "/bin/bash"              9 hours ago         Exited (0) 9 hours ago                             fervent_mirzakhani
​
# 容器数据拷贝到主机
[root@192 home]# docker cp 0569081aa89c:/home/test.java /home
[root@192 home]# ls
test.java
​
# 拷贝是一个手动过程,未来我们使用 -v 卷的技术,可以实现自动同步 /home /home

查看内容占用

docker stats
​

小结

[root@192 home]# docker --help
​
Usage:  docker [OPTIONS] COMMAND
​
A self-sufficient runtime for containers
​
Options:
      --config string      Location of client config
                           files (default "/root/.docker")
  -c, --context string     Name of the context to use to
                           connect to the daemon
                           (overrides DOCKER_HOST env var
                           and default context set with
                           "docker context use")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket(s) to connect to
  -l, --log-level string   Set the logging level
                           ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by
                           this CA (default
                           "/root/.docker/ca.pem")
      --tlscert string     Path to TLS certificate file
                           (default "/root/.docker/cert.pem")
      --tlskey string      Path to TLS key file (default
                           "/root/.docker/key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit
​
Management Commands:
  builder     Manage builds
  config      Manage Docker configs
  container   Manage containers
  context     Manage contexts
  engine      Manage the docker engine
  image       Manage images
  network     Manage networks
  node        Manage Swarm nodes
  plugin      Manage plugins
  secret      Manage Docker secrets
  service     Manage services
  stack       Manage Docker stacks
  swarm       Manage Swarm
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes
​
Commands:
  attach      Attach local standard input, output, and error streams to a running container
  build       Build an image from a Dockerfile
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  images      List images
  import      Import the contents from a tarball to create a filesystem image
  info        Display system-wide information
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  login       Log in to a Docker registry
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes
​

作业练习

部署Nginx

# 官网搜索nginx,可以看到帮助文档
​
# 下载镜像
[root@192 home]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
8559a31e96f4: Pull complete 
8d69e59170f7: Pull complete 
3f9f1ec1d262: Pull complete 
d1f5ff4f210d: Pull complete 
1e22bfa8652e: Pull complete 
Digest: sha256:21f32f6c08406306d822a0e6e8b7dc81f53f336570e852e25fbe1e3e3d0d0133
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
​
# 查看镜像
[root@192 home]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              831691599b88        13 hours ago        215MB
nginx               latest              2622e6cca7eb        7 days ago          132MB
​
# 运行测试
# -d 后台运行,--name 命名,-p 暴露端口,3344服务器、宿主机的端口,容器内部端口
[root@192 home]# docker run -d --name nginx01 -p:3344:80 nginx
38dbf7bdcaef232d269b7184d91e44e06087181b5ee929494e177ad526810fa8
[root@192 home]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
38dbf7bdcaef        nginx               "/docker-entrypoint.…"   7 seconds ago       Up 6 seconds        0.0.0.0:3344->80/tcp   nginx01
​
# 使用3344可以访问成功
[root@192 home]# curl localhost:3344
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    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>
​

端口暴露

可以公网访问

找到服务器地址

浏览器输入 192.168.147.132:3344/

[root@192 home]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
38dbf7bdcaef        nginx               "/docker-entrypoint.…"   21 minutes ago      Up 21 minutes       0.0.0.0:3344->80/tcp   nginx01
​
# 进入容器
[root@192 home]# docker exec -it nginx01 /bin/bash
​
# 查一下nginx在哪
root@38dbf7bdcaef:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
​
# 到这个目录
root@38dbf7bdcaef:/# cd /etc/nginx
root@38dbf7bdcaef:/etc/nginx# ls
conf.d      koi-utf  mime.types  nginx.conf   uwsgi_params
fastcgi_params  koi-win  modules     scgi_params  win-utf
​
# 退出
root@38dbf7bdcaef:/etc/nginx# exit
exit
​
# 停止
[root@192 home]# docker stop 38dbf7bdcaef
38dbf7bdcaef
​
​

再次刷新网页,服务关闭

思考问题:每次改动nginx配置文件,都需要进入容器内部,十分麻烦,要是可以在容器外部提供一个映射路径,达到在容器修改文件名,容器内部就可以自动修改?-v 数据卷技术!

部署tomcat

在docker hub上查看版本号和使用方法

官方文档一定要翻烂,超多版本,我的天呐~

官方方法

docker run -it --rm tomcat:9.0
​
# docker run 可以不用pull,能自动下载
# -it 直接进去运行
# --rm 是什么意思?入门的意思?
# 我们之前的启动都是后台,停止了容器之后,容器还是可以查到
# 写了--rm,类似阅后即焚模式,用完即删除,这种通常用来测试
​
# 最后冒号查好的版本号

ctrl+c退出

docker ps -a

可以看到并没有tomcat,印证阅后即焚模式,容器会删除,镜像不会删除

平时不建议这样搞

正常方法

docker pull tomcat:9.0 # 之前下过了,应该不用下了,这里老师讲错了

# 启动运行,应该加上版本号
docker run -d -p 3355:8080 --name tomcat01 tomcat

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

发现问题

  1. linux命令少了

  2. 没有webapps

这是阿里云镜像的原因:默认使用最小镜像,所有不必要的都剔除了,保证最小可运行环境

再次找到结构

在浏览器中输入:http://192.168.147.132:3355/

思考问题:我们以后部署项目,如果每次都要进入容器是不是身份麻烦?我要是可以在容器外部提供一个映射路径,webapps,我们在外部放置项目,就自动同步到内部就好了!

docker容器 tomcat+网站

docker mysql

部署es+kibana

# es 暴露的端口很多
# es 十分耗内存
# es 的数据一般需要放置到安全目录!挂载
​
# 启动 elasticsearch
$ docker run -d --name elasticsearch01 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
​
# 查看内存占用情况
docker stats

# 先感觉stop一下
docker stop ba18713ca536

# 通过 -e 限制内存
$ docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS=“-Xms64m -Xmx512m” elasticsearch:7.6.2

没成功啊,SEI能告诉我为啥!!

docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2

py0003null大佬: “ES_JAVA_OPTS=-Xms64m -Xmx512m”

py0003null大佬: 引号提前试试

原因是引号!!你没觉得怪怪的嘛

此时查看stats,发现内存占用在控制范围内

ctrl + C退出,记得stop

思考:用kibana链接elasticsearch

可视化

  • portainer(先用这个)

  • Rancher(CI/CD时用)

portainer

Docker图像化界面管理工具,提供一个后台面板供我们操作!

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

访问外网8088

用户名

密码

【中午吃饭重连了一下,失败,不知道发生了啥】

【平时不会用这个,好吧,先往下】

Docker镜像

原理

UnionFS 联合文件系统

bootfs:boot file system

rootfs:root file system

Docker镜像都是只读的,当容器启动时,一个新的可写层被加到镜像的顶部,这一层就是我们通常说的容器层,容器层之下的都叫镜像层

commit提交镜像

docker commit # 提交容器成为一个新的副本
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker images
docker run -it -p 8080:8080 tomcat

这是一个前台程序

将webapps.dist里面所有的文件拷贝到webapps里面,其中-r必须有,表示目录递归拷贝

docker commit -a="paidaxing" -m="add webapps app" 当前容器的id tomcat02:1.0

发现新的版本,比之前的大了一些,因为里面记录了我们的改动

如果想保存当前容器的状态,可以通过commit提交,获得一个镜像

好比我们以前学习VM的时候的快照

到这里算是入门了

接下来三个部分是docker的精髓

容器数据卷

什么是容器卷

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

这样,数据就不应该在容器中,否则容器删除,数据就会丢失,这就是删库跑路

故容器之间要有一个数据共享技术

在Docker容器中产生的数据,同步到本地,这就是卷技术

本质上是一个目录挂载,将容器内的目录挂载到虚拟机上

目的:容器的持久化和同步操作

容器间可以数据共享

使用数据卷

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

docker run -it -v -p
# -it 交互式进入
# -v volume卷技术
# -p 主机端口

新开一个窗口

docker inspect 容器id

找到挂载信息Mounts

测试

容器停止后,修改主机文件,再启动容器的时候,数据同样改变

双向同步

实战安装mysql

MySQL的数据持久化命令

docker search mysql
​
# 拉取
docker pull mysql:5.7
​
# 挂载
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql5.7
​
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置 安装启动mysql需要配置密码
--name 容器名字
​

链接测试:打开SQLyog

点 测试链接

点 链接

具名和匿名挂载

DockerFile使用来构建docker镜像的文件

kas: 没有安装吧?

kas: 安装一下就可以了

py9001021曾叙坚: centos 默认使用vi写内容,vim需要下载

py9001021曾叙坚: 是的,需要下载vim才能使用

YF: 配置可以改下,字体就很炫酷了

都建民: 用vi 试试

都建民: 你没有安装vim

都建民: yum install vim

都建民: 试试这个命令

yum install vim # 编辑文件的,没有装一下

安装完之后就可以运行这个命令了

# 镜像是一层一层的,脚本是一行一行的
# 指令都是大写的
# 这里的每个命令可以理解为镜像的一层
​
FROM centos
​
VOLUME ["volume01","volume02"] # 再创建镜像的时候就挂载出来
​
CMD echo "---end---"
CMD /bin/bash
​

想保存并退出

Wesley.: shift 加 冒号

cat dockerfile1
​
docker build -f dockerfile1 -t padaxing/centos:1.0 .  # 最后的点很重要 镜像名不能有/

docker images

启动生成的镜像

在容器内部创建一个文件

查看Mounts,Source对应容器外目录,匿名挂载卷

测试一下,在container volume01下生成文件

在主机挂载路径下,也同样生成

多个容器数据共享

看一下有啥images

启动docker01,用之前建的padaxing/centos 1.0 镜像

docker run -it --name docker01 padaxing/centos:1.0 # 1.0必须写

当前这个ctrl+p+q不停止退出

依次启动docker02、docker03

docker run -it --name docker02 --volumes-from docker01 padaxing/centos:1.0

docker02继承docker01的volumes

可以验证,在docker01下加一个数据,在docker02下也会出现

创建docker03,同样继承docker01

docker run -it --name docker03 --volumes-from docker01 padaxing/centos:1.0

在docker03的volume01下建立文件,在docker01的volume01下同样也有

即通过--volumes-from 可以实现不同容器间的数据共享

删除docker01,数据还在

docker rm -f 

可以看到,删除docker01,进入docker02,数据依然在

结论:

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

但是如果持久化到了本地,即使所有容器删除了,本地数据是不会删除的


DockerFile

是用来构建docker镜像的文件,可以理解为命令参数脚本

构建步骤:

  1. 编写一个dockerfile文件

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

  3. docker run运行镜像

  4. docker push 发布镜像(DockerHub、阿里云镜像仓库 私有/共有)

这个写一个项目时一样的

官方DockerFile示例

看一下官方的DockerFile

可以看到官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像

官方既然可以制作镜像,我们亦可以


DockerFile基础知识

  1. 每个指令都必须是大写字母

  2. 按照从上到下顺序执行

  3. #表示注释

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

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

Docker镜像逐渐成为企业的交付标准,必须掌握!


DockerFile命令

FROM # 基础镜像 比如centos
MAINTAINER # 镜像是谁写的 姓名+邮箱
RUN # 镜像构建时需要运行的命令
ADD # 添加,比如添加一个tomcat压缩包
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 指定暴露端口,跟-p一个道理
RUN # 最终要运行的
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,而且可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承Dockerfile 这个时候运行ONBUILD指定,触发指令
COPY # 将文件拷贝到镜像中
ENV # 构建的时候设置环境变量

实战构建自己的centos

Docker Hub中99%的镜像都是从FROM scratch开始的

添加centos7的压缩包

# 创建一个自己的centos
​
# 进入home目录
cd /home
​
# 创建一个目录,之后的东西都保存到这里
mkdir dockerfile
# 进入这个目录
cd dockerfile/
# 创建一个dockerfile,名字叫mydockerfile
vim mydockerfile-centos
​
​

xshell新开一个界面

# 官方默认centos
docker run -it centos
pwd # 官方默认有pwd命令
vim # 官方默认没有vim命令
ifconfig # 官方默认没有ifconfig命令

回到mydockerfile

# 下面给官方centos加上自定义的内容
FROM centos
MAINTAINER li<1374216232@qq.com>
​
ENV MYPATH /usr/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

ESC, shif + : 输入wq保存并退出

如果写错了需要修改、

vim mydockerfile-centos
# 进入之后按i或者INSERT键即可修改

下面通过这个这个文件创建镜像

docker build -f dockerfile-centos -t mycentos:0.1 .

如果遇见Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist

FROM centos:centos7
MAINTAINER li<1374216232@qq.com>
​
ENV MYPATH /usr/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

依次执行命令

最终返回Successfully表示成功

docker run -it mycentos:0.1 # 版本号必须写,不然他会去找最新的
pwd
vim
ifconfig

这时可以看到这些功能都有了

可以通过查看docker构建历史

可以看到当前这个镜像是怎么一步一步构建起来的

我们平时拿到一个镜像也可以通过这个方法研究一下他是怎么做的

CMD与ENTRYPOINT

【视频书签,【狂神说Java】Docker最新超详细版教程通俗易懂_哔哩哔哩_bilibili,雨终于停了,想去江边跑步】

CMD与ENTRYPOINT

FROM centos
CMD ["ls","-a"] # 启动centos展示目录

测试ENTRYPOINT

run的时候可以直接加命令

Docker中许多命令都十分相似,我们需要了解他们的区别,最好的方式就是这样对比测试


实战Tomcat镜像

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

  2. 编写Dockerfile文件官方命名Dockerfile ,build 会自动寻找这个文件,就不需要-f 指定了

    FROM centos
    MAINTAINER li<1374216232@qq.com>
     
    COPY readme.txt /usr/local/readme.txt
     
    ADD jdk-8u131-linux-x64.tar.gz /usr/local/
    ADD apache-tomcat-9.0.31.tar.gz /usr/local/
     
    RUN yum -y install vim
     
    ENV MYPATH /usr/local
    WORKDIR SMYPATH
     
    ENV JAVA_HOME /usr/local/jdk1.8.0_131
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.31
    ENV CATALIBA_BASH /usr/local/apache-tomcat-9.0.31
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
    ​
    EXPOSE 8080
    ​
    CMD /usr/local/apache-tomcat-9.0.31/bin/startup.sh $$ tail -F /usr/local/apache-tomcat-9.0.31/bin/logs/catalina.out
    ​

    3.构建镜像

    docker build -t diytomcat .

发布自己的镜像

DockerHup

1、地址 Docker Hub 注册自己的账号

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

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

[root@root ~]# 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
​

4、登录完毕之后就可以提交镜像了,就是一步 docker push

# push 自己的镜像到服务器上
[root@root ~]# docker push mycentos:0.1
The push refers to repository [docker.io/library/mycentos]
bdc0605c3fcd: Preparing 
8289035316ad: Preparing 
174f56854903: Preparing 
denied: requested access to the resource is denied # 拒绝
​
The push refers to repository [docker.io/li/mycentos]
An image does not exist locally with the tag: li/mycentos
​
# 解决,增加一个tag
[root@root ~]# docker tag da1a7d1441f7 li/centos:1.0
​
[root@root ~]# docker push li/centos:1.0
The push refers to repository [docker.io/li/centos]
bdc0605c3fcd: Preparing 
8289035316ad: Preparing 
174f56854903: Preparing

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

阿里云镜像服务上

1、登录阿里云

2、找到容器镜像服务

小结

Docker网络

测试

三个网络

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

# docker run -d -P --name tomcat01 tomcat 
​
# 查看容器的内部地址 ip addr
# linux 可以ping 通 docker 容器内容

原理

1、我们每启动一个docker容器,docker 就会给docker容器分配一个ip,我们只要安装docker,就会有一个网卡docker0桥接模式,使用的技术是evth-pair技术!

2、再次测试: 发现又多了一对网卡

# 我们发现这个容器带来网卡,都是一对对的
# evth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连
# 正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备的
# OpenStac,Docker容器之间的连接,OVS的连接,都是使用 evth-pair 技术

3、我们来测试下 tomcat01 和tomcat02 是否可以ping通!

docker exec -it tomcat02 ping 172.18.0.2
# 结论容器和容器之间是可以互相ping通的

结论:tomcat01 和tomcat02 是公用的一个路由器,docker0,

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

小结

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

Docker 中的所有的网络接口都是虚拟的,虚拟的转发效率高!

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

--link

我们编写了一个微服务,database url-ip;项目不重启,数据库IP换掉了,我们希望可以处理这个问题,可以用名字来进行访问容器?

docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
​
# 如何解决呢
# 通过 --link 就可以解决了网络连接问题

# 反向能够ping通吗
docker exec -it tomcat02 ping tomcat03
ping: tomcat01: Name or service not known

本质探究:--link就是我们在hosts配置中增加了一个 tomcat02的映射

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

自定义网络,不是用docker0

docker0问题:他不支持容器名连接访问

自定义网络

查看所有的docker网络

网络模式

bridge :桥接 docker(默认,自己创建也使用bridge 模式)

none : 不配置网络

host : 和宿主机共享网络

container :容器内网络连接(用的少!局限很大)

测试

# 我们直接启动的命令 --net bridge,而这个就是docker0
docker run -d -P --name tomcat01 --net bridge tomcat
​
# docker特点,默认,域名不能访问, --link可以打通连接
​
# 我们可以自定义一个网络
# --driver bridge
# --subnet 192.168.0.0/16 192.168.0.2 192.168.255.255
# --gateway 192.168.0.1
[root@root /]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
d4775d9f016134cd0b325ed827cbbed2eff147bcdc52f95dbb4f872e2a6be7f1
[root@root /]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
60851e715a46   bridge    bridge    local
7bedd506d95a   host      host      local
d4775d9f0161   mynet     bridge    local
5de23d719f21   none      null      local
​

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

[root@root /]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
Unable to find image 'tomcat:latest' locally
latest: Pulling from library/tomcat
0e29546d541c: Already exists 
9b829c73b52b: Already exists 
cb5b7ae36172: Already exists 
6494e4811622: Already exists 
668f6fcc5fa5: Already exists 
dc120c3e0290: Already exists 
8f7c0eebb7b1: Already exists 
77b694f83996: Already exists 
0f611256ec3a: Already exists 
4f25def12f23: Already exists 
Digest: sha256:9dee185c3b161cdfede1f5e35e8b56ebc9de88ed3a79526939701f3537a52324
Status: Downloaded newer image for tomcat:latest
0065ff3aa54bec0df7b65a9cbc4eb6179aabb78dc11551d7dccb14acb464633a
[root@root /]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
26adcb72635509de5a9e0ebfba536eaf91b7e8ed9fd9f0d5fe295b06026c755c
[root@root /]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "d4775d9f016134cd0b325ed827cbbed2eff147bcdc52f95dbb4f872e2a6be7f1",
        "Created": "2022-05-13T07:38:27.9262617-04: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": {
            "0065ff3aa54bec0df7b65a9cbc4eb6179aabb78dc11551d7dccb14acb464633a": {
                "Name": "tomcat-net-01",
                "EndpointID": "5cc18e244ee4ba6d5ba6e44f6ca3ede0059bd4d4ad856a2ecea23b99f382b3cc",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "26adcb72635509de5a9e0ebfba536eaf91b7e8ed9fd9f0d5fe295b06026c755c": {
                "Name": "tomcat-net-02",
                "EndpointID": "c7a062812353f75b8f482986e63f85b4dac39636305ab0b3d496bf88e7a59d75",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
# 再次测试ping连接
# 发现现在不使用--link也可以ping名字了

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

好处:

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

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

网络连接

# 测试打开 tomcat01 - mynet
​
# 联通之后就是将 tomcat01 放到了 mynet 网络下
​
#一个容器两个ip地址
# 阿里云服务,公网ip 私网ip

docker exec -it tomcat01 ping tomcat-net-01

结论:假设要跨网络操作别人,就需要使用docker network connect 联通!

Redis集群

# 创建网卡
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
# 创建结点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
 
# 创建集群
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# 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 Compose

概述

Docker

DockerFile build run 手动操作,单个容器

微服务,依赖关系

Docker Compose 来轻松高效的管理容器。定义运行多个容器

官方介绍

定义,运行多个容器

YAML file 配置文件

single command 命令有哪些

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features.

所有的环境都可以使用 Compose

Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases.

三个步骤:

Using Compose is basically a three-step process:

  1. Define your app’s environment with a Dockerfile so it can be reproduced anywhere.

    • Docker 保证我们的项目在任何地方可以运行

  2. Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.

    • docker-compose.yml 这个文件怎么写

  3. Run docker compose up and the Docker compose command starts and runs your entire app. You can alternatively run docker-compose up using the docker-compose binary.

    • 启动项目

作用:批量容器编排

理解

Compose 是Docker官方的开源项目,需要安装

Dockerfile 让程序存在任何地方运行,web服务 redis ,mysql .... 多个容器

Compose

version: "3.9"  # optional since v1.27.0
services:
  web:
    build: .
    ports:
      - "8000:5000"
    volumes:
      - .:/code
      - logvolume01:/var/log
    links:
      - redis
  redis:
    image: redis
volumes:
  logvolume01: {}

docker-compose up 个服务

Compose:重要的概念

  • 服务services,容器,应用(web,redis,mysql....)

  • 项目project,一组关联的容器,博客,web,mysql,wp

安装

1、下载

 sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
 
# 速度快一点
 curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
​

2、授权

sudo chmod +x /usr/local/bin/docker-compose

安装成功:

[root@root bin]# docker-compose version
docker-compose version 1.25.5, build 8a1c60f6
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019

3.体验

地址: Get started with Docker Compose | Docker Documentation

  1. 应用 app.py

  2. Dockerfile 应用打包为镜像

  3. Docker-compose.yaml (定义整个服务、需要的环境:web、redis),完整的上线服务

  4. 启动compose 项目(docker-compose up)

[root@root ceshi]# mkdir composetest
[root@root ceshi]# cd composetest
[root@root composetest]# vim app.py
[root@root composetest]# vim requirements.txt
[root@root composetest]# vim Dockerfile
[root@root composetest]# vim docker-compose.yml
[root@root composetest]# ls
app.py  docker-compose.yml  Dockerfile  requirements.txt
[root@root composetest]# docker-compose up
​

app.py文件

import time
​
import redis
from flask import Flask
​
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
​
def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)
​
@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)

requirements.txt

flask
redis

Dockerfile

# syntax=docker/dockerfile:1
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]

docker-compose.yml

version: "3.9"
services:
  web:
    build: .
    ports:
      - "8000:5000"
  redis:
    image: "redis:alpine"

Docker Swarm

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Docker 的相关文章

随机推荐

  • C++互斥锁std::mutex

    目录 std mutex 成员函数 std lock guard std unique lock std mutex实测代码 std mutex 是C 11 中最基本的互斥量 std mutex 对象提供了独占所有权的特性 即不支持递归地对
  • 统计学习方法(第三章)--KNN分类器python实现及kd树实现及sklearn调用

    KNN算法的的原理 KNN不存在显式的学习过程 对于一个测试样本 根据给定的距离计算公式 和k值 找到距离测试样本最近的k个训练样本 k个训练样本得票最高的类别作为测试样本的类别 三要素 距离的度量 np linalg norm x y p
  • springboot集成kafka

    1 pom xml中增加依赖包
  • 阿里云 一键web 部署

    阿里云 一键web 部署 软件下载地址 包含下文中所需要用到的文件 下面文中提到的文件下载地址 提取码 688c xftp 和 xshell下载地址 提取码 ertk 参考下面这篇文章 经测试 成功部署 https www cnblogs
  • shell输入内容时不显示内容

    简介 大家都知道当我们ssh登录linux服务器的时候输入密码密码是不显示在屏幕上的 同样在我们写shell脚本的时候在获取用户密码的时候 有时候也希望不显示密码 这个是怎么做的呢 实例脚本 bin bash echo 请输入密码 stty
  • pytorch输出tensor维度时报错:built-in method size of Tensor object at 0x7f2051c31ea0

    使用python输出某tensor的维度 print tensor size 出现报错 built in method size of Tensor object at 0x7f2051c31ea0 原因是size后面少了括号 加上即可 p
  • Linux 安装jenkins和jdk11

    Linux 安装jenkins和jdk11 1 Install Jdk11 2 Jenkins Install 2 1 Install Jenkins 2 2 Start 2 3 Error 3 Awakening 1 1 Big Data
  • opencv_contrib_python-3.4.0.12-cp36-cp36m(32位 64位)百度云资源

    官方下载地址下载太慢 贴一个百度云的地址 https pan baidu com s 1gguVL55 32位 https pan baidu com s 1bqP8c0Z 64位
  • STL标准模板库

    目录 一 容器 1 所有容器 2 常用容器 3 容器主要用法 4 resize和reserve 二 关系模型 1 谁需要关系 2 运算符最小集 3 弱序关系和严格弱序关系 4 相等关系 5 序关系和相等关系的关系 三 算法 1 sort函数
  • 华为机试HJ2-计算字符串中给定字符出现次数

    输入字符串以及特定字符 计算字符串中特定字符出现次数 include
  • spring cloud mybatis+mysql实现对数据库数据的访问

    MyBatis 是一款优秀的持久层框架 它支持定制化 SQL 存储过程以及高级映射 MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集 MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型 接口和 J
  • Linux指令

    1 pwd 显示当前用户所处的工作路径 2 ls 列出当前目录下所有文件和文件夹 ls 选项 常见的命令 ls l 显示文件的具体信息 文件的属性 大小 一行显示一个文件 ls a 显示所有的文件和文件夹 包含了以 开头的隐藏文件和文件夹
  • $(function(){})和$(document).ready(function(){})

    document ready和onload的区别 JavaScript文档加载完成事件 页面加载完成有两种事件 一是ready 表示文档结构已经加载完成 不包含图片等非文字媒体文件 二是onload 指示页面包含图片等文件在内的所有元素都加
  • R语言-多元统计学分析课程报告

    本文我们应用的软件为R语言 进行多元统计分析 所用的数据集为鸢尾花数据集 我们进行了Bayes判别 Fisher判别 系统聚类法 k 均值聚类和主成分分析 导入鸢尾花数据集 data lt read csv E 数学专业 多元统计学上机作业
  • 【Windows】win10任务栏图标空白的解决方案

    win10任务栏图标空白的解决方案 一 错误原因 在 Windows 10 系统中 为了加速图标的显示 当第一次对图标进行显示时 系统会对文件或程序的图标进行缓存 之后 当我们再次显示该图标时 系统会直接从缓存中读取数据 从而大大加快显示速
  • h5跳转小程序

    h5跳转小程序 我的所写的项目是react框架 在h5跳转小程序时 需要引入wx jssdk 具体操作看我上篇文章 https blog csdn net weixin 45315794 article details 122448088
  • Spring中@Autowired注解、J2EE @Resource注解的区别

    Spring不但支持自己定义的 Autowired注解 还支持几个由JSR 250规范定义的注解 它们分别是 Resource PostConstruct以及 PreDestroy Resource的作用相当于 Autowired 只不过
  • Android逆向工程:MIUI系统大揭秘:去不掉的小米账号!

    哈喽小伙伴们大家好 欢迎继续学习探讨MIUI系统的安全防范知识 在上篇博客中 Android逆向工程 带你领略MIUI系统的账号安全防范机制 账号是从哪里获取的 我们了解到了MIUI系统通过对关键代码进行封装进系统内 对外采用统一调用接口的
  • Web集群部署实战

    Web集群部署实战 Web集群架构图 系统规划 实验要求 购买一个 SFS 服务 以及 3 台云主机 部署 apache php 的网站 购买云主机3台 部署网页数据 挂载 SFS 服务到跳板机 root ecs proxy dnf ins
  • Docker

    参考资料 官方文档 Redirecting 官方文档超级详细 仓库地址 Docker Hub 发布到仓库 git pull push b站教程 狂神说Java Docker最新超详细版教程通俗易懂 哔哩哔哩 bilibili 这个教程非常简