Docker基础

Docker使用

Docker简介

Docker是一个用来装应用的容器,就像杯子可以装水,笔筒可以放笔,书包可以放书,可以把hello word放在Docker中,可以把网站放入Docker中,可以把任何想得到的程序放在Docker中.

Docker解决的问题?

  • 系统环境不一致

    开发:我本地没问题.运维:服务器没问题. 这个问题就变成了皮球。下面docker来了,它把操作系统,jdk,tomcat,代码,配置全部放到集装箱里.再打包放到鲸鱼上,由鲸鱼给我们送到服务器上,在我的机器上怎么运行,在别的机器上也怎么运行.不会有任何的问题.一句话就是docker解决了运行环境不一致所带来的问题.

  • 隔离问题

    因为Linux本身就是一个多用户的操作系统本身就可以供多个用户同时使用。然而docker的隔离性可以解决这个问题,就算别人的程序还是死循环疯狂吃CPU,还是疯狂打日志把硬盘占满,还是内存泄漏,把内存占满,都不会导致我们的程序运行错误.因为docker在启动的时候就限定好了,它最大使用的CPU硬盘,如果超过了,就会杀掉对应进程.

  • 方便扩容

    大部分系统业务量并不是每天都比较平均的,特别是一些电商系统,每天总有那么几天业务量是平时的几倍甚至几十倍,如果按双11的规模去准备服务器那么对于平时的规模来说又是极大的浪费,所以就在节日前临时扩展机器,过完节再把多余的节点下线,这就给运维带来了非常大的工作量,一到过节就在各个机器上部署各种各样的服务,我们启动程序需要java,tocmat等等,并且还可能起不来还要调试,这是非常恶心的工作,有了docker一切都变得美好了,只要点一下服务器就可以从10台变成100台甚至1000,1W台.都是分分钟的事情

Docker的基本组成

点击查看源网页

  • 仓库(Repository)

    仓库是存放镜像的地方,总共分为共有仓库(所有人可以访问)和私有仓库(只有自己可以访问)

  • 镜像(image)

    Docker镜像是提前制作好的模板,类似的有tomcat镜像从仓库里面拉去下来可以直接运行

  • Container(容器)

    执行运行镜像的命令时候就是运行在容器里面,容器容器相互隔离,降低了软件与软件的耦合性

    使用流程是仓库->镜像->容器 就是从仓库拉取进行本地运行在容器当中

安装Docker

安装命令

环境查看 cat /etc/os-release 我的是CentOS7

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XrxW6zCe-1631176874108)(https://i.loli.net/2021/04/19/M13KLCWAQqpcV6o.png)]

        #1.卸载旧的Docker版本
        yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
        #2.需要的安装包
        yum install -y yum-utils
        #3.设置镜像的仓库
        yum-config-manager \
          --add-repo \
          http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
        #4.更新软件包索引
        yum makecache fast
        #5.安装Docker docker-ce(社区版) 
        yum install docker-ce docker-ce-cli containerd.io
        #6.查看Docker是否安装成功 显示版本说明安装成功
        docker version
        #7.启动Docker
        systemctl start docker
        #8.卸载Docker(了解)
        #8.1卸载依赖
        yum remove docker-ce docker-ce-cli containerd.io
        #8.2删除资源
        rm -rf /var/lib/docker
        rm -rf /var/lib/containerd

运行一个Docker程序

#1.运行这个镜像如果本地没有则从远程镜像仓库下载
docker run hello-world
#2.查看本地镜像
docker image

配置阿里云镜像加速

登录自己的阿里云账号然后访问下面的网站然后复制加速地址,四个命令挨个执行(也要复制sudo)

https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["填写你自己的地址"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

docker run hello-world流程

未命名文件.png

Docker常用命令

帮助命令

# docker版本
docker version
# docker详情
docker info
# docker帮助命令
docker --help
# 查看容器的内存cpu占用情况
docker states 

镜像命令

docker images 查看所有的本地镜像

镜像仓库源      标签       镜像id         镜像创建时间     镜像大小
REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
hello-world   latest    d1165f221234   7 weeks ago   13.3kB

docker search mysq 搜索镜像l

镜像名称                            描述                                            点赞    
NAME                              DESCRIPTION                                     STARS     
mysql                             MySQL is a widely used, open-source relation…   10777            
mariadb                           MariaDB Server is a high performing open sou…   4058    

docker pull mysql 下载镜像

# 下载镜像 docker pull 镜像名[:tag]
[root@pinyoyougou-docker /]# docker pull mysql[:tag]
Using default tag: latest # 如果不些tag,默认就是最新版
latest: Pulling from library/mysql
f7ec5a41d630: Pull complete  # 分享下载,docker image的核心 联合文件系统
9444bb562699: Pull complete 
6a4207b96940: Pull complete 
181cefd361ce: Pull complete 
8a2090759d8a: Pull complete 
15f235e0d7ee: Pull complete 
d870539cd9db: Pull complete 
493aaa84617a: Pull complete 
bfc0e534fc78: Pull complete 
fae20d253f9d: Pull complete 
9350664305b3: Pull complete 
e47da95a5aab: Pull complete 
Digest: sha256:04ee7141256e83797ea4a84a4d31b1f1bc10111c8d1bc1879d52729ccd19e20a
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真正的下载地址
# 指定版本下载
[root@pinyoyougou-docker /]# docker pull mysql:5.7
5.7: Pulling from library/mysql
f7ec5a41d630: Already exists #因为之前下载过mysql 所以已经存在的文件就不需要下载
9444bb562699: Already exists 
6a4207b96940: Already exists 
181cefd361ce: Already exists 
8a2090759d8a: Already exists 
15f235e0d7ee: Already exists 
d870539cd9db: Already exists 
cb7af63cbefa: Pull complete 
151f1721bdbf: Pull complete 
fcd19c3dd488: Pull complete 
415af2aa5ddc: Pull complete 
Digest: sha256:a655529fdfcbaf0ef28984d68a3e21778e061c886ff458b677391924f62fb457
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

删除镜像

[root@pinyoyougou-docker /]# docker rmi -f 0627ec6901db

容器命令

新建容器并启动


docker run [可选参数]   image
# 参数署命
--name="Myname"  #给容器起一个自己的名字
-d               #后台方式运行
-it              #进入容器内部
-p               #指定容器的端口 8080:8080

#测试 启动容器并进入容器
[root@pinyoyougou-docker /]# docker run -it centos  /bin/bash
#进入容器内部发现root@后面内容改变
[root@2f5ce69a584c /]# 
#从容器推出
[root@2f5ce69a584c /]# exit;

列出所有运行容器

# docker ps 命令
-a #列出当前正在运行的容器+带出历史运行过的容器
-n=5 #列出最近创建的5个容器

# 查看正在运行的容器
[root@pinyoyougou-docker /]# docker ps    
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
# 查看正在运行的容器和历史运行过的容器
[root@pinyoyougou-docker /]# docker ps -a
CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS                       PORTS     NAMES
2f5ce69a584c   centos        "/bin/bash"              7 minutes ago   Exited (127) 9 seconds ago             nervous_chaum

退出容器

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

删除容器

docker rm 容器id  # 删除指定的容器,不能删除正在运行的容器 如果要删除需要先停止容器  docker stop 容器id

启动和停止容器

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

常用其他命令

后台启动容器

# 通过-d 后台方式运行容器
[root@pinyoyougou-docker /]# docker run -d centos
f9d39ffbbbb2d2547ffd5707ed49cef41bc307dfeab3cf1b1817d70d4f9c8379
# 发现容器并没有运行 
[root@pinyoyougou-docker /]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
# 常见的坑: docker 容器使用后台运行,就必须要有一个前台进程,docker 发现没有应用就自动停止了容器
# 例如nginx容器启动后,发现自己没有提供服务就会立即停止

查看容器日志

# 创建一个容器并植入一个shell脚本
[root@pinyoyougou-docker /]# docker run -it  centos /bin/sh -c "while true;do echo xiye;sleep 1;done"
# 然后用日志查询命令查看容器日志
[root@pinyoyougou-docker /]# docker logs -tf --tail 10 8c

查看容器内部的进程id

# docker top 容器id
[root@pinyoyougou-docker /]# docker top 8c
UID                 PID                 PPID                C                   STIME               TTY                 TIME     
root                6434                6414                0                   15:18               pts/0               00:00:00 
root                6659                6434                0                   15:21               pts/0               00:00:00 

查看镜像源数据

# docker inspect 8c
[root@pinyoyougou-docker /]# docker inspect 8c
[
    {
        "Id": "8c3e68bd05e77a1fc2f89c184fc796d1755e9b05973c1c3ff0d6a66c1f9a92ff",
        "Created": "2021-04-26T07:18:41.899275562Z",
        "Path": "/bin/sh",
        "Args": [
            "-c",
            "while true;do echo xiye;sleep 1;done"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 6434,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-04-26T07:18:42.244231037Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55",
        "ResolvConfPath": "/var/lib/docker/containers/8c3e68bd05e77a1fc2f89c184fc796d1755e9b05973c1c3ff0d6a66c1f9a92ff/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/8c3e68bd05e77a1fc2f89c184fc796d1755e9b05973c1c3ff0d6a66c1f9a92ff/hostname",
        "HostsPath": "/var/lib/docker/containers/8c3e68bd05e77a1fc2f89c184fc796d1755e9b05973c1c3ff0d6a66c1f9a92ff/hosts",
        "LogPath": "/var/lib/docker/containers/8c3e68bd05e77a1fc2f89c184fc796d1755e9b05973c1c3ff0d6a66c1f9a92ff/8c3e68bd05e77a1fc2f89c184fc796d1755e9b05973c1c3ff0d6a66c1f9a92ff-json.log",
        "Name": "/exciting_kapitsa",
        "RestartCount": 0,
        "Driver": "devicemapper",
        "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": {
                "DeviceId": "93",
                "DeviceName": "docker-253:0-674-7bac96387f711f8431ebbcfaf2280105eb5496e05b111f04cb254feac8f77f4e",
                "DeviceSize": "10737418240"
            },
            "Name": "devicemapper"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "8c3e68bd05e7",
            "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/sh",
                "-c",
                "while true;do echo xiye;sleep 1;done"
            ],
            "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": "889d86bb8d9e49fdee735cc2e3bea300c1ce6de5e1b2eebdc59e93399125b0c1",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/889d86bb8d9e",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "f607c2da6df4ff7fa317f83467acc0a7617ceaeaf909909a05ce697913a3a1e0",
            "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": "57dfc8e244c598a843116e956699ee11c32eaac81ebdd1c67c3c6b5439c94df5",
                    "EndpointID": "f607c2da6df4ff7fa317f83467acc0a7617ceaeaf909909a05ce697913a3a1e0",
                    "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 /bin/bash
#这个命令是进入这个容器正在运行的命令行
docker attach 容器id  

拷贝容器文件到主机上

# docker cp 容器id:容器内路径 外部主机路径
[root@pinyoyougou-docker /]# docker cp 8c3e68bd05e7:/fyx/nihaio.txt /

作业练习

练习1(nginx部署)

Docker 安装Nginx

# 搜索镜像
docker searcg nginx;
# 下载最新镜像;
docker pull nginx;
# -d 后台运行 --name 起名字 -p3352:80 向外主机爆露3352的端口容器内部是80的端口
docker run -d --name nginx1 -p 3352:80 nginx;
#本机发起一个请求
[root@pinyoyougou-docker devicemapper]# curl 127.0.0.1:3352
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
# 发现能收到返回的网页数据

练习2(tomcat)

安装一个tomcat

# 直接运行命令如果没有tomcat 默认会下载tomcat
docker run  -d -p 8080:8080 tomcat;
# 外网访问发现404 这个原因是因为阿里云镜像会默认下载最小的镜像 导致tomcat是阉割版的 里面的内容一部分是少的

练习3(es+kibana)

安装es

#es 暴漏的端口很多
#es 十分的耗内存
#es 的数据一般需要放置到安全目录 ! 挂载
#--net somenetwork ? 网络配置
#这样运行起来发现占用内存太大所以要加内存限制
docker run -d --name myes -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
#使用-e 来指定docker 的运行时内存占用大小
docker run -d --name myes -p 9200:9200 -p 9300:9300 -e ES_JAVA_OPTS="-Xms64m -Xmx512m" -e "discovery.type=single-node" elasticsearch:7.6.2

安装kibana

安装前要思考的问题由于Docker容器之间是相互隔离的kibana改如何链接es?

#答案是可以通过docker 内部网络ip来连接 
docker  inspect  es镜像id

@M__K_IH_BV2IOV5YRKC8NG.png

# 然后通过你获取到的ip 更改kibana启动的ip命令 启动成功访问就可以了
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://172.17.0.3:9200 -p 5601:5601 -d kibana:7.4.2

Docker图形化管理工具(Portainer)

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

Docker镜像详解

镜像是什么

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

如何获得镜像

  • 从远程仓库下载
  • 朋友拷贝给你
  • 自己制作一个镜像DockerFile

Docker镜像加载原理

联合文件系统

就类似与Git的提交记录,简单来讲就是有两个镜像如果镜像B有了镜像A的环境,就不需要再进行下载了

commit镜像

docker commit 提交容器成为一个新的副本
# 命令和git原理类似
docker commit -m="描述" -a=“xiye” 容器id 镜像id

实战测试

# 启动一个tomcat 然后把webapss.dist 文件目录放置到webapps可访问
# 运行nginx 镜像
docker run  -p 80:8080 -d e1ac7618b15d 
# 然后进入正在运行的程序
[root@pinyoyougou-docker devicemapper]# docker exec -it 940b08cf57f2 /bin/bash
root@940b08cf57f2:/usr/local/tomcat# 
# 修改内容后然后提交
docker commit -a="xiye" -m="提交的内容" 940b08cf57f2 e1ac7618b15d
# 查看自己的镜像
[root@pinyoyougou-docker devicemapper]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
e1ac7618b15d          latest    5f4963f45438   45 docker ago   454MB

容器数据卷

什么是容器数据卷

docker的理念回顾

将应用打包成一个镜像

那应用的数据怎么办?

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

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

这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面实现持久化

所以数据卷就是容器的持久化和同步操作

使用数据卷

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

docker  run -it -v 主机目录:容器目录 centos 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X7ahLBFY-1631176874112)(https://i.loli.net/2021/05/07/nH8UB56DIiQWJwO.png)]

**接一下来主机和容器内部就建立了链接 任何操作的目录都会同步类似vue双向绑定 就算容器停止当容器再次启动时 也会去同步主机绑定数据 **

好处:我们以后修改只需要在本地修改,容器内会自动同步!

实战:安装MySQL

思考:mysql数据持久化的问题

# 获取镜像
[root@pinyoyougou-docker ~]# docker pull  mysql:5.7
# 运行 参数详解-d后台运行 -p 爆露端口 -v 挂在主机与容器的数据卷和配置文件 -e 指定Mysql密码 --name 指定运行容器名称
docker run -d -p 3301:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysqk/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=fyxzuishuai12 --name fyxmysql mysql:5.7

我们接下来在本地连接mysql创建一个fyxdatabase的表然后删除容器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kG5gtTIT-1631176874113)(https://i.loli.net/2021/05/08/jy4xHVO2hZN1Tlt.png)]

接下来重新运行和上面命令一样的docker 运行命令我们发现数据还是存在的

OX664_0_`__6_FYMM_SZJ5Q.png

具名挂载和匿名挂载

# 匿名挂载(不起名字)
-v 容器路径
# 具名挂载(起名字)
-v juming-name:容器路径
# 指定路径挂载
-v /宿主机路径:容器内路径
# 查看所有的卷情况
docker volume ls
DRIVER    VOLUME NAME
local     00afc05713216e1df34ebcef8454d67b8072e67ab76353455dbb449650200515
local     75e2cf012dece07504b8c83ea4b55d66fe8c8e8a6de027618bae71d75cb7143d
local     3907c368ad104eec5f5def2a6d9df9d53a06a23b3355aac9a09f7fed0d47e3bd
local     a74534db8cc3042061bc2596d366d75907378d4db63fad19d2bf41a3fcb90721
#查看卷的具体挂载路径
[root@pinyoyougou-docker data]# docker volume inspect 00afc05713216e1df34ebcef8454d67b8072e67ab76353455dbb449650200515
[
    {
        "CreatedAt": "2017-10-24T11:17:26+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/00afc05713216e1df34ebcef8454d67b8072e67ab76353455dbb449650200515/_data",
        "Name": "00afc05713216e1df34ebcef8454d67b8072e67ab76353455dbb449650200515",
        "Options": null,
        "Scope": "local"
    }
]

所有docker容器内的卷没有指定本机路径的情况下都是在**/var/lib/docker/volumes/xxxx_data**

我们通过具名挂载可以方便的找到我们的一个卷

不建议使用匿名挂载

拓展

# ro 或者rw 是什么意思
# 通过 -v juming-nginx:/etc/nginx:ro 表示这个文件下的内容是只读 rw 就是可读和可写
docker run -d -P --name ngixnp01 -v juming-nginx:/etc/nginx:ro nginx

初识Dockerfile

Dockerfile就是构建docker镜像的脚本文件!

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

[root@pinyoyougou-docker ~]# vim dockerfile1
# 再centos镜像基础之上构建
FROM centos
#挂在卷
VOLUME ["volume01","volume02"]
# 输出
CMD echo "---end-----"
# 默认走这个控制台
CMD /bin/bash
#使用命令构建镜像
[root@pinyoyougou-docker ~]# docker build -f dockerfile1  -t myimages .
#使用查看命令
[root@pinyoyougou-docker dockerdata]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
myimages              latest    e448eb8c6a43   2 minutes ago   209MB

进入容器查看目录发现了两个我们构建docker文件的卷挂载

1621824402_1_.jpg

然后我们使用docker inspect 命令查看数据时会发现镜像默认的在宿主机上面开辟了两个同步卷路径

1621824785_1_.jpg

容器数据卷

实现容器与容器之间的数据共享就是数据卷容器

未命名文件.jpg

多个mysql实现数据共享(下面代码可能有问题可以参考网络)

# 创建父容器
docker run -d -p 3301:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysqk/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=fyxzuishuai12 --name fyxmysql mysql:5.7
# 创建子容器去继承父容器的卷挂载
docker run -d -p 3302:3306  -e MYSQL_ROOT_PASSWORD=fyxzuishuai12 --name fyxmysql2 mysql:5.7 --volumes-form fyxmysql

结论:

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

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

DockerFile

Dockerfile介绍

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

构建步骤:

  • 编写一个dockerfile文件
  • docker build 构建成为一个镜像
  • docker run 运行镜像
  • docker push 发布镜像(dockerhub,阿里云镜像仓库)

DockerFile构建过程

基础知识:

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

2、执行从上到下顺序执行

3、# 表示注释

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

f136030cb2ffa2c4286b4ea12408217c.jpeg

DockerFile:构建文件,定义了一切的步骤,源代码

DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品,原来是jar或者是war

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

DockerFile的指令

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LWDEAzkH-1631176874117)(https://i.loli.net/2021/05/24/6m4eOzoHF5PlY2v.png)]

实战基础

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

创建一个自己的Centos

编写DockerFile文件

# 在centos基础上构建镜像
FROM centos
# 镜像作者信息
MAINTAINER fanyuanxin<1349516890@qq.com>
# 构建环境变量
ENV MYPATH /usr/local
# 镜像的工作目录
WORKDIR $MYPATH
# 镜像构建的时候运行的命令
RUN yum -y install vim
RUN yum -y install net-tools

# 爆露的端口
EXPOSE 8080

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

构建镜像并运行

# 构建dockerfile
[root@pinyoyougou-docker mydockerfile]# docker build -f mydockerfile-centos -t mycentos:0.1 .
# 运行自己的容器
root@pinyoyougou-docker mydockerfile]# docker run -it mycentos:0.1
[root@442f7693c9c8 local]# pwd
/usr/local
[root@442f7693c9c8 local]# vim dockerfile
# 发现vim 命令已经安装过了
[root@442f7693c9c8 local]# vim --version
VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Jun 18 2020 15:49:08)

CMD命令使用&ENTRYPOINT区别

# 编写dockerfile文件
[root@pinyoyougou-docker ~]# vim dockerfile 

FROM centos
# 区别 CMD 和ENTRYPOINT 区别就是docker run CMD构建的镜像不能追加指令而ENTRYPOINT构建的镜像可以追加命令
CMD ["ls","-a" ]
# ENTRYPOINT ["ls","-a" ]

# 构建dockerfile
[root@pinyoyougou-docker ~]# docker build -f dockerfile -t cmdtest .
# 运行docker容器 发现ls命令生效 
[root@pinyoyougou-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


实战:Tomcat镜像

1、准备镜像文件,tomcat压缩包,jdk的压缩包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bRA3rS8N-1631176874117)(https://i.loli.net/2021/05/26/qukdrVCnpw7bZzv.png)]

2、编写dockerfile文件

# 基础镜像
FROM centos
# 作者信息
MAINTAINER fanyuanxin<1349516890@qq.com>
# 复制当前我目录下的readme.txt 到/usr/local/目录下
COPY readme.txt /usr/local/readme.txt
# 添加jdk环境
ADD jdk-8.tar.gz /usr/local/
# 添加apache-tomcat目录
ADD apache-tomcat-8.5.66.tar.gz /usr/local/
# 运行的时候安装vim
RUN yum -y install vim
# 配置环境变量
ENV MYPATH /usr/local
# 配置工作目录
WORKDIR $MYPATH

# 配置java环境变量和tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATG $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.66
ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.66
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

# 爆露8080端口
EXPOSE 8080
# 执行tomcat运行命令和显示日志
CMD /usr/local/apache-tomcat-8.5.66/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.66/bin/logs/catalina.out

3、构建docker镜像

docker build -t diytocmat .

4、运行tomcat容器

docker run -d -p 9090:8080 -v /usr/local/code/:/usr/local/apache-tomcat-8.5.66/webapps/ -v /usr/local/codelogs/:/usr/local/apache-tomcat-8.5.66/logs/  diytocmat

5、发布代码到/usr/local/code (我这里用tomcat自带的ROOT代码发布进去测试)

发布自己的镜像

DockerHub

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

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

3、在服务器上面提交自己的镜像

docker login -u 自己的账号然后回车输入自己的密码

4、提交自己的镜像

# 首先需要tag 你的镜像生成发布镜像 镜像名格式必须是dockerhub账号id/镜像名:版本号
docker tag 1124195418ad xiye1234/diytomcat:1.0
# 发布镜像 
docker push xiye1234/diytomcat:1.0
# 成功后会受到一封邮件点击确定就能最终上传到仓库了

阿里云镜像发布

1、登录阿里云并搜索容器镜像服务

2、进入个人版uTools_1622444221888.png

3、创建命名空间

uTools_1622444247512.png

4、创建镜像仓库,代码源选择本地仓库

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xRqMrbCb-1631176874119)(https://i.loli.net/2021/05/31/q4OxEK96fwTLgzG.png)]

5、点击自己创建的仓库名里面有详细的发布镜像教程

uTools_1622444793117.png

可以在镜像版本的地方查看自己发布的镜像

小结

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sxeX0Vax-1631176874121)(https://i.loli.net/2021/05/31/8ZgofT5mM1IOGJp.png)]

Docker网络

理解Docker0

  • ip addr查看本机网卡

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jwfFukVp-1631176874121)(https://i.loli.net/2021/05/31/zLpi8IsugtmqP3U.png)]

发现有三个网络 docker0网络是安装docker自动安装的

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

未命名文件.png

# 准备一个docker 容器
docker run -d -P --name tomcat01 tomcat
# 查看容器ip地址
[root@pinyoyougou-docker usr]# docker exec -it dcdbb51e1cf7 ip addr
#  容器本机回环
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
# 这个容器网络地址是docker 分配
56: eth0@if57: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global
 # ping 容器ip发现可以ping通
[root@pinyoyougou-docker usr]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.183 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.044 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.041 ms

当我们运行过一个容器后再使用ip addr时 会发现又多了一个网络会发现@后面的网络名和容器内部网络名相似

uTools_1622449289696.png

# 这个就是使用的evth-pair技术 就是一对的虚拟设备接口,他门都是称对出现的,一段连着协议,一段彼此相连
# 正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备
# 我们再启动一个tomcat2
docker run -d -P --name tomcat02 tomcat
# 然后ping tomcat1 发现是可以ping 通的
[root@pinyoyougou-docker usr]# docker exec -it tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.199 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.045 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.043 ms
# 然后我们发现容器和容器是可以ping通的
# 小知识点 可以使用 arp -a 命令查看

结论:docker0就相当于是个交换机的角色 容器容器相互访问都是先通信到docker0解析到要的具体容器内部

docker容器中所有的网络接口都是虚拟的,虚拟转发效率高只要容器删除,对应网桥一对就没有了

–link

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

# 我们先启动两个tomcat01 和tomcat 02
[root@pinyoyougou-docker ~]# docker run -d -P  --name tomcat01 tomcat
[root@pinyoyougou-docker ~]# docker run -d -P  --name tomcat02 tomcat
# 然后我们通过容器名ping tomcat网络 发现并不能通过容器名ping通
[root@pinyoyougou-docker ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: No address associated with hostname
# 当我们通过--link指定容器名 发现tomcat03 可以通过ping同 但是link是单向的 tomcat02 ping不同tomcat03
[root@pinyoyougou-docker ~]# docker run -d -P  --name tomcat03 --link tomcat02 tomcat
[root@pinyoyougou-docker ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.096 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.062 ms
# 为什么ping 查看tomcat03的hosts
[root@pinyoyougou-docker ~]# docker exec -it tomcat03 cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.3	tomcat02 a922370e128d
172.17.0.4	559b325edc65

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

我们现在玩Docker已经不建议使用–link 因为–link不是双向的

我们可以使用自定义网络,不使用docker0!

自定义网络

解决–link 不能双向访问的问题

查看docker的所有网络

[root@pinyoyougou-docker ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
eb50498883b1   bridge    bridge    local
c2b8cb191da4   host      host      local
d11777ea36d7   none      null      local

网络模式

bridge :桥接模式 docker(默认)

none : 不配置网络

host : 和宿主机共享网络

container :容器网络连接(局限性很大不推荐使用)

测试

# 我们直接启动的命令 不指定--net 就默认使用的是--net bridge 桥接模式 就是我们的docker0
docker run -d -P --name tomcat01 tomcat     
docker run -d -P --name tomcat01 --net bridge tomcat
# docker0特点: 域名不能访问,--link可以打通连接!但是只是单向的极为不方便
# 所以我们可以自定义一个网络
[root@pinyoyougou-docker ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
3de228bd7998a41ef4d1537386f07c8959f521eb6e2738476a750bca6012cf27
[root@pinyoyougou-docker ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
eb50498883b1   bridge    bridge    local
c2b8cb191da4   host      host      local
3de228bd7998   mynet     bridge    local
d11777ea36d7   none      null      local
# 使用我们自己创建的网络运行容器 发现我们自定义的网络可以直接通过容器名ping通
[root@pinyoyougou-docker ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
[root@pinyoyougou-docker ~]# docker run -d -P --name tomcat01-mynet  --net mynet tomcat
[root@pinyoyougou-docker ~]# docker run -d -P --name tomcat02-mynet  --net mynet tomcat
[root@pinyoyougou-docker ~]# docker exec -it tomcat01-mynet ping tomcat02-mynet
PING tomcat02-mynet (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat02-mynet.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.077 ms
64 bytes from tomcat02-mynet.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.063 ms

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

网络连通

解决不处于同一个网络下如何实现容器连接到不同的网络的容器

Docker network connect

# 先创建一个桥接模式的tomcat
[root@pinyoyougou-docker ~]# docker run -d -P --name tomcat01-bridge tomcat
# 发现ping不通 
docker exec -it tomcat01-bridge ping tomcat02-mynet
ping: tomcat02-mynet: No address associated with hostname
# 使用docker network connect 网络名 荣启铭
docker network connect mynet tomcat01-bridge
# 之后发现不处于同一个网络下也是可以正常使用的
docker exec -it tomcat01-bridge ping tomcat02-mynet
PING tomcat02-mynet (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat02-mynet.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.088 ms
64 bytes from tomcat02-mynet.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.062 ms

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值