Docker概述

  • 发布一个项目,能不能带上环境安装打包
# 发布一个安卓app
java --> apk --> 发布(应用商店) --> 张三使用apk --> 安装即可用
# 同理,发布一个jar包,利用docker
java --> jar(环境) -->打包项目带上环境(镜像) --> (Docker仓库: 类比商店) --> 下载我们发布的镜像 --> 直接运行即可
  • 隔离:Docker核心思想,打包装箱,每个箱子是互相隔离的
  • 虚拟机:在window中装一个VMware,通过这个软件,我们可以虚拟化出来一台或者多台电脑,硬件也虚拟出来,比较笨重,属于虚拟化技术
  • Docker容器技术也是一种虚拟化技术
VM: Linux centos原生镜像(相当与一台电脑),互相隔离,需要开启多个虚拟机,大小几个G
Docker: 隔离,镜像(最核心的环境 4M),十分小巧,运行镜像就可以了,几个M

Docker是基于Golang开发的

文档地址:https://docs.docker.com/

仓库地址:https://hub.docker.com/

虚拟机技术

  • 资源占用十分多
  • 冗余步骤多
  • 启动很慢
  • 虚拟化一些硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件

容器化技术

  • 容器化技术不是模拟一个完整的操作系统
  • 容器内的应用直接运行在宿主机的内核中,容器是没有自己的内核的,也没有虚拟我们的硬件,所以轻便了
  • 每个容器内是相互隔离的,每个容器内都有一个属于自己的文件系统,互不影响

基本组成

镜像

  • image好比一个模版,可以通过这个模版来创建容器服务

  • tomcat镜像 --> run --> tomcat 容器

  • 通过这个镜像可以创建多个容器,最终服务运行或者项目运行就是在容器中

容器

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

  • 启动、停止、删除、基本命令

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

仓库

  • 仓库是存放镜像的地方

  • 仓库分为共有仓库和私有仓库

  • Docker Hub默认是国外的

开始

Docker安装

  • 官方安装文档

    https://docs.docker.com/engine/install/centos/

  • 测试hello-world

jiangsiyong: ~ $ docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
93288797bd35: Pull complete 
Digest: sha256:393b81f0ea5a98a7335d7ad44be96fe76ca8eb2eaa76950eb8c989ebf2b78ec0
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.
  • 查看下载的镜像
jiangsiyong: ~ $ docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    18e5af790473   37 hours ago   9.14kB
centos        latest    300e315adb2f   9 months ago   209MB
  • docker run hello-world流程
    1. 开始,Docker会在本机寻找镜像
    2. 判断本机是否有这个镜像
    3. 如果本机有这个镜像,就直接使用这个镜像运行
    4. 否则,去Docker Hub下载
    5. 判断Docker Hub是否有这个镜像
    6. 如果有,下载这个镜像到本地,转向流程3
    7. 否则,返回找不到镜像的错误

通信模型

Docker是一个Client-Server结构的系统,Docker的守护进程运行在本机上,客户端通过Socker来访问Docker

Docker Server接收到Client发来的指令,就会执行这个指令

Docker为什么比VM快

  • Docker有着比虚拟机更少的抽象层
  • Docker利用的是宿主机的内核,VM需要的是Guest OS
  • Docker不需要像虚拟机一样重新加载一个操作系统的内核,避免引导

Docker常用命令

帮助命令

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

官方命令文档:https://docs.docker.com/reference/

镜像命令

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

    docker images [OPTIONS] [REPOSITORY[:TAG]]

    jiangsiyong: ~ $ docker images
    REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
    hello-world   latest    18e5af790473   38 hours ago   9.14kB
    centos        latest    300e315adb2f   9 months ago   209MB
    
    #解释
    REPOSITORY 镜像的仓库源
    TAG 镜像的标签
    IMAGE ID 镜像的ID
    CREATED 镜像的创建时间
    SIZE 镜像的大小
    
    #可选项
    --all, -a		列出所有的镜像
    --quiet, -q		只显示镜像的id
    
  • 搜索镜像

    docker search [OPTIONS] TERM

    jiangsiyong: ~ $ docker search mysql
    NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    mysql                             MySQL is a widely used, open-source relation…   11470     [OK]       
    mariadb                           MariaDB Server is a high performing open sou…   4354      [OK]       
    mysql/mysql-server                Optimized MySQL Server Docker images. Create…   848                  [OK]
    
    #可选项
    --filter=STARS=3000 搜出星级在3000以上的
    
  • 拉取下载镜像

    docker pull [OPTIONS] NAME[:TAG|@DIGEST]

    jiangsiyong: ~ $ docker pull redis
    Using default tag: latest #如果不写,默认是最新的
    latest: Pulling from library/redis
    d10c227306ce: Pull complete #分层下载,docker image的核心,联合文件系统
    71f6c833430f: Pull complete 
    f6169272c13d: Pull complete 
    17db4d790ed8: Pull complete 
    c5b59ebbf80e: Pull complete 
    177c4d24fee3: Pull complete 
    Digest: sha256:e595e79c05c7690f50ef0136acc9d932d65d8b2ce7915d26a68ca3fb41a7db61
    Status: Downloaded newer image for redis:latest
    docker.io/library/redis:latest #真实地址
    
  • 删除镜像

    docker rmi [OPTIONS] IMAGE [IMAGE...]

    jiangsiyong: ~ $ docker rmi redis #删除指定的镜像
    Untagged: redis:latest
    Untagged: redis@sha256:e595e79c05c7690f50ef0136acc9d932d65d8b2ce7915d26a68ca3fb41a7db61
    Deleted: sha256:33945ca6b5bfb35714f54f172737353a3e493c0866c238eb5e9034bdfe3ff798
    Deleted: sha256:d11fdd6b15b07a0a1374773038f4f95881cde45357b8f028b63f147152f84821
    Deleted: sha256:4ed432f18c5944c2c8eaa846424cdcbecf77ca65a49b9c27c2407c14c45dc24f
    Deleted: sha256:fe4801e23a4ce9410c27576d7432e6e0d277593c71461f82cad1458f26fb8527
    Deleted: sha256:a339fc4111fd6563276f4f8b994062480416c25f2beb5c01281942ad94b00184
    Deleted: sha256:a2bbab4dc2e346ff93626bd68c14d2f182a9d719521a6987c0f8b3b64c9b9d43
    Deleted: sha256:5f140fe6ea259f8caec3cb6a4f230fe761c8efa223579bf3c5f9af9e5883e986
    

容器命令

我们有了镜像,才可以创建容器

  • 新建容器并启动

    docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

    #参数说明
    --name="Name" 容器名字 tomcat01 tomcat02用来区分容器
    -d 后台方式运行
    -it 使用交互方式运行,进入容器查看内容
    -p 指定容器端口 -p 8080:8080
    	-p ip:主机端口:容器端口
    	-p 主机端口:容器端口(常用)
    	-p 容器端口
    -P 指定随机端口
    
    #测试
    
    #启动并进入容器
    jiangsiyong: ~ $ docker run -it centos /bin/bash
    [root@4d5a31acfaa7 /]# ls #进入容器内部
    bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    [root@4d5a31acfaa7 /]# exit #从容器中退出主机
    exit
    
  • 列出当前正在运行的容器

    docker ps [OPTIONS]

    jiangsiyong: ~ $ docker ps -a
    CONTAINER ID   IMAGE         COMMAND       CREATED         STATUS                          PORTS     NAMES
    4d5a31acfaa7   centos        "/bin/bash"   3 minutes ago   Exited (0) About a minute ago             dreamy_leakey
    578f57807749   hello-world   "/hello"      23 hours ago    Exited (0) 23 hours ago                   vibrant_cartwright
    
    #参数
    --all, -a		显示当前正在运行的容器+带出历史运行过的容器
    -n=? 显示最近创建的容器
    -q 只列出容器的编号
    
  • 退出容器

    exit #直接容器停止并退出
    Ctrl + P + Q #容器不停止退出
    
  • 删除容器

    docker rm 容器id #删除指定的容器,不能删除正在运行的容器,如果要强制删除,要用rm -rf
    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 镜像名
    jiangsiyong: ~ $ docker run -d centos
    #问题docker ps发现centos停止了
    #常见问题:docker容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
    
  • 查看容器的日志

    jiangsiyong: ~ $ 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:37Z) or relative (e.g. 42m for 42 minutes)
      -n, --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:37Z) or relative (e.g. 42m for 42 minutes)
    
    #显示日志
    -tf 显示日志,带上时间戳
    --tail number 要显示的日志条数
    
  • 显示容器内部的进程信息

    docker top 容器id
    
    jiangsiyong: ~ $ docker top d1c
    UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
    root                2467                2441                0                   14:38               ?                   00:00:00            /usr/bin/qemu-x86_64 /bin/bash
    
  • 查看容器的元数据

    jiangsiyong: ~ $ docker inspect --help
    Usage:  docker inspect [OPTIONS] NAME|ID [NAME|ID...]
    Return low-level information on Docker objects
    Options:
      -f, --format string   Format the output using the given Go template
      -s, --size            Display total file sizes if the type is container
          --type string     Return JSON for specified type
    
    
    jiangsiyong: ~ $ docker inspect d1c
    [
        {
            "Id": "d1c319b79b76e974fa4644c0cf154a0dd80bd68db012a6ba61cf8334de2fc0e4",
            "Created": "2021-09-26T14:38:10.65482422Z",
            "Path": "/bin/bash",
            "Args": [],
            "State": {
                "Status": "running",
                "Running": true,
                "Paused": false,
                "Restarting": false,
                "OOMKilled": false,
                "Dead": false,
                "Pid": 2467,
                "ExitCode": 0,
                "Error": "",
                "StartedAt": "2021-09-26T14:38:10.840967845Z",
                "FinishedAt": "0001-01-01T00:00:00Z"
            },
            "Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55",
            "ResolvConfPath": "/var/lib/docker/containers/d1c319b79b76e974fa4644c0cf154a0dd80bd68db012a6ba61cf8334de2fc0e4/resolv.conf",
            "HostnamePath": "/var/lib/docker/containers/d1c319b79b76e974fa4644c0cf154a0dd80bd68db012a6ba61cf8334de2fc0e4/hostname",
            "HostsPath": "/var/lib/docker/containers/d1c319b79b76e974fa4644c0cf154a0dd80bd68db012a6ba61cf8334de2fc0e4/hosts",
            "LogPath": "/var/lib/docker/containers/d1c319b79b76e974fa4644c0cf154a0dd80bd68db012a6ba61cf8334de2fc0e4/d1c319b79b76e974fa4644c0cf154a0dd80bd68db012a6ba61cf8334de2fc0e4-json.log",
            "Name": "/thirsty_kowalevski",
            "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,
                "CgroupnsMode": "host",
                "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/7facde6cefe6fb84fe71d61a08ab2b7d7bd16069c0e787e222d708ebd1dd9e02-init/diff:/var/lib/docker/overlay2/20d51d86652fa745c1f32efb2f77682f0a7ae3a0aa4f2d876ac8a85a2a269e98/diff",
                    "MergedDir": "/var/lib/docker/overlay2/7facde6cefe6fb84fe71d61a08ab2b7d7bd16069c0e787e222d708ebd1dd9e02/merged",
                    "UpperDir": "/var/lib/docker/overlay2/7facde6cefe6fb84fe71d61a08ab2b7d7bd16069c0e787e222d708ebd1dd9e02/diff",
                    "WorkDir": "/var/lib/docker/overlay2/7facde6cefe6fb84fe71d61a08ab2b7d7bd16069c0e787e222d708ebd1dd9e02/work"
                },
                "Name": "overlay2"
            },
            "Mounts": [],
            "Config": {
                "Hostname": "d1c319b79b76",
                "Domainname": "",
                "User": "",
                "AttachStdin": true,
                "AttachStdout": true,
                "AttachStderr": true,
                "Tty": true,
                "OpenStdin": true,
                "StdinOnce": true,
                "Env": [
                    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
                ],
                "Cmd": [
                    "/bin/bash"
                ],
                "Image": "centos",
                "Volumes": null,
                "WorkingDir": "",
                "Entrypoint": null,
                "OnBuild": null,
                "Labels": {
                    "org.label-schema.build-date": "20201204",
                    "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": "7d0b3806ffe95fa22f8c1a6950b60fc1eb35f684031d37cc9e1e87c84ddb5728",
                "HairpinMode": false,
                "LinkLocalIPv6Address": "",
                "LinkLocalIPv6PrefixLen": 0,
                "Ports": {},
                "SandboxKey": "/var/run/docker/netns/7d0b3806ffe9",
                "SecondaryIPAddresses": null,
                "SecondaryIPv6Addresses": null,
                "EndpointID": "c17a0ad271ea7b704292a6dd26cc02991543a3ade37dd4fbd0f413ad90dd474e",
                "Gateway": "172.17.0.1",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "IPAddress": "172.17.0.2",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "MacAddress": "02:42:ac:11:00:02",
                "Networks": {
                    "bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "NetworkID": "6a9b6e6db0fc67a93be97d23f7c086d6aa713a5b521a03e0f992553360109258",
                        "EndpointID": "c17a0ad271ea7b704292a6dd26cc02991543a3ade37dd4fbd0f413ad90dd474e",
                        "Gateway": "172.17.0.1",
                        "IPAddress": "172.17.0.2",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "MacAddress": "02:42:ac:11:00:02",
                        "DriverOpts": null
                    }
                }
            }
        }
    ]
    
  • 进入当前正在运行的容器

    #通常容器都是使用后台的方式运行的,需要进入容器修改一些配置
    docker exec -it 容器id bashshell 进入容器后开启一个新的终端,可以在里面操作
    docker attach 容器id 进入容器正在执行的终端,不会启动新的进程
    
  • 从容器拷贝文件到主机上

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

常见部署

部署Nginx

#1 搜索镜像
#2 下载镜像
docker pull nginx
#3 运行容器 --name 给容器命名 -p 宿主机:容器内端口
docker run -d --name nginx -p 3344:80 nginx
#4 查看容器
docker ps
#5 本机自测
curl localhost:3344

#进入ngnix
jiangsiyong: ~ $ docker exec -it nginx /bin/bash
root@e2fc2bef14b4:/# ls
bin   dev		   docker-entrypoint.sh  home  media  opt   root  sbin	sys  usr
boot  docker-entrypoint.d  etc			 lib   mnt    proc  run   srv	tmp  var

部署Tomcat

#1 下载镜像
docker pull tomcat
#2 启动运行
docker run -d -p 3355:8080 --name tomcat tomcat
# 测试访问没有问题
# 进入tomcat
jiangsiyong: ~ $ docker exec -it tomcat /bin/bash
root@4ae869212724:/usr/local/tomcat# ls
BUILDING.txt	 LICENSE  README.md	 RUNNING.txt  conf  logs	    temp     webapps.dist
CONTRIBUTING.md  NOTICE   RELEASE-NOTES  bin	      lib   native-jni-lib  webapps  work
root@4ae869212724:/usr/local/tomcat# cp -r  webapps.dist/* webapps

部署ES + Kibana

# es 暴露的端口很多
# es 十分耗内存
# es的数据一般需要放到安全目录
# --net somenetwork 网络配置
# 下载启动
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300  -e "discovery.type=single-node" elasticsearch:7.14.1

# 启动了,很卡: es十分耗内存
docker stats #查看cpu的状态

# 增加内存限制
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300  -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.14.1

可视化工具portainer

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

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

访问测试:http://localhost:8088/

Docker镜像

  • 从远程仓库下载
  • 拷贝过来
  • 通过DockerFile制作

UnionFS联合文件系统

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

Docker镜像加速的原理

  • Docker镜像实际上是由一层层的文件系统组成,这种层级叫联合文件系统
  • bootfs主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时候会加载bootfs文件系统,在Docker镜像最底层是bootfs。这一层与我们典型的Linux/Unix是一样的。包含了boot加速器和内核。当boot加载完成后整个内核就在内存中了,此时内存的使用权由bootfs转交给内核,此时系统会卸载bootfs
  • rootfs:在bootfs之上,包含了典型的Linux系统的/dev、/proc、/bin、/etc等标准目录和文件。rootfs就是各种不同的操作系统的发行版。
  • 对于一个精简的OS、rootfs可以很小、只需要包含基本的命令、工具和程序库就行。因为底层直接用Host的kernel,自己只需要提供rootfs就可以了,由此可见对于不同的linux发行版,rootfs会有差异,因此不同的发行版可以共用bootfs

分层原理

  • 我们可以下载一个镜像,注意观察下载的日志输出,可以看到是一层一层下载的

  • 采用分层结构,最大的好处是资源共享,比如有多个镜像都是从相同的Base镜像构建来的,那么宿主机只需要在磁盘中保留一份Base镜像就可以了,同时内存也只需要加载一份Base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以共享。

  • 查看镜像的分层的方式可以通过docker image inspect命令

    jiangsiyong: ~ $ docker image inspect nginx
    [
        {
            "Id": "sha256:9fa3786cd6acd84e0c642aac376e374d55231e48546b1ec0611eb1d31f0a9f3d",
            "RepoTags": [
                "nginx:latest"
            ],
            "RepoDigests": [
                "nginx@sha256:853b221d3341add7aaadf5f81dd088ea943ab9c918766e295321294b035f3f3e"
            ],
            "Parent": "",
            "Comment": "",
            "Created": "2021-09-09T17:51:09.078592214Z",
            "Container": "e4a792602a7cb512b981296eccb2b50ae9e3ce77edc945db3bb8b0291c8655b3",
            "ContainerConfig": {
                "Hostname": "e4a792602a7c",
                "Domainname": "",
                "User": "",
                "AttachStdin": false,
                "AttachStdout": false,
                "AttachStderr": false,
                "ExposedPorts": {
                    "80/tcp": {}
                },
                "Tty": false,
                "OpenStdin": false,
                "StdinOnce": false,
                "Env": [
                    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                    "NGINX_VERSION=1.21.3",
                    "NJS_VERSION=0.6.2",
                    "PKG_RELEASE=1~buster"
                ],
                "Cmd": [
                    "/bin/sh",
                    "-c",
                    "#(nop) ",
                    "CMD [\"nginx\" \"-g\" \"daemon off;\"]"
                ],
                "Image": "sha256:d06c4989171f08174a38d621f11f1adaa0668f9894f518a215624e957889767b",
                "Volumes": null,
                "WorkingDir": "",
                "Entrypoint": [
                    "/docker-entrypoint.sh"
                ],
                "OnBuild": null,
                "Labels": {
                    "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
                },
                "StopSignal": "SIGQUIT"
            },
            "DockerVersion": "20.10.7",
            "Author": "",
            "Config": {
                "Hostname": "",
                "Domainname": "",
                "User": "",
                "AttachStdin": false,
                "AttachStdout": false,
                "AttachStderr": false,
                "ExposedPorts": {
                    "80/tcp": {}
                },
                "Tty": false,
                "OpenStdin": false,
                "StdinOnce": false,
                "Env": [
                    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                    "NGINX_VERSION=1.21.3",
                    "NJS_VERSION=0.6.2",
                    "PKG_RELEASE=1~buster"
                ],
                "Cmd": [
                    "nginx",
                    "-g",
                    "daemon off;"
                ],
                "Image": "sha256:d06c4989171f08174a38d621f11f1adaa0668f9894f518a215624e957889767b",
                "Volumes": null,
                "WorkingDir": "",
                "Entrypoint": [
                    "/docker-entrypoint.sh"
                ],
                "OnBuild": null,
                "Labels": {
                    "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
                },
                "StopSignal": "SIGQUIT"
            },
            "Architecture": "arm64",
            "Variant": "v8",
            "Os": "linux",
            "Size": 125996525,
            "VirtualSize": 125996525,
            "GraphDriver": {
                "Data": {
                    "LowerDir": "/var/lib/docker/overlay2/1e6c6e8e97a4062494f53ffffa2ff7b4272bf0c3789f97b9be177a98ff94f907/diff:/var/lib/docker/overlay2/60771f42be72e06623f7587b36e791927f0dac7a09c72972ff9ac80248d9c802/diff:/var/lib/docker/overlay2/e08ef36312b415cbb803829b9baed945d7d4eca637bf97ec6c94fe9038693635/diff:/var/lib/docker/overlay2/b38e18d2dabe4004fcb630d8f1e1450a409ca5b3373f019f08b1c61b9982f9ab/diff:/var/lib/docker/overlay2/74867c601bb2e4cf4fa04d40c3f91adc74f6dbc6749ef454cfaf55b7187e35c0/diff",
                    "MergedDir": "/var/lib/docker/overlay2/6d855dc4415773ce4a4269df4441f2110c40b89ea2f048b249d18caa3c0d6ef1/merged",
                    "UpperDir": "/var/lib/docker/overlay2/6d855dc4415773ce4a4269df4441f2110c40b89ea2f048b249d18caa3c0d6ef1/diff",
                    "WorkDir": "/var/lib/docker/overlay2/6d855dc4415773ce4a4269df4441f2110c40b89ea2f048b249d18caa3c0d6ef1/work"
                },
                "Name": "overlay2"
            },
            "RootFS": {
                "Type": "layers",
                "Layers": [
                    "sha256:5f140fe6ea259f8caec3cb6a4f230fe761c8efa223579bf3c5f9af9e5883e986",
                    "sha256:5ac2af1ad4fd920bb7e5cd04802bfda1b991c22a42d7bb1df773620553502d9a",
                    "sha256:1fbe13821665fc8bd205e02dde22c5d72605c2170680c08401a6d3b8566c5dcb",
                    "sha256:19d1177a9d832c9d7fb6f4285d74a5e35377fcc68242860abdf319293c4e2664",
                    "sha256:a878019e90336fb68b6985982baf9f13b13d21f5230cbd1ce6c1d6b18f4ff6a3",
                    "sha256:a97ebc9f68a9e9626354413ea31e221966d379567317a2bb59d0d15a89b230a4"
                ]
            },
            "Metadata": {
                "LastTagTime": "0001-01-01T00:00:00Z"
            }
        }
    ]
    
  • 所有的镜像都起始于一个基础的镜像层,当进行修改或者添加新的内容的时候,就会在当前镜像层上面创建新的镜像层,比如给予Ubuntu Linux 16.04创建一个新的镜像,这就是新的镜像的第一层,如果在该镜像中添加Python包,就会在基础的镜像层之上创建第二个镜像层,如果继续添加一个安全补丁,就会创建第三个镜像层。

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

commit镜像

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

#命令和git类似
docker commit -m "提交的描述信息" -a "作者" 容器id 目标镜像名:[TAG]

容器数据卷

概念

Docker的理念是将应用和环境打包成一个镜像,如果数据在容器中,那么我们将容器删除,数据就会丢失。

需要容器之间可以有一个数据共享的技术。在Docker容器中产生的数据,可以同步到本地,这就是卷技术

就是目录的挂载,将我们容器中的目录,挂载到Linux上面

容器间也是可以数据共享的

使用数据卷

  • 方式一:直接使用命令来挂载
docker run -it -v 宿主机的目录:容器目录 容器 bash

jiangsiyong: ~ $ docker run -it -v ~/Downloads/testDocker:/home/test centos
[root@46d5de98a240 /]# 
jiangsiyong: ~ $ docker inspect 46d5de98a240
…………
"Mounts": [
    {
        "Type": "bind",
        "Source": "/Users/jiangsiyong/Downloads/testDocker",
        "Destination": "/home/test",
        "Mode": "",
        "RW": true,
        "Propagation": "rprivate"
    }
]
…………

#假设将容器删除,挂载到本地的数据卷依旧没有消失
  • 具名挂载和匿名挂载
#匿名挂载
-v 容器内路径
docker run -d -P --name ngnix01 -v /etc/nginx nginx

#查看所有卷volume的情况
docker volume ls
#发现
jiangsiyong: ~ $ docker volume ls
DRIVER    VOLUME NAME
local     19580df3d818a1df43a2862e6c43437eba4c53b9c75da048015a215df1ff4b37

#具名挂载
docker run -d -P --name ngnix01 -v juming-nginx:/etc/nginx nginx
#发现
jiangsiyong: ~ $ docker volume ls
DRIVER    VOLUME NAME
local     19580df3d818a1df43a2862e6c43437eba4c53b9c75da048015a215df1ff4b37
local     juming-nginx

#查看卷的路径
docker volume inspect 卷名
jiangsiyong: ~ $ docker volume inspect 19580df3d818a1df43
[
    {
        "CreatedAt": "2021-09-28T13:57:20Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/19580df3d818a1df43a2862e6c43437eba4c53b9c75da048015a215df1ff4b37/_data",
        "Name": "19580df3d818a1df43a2862e6c43437eba4c53b9c75da048015a215df1ff4b37",
        "Options": null,
        "Scope": "local"
    }
]

#通过 -v 容器内路径:[ro:rw]来改变读写权限
#ro readonly 只读
#rw readwrite 可读可写
docker run -d -P --name ngnix01 -v juming-nginx:/etc/nginx:ro nginx
#一旦设置了容器权限,容器对我们挂载出来的内容就有限定了
#ro 只要看到ro,就说明这个路径只能通过宿主机来操作,容器内部是无法操作的

数据卷容器

实现数据同步--volumes-from
容器1
容器2
#启动第一个容器
docker run -it --name docker01 centos
#第二个容器volumes-from docker01
docker run -it --name docker02 --volumes-from docker01 centos
#docker01容器创建的内容同步到docker02上
#启动docker03
docker run -it --name docker03 --volumes-from docker01 centos
#发现docker01、docker02和docker03之间的数据都是共享的
  • 可以删除docker01,发现docker02和docker03的数据还是存在,是一种数据备份机制
  • 多个mysql或者多个redis来实现数据共享
  • 容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用

Mac上进入容器目录

对于Mac操作系统,无法看到/var/lib/docker目录,因为Mac上安装的Docker是将Docker安装在虚拟机上的。

我们需要用以下方式进入

jiangsiyong: ~ $ docker run -it --rm --privileged --pid=host justincormack/nsenter1
Unable to find image 'justincormack/nsenter1:latest' locally
latest: Pulling from justincormack/nsenter1
726619a9fa8c: Pull complete 
Digest: sha256:e876f694a4cb6ff9e6861197ea3680fe2e3c5ab773a1e37ca1f13171f7f5798e
Status: Downloaded newer image for justincormack/nsenter1:latest
/ # 

Dockerfile

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

  • 创建一个Docker File文件:dockerfile1
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "---end---"
CMD /bin/bash
  • 构建一个镜像

    docker build -f dockerfile1 -t hello/centos:1.0 .

  • 执行

jiangsiyong: Docker $ docker build -f dockerfile1 -t hello/centos:1.0 .
[+] Building 1.3s (5/5) FINISHED                                                                                        
 => [internal] load build definition from dockerfile1                                                              0.0s
 => => transferring dockerfile: 121B                                                                               0.0s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load metadata for docker.io/library/centos:latest                                                   1.2s
 => [1/1] FROM docker.io/library/centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177    0.0s
 => => resolve docker.io/library/centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177    0.0s
 => exporting to image                                                                                             0.0s
 => => exporting layers                                                                                            0.0s
 => => writing image sha256:0f3f2a3f60442405fcd2a2cb17113bd0c796ad26e470db3ff1a9c4bd9edbb114                       0.0s
 => => naming to docker.io/hello/centos:1.0                                                                        0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

基础

  • 每个保留关键字都必须是大写字母
  • 执行从上到下顺序执行
  • #表示注释
  • 每个执行都会创建一个新的镜像层,并提交

指令

FROM					#基础镜像,一切从这里开始构建
MAINTAINER		#镜像是谁写的,姓名+邮箱
RUN						#镜像构建的时候需要运行的命令
ADD						#步骤:tomcat镜像,这个tomcat的压缩包!添加内容
WORKDIR				#镜像的工作目录
VOLUME				#挂载的目录
EXPOSE 				#指定暴露的端口配置

#ls -a --> docker run -l
CMD 					#指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替换
ENTRYPOINT 		#指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD 			#当构建一个被继承的DockerFile的,这个时候就会运行ONBUILD指令,触发指令
COPY 					#将文件拷贝到镜像中,类似于ADD
ENV 					#构建的时候设置环境变量

构建自己的镜像

Docker Hub中99%的镜像都是从scratch过来的,然后配置需要的软件和配置进行构建的

  • 创建一个自己的centos

My docker

#编写dockerfile镜像文件
jiangsiyong: Docker $ vim mydockerfile-centos 
FROM centos
MAINTAINER helloworld<12345678@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

#通过这个文件构建镜像
#通过docker build -f dockerfile 文件路径 -t 镜像名:[tag]
jiangsiyong: Docker $ docker build -f mydockerfile-centos -t mycentos:0.1 .
[+] Building 17.4s (8/8) FINISHED                                                                                       
 => [internal] load build definition from mydockerfile-centos                                                      0.0s
 => => transferring dockerfile: 262B                                                                               0.0s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load metadata for docker.io/library/centos:latest                                                   1.1s
 => CACHED [1/4] FROM docker.io/library/centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f43  0.0s
 => [2/4] WORKDIR /usr/local                                                                                       0.0s
 => [3/4] RUN yum -y install vim                                                                                  14.2s
 => [4/4] RUN yum -y install net-tools                                                                             1.9s
 => exporting to image                                                                                             0.2s 
 => => exporting layers                                                                                            0.2s 
 => => writing image sha256:8ce98b373ff5f4fa14fa7c90c99e52ffbe61b5b103de2a1286dc19f7d46a3141                       0.0s 
 => => naming to docker.io/library/mycentos:0.1                                                                    0.0s 
                                                                                                                        
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them                    
  • 查看当前镜像的构建过程
jiangsiyong: Docker $ docker history 8ce98b373ff5
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
8ce98b373ff5   5 minutes ago   CMD ["/bin/sh" "-c" "/bin/bash"]                0B        buildkit.dockerfile.v0
<missing>      5 minutes ago   CMD ["/bin/sh" "-c" "echo \"----end----\""]     0B        buildkit.dockerfile.v0
<missing>      5 minutes ago   CMD ["/bin/sh" "-c" "echo $MYPATH"]             0B        buildkit.dockerfile.v0
<missing>      5 minutes ago   EXPOSE map[80/tcp:{}]                           0B        buildkit.dockerfile.v0
<missing>      5 minutes ago   RUN /bin/sh -c yum -y install net-tools # bu…   15.1MB    buildkit.dockerfile.v0
<missing>      5 minutes ago   RUN /bin/sh -c yum -y install vim # buildkit    66.6MB    buildkit.dockerfile.v0
<missing>      5 minutes ago   WORKDIR /usr/local                              0B        buildkit.dockerfile.v0
<missing>      5 minutes ago   ENV MYPATH=/usr/local                           0B        buildkit.dockerfile.v0
<missing>      5 minutes ago   MAINTAINER helloworld<12345678@qq.com>          0B        buildkit.dockerfile.v0
<missing>      3 weeks ago     /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
<missing>      3 weeks ago     /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B        
<missing>      3 weeks ago     /bin/sh -c #(nop) ADD file:420712a90b0934202…   272MB     

  • CMD和ENTRYPOINT的区别

CMD

#编写dockerfile命令
jiangsiyong: Docker $ vim dockerfile-cmd-test
jiangsiyong: Docker $ cat dockerfile-cmd-test 
FROM centos
CMD ["ls","-a"]

#构建镜像
jiangsiyong: Docker $ docker build -f dockerfile-cmd-test -t cmdtest .
[+] Building 0.4s (5/5) FINISHED                                                                                        
 => [internal] load build definition from dockerfile-cmd-test                                                      0.0s
 => => transferring dockerfile: 79B                                                                                0.0s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load metadata for docker.io/library/centos:latest                                                   0.3s
 => CACHED [1/1] FROM docker.io/library/centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f43  0.0s
 => exporting to image                                                                                             0.0s
 => => exporting layers                                                                                            0.0s
 => => writing image sha256:800ae6f76bf9bd620270ac45363d160888daaa2e8d4fd17c155f573761ddca66                       0.0s
 => => naming to docker.io/library/cmdtest                                                                         0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

#运行该镜像,发现ls -a生效
jiangsiyong: Docker $ docker run cmdtest
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
#想追加一个命令-l即ls -a -l
#cmd的情况下 -l会替换CMD ["ls","-a"]命令,而-l不是命令,所以报错
jiangsiyong: Docker $ docker run cmdtest -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled 

ENTRYPOINT

#编写dockerfile命令
jiangsiyong: Docker $ vim dockerfile-entrypoint-test 
jiangsiyong: Docker $ cat dockerfile-entrypoint-test  
FROM centos
ENTRYPOINT ["ls","-a"]

#构建镜像
jiangsiyong: Docker $ docker build -f dockerfile-entrypoint-test -t entrypoint-test .
[+] Building 0.4s (5/5) FINISHED                                                                                        
 => [internal] load build definition from dockerfile-entrypoint-test                                               0.0s
 => => transferring dockerfile: 93B                                                                                0.0s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load metadata for docker.io/library/centos:latest                                                   0.3s
 => CACHED [1/1] FROM docker.io/library/centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f43  0.0s
 => exporting to image                                                                                             0.0s
 => => exporting layers                                                                                            0.0s
 => => writing image sha256:9f1a36acb55321d87fe7400634a6d558f473f6905d4caf1c6734e627f2325abc                       0.0s
 => => naming to docker.io/library/entrypoint-test                                                                 0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

#效果跟cmd命令一样
jiangsiyong: Docker $ docker run entrypoint-test
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

#不是替换cmd命令,而是追加的方式
jiangsiyong: Docker $ docker run entrypoint-test -l
total 56
drwxr-xr-x   1 root root 4096 Oct  9 13:37 .
drwxr-xr-x   1 root root 4096 Oct  9 13:37 ..
-rwxr-xr-x   1 root root    0 Oct  9 13:37 .dockerenv
lrwxrwxrwx   1 root root    7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root  340 Oct  9 13:37 dev
drwxr-xr-x   1 root root 4096 Oct  9 13:37 etc
drwxr-xr-x   2 root root 4096 Nov  3  2020 home
lrwxrwxrwx   1 root root    7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Nov  3  2020 lib64 -> usr/lib64
drwx------   2 root root 4096 Sep 15 14:25 lost+found
drwxr-xr-x   2 root root 4096 Nov  3  2020 media
drwxr-xr-x   2 root root 4096 Nov  3  2020 mnt
drwxr-xr-x   2 root root 4096 Nov  3  2020 opt
dr-xr-xr-x 185 root root    0 Oct  9 13:37 proc
dr-xr-x---   2 root root 4096 Sep 15 14:26 root
drwxr-xr-x  11 root root 4096 Sep 15 14:26 run
lrwxrwxrwx   1 root root    8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 Nov  3  2020 srv
dr-xr-xr-x  13 root root    0 Oct  9 13:37 sys
drwxrwxrwt   7 root root 4096 Sep 15 14:26 tmp
drwxr-xr-x  12 root root 4096 Sep 15 14:25 usr
drwxr-xr-x  20 root root 4096 Sep 15 14:25 var

构建Tomcat镜像

  • 准备镜像文件tomcat压缩包,jdk压缩包
  • 编写dockerfile文件
jiangsiyong: Docker $ vim dockerfile-tomcat
jiangsiyong: Docker $ 
jiangsiyong: Docker $ 
jiangsiyong: Docker $ cat dockerfile-tomcat 
FROM centos
MAINTAINER hello<12345678@qq.com>

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

ADD jdk-8u11-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.22.tar.gz /usr/local/

RUN yum -y -install vim

ENV MYPATH /usr/local
WORK $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tolls.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out
jiangsiyong: Docker $ 
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐