Docker 完整版教程
阅读原文时间:2023年07月10日阅读:4

Docker 安装

在安装 Docker 之前,先说一下配置,我这里是Centos7 Linux 内核:官方建议 3.10 以上,3.8以上貌似也可。

注意:本文的命令使用的是 root 用户登录执行,不是 root 的话所有命令前面要加 sudo

1.查看当前的内核版本

uname -r

复制

我这里是3.10 ,满足条件。

2.使用 root 权限更新 yum 包(生产环境中此步操作需慎重,看自己情况,学习的话随便搞)

yum -y update

复制

这个命令不是必须执行的,看个人情况,后面出现不兼容的情况的话就必须update了

注意
yum -y update:升级所有包同时也升级软件和系统内核;
yum -y upgrade:只升级所有包,不升级软件和系统内核

复制

3.卸载旧版本(如果之前安装过的话)

yum remove docker  docker-common docker-selinux docker-engine

复制

1.安装需要的软件包, yum-util 提供yum-config-manager功能,另两个是devicemapper驱动依赖

yum install -y yum-utils device-mapper-persistent-data lvm2

复制

2.设置 yum 源

设置一个yum源,下面两个都可用

yum-config-manager --add-repo http://download.docker.com/linux/centos/docker-ce.repo(中央仓库)

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo(阿里仓库)

复制

3.选择docker版本并安装 (1)查看可用版本有哪些

yum list docker-ce --showduplicates | sort -r

复制,查看里面的版本号

(2)选择一个版本并安装:yum install docker-ce-版本号

yum -y install docker-ce-20.10.4

复制

出现下图说明安装成功

4.启动 Docker 并设置开机自启

systemctl start docker
systemctl enable docker

复制

Docker 基础

底层

Docker Engine是一个客户端-服务器应用程序,具有以下主要组件:

  • 一个服务器,它是一种长期运行的程序,称为守护进程(dockerd命令)

  • 一个REST API,它指定程序可以用来与守护进程对话并指示它做什么的接口。

    Docker是一个Client Server结构的系统,Docker守护进程运行在主机上,然后通过Socket连接从客户 端访问,守护进程从客户端接受命令并管理运行在主机上的容器。容器,是一个运行时环境就是我们所说的集装箱。

Docker 为什么比 VM 快

  • docker有着比虚拟机更少的抽象层。由于docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。
  • docker利用的是宿主机的内核,而不需要Guest OS。因此,当新建一个 容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。仍而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载GuestOS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了返个过程,因此新建一个docker容器只需要几秒钟。

帮助文档:参考文档|Docker 文档

VM 安装 Docker 执行命令会有点小问题

问题如下:

Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/version": dial unix /var/run/docker.sock: connect: permission denied

解决方式

切换 root 权限即可
su root           su的解释(switch user)

帮助命令

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

镜像命令

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

[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        7 months ago        13.3kB

# 解释
REPOSITORY      # 镜像的仓库
TAG             # 镜像的标签
IMAGE ID        # 镜像的ID
CREATED         # 镜像的创建时间
SIZE            # 镜像的大小

# 可选项
--all , -a      # 列出所有镜像
--quiet , -q    # 只显示镜像的id

docker search 查找镜像

  • --filter=STARS=3000 搜素出来的镜像就是STARS大于3000的

    NAME DESCRIPTION STARS OFFICIAL AUTOMATED
    mysql MySQL is a widely used, open-source relation… 9822 [OK]
    mariadb MariaDB is a community-developed fork of MyS… 3586 [OK]
    mysql/mysql-server Optimized MySQL Server Docker images. Create… 719 [OK]

    可选项

    --filter=STARS=3000 # 搜素出来的镜像就是STARS大于3000的

    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker search mysql --filter=STARS=3000
    NAME DESCRIPTION STARS OFFICIAL AUTOMATED
    mysql MySQL is a widely used, open-source relation… 9822 [OK]
    mariadb MariaDB is a community-developed fork of MyS… 3586 [OK]

  • 过滤 STARS 的数量

docker pull 下拉镜像

  • 如果不写tag,默认就是latest

  • 版本去 Docker 官网搜索查看

  • 查询地址:tomcat Tags | Docker Hub

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

    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker pull mysql
    Using default tag: latest # 如果不写tag,默认就是latest
    latest: Pulling from library/mysql
    bf5952930446: Pull complete # 分层下载,dockerimages的核心,联合文件系统
    8254623a9871: Pull complete
    938e3e06dac4: Pull complete
    ea28ebf28884: Pull complete
    f3cef38785c2: Pull complete
    894f9792565a: Pull complete
    1d8a57523420: Pull complete
    6c676912929f: Pull complete
    ff39fdb566b4: Pull complete
    fff872988aba: Pull complete
    4d34e365ae68: Pull complete
    7886ee20621e: Pull complete
    Digest: sha256:c358e72e100ab493a0304bda35e6f239db2ec8c9bb836d8a427ac34307d074ed # 签名
    Status: Downloaded newer image for mysql:latest
    docker.io/library/mysql:latest # 真实地址

    等价于

    docker pull mysql
    docker pull docker.io/library/mysql:latest

    指定版本下载

    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker pull mysql:5.7
    5.7: Pulling from library/mysql
    bf5952930446: Already exists
    8254623a9871: Already exists
    938e3e06dac4: Already exists
    ea28ebf28884: Already exists
    f3cef38785c2: Already exists
    894f9792565a: Already exists
    1d8a57523420: Already exists
    5f09bf1d31c1: Pull complete
    1b6ff254abe7: Pull complete
    74310a0bf42d: Pull complete
    d398726627fd: Pull complete
    Digest: sha256:da58f943b94721d46e87d5de208dc07302a8b13e638cd1d24285d222376d6d84
    Status: Downloaded newer image for mysql:5.7
    docker.io/library/mysql:5.7

    查看本地镜像

    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    mysql 5.7 718a6da099d8 6 days ago 448MB
    mysql latest 0d64f46acfd1 6 days ago 544MB
    hello-world latest bf756fb1ae65 7 months ago 13.3kB

docker rmi 删除镜像

  • i 是镜像

  • docker images 查询 ID ,然后删除

  • docker rmi -f $(docker images -aq) 删除所有

    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker rmi -f IMAGE ID # 删除指定镜像
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker rmi -f IMAGE ID1 IMAGE ID2 IMAGE ID3 # 删除多个镜像,中间空格隔开
    [root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker rmi -f $(docker images -aq) # 删除所有镜像

容器命令

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

docker pull centos

新建容器启动

$ docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]


docker run [可选参数] image[:tag]

# 参数说明
--name=“Name”   容器名字    tomcat01    tomcat02    用来区分容器
-d      后台方式运行
-it     使用交互方式运行,进入容器查看内容
-p      指定容器的端口     -p 8080:8080
    -p  ip:主机端口:容器端口
    -p  主机端口:容器端口(常用)
    -p  容器端口
    容器端口
-p      随机指定端口

# 测试,启动并进入容器
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker run -it centos /bin/bash
[root@74e82b7980e7 /]# ls   # 查看容器内的centos,基础版本,很多命令是不完善的
bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr

# 从容器中退回主机,这个是退出关闭容器
[root@77969f5dcbf9 /]# exit
exit
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# ls
bin   dev  fanfan  lib    lost+found  mnt  proc  run   srv  tmp  var
boot  etc  home    lib64  media       opt  root  sbin  sys  usr

退出容器

exit            # 直接退出容器并关闭
Ctrl + P + Q    # 容器不关闭退出

退出之后又想重新进入

docker exec -it 容器id bash       (新的终端)
docker attach 容器id(通过ps获取)   (原来的)
attach 和 exec的区别
  • 用docker exec -it命令进入容器如果输入exit命令直接退出container,但是不会使得container停止,平时我用这个命令比较多。
  • docker attach可以attach到一个已经运行的容器的stdin,然后进行命令执行的动作。但是需要注意的是,如果从这个stdin中exit,会导致容器的停止。

列出所有的运行的容器

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

[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
77969f5dcbf9        centos              "/bin/bash"         5 minutes ago       Exited (0) 5 minutes ago                       xenodochial_bose
74e82b7980e7        centos              "/bin/bash"         16 minutes ago      Exited (0) 6 minutes ago                       silly_cori
a57250395804        bf756fb1ae65        "/hello"            7 hours ago         Exited (0) 7 hours ago                         elated_nash
392d674f4f18        bf756fb1ae65        "/hello"            8 hours ago         Exited (0) 8 hours ago                         distracted_mcnulty
571d1bc0e8e8        bf756fb1ae65        "/hello"            23 hours ago        Exited (0) 23 hours ago                        magical_burnell

[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker ps -qa
77969f5dcbf9
74e82b7980e7
a57250395804
392d674f4f18
571d1bc0e8e8

删除容器

docker rm -f 容器id                       # 删除指定容器
docker rm -f $(docker ps -aq)       # 删除所有容器
docker ps -a -q|xargs docker rm -f  # 删除所有的容器

启动和停止容器的操作

docker start 容器id           # 启动容器
docker restart 容器id         # 重启容器
docker stop 容器id            # 停止当前正在运行的容器
docker kill 容器id            # 强制停止当前的容器
  • 删除容器和镜像没有太大的关系

常用的其他命令

后台启动

  • docker 容器使用后台运行, 就必须要有一个前台进程,docker发现没有应用,就会自动停止

  • docker run -dit centos (后台启动,不会关闭)

    命令 docker run -d 镜像名[:tag]

    [root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker run -d centos

    问题 docker ps, 发现centos停止了

    常见的坑, docker 容器使用后台运行, 就必须要有一个前台进程,docker发现没有应用,就会自动停止

    nginx, 容器启动后,发现自己没有提供服务,就会立即停止,就是没有程序了

查看日志

docker logs -tf --tail number 容器id
# 显示日志
-tf                 # 显示日志
--tail number       # 显示日志条数

docker logs -tf --tail number 容器id

[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker logs -tf --tail 1 8d1621e09bff
2020-08-11T10:53:15.987702897Z [root@8d1621e09bff /]# exit      # 日志输出

# 自己编写一段shell脚本
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker run -d centos /bin/sh -c "while true;do echo xiaofan;sleep 1;done"
a0d580a21251da97bc050763cf2d5692a455c228fa2a711c3609872008e654c2

[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
a0d580a21251        centos              "/bin/sh -c 'while t…"   3 seconds ago       Up 1 second                             lucid_black

# 显示日志
-tf                 # 显示日志
--tail number       # 显示日志条数
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker logs -tf --tail 10 a0d580a21251

查看容器中进程信息ps

# 命令 docker top 容器id
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker top df358bc06b17
UID                 PID                 PPID                C                   STIME               TTY
root                28498               28482               0                   19:38               ?

查看镜像的元数据

# 命令
docker inspect 容器id

[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker inspect df358bc06b17
[
    {
        "Id": "df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3",
        "Created": "2020-08-11T11:38:34.935048603Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 28498,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2020-08-11T11:38:35.216616071Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:0d120b6ccaa8c5e149176798b3501d4dd1885f961922497cd0abef155c869566",
        "ResolvConfPath": "/var/lib/docker/containers/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3/hostname",
        "HostsPath": "/var/lib/docker/containers/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3/hosts",
        "LogPath": "/var/lib/docker/containers/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3-json.log",
        "Name": "/hungry_heisenberg",
        "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/5af8a2aadbdba9e1e066331ff4bce56398617710a22ef906f9ce4d58bde2d360-init/diff:/var/lib/docker/overlay2/62926d498bd9d1a6684bb2f9920fb77a2f88896098e66ef93c4b74fcb19f29b6/diff",
                "MergedDir": "/var/lib/docker/overlay2/5af8a2aadbdba9e1e066331ff4bce56398617710a22ef906f9ce4d58bde2d360/merged",
                "UpperDir": "/var/lib/docker/overlay2/5af8a2aadbdba9e1e066331ff4bce56398617710a22ef906f9ce4d58bde2d360/diff",
                "WorkDir": "/var/lib/docker/overlay2/5af8a2aadbdba9e1e066331ff4bce56398617710a22ef906f9ce4d58bde2d360/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "df358bc06b17",
            "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": "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": "4822f9ac2058e8415ebefbfa73f05424fe20cc8280a5720ad3708fa6e80cdb08",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/4822f9ac2058",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "5fd269c0a28227241e40cd30658e3ffe8ad6cc3e6514917c867d89d36a31d605",
            "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": "30d6017888627cb565618b1639fecf8fc97e1ae4df5a9fd5ddb046d8fb02b565",
                    "EndpointID": "5fd269c0a28227241e40cd30658e3ffe8ad6cc3e6514917c867d89d36a31d605",
                    "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 cp 容器id:容器内路径    目的地主机路径

[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker cp 7af535f807e0:/home/Test.java /home

小结

attach      Attach local standard input, output, and error streams to a running container
#当前shell下 attach连接指定运行的镜像
build       Build an image from a Dockerfile # 通过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
#查看docker容器的变化
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
#导出容器文件系统作为一个tar归档文件[对应import]
history     Show the history of an image # 展示一个镜像形成历史
images      List images #列出系统当前的镜像
import      Import the contents from a tarball to create a filesystem image #从tar包中导入内容创建一个文件系统镜像
info        Display system-wide information # 显示全系统信息
inspect     Return low-level information on Docker objects #查看容器详细信息
kill        Kill one or more running containers # kill指定docker容器
load        Load an image from a tar archive or STDIN #从一个tar包或标准输入中加载一个镜像[对应save]
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

镜像下载

  • 首先es有诸多不足,咱们要想办法解决:

    #测试成功就关掉elasticSearch,可以看出elasticsearch非常占内存,我们可以修改配置文件,进行限制内存使用#修改配置文件 -e 环境配置修改

    在我们之前的启动命令中加入:-e ES_JAVA_OPTS="-Xms64m -Xmx512m",限定内存在64mb-512mb之间

    #1. --net somenetwork,这个是网络配置,之后再讲
    #2. -p 9200:9200 -p 9300:9300,暴露了9200和9300端口
    #3. "discovery.type=single-node",这个是一个集群,表示单个节点
    docker run -d --name elasticsearch2 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.10.1

    #再次查看docker stats,发现变小了,非常爽到

使用kibana连接es (elasticSearch)

现在elasticsearch容器和kibana容器都是相互隔离的,elasticsearch和kibana都有各自的内部地址。我们可以通过Linux的内网的ip作为一个中间商就可以实现elasticsearch到kibana访问,但是会涉及到Docker的网络相关的知识,在之后讲解。(请记住veth-pair)

镜像原理

参考:(95条消息) ️狂神Docker学习笔记_Lemonyuki的博客-CSDN博客

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

# 命令和git原理类似
docker commit -m="描述信息" -a="作者名字" 容器id 目标镜像名:[版本TAG]


#1. 启动一个默认的tomcat
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker run -it -p 8080:8080 tomcat

#2. 发现这个默认的tomcat 是没有webapps应用,官方的镜像默认webapps下面是没有文件的!
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker exec -it 079f8174730f /bin/bash

#3. 将webapps.dist里的所有东西拷贝文件进webapps,并查看
root@079f8174730f:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@079f8174730f:/usr/local/tomcat# cd webapps
root@079f8174730f:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager

#4. 操作过的容器通过commit调教为一个镜像!我们以后就使用我们修改过的镜像即可,而不需要每次都重新拷贝webapps.dist下的文件到webapps了,这就是我们自己的一个修改的镜像。
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker commit -a="peng" -m="add webapps app" 容器id tomcat02:1.0

[root@iZ2vc28obhvfham8wewhh0Z ~]# docker commit -a="haha" -m="add webapps app" 079f8174730f tomcat02:1.0
sha256:b0a602f7e277d044ec71dbc36450609a0652f316e06c51fdcc82338de792793e
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED              SIZE
#看下方这个tomcat02.1.0就是我们创建的镜像,发布之后再说
tomcat02.1.0          1            b0a602f7e277   About a minute ago   672MB
tomcat                9         6654503f1940   7 hours ago          667MB
nginx                 latest    d1a364dc548d   4 weeks ago          133MB
tomcat                latest    c43a65faae57   5 weeks ago          667MB
mysql                 latest    c0cdc95609f1   6 weeks ago          556MB
portainer/portainer   latest    580c0e4e98b0   3 months ago         79.1MB
hello-world           latest    d1165f221234   3 months ago         13.3kB
centos                latest    300e315adb2f   6 months ago         209MB
elasticsearch         7.6.2     f29a1ee41030   15 months ago        791MB

容器数据卷

​ docker的理念是将应用和环境打包成一个镜像!

如果数据都在容器中,那么我们容器删除,数据就会丢失!所以我们就有需求:数据可以持久化

比如:安装了MySQL,容器删除了,相当于删库跑路!所以我们就有需求:MySQL数据可以存储在本地!

所以我们需要容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!

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

总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!

将mysql容器内部的文件系统映射(挂载)到linux上边,实现数据的持久化和同步

# 涉及命令
docker volume --help


#1. 语法:主要是这个-v
docker run -it -v 主机目录:容器内目录  -p 主机端口:容器内端口

#2. run一个centos容器,并使用目录挂载
# /home/ceshi:主机home目录下的ceshi文件夹  映射:centos容器中的/home
# 将容器里边的home目录挂载到linux的home下边的ceshi目录
docker run -it -v /home/ceshi:/home centos /bin/bash

#3.  docker inspect 容器id 查看是否挂载成功
[root@iZ2vc28obhvfham8wewhh0Z /]# docker inspect 54db68df3d7f
#具体看下图的Mounts部分,以后两个地址的内的数据可以相互同步的

数据是双向的,以后修改只需要在本地修改即可,容器内会自动同步!,删除容器数据依旧还在

官网启动:mysql - 官方图片|Docker Hub

# 选择密码连接
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag


#1. 获取mysql镜像
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker pull mysql:5.7

#2. 运行容器的时候需要做数据挂载,此处我们挂载了配置文件以及数据目录(有两个哦),同时咱们也配置了mysql的密码
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
-- name 容器名字
[root@iZ2vc28obhvfham8wewhh0Z ~]# 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 mysql:5.7

#3. 启动成功之后,我们可以在本地去连接上服务器的mysql,如下图所示
#咱们走的是3310端口,3310端口映射了容器的3306端口,所以说我们本质还是访问到的容器
  • 可以使用工具测试连接

  • 创建数据库可以同步过来

挂载方式

# 三种挂载: 匿名挂载、具名挂载、指定路径挂载
-v 容器内路径            #匿名挂载
-v 卷名:容器内路径          #具名挂载,前面没有带/
-v /宿主机路径:容器内路径 #指定路径挂载 docker volume ls 是查看不到的


#1. 匿名挂载
-v 容器内路径!,这里我们没有写主机的路径,那么它就会自动的生成一个目录
#1-1. 使用命令匿名挂载
docker run -d -P --name nginx01 -v /etc/nginx nginx

#1-1. 查看所有volume(卷)的情况
[root@iZ2vc28obhvfham8wewhh0Z data]# docker volume ls
DRIVER    VOLUME NAME(卷名字,这个一串乱码其实是真实存在的目录)
local     dd3decdb4e2533d16d216ba19d8797c2ad95b4a2a1b6a90f87eb98bbed3b3758
# 注:这里发现,这种就是匿名挂载,我们在 -v只写了容器内的路径,没有写容器外的路径!

#2. 具名挂载
#2-1. 使用命令具名挂载
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
# 注1:juming-nginx:/etc/nginx,给/etc/nginx命名为juming-nginx,并没有写主机地址哈
# 注2:说白了就是 -v 卷名:容器内路径

#2-2. 查看一下这个卷
[root@iZ2vc28obhvfham8wewhh0Z data]# docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2021-06-25T20:18:22+08:00",
        "Driver": "local",
        "Labels": null,
        #注意看这儿:下方就是我们挂载到主机的具体路径了
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]
  • 位置和一些信息

  • 只读和读写

    通过 -v 容器内路径: ro rw 改变读写权限

    ro #readonly 只读
    rw #readwrite 可读可写
    $ docker run -d -P --name nginx05 -v juming:/etc/nginx:ro nginx
    $ docker run -d -P --name nginx05 -v juming:/etc/nginx:rw nginx

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

  • 挂载的位置和主机的映射位置

    [root@localhost haha]# docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    835a85158acd nginx:1.20.2 "/docker-entrypoint.…" 21 minutes ago Up 21 minutes 80/tcp nginx-01
    [root@localhost haha]# docker inspect 835a85158acd

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

通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个个的命令,每个命令都是一层!

#1. 在主机/home目录下创建一个dockerfile文件,名字可以随便,这里建议dockerfile
[root@iZ2vc28obhvfham8wewhh0Z home]# mkdir dockerfile
#2. 然后进入dockerfile文件夹
[root@iZ2vc28obhvfham8wewhh0Z home]# cd dockerfile/
#3. 我们在dockerfile文件夹里边写一个脚本文件
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# vim dockerfile1

# dockerfile1内部内容如下,每个命令就是一层:
FROM centos                     # 当前这个镜像是以centos为基础的
#这里与阿狂不同,不加斜杠死活运行不了
VOLUME ["volume01","volume02"]    # 挂载卷的卷目录列表(多个目录),记得空格
CMD echo "-----end-----"        # 输出一下用于测试
CMD /bin/bash                    # 默认走bash控制台

#4. 使用脚本去创建自己的镜像
# 命令解释:
-f dockerfile1             # f代表file,指这个当前文件的地址(这里是当前目录下的dockerfile1)
-t caoshipeng/centos     # t就代表target,指目标目录(注意caoshipeng镜像名前不能加斜杠‘/’)
.                         # 表示生成在当前目录下
#--------------------------------------------------------------
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# docker build -f dockerfile1 -t xixi/centos .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos #我们自己写的
 ---> 300e315adb2f
Step 2/4 : VOLUME ["volume01","volume02"] #我们自己写的
 ---> Running in f2d6c4400114
Removing intermediate container f2d6c4400114
 ---> 060cfd84e017
Step 3/4 : CMD echo "-----end-----" #我们自己写的
 ---> Running in 871b9a8bb9c0
Removing intermediate container 871b9a8bb9c0
 ---> 4c71c64c5cc6
Step 4/4 : CMD /bin/bash #我们自己写的
 ---> Running in 1f30a125b5ff
Removing intermediate container 1f30a125b5ff
 ---> 0db8611ac208
Successfully built 0db8611ac208
Successfully tagged haha/centos:latest

  • 查看映射文件夹位置

    查看一下卷挂载的路径,如下图所示:
    docker inspect 自定义的镜像名字

  • 容器之间的数据映射

  • 父容器:A去挂载B,那么B就是A的父容器

  • 数据卷容器:被挂载的容器

  • 使用 run 命令

#1. 测试 启动3个容器,通过刚才自己写的镜像启动
# 启动第一个centos,注意版本如果不写默认是找最新版
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# docker run -it --name docker0001 6ce95e6fc524
[root@d07b05bae720 /]# ls -l
total 0
lrwxrwxrwx   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root 360 Jun 27 10:58 dev
drwxr-xr-x   1 root root  66 Jun 27 10:58 etc
drwxr-xr-x   2 root root   6 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   6 Dec  4  2020 lost+found
drwxr-xr-x   2 root root   6 Nov  3  2020 media
drwxr-xr-x   2 root root   6 Nov  3  2020 mnt
drwxr-xr-x   2 root root   6 Nov  3  2020 opt
dr-xr-xr-x 156 root root   0 Jun 27 10:58 proc
dr-xr-x---   2 root root 162 Dec  4  2020 root
drwxr-xr-x  11 root root 163 Dec  4  2020 run
lrwxrwxrwx   1 root root   8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x   2 root root   6 Nov  3  2020 srv
dr-xr-xr-x  13 root root   0 Jun 27 10:58 sys
drwxrwxrwt   7 root root 145 Dec  4  2020 tmp
drwxr-xr-x  12 root root 144 Dec  4  2020 usr
drwxr-xr-x  20 root root 262 Dec  4  2020 var
# 容器数据卷在此
drwxr-xr-x   2 root root   6 Jun 27 10:58 volume01
drwxr-xr-x   2 root root   6 Jun 27 10:58 volume02

#2. ctrl+p+q退出容器

#3. 创建第二个容器docker0002,继承docker0001
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# docker run -it --name docker0002 --volumes-from docker0001 xixi/centos
[root@77e4999257f6 /]# ls -l
total 0
lrwxrwxrwx   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root 360 Jun 27 11:02 dev
drwxr-xr-x   1 root root  66 Jun 27 11:02 etc
drwxr-xr-x   2 root root   6 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   6 Dec  4  2020 lost+found
drwxr-xr-x   2 root root   6 Nov  3  2020 media
drwxr-xr-x   2 root root   6 Nov  3  2020 mnt
drwxr-xr-x   2 root root   6 Nov  3  2020 opt
dr-xr-xr-x 158 root root   0 Jun 27 11:02 proc
dr-xr-x---   2 root root 162 Dec  4  2020 root
drwxr-xr-x  11 root root 163 Dec  4  2020 run
lrwxrwxrwx   1 root root   8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x   2 root root   6 Nov  3  2020 srv
dr-xr-xr-x  13 root root   0 Jun 27 11:02 sys
drwxrwxrwt   7 root root 145 Dec  4  2020 tmp
drwxr-xr-x  12 root root 144 Dec  4  2020 usr
drwxr-xr-x  20 root root 262 Dec  4  2020 var
drwxr-xr-x   2 root root   6 Jun 27 10:58 volume01
drwxr-xr-x   2 root root   6 Jun 27 10:58 volume02

#4. 在docker0001中的volume01中创建文件,然后在docker0002中的volume01中查看,如下图

结论:

#1. docker0003创建的文件,docker0001可以查询到,说明容器之间的数据形成了共享(本质是双向拷贝)
#2. 此时删除或者停掉docker0001,我们查看docker0002和docker0003的数据依旧能够查询到,说明数据形成了共享(本质是双向拷贝,容器之间的相互数据拷贝)
#3. 只要有一个容器还在用这组数据就不会丢失,很nice

DockerFile

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

区别

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

脚本

FROM centos
ENTRYPOINT ["ls","-a"]    #这里与之前不一样哦(☆)


docker run cmd-test:0.1

执行时,CMD如果执行docker run cmd-test:0.1 -l 会报错,他是替换了,执行 -l 命令,肯定报错
ENTRYPOINT不会
追加后成为  ls -al


#1./home下新建dockerfile目录,并进入
[root@iZ2vc28obhvfham8wewhh0Z home]# mkdir dockerfile
[root@iZ2vc28obhvfham8wewhh0Z home]# cd dockerfile/

#2. dockerfile目录下新建mydockerfile-centos文件,填写内容如下:
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# vim mydockerfile-centos
  • 记得指定 Centos 版本

  • 注释写上面

    FROM centos:7 # 基础镜像是官方原生的centos
    MAINTAINER peng951770031@qq.com # 作者

    ENV MYPATH /usr/local # 配置环境变量的目录
    WORKDIR $MYPATH # 将工作目录设置为 MYPATH

    RUN yum -y install vim # 给官方原生的centos 增加 vim指令
    RUN yum -y install net-tools # 给官方原生的centos 增加 ifconfig命令

    EXPOSE 80 # 暴露端口号为80

    CMD echo $MYPATH # 输出下 MYPATH 路径
    CMD echo "-----end----"
    CMD /bin/bash # 启动后进入 /bin/bash

  • 查看镜像的构建过程,看它如何一步步的构建的

    docker history 镜像id

Docker 网络

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

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

容器和容器之间的连接

Docker使用的是Linux的桥接,宿主机是一个Docker容器的网桥 docker0,如下图所示:

Docker中所有网络接口都是虚拟的,虚拟的转发效率高(比如:内网传递文件)

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

思考:我们编写了一个微服务,我们以前连接数据库都是database url=ip: 项目不重启,数据ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器

方法1

使用 --link

docker run -d -P --name tomcat03 --link tomcat02 tomcat
  • 上面是 tomcat03 连接到 tomcat02,本质是添加了映射关系,相当于 hosts 映射

  • 3 可以通过名字 ping 通 2 ,但是相反不能,因为 2 没有添加映射关系

探究

docker exec -it tomcat03 cat /etc/hosts

方法2

使用自定义网络

网络模式:

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

  • none :不配置网络,一般不用

  • host :和宿主机共享网络

  • container :容器网络连通(用得少!局限很大)

  • 创建自定义网络

    . 创建一个子网为“192.168.0.0/16”,网关(路由)为“192.168.0.1”,网络名字为“mynet”的网络
    docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

  • 创建2个使用自定义网络的容器

    #4. 创建两个个tomcat使用我们自定义的网络
    docker run -d -P --name tomcat-net-01 --net mynet tomcat
    docker run -d -P --name tomcat-net-02 --net mynet tomcat

    #5. 然后查看我们自定义的网络,如下图所示
    docker network inspect 56505443b59d
    #发现容器使用的是我们配置的网络

我们自定义的网络docker当我们维护好了对应的关系,推荐我们平时这样使用网络!

好处:

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

Docker 实战

  • 查看已启动的服务

    systemctl list-units --type=service

  • 查看是否设置开机启动

    systemctl list-unit-files | grep enable

  • 设置开机启动

    systemctl enable docker.service

  • 启动时加 --restart=always

    docker run -tid --name isaler_v0.0.11 -p 8081:8080 --restart=always -v /alidata/iDocker/run/projectImages/isaler/v0.0.11/log:/usr/local/tomcat/logs isaler_v0.0.11

    Flag Description
    no 不自动重启容器. (默认value)
    on-failure 容器发生error而退出(容器退出状态不为0)重启容器
    unless-stopped 在容器已经stop掉或Docker stoped/restarted的时候才重启容器
    always 在容器已经stop掉或Docker stoped/restarted的时候才重启容器

  • 已经启动的项目

    如果已经启动的项目,则使用update更新:
    docker update --restart=always isaler_v0.0.11

1.1.安装Docker

yum install -y yum-utils device-mapper-persistent-data lvm2    //安装必要工具
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo //设置yum源
yum install -y docker-ce  //下载docker
systemctl start docker   //启动docker

1.2.安装MySQL

docker pull mysql //下载MySQL镜像
docker run --name mysql --restart=always -p 3306:3306 -e MYSQL_ROOT_PASSWORD=密码 -d mysql //启动MySQL
docker run --name mysql --restart=always -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456789 -d mysql:8.0

1.3.安装Redis

docker pull redis //下载Redis镜像
docker run --name redis  --restart=always -p 6379:6379 -d redis --requirepass "密码" //启动Redis
docker run --name redis  --restart=always -p 6379:6379 -d redis --requirepass "123456789"

1.4.安装nginx(请先部署项目再启动)

docker pull nginx //下载nginx镜像
docker run --name nginx --restart=always -p 80:80 -p 443:443 -d -v /usr/local/nginx/nginx.conf:/etc/nginx/nginx.conf -v /usr/local/vue:/usr/local/vue -v /usr/local/upload:/usr/local/upload nginx  //启动nginx,映射本地配置文件

1.5.安装RabbitMQ

docker pull rabbitmq:management //下载RabbitMQ镜像
docker run --name rabbitmq --restart=always -p 15672:15672 -p 5672:5672 -d  rabbitmq:management   //启动RabbitMQ,默认guest用户,密码也是guest。

安装插件

docker exec -it rabbitmq rabbitmq-plugins enable rabbitmq_management

1.6.安装elasticsearch

# 下载elasticsearch镜像
docker pull elasticsearch:7.9.2 

# //启动elasticsearch
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.9.2 

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

# 安装ik分词器
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.9.2/elasticsearch-an


docker pull zendesk/maxwell //下载MaxWell镜像

docker run --name maxwell --restart=always  -d  zendesk/maxwell bin/maxwell  --user='数据库用户名' --password='数据库密码'  --host='IP地址'  --producer=rabbitmq --rabbitmq_user='MQ用户名' --rabbitmq_pass='MQ密码' --rabbitmq_host='IP地址' --rabbitmq_port='5672' --rabbitmq_exchange='maxwell_exchange'  --rabbitmq_exchange_type='fanout' --rabbitmq_exchange_durable='true' --filter='exclude: *.*, include: blog.tb_article.article_title = *, include: blog.tb_article.article_content = *, include: blog.tb_article.is_delete = *, include: blog.tb_article.status = *' //运行MaxWell

docker run --name maxwell --rm   -it  zendesk/maxwell bin/maxwell  --user='root' --password='123456789'  --host='192.168.80.80'  --producer=rabbitmq --rabbitmq_user='guest' --rabbitmq_pass='guest' --rabbitmq_host='192.168.80.80' --rabbitmq_port='5672' --rabbitmq_exchange='maxwell_exchange'  --rabbitmq_exchange_type='fanout' --rabbitmq_exchange_durable='true' --filter='exclude: *.*, include: blog-github.tb_article.article_title = *, include: blog-github.tb_article.article_content = *, include: blog-github.tb_article.is_delete = *, include: blog-github.tb_article.status = *'  --producer=stdout
//运行MaxWell


docker run --name maxwell --rm   -it  zendesk/maxwell bin/maxwell  --user='root' --password='123456789'  --host='192.168.80.80'   --filter='exclude: *.*, include: blog-github.tb_article.article_title = *, include: blog-github.tb_article.article_content = *, include: blog-github.tb_article.is_delete = *, include: blog-github.tb_article.status = *'  --producer=stdout

Docker Compose

  • Compose是Docker官方的开源项目。需要安装!

作用:

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

    微服务。100个微服务!依赖关系。

    Docker Compose 来轻松高效的管理容器。

概念:

Compose是一个用于定义和运行多容器Docker应用程序的工具。

使用Compose,您可以使用yaml文件配置应用程序的服务。然后,使用一个命令,从配置中创建并启动所有服务

使用Compose基本上是一个三步过程:

  1. 使用 定义应用的环境,以便可以在任何位置重现它。Dockerfile
  2. 定义构成应用的服务,以便它们可以在隔离的环境中一起运行。docker-compose.yml
  3. 运行,Docker 撰写命令将启动并运行整个应用。您也可以使用 docker-compose 二进制文件运行

docker-compose.yml (yaml配置文件)示列:

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

从上面的配置文件可以看出:

  • 服务services: 容器。应用。(web、redis、mysql…)
  • 项目project: 一组关联的容器。博客、web网站

安装:

卸载:

rm /usr/local/bin/docker-compose

看官网开始:开始使用 Docker Compose |Docker 文档

  • 官网是一个计数器

细节

  • 官网的实例 Redis 和 Web 在同一个网络下

  • 注意下面的 Host ,这样重启服务,ip 会改变,但是他们在同一个网络,可以使用名字 Ping 通

Buster、Alpine、Stretch

redis:alpine    体积小

Docker的几种精简版本Buster、Alpine、Stretch比较, - 知乎 (zhihu.com)

Docker小结

  1. Docker镜像,run =>容器
  2. DockerFile 构建镜像(服务打包)
  3. Docker-composer
  4. Docker网络

官网:Compose file version 3 reference | Docker Documentation

  • 依赖关系,web 依赖 Redis 和 db ,所以有一个先后关系

version: "3"

services:
        web:
                build:                                          # 构建镜像
                        context: ./                             # 上下文环境
                        dockerfile: ./compose/node/Dockerfile   # Dockerfile路径
                ports:
                        - "3000:3000"
                volumes:
                        - static:/code/static       # 使用前面声明的static挂在容器/code/static
                restart: always                     # 总是重启
        nginx:
                build:
                        context: ./
                        dockerfile: ./compose/nginx/Dockerfile
                ports:
                        - "80:80"
                volumes:
                        - static:/code/static
                restart: always
        mysql:
                image: mysql:5.7        # 直接使用镜像构建
                env_file: .env          # 环境变量env,我们写入到了配置文件里,避免密码泄漏
                volumes:
                        - db:/var/lib/mysql
                ports:
                        - "3306:3306"
                restart: always 

volumes:
        static:         # 数据卷名称
        db:             # 数据卷名称
  1. 编写一个 springboot 程序

  2. 创建 Dockerfile 构建镜像

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

  3. 创建 docker-compose.yml 编排项目

    version '3.8'
    services:
      xiaofanapp:
        build: .
        image: xiaofanapp
        depends_on:
          - redis
        ports:
          - "8080:8080"
      redis:
        image: "library/redis:alpine"
    # alpine 是轻小版

    docker-compose up # 启动容器
    docker-compose down # 关闭容器
    docker-compose up --build # 重新构建(出现问题可以重构一下)

IDEA 使用插件连接远程 Docker

https://github.com/Rain-with-me/JavaStudyCode/tree/main/2-springboot-docker

  • 下载插件

  • 版本

    <properties>
            <java.version>1.8</java.version>
            <docker.host>http://192.168.80.80:2375</docker.host>
            <docker.maven.plugin.version>0.40.0</docker.maven.plugin.version>
     </properties>
  • 插件

    io.fabric8 docker-maven-plugin ${docker.maven.plugin.version} ${docker.host} mall-tiny/${project.name}:${project.version} java:8 ${project.build.finalName}.jar / artifact ["java", "-jar","/${project.build.finalName}.jar"] macrozheng

  • IDEA 使用插件

登录远程主机,更改 Docker 配置

## 修改docker服务文件
vi  /lib/systemd/system/docker.service

## 将原来的ExecStart前面加上#号注释掉,然后再下面追加一行
ExecStart=/usr/bin/dockerd    -H tcp://0.0.0.0:2375    -H unix:///var/run/docker.sock

## 重新加载配置
systemctl daemon-reload

## 重启docker服务
systemctl restart docker.service

  • 打开IDEA底部的Services面板,双击 Docker 图标进行连接,可以对远程服务器上的Docker容器和镜像进行管理

  • 随便搞个小 Demo 测试即可

注意:java:8 已经被弃用

  • 创建 Dockerfile

    该镜像需要依赖的基础镜像

    FROM openjdk:8

    将当前目录下的jar包复制到docker容器的/目录下

    COPY ./demo-0.0.1-SNAPSHOT.jar /test/demo-0.0.1-SNAPSHOT.jar

    声明服务运行在8080端口

    EXPOSE 8080

    指定docker容器启动时运行jar包

    ENTRYPOINT ["java", "-jar","/test/demo-0.0.1-SNAPSHOT.jar"]

    指定维护者的名字

    MAINTAINER haha

  • 打开配置,记得配置下面设置,不然无法访问

  • 配置成功的样子

  • 运行之后更改下面的配置,然后执行配置即可

可以参考:

也可以去参考 mall 的配置

对照下之前使用的docker run命令,大概就能知道这些配置的作用了;

docker run -p 8080:8080 --name mall-tiny \
--link mysql:db \
--link redis:redis \
-e 'spring.profiles.active'=prod \
-v /etc/localtime:/etc/localtime \
-v /mydata/app/mall-tiny/logs:/var/logs \
-d mall-tiny/mall-tiny:1.0.0-SNAPSHOT
  • 查看日志,成功就可以直接访问

docker logs 容器
  • 这玩意有点玄学,有时就报错,重启即可

  • IDEA 找到 docker-compose.exe 文件