Docker

Docker

Docker概述

Docker为什么出现

一款产品:开发--上线 两套环境 应用环境,应用配置

开发----运维

环境配置是十分的麻烦,每一个机器都要部署环境(集群Redis,ES,Hadoop。。。。)!费时费力

发布项目jar+(Redis,MySQL,jdk,ES...),项目能不能带上环境安装打包!

之前在服务器配置一个应用的环境Redis,MySQL,jdk,ES,Hadoop,配置超麻烦,不能跨平台

Windows,最后发布到Linux

传统:开发jar,运维来做部署的事情

现在:开发打包部署上线,一套流程做完

 

java--jar(环境)---打包项目带上环境(形成镜像)---(Docker仓库:商店)--下载我们发布的镜像--直接运行

 

Docker给以上的问题,提出了解决方案

docker的思想就来自集装箱

JRE--多个应用(端口冲突)--原来是交叉的

隔离:Docker的核心思想,打包装箱!每个箱子是互相隔离。

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

Docker历史

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

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

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

Docker刚刚创建时,没有引起行业的注意,dotCloud就活不下去

 

开源

开发源代码

2013年,Docker开源

Docker越来越火,Docker每个月都或更新一个版本

2014年4月9日。Docker1.0发布

Doker为什么这么火,十分轻巧

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

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

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

 vm:linux centOS原生镜像(一台电脑) 隔离:需要开启多个虚拟机  几个G 几分钟
 docker:隔离,镜像(最核心的环境 4m + jdk +mysql) 十分轻巧,运行镜像即可!小巧 几个m kb 秒级启动

到现在,多有开发人员都必须会Docker

 

Docker是基于GO语言开发!开源项目

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

文档地址:https://docs.docker.com/,Docker的文档是超级详细的

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

 

Docker能做什么

  1. 之前的虚拟机技术

  • 资源占用十分多

  • 冗余步骤多

  • 启动很慢

  1. 容器化技术

    容器化技术不是模拟的一个完整的操作系统

比较Docker和虚拟机技术的区别:

  • 传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件

  • 容器内应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了

  • 每个容器是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响

 

  1. DevOps(开发,运维)

    应用更快速的交付和部署

    传统:一堆文档,安装程序

    Docker:打包镜像发布测试,一键运行。

    更便捷的升级和扩缩容

    使用了Docker之后,我们部署应用就和搭积木一样

    项目打包为一个镜像,扩展 服务器A!服务器B

    更简单的系统运维

    在容器化之后,我们的开发,测试环境都是高度一致的

    更高效的计算资源的利用

    Docker是内核级别的虚拟化,可以在一个物理机上运行很多容器实例!服务器性能可以被压榨到极致。

Docker安装

Docker基本组成

点击查看源网页

镜像(image):

docker镜像就好比是一个模板,通过这个模板来创建容器服务,tomcat镜像--->run-->tomcat01容器(提供服务)

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

容器(containers):

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

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

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

仓库(repository):

仓库就是存放镜像的地方!

仓库分为私有和共有仓库

Docker Hub(默认是国外的)

阿里云。。。都有容器服务(配置镜像加速)

Docker安装

环境安装

  1. 需要一些linux的基础

  2. CentOS7

  3. 我们使用Xshell连接远程服务器进行操作

环境查看

 #系统内核是3.10
 [zhoudelin@localhost ~]$ uname -r
 3.10.0-1127.el7.x86_64
 
 #系统版本
 [zhoudelin@localhost ~]$ cat /etc/os-release
 NAME="CentOS Linux"
 VERSION="7 (Core)"
 ID="centos"
 ID_LIKE="rhel fedora"
 VERSION_ID="7"
 PRETTY_NAME="CentOS Linux 7 (Core)"
 ANSI_COLOR="0;31"
 CPE_NAME="cpe:/o:centos:centos:7"
 HOME_URL="https://www.centos.org/"
 BUG_REPORT_URL="https://bugs.centos.org/"
 
 CENTOS_MANTISBT_PROJECT="CentOS-7"
 CENTOS_MANTISBT_PROJECT_VERSION="7"
 REDHAT_SUPPORT_PRODUCT="centos"
 REDHAT_SUPPORT_PRODUCT_VERSION="7"

安装

帮助文档

 #1.卸载旧的版本
 $ sudo yum remove docker
                  docker-client
                  docker-client-latest
                  docker-common
                  docker-latest
                  docker-latest-logrotate
                  docker-logrotate
                  docker-engine
 
 #2.需要的安装包
 $ sudo yum install -y yum-utils
 
 #3.设置镜像的仓库
 $ sudo yum-config-manager
     --add-repo
    https://download.docker.com/linux/centos/docker-ce.repo  #国外的地址,非常慢
     
    yum-config-manager
     --add-repo
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo  #推荐使用阿里云
     
 #先更新yum软件包索引
 yum makecache fast
     
 #4.安装docker docker-ce社区版 ee 企业版
 $ sudo yum install docker-ce docker-ce-cli containerd.io
 
 #5.启动docker
 $ sudo systemctl start docker
 
 #6.判断是否成功
 [zhoudelin@localhost ~]$ docker version
 
 #7.hello-world
 $ sudo docker run hello-world
 结果显示:
 [zhoudelin@localhost ~]$ sudo docker run hello-world
 Unable to find image 'hello-world:latest' locally
 latest: Pulling from library/hello-world
 0e03bdcc26d7: Pull complete
 Digest: sha256:7f0a9f93b4aa3022c3a4c147a449bf11e0941a1fd0bf4a8e6c9408b2600777c5
 Status: Downloaded newer image for hello-world:latest
 
 Hello from Docker!
 This message shows that your installation appears to be working correctly.
 
 To generate this message, Docker took the following steps:
  1. The Docker client contacted the Docker daemon.
  2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
  3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
  4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.
 
 To try something more ambitious, you can run an Ubuntu container with:
  $ docker run -it ubuntu bash
 
 Share images, automate workflows, and more with a free Docker ID:
  https://hub.docker.com/
 
 For more examples and ideas, visit:
  https://docs.docker.com/get-started/
 
 #8.查看一下下载的这个hello-world镜像
 $ sudo docker images
 [zhoudelin@localhost ~]$ sudo docker images
 REPOSITORY         TAG                 IMAGE ID           CREATED             SIZE
 hello-world         latest             bf756fb1ae65        8 months ago        13.3kB

了解卸载docker

 #卸载依赖
 $ sudo yum remove docker-ce docker-ce-cli containerd.io
 
 #删除目录
 $ sudo rm -rf /var/lib/docker   #docker默认工作路径:/var/lib/docker

阿里云镜像加速

 

 

回顾HelloWorld流程

底层原理

Docker是干什么工作的?

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

DockerServer接收到Docker-Client的指令,就会执行这个命令!

Docker为什么比VM快

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

  1. Docker利用的是宿主机的内核,vm更需要的是Guest OS

    所以说,新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导。虚拟机是加载Guest OS,分钟级别,而Docker是利用宿主机的操作系统,省略了这个复杂的过程。

Docker常用命令

帮助命令

 docker version           # 显示docker版本
 docker info              # 显示docker系统信息,包括镜像和容器
 docker command --help    # 帮助命令
 systemctl start docker   # 启动docker服务

帮助文档:https://docs.docker.com/reference/

镜像命令

docker images 查看本机上的所有镜像

 [root@localhost ~]$ sudo docker images
 REPOSITORY         TAG                 IMAGE ID           CREATED             SIZE
 hello-world         latest             bf756fb1ae65        8 months ago        13.3kB
 
 #解释
 REPOSITORY     镜像的仓库源
 TAG             镜像的标签
 IMAGE ID       镜像的id
 CREATED         镜像的创建时间
 SIZE           镜像的大小
 
 Options:        #可选项
   -a, --all             Show all images (default hides intermediate images)#列出所有的镜像
       --digests         Show digests
   -f, --filter filter   Filter output based on conditions provided
       --format string   Pretty-print images using a Go template
       --no-trunc       Don't truncate output
   -q, --quiet           Only show numeric IDs   #只显示镜像的ID
 

docker search 搜索镜像

 [root@localhost ~]$ sudo docker search mysql
 [sudo] root 的密码:
 NAME                             DESCRIPTION                                     STARS               OFFICIAL           AUTOMATED
 mysql                             MySQL is a widely used, open-source relation…   9934               [OK]                
 
 #可选项
 [root@localhost ~]$ sudo docker search --help
 
 Usage: docker search [OPTIONS] TERM
 
 Search the Docker Hub for images
 
 Options:
   -f, --filter filter   Filter output based on conditions provided
       --format string   Pretty-print search using a Go template
       --limit int       Max number of search results (default 25)
       --no-trunc       Don't truncate output
 
 #通过收藏来过滤
 --filter-STARTS-3000   #搜索出来的镜像就是STARTS大于3000的
 

docker pull 下载镜像

 #下载镜像  docker pull 镜像名[:tag]
 [root@localhost ~]$ sudo docker pull mysql
 [sudo] root 的密码:
 Using default tag: latest   #如果不写tag,默认就是latest
 latest: Pulling from library/mysql
 bf5952930446: Pull complete   #分层下载,docker images的核心 联合文件系统
 8254623a9871: Pull complete
 938e3e06dac4: Pull complete
 ea28ebf28884: Pull complete
 f3cef38785c2: Pull complete
 894f9792565a: Pull complete
 1d8a57523420: Pull complete
 6c676912929f: Pull complete
 3cdd8ff735c9: Pull complete
 4c70cbe51682: Pull complete
 e21cf0cb4dc3: Pull complete
 28c36cd3abcc: Pull complete
 Digest: sha256:6ded54eb1e5d048d8310321ba7b92587e9eadc83b519165b70bbe47e4046e76a  #签名
 Status: Downloaded newer image for mysql:latest
 docker.io/library/mysql:latest  #真实的
 
 #两者等价
 docker pull mysql
 docker.io/library/mysql:latest

docker rmi 删除镜像

[root@localhost ~]$ sudo docker rmi -f 容器id   #删除指定内容
[root@localhost ~]$ sudo docker rmi -f 容器id 容器id 容器id   #删除多个容器
[root@localhost ~]$ sudo docker rmi -f $(docker images -aq)#删除全部的容器

容器命令

说明:我们有了镜像才可以创建容器,Linux,下载一个CentOS镜像来测试学习

docker pull centos

新建容器,并启动

docker run [可选参数] image

#参数说明
--name="Name"  容器名字 tomcat01 tomcat02,用来区分容器
-d             后台方式运行
-it            使用交互方式运行,进入容器查看内容
-p             指定容器的端口 -p 8080:8080
     -p ip:主机端口:容器端口
     -p 主机端口:容器端口(常用)
     -p 容器端口
     容器端口
-p             随机指定端口
#测试,启动并进入容器
[root@localhost ~]$ sudo docker run -it centos /bin/bash
[sudo] root 的密码:
[root@a4533364bee2 /]# ls  #查看容器内的centos,基础版本,很多命令都是不完善的!
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

#从容器中退回主机
[root@a4533364bee2 /]# exit

列出运行中的容器

#docker ps命令
         #列出当前正在运行的容器
-a         #列出当前正在运行的容器+带出历史运行过的容器
-n=?         #显示最近创建的容器
-q       #只显示容器的编号

[root@localhost ~]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@localhost ~]$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
a4533364bee2        centos              "/bin/bash"         9 minutes ago       Exited (127) 3 minutes ago                       upbeat_keller
2a726ed3ab4b        bf756fb1ae65        "/hello"            2 hours ago         Exited (0) 2 hours ago                           blissful_maxwell

 

退出容器

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

 

删除容器

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

 

启动和停止容器操作

docker start 容器id  #启动容器
docker restart 容器id  #重启容器
docker stop 容器id   #
docker kill 容器id

 

常用其他命令

后台启动容器

#命令 docker run -d 镜像名
[root@localhost ~]$ sudo docker run -d centos

#问题docker ps 发现centos停止了

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

查看日志

docker logs -f -t --tail 容器,没有日志

查看容器中进程信息

# 命令 docker top 容器id

镜像元数据

# 命令 docker inspect 容器id
[root@localhost ~]$ sudo docker inspect b4af22c18647
[sudo] root 的密码:
[
    {
        "Id": "b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8",
        "Created": "2020-09-08T02:02:35.268831886Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2020-09-08T02:04:58.767625388Z",
            "FinishedAt": "2020-09-08T02:04:58.778547336Z"
        },
        "Image": "sha256:0d120b6ccaa8c5e149176798b3501d4dd1885f961922497cd0abef155c869566",
        "ResolvConfPath": "/var/lib/docker/containers/b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8/hostname",
        "HostsPath": "/var/lib/docker/containers/b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8/hosts",
        "LogPath": "/var/lib/docker/containers/b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8/b4af22c186475328b9dda30e03e8e6915a29b65430c7a3ef126a3fa7b4d847c8-json.log",
        "Name": "/nervous_gates",
        "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/4915f4244512c71cc03733fe4d007c6565de019a9b77944122591f74efa1d337-init/diff:/var/lib/docker/overlay2/f75740f43db3aa996a6f4b57893c909b313d94f1e2f2aff368ffe5532c3078d9/diff",
                "MergedDir": "/var/lib/docker/overlay2/4915f4244512c71cc03733fe4d007c6565de019a9b77944122591f74efa1d337/merged",
                "UpperDir": "/var/lib/docker/overlay2/4915f4244512c71cc03733fe4d007c6565de019a9b77944122591f74efa1d337/diff",
                "WorkDir": "/var/lib/docker/overlay2/4915f4244512c71cc03733fe4d007c6565de019a9b77944122591f74efa1d337/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "b4af22c18647",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "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": "20200809",
                "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": "1b993ccc98a55b6da5c5db799f1d8c5273d72810a3357b51ce776faa2bec96fc",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/1b993ccc98a5",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "b1923d034b83452efca1c670efe2357579bdd03170647fa6f70761d46c5e9eb0",
                    "EndpointID": "",
                    "Gateway": "",
                    "IPAddress": "",
                    "IPPrefixLen": 0,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "",
                    "DriverOpts": null
                }
            }
        }
    }
]

进入当前正在运行的容器

# 我们通常容器都是使用后台的方式运行的,需要进入容器,修改一些配置

# 命令 docker exec -it 容器id 

#方式二:docker attach 容器id

# docker exec     # 进入容器后开启一个新的终端,可以在里面操作(常用)
# docker attach   # 进入容器正在执行的终端,不会启动新的进程

从容器内拷贝到主机上

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

[root@localhost ~]$ sudo docker run -it centos /bin/bash
[sudo] root 的密码:
[root@7222c4dfd973 /]# [root@localhost ~]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
7222c4dfd973        centos              "/bin/bash"         46 seconds ago      Up 45 seconds                           vigilant_blackburn
# 查看当前主机目录下的文件
[root@localhost ~]$ cd /home
[root@localhost home]$ ls
root
[root@localhost home]$ sudo touch antia.java
[root@localhost home]$ ls
antia.java  root
[root@localhost home]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
7222c4dfd973        centos              "/bin/bash"         2 minutes ago       Up 2 minutes                            vigilant_blackburn
# 进入容器内部
[root@localhost home]$ sudo docker attach 7222c4dfd973
[root@7222c4dfd973 /]# cd /home
# 在容器内新建一个文件
[root@7222c4dfd973 home]# touch test.java
[root@7222c4dfd973 home]# ls
test.java
[root@7222c4dfd973 home]# exit
exit
[root@localhost home]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
# 将文件拷贝到主机中
[root@localhost home]$ sudo docker cp 7222c4dfd973:/home/test.java /home
[root@localhost home]$ ls
antia.java  test.java  root


# 拷贝是一个手动过程,未来我们使用-v卷的技术,可以实现,自动同步 容器/home 到  主机/home

 

docker命令是十分多的。

作业练习

  1. nginx安装

    # 1. 搜索镜像  search 
    # 2. 下载镜像  pull
    # 3. 运行测试
    # -d 后台运行
    # --name 给容器命名
    # -p 宿主机端口:容器内部端口
    [root@localhost home]$ sudo docker run -d --name nginx01 -p 3344:80 nginx
    6259fe2d44a41272eebd4719ac6fd18c088baf811a692db5f665faff5106cb5b
    [root@localhost home]$ sudo docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
    6259fe2d44a4        nginx               "/docker-entrypoint.…"   17 seconds ago      Up 16 seconds       0.0.0.0:3344->80/tcp   nginx01
    [root@localhost home]$ curl localhost:3344
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
             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>

思考问题:

我们每次改动nginx配置文件,都需要进入容器内部?

十分麻烦,我要是在容器外部提供一个映射路径,达到在容器修改文件名,容器内部就可以自动修改?-v 数据卷

  1. docker来装一个tomcat

    # 官方的使用
    docker run -it --rm tomcat:9.0
    
    # 我们之前的启动都是后台,停止容器之后,容器还是可以查到   一般用来测试,用完即删
    
    # 一般下载再启动
    docker pull tomcat
    
    # 启动运行
    docker run -d -p 3355:8080 --name tomcat01 tomcat
    
    # 测试访问没有问题
    192.168.72.129:3355
    
    # 进入容器
    docker exec -it tomcat01 /bin/bash
    
    # 发现问题
    1. linux命令少了  2. 没有webapps    如果是的话,可能是阿里云的原因,默认是最小镜像,所有不必要的都剔除。
                                      仅保证最小启动。

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

    1. 部署es+kabana

      # es 暴露端口很多
      # es 耗内存
      # 版本配置 7.6.2
      # --net somenetwork 网络配置
      docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:tag  
      
      # 启动 elasticsearch
      docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
      
      # 测试es是否成功了
      curl localhost:9200
      
      # 启动 linux就很卡          docker stats 查看   cpu的状态
      
      # es 是十分耗内存的,占用1.XG,   服务器不行
      
      # 查看CPU状态
      docker stats
      
      # 赶紧关闭,增加内存限制,修改配置文件 -e 环境配置修改
      docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" 
      -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
      

      使用kabana连接elasticsearch

可视化

  • portainer(先用这个)

    docker run -d -p 8088:9000 
    --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
  • Rancher(CI/CD再用)

 

什么是portainer?

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

Docker镜像讲解

镜像是什么?

镜像是一种轻量级,可执行的的独立软件包,用来打包软件运行环境和基于环境运行的软件,它包含了某个软件所需的所有内容,包括代码,运行时,库,环境变量和配置文件。

所有的应用,直接打成docker镜像,就可以直接跑起来!

如何得到镜像:

  • 从远程仓库下载

  • 别人拷贝给你

  • 自己制作一个镜像DockerFile

Docker镜像加载原理

UnionFS(联合文件系统)

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

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

 

Docker分层理解

我们看到CentOS的镜像大小不到200MB,平时我们安装一个CentOS至少是几个GB,怎么可能才 200MB !

下面我们来解释这个问题,Linux 操作系统由内核空间和用户空间组成。

典型的Linux启动到运行需要两个FS,bootfs + rootfs,如下图:

rootf

内核空间是 kernel,Linux 刚启动时会加载 bootfs 文件系统,之后 bootfs 会被卸载掉。用户空间的文件系统是 rootfs,包含我们熟悉的 /dev, /proc, /bin 等目录。

对于 base 镜像来说,底层直接用 Host 的 kernel,自己只需要提供 rootfs 就行了。

而对于一个精简的 OS,rootfs 可以很小,只需要包括最基本的命令、工具和程序库就可以了。相比其他 Linux 发行版,CentOS 的 rootfs 已经算臃肿的了,alpine 还不到 10MB。

我们平时安装的 CentOS 除了 rootfs 还会选装很多软件、服务、图形桌面等,需要好几个 GB 就不足为奇了。

可以看到,新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。

问什么 Docker 镜像要采用这种分层结构呢?

最大的一个好处就是 - 共享资源。

比如:有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享,我们将在后面更深入地讨论这个特性。

这时可能就有人会问了:如果多个容器共享一份基础镜像,当某个容器修改了基础镜像的内容,比如 /etc 下的文件,这时其他容器的 /etc 是否也会被修改?

答案是不会! 修改会被限制在单个容器内。 这就是我们接下来要说的容器 Copy-on-Write 特性。

  1. 新数据会直接存放在最上面的容器层。

  2. 修改现有数据会先从镜像层将数据复制到容器层,修改后的数据直接保存在容器层中,镜像层保持不变。

  3. 如果多个层中有命名相同的文件,用户只能看到最上面那层中的文件。

 

Docker镜像

Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!

这一层就是我们通常说的容器层,容器之下的都叫镜像层

 

如何提交一个自己的镜像

commit镜像

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

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

实战测试


 

 

 

 

Dockerfile、Image、Container

img

Dockerfile Image Container 的关系.png

  • Dockerfile: 用于描述镜像的生成规则。 Dockerfile中的每一条命令,都在Docker镜像中以一个独立镜像层的形式存在。

  • Image: 由Dockerfile生成, 呈现层级结构, 每层镜像包含:镜像文件以及镜像json元数据信息。

  • Container: Container 是Image 的动态运行结果,概括而言,就是在Docker镜像之上,运行进程。

  •  

 

原文地址:https://www.cnblogs.com/Athena-life/p/13634694.html