Docker入门

Docker概述

为什么会出现Docker?

*两套环境,配置繁琐,集群搭错一个地方只有推倒重来,重复工作太多*

Docker的思想就是隔离。

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

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

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

本质:所有的技术的出现都是因为产生了问题,去解决问题才出现的。

虚拟机:在windows中装一个VMware,通过这个软件我们可以虚拟出来一台或地平台电脑!笨重!

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

VM: linux centos原生镜像(一台电脑)隔离,需要开机多个虚拟机! 最小几个G,开机要几分钟

docker:隔离,镜像(只要最核心的环境,最小为4M,在此基础上装所需要的软件+jdk+mysql)十分的小巧,运行镜像就可以启动! 最小几M,秒级启动

Docker是基于Go语言开发的!,开源项目!

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

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

Docker能干嘛

虚拟机技术:这里的lib是运行所需要的库,可以更改

虚拟机缺点:

  1. 资源占用十分多(因为是一个电脑一个电脑的虚拟)

  2. 冗余步骤多

  3. 启动慢

容器化技术

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

比较虚拟机和Docker的不同

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

容器是的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟的硬件,所以就轻便了,每个容器间是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响

Docker的基本组成

*镜像(image):*

Docker镜像就好比是一个模板,通过这个模板来创建容器服务,tomcat镜像===>run===>tomcat01容器(提供服务器),通过这个镜像可以创造多个容器(最终服务运行或项目运行就是在容器中)

*容器(container)*

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

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

目前就开源把这个容器理解为就是一个简易的Linux系统

*仓库(repository):*

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

仓库分为公有仓库和私有仓库

Docker Hub(默认是国外的下载镜像很慢)

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

总结:从仓库远程拉取一个镜像到本地,run镜像启动一个容器

底层原理

Docker是怎么工作的?

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

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

Docker为什么比VM快?

1.Docker比VM有更少的抽象层

2.Docker利用宿主机的内核,VM是需要Guest OS(再搭建一个这样的环境)

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

Docker安装

内核是3.10以上的

uname -r

  1. 卸载旧的版本(粘贴,复制)
yum remove docker \​         docker-client \​         docker-client-latest \​         docker-common \​         docker-latest \​         docker-latest-logrotate \​         docker-logrotate \​         docker-engine
  1. 需要安装包
yum install -y yum-utils
  1. 设置镜像的仓库,这里的镜像地址更换为了阿里云
yum-config-manager \--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repoyum makecache fast           #更新索引再去安装
  1. 安装docker相关的内容,docker-ce 社区版 ee企业版
 yum install docker-ce docker-ce-cli containerd.io
  1. 启动Docker
 systemctl start docker
  1. 查看是否安装成功
 docker versiondocker run hello-world
  1. 查看下载的镜像
docker images

卸载Docker:

  1. 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
  1. 删除目录
rm -rf /var/lib/docker

1.配置阿里云镜像加速器

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

2.配置使用

sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF'{ "registry-mirrors": ["https://u4yijdry.mirror.aliyuncs.com"]}EOFsudo systemctl daemon-reloadsudo systemctl restart docker

Docker的常用命令:

帮助命令:

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

镜像命令

[root@docker ~]# docker imagesREPOSITORY        TAG    IMAGE ID       CREATED       SIZEhello-world     latest    bf756fb1ae65     5 months ago     13.3kB

#解释

REPOSITORY 镜像的仓库

TAG 镜像的标签

IMAGE ID 镜像的ID

CREATED 镜像的创建时间

SIZE 镜像的大小

#可选项

-a   --all       #列出所有镜像-q   --quiet #只显示镜像的IDdocker search 镜像       #搜索镜像

#下载镜像*

docker pull mysql[:tag]
[root@docker ~]# docker pull mysqlUsing default tag: latest                #如果不写tag,默认就是latestlatest: Pulling from library/mysql        8559a31e96f4: Pull complete             #分层下载,docker image的核心,联合文件系统d51ce1c2e575: Pull complete c2344adc4858: Pull complete fcf3ceff18fc: Pull complete 16da0c38dc5b: Pull complete b905d1797e97: Pull complete 4b50d1c6b05c: Pull complete c75914a65ca2: Pull complete 1ae8042bdd09: Pull complete 453ac13c00a3: Pull complete 9e680cd72f08: Pull complete a6b5dc864b6c: Pull complete Digest: sha256:8b7b328a7ff6de46ef96bcf83af048cb00a1c86282bfca0cb119c84568b4caf6   #签名Status: Downloaded newer image for mysql:latestdocker.io/library/mysql:latest            #真实地址# 两者相同
docker pull mysqldocker pull docker.io/library/mysql:latest

指定版本下载:

docker pull mysql:5.7docker rmi -f 镜像id          #删除指定镜像docker rmi -f 镜像id 镜像id 镜像id     #删除多个镜像docker rmi -f $(docker images -aq)       #删除全部镜像

容器命令

docker pull centos   #下载一个最新的centos镜像
docker run [可选参数] image\#参数说明--name=”Name”      容器名字,tomcat01,tomcat02 ,用来区分容器-d                   后台方式运行-it                   使用交互方式运行,进入容器查看内容-p                  指定容器的端口 -p  8080:8080-p                  ip:主机端口:容器端口-p                  主机端口:容器端口-p                     容器端口-P                  随机指定端口\#测试,启动并进入容器docker run -it 容器id/镜像名    /bin/bash

*退出容器*

[root@4bb285138de4 /]# exit #直接停止容器并退出

[root@docker ~]#

ctrl+P+Q #容器不停止退出

列出所有运行的容器

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

[root@docker ~]# docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

[root@docker ~]# docker ps -a

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

4bb285138de4 831691599b88 “/bin/bash” 8 minutes ago Exited (0) 5 minutes ago musing_ganguly

c5dc2112d9a9 bf756fb1ae65 “/hello” 3 hours ago Exited (0) 3 hours ago vibrant_wescoff

5b97245a8bc3 bf756fb1ae65 “/hello” 3 hours ago Exited (0) 3 hours ago vigilant_hertz

[root@docker ~]# docker ps -qa

4bb285138de4

c5dc2112d9a9

5b97245a8bc3

删除容器

docker rm 容器id               #删除指定容器,不能删除正在运行的容器docker rm -f $(docker ps -aq)     #删除全部容器

启动和停止容器的操作

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

查看日志

docker logs -tf 容器id                 #显示日志docker logs -tf --tail number 容器id #显示日志条数,这里用number控制条数docker logs -tf --tail 10 dce7b8628bf

查看容器中的进程信息

[root@docker ~]# docker top 4bb285138de4

UID PID PPID C STIME TTY TIME CMD

root 8900 8884 1 22:36 pts/0 00:00:00 /bin/bash

查看镜像源数据

# 命令

docker inspect 容器id

#测试

[root@docker ~]# docker inspect 4bb285138de4[{​    "Id": "4bb285138de45ed2dda34546ef8547d74fb5d5922acd3624ea9e3b93f53ded04",​    "Created": "2020-06-29T10:18:02.112722322Z",​    "Path": "/bin/bash",​    "Args": [],​    "State": {​      "Status": "running",​      "Running": true,​      "Paused": false,​      "Restarting": false,​      "OOMKilled": false,​      "Dead": false,​      "Pid": 8900,​      "ExitCode": 0,​      "Error": "",​      "StartedAt": "2020-06-30T02:36:03.304931826Z",​      "FinishedAt": "2020-06-29T10:20:35.269240929Z"​    },​    "Image": "sha256:831691599b88ad6cc2a4abbd0e89661a121aff14cfa289ad840fd3946f274f1f",​    "ResolvConfPath": "/var/lib/docker/containers/4bb285138de45ed2dda34546ef8547d74fb5d5922acd3624ea9e3b93f53ded04/resolv.conf",​    "HostnamePath": "/var/lib/docker/containers/4bb285138de45ed2dda34546ef8547d74fb5d5922acd3624ea9e3b93f53ded04/hostname",​    "HostsPath": "/var/lib/docker/containers/4bb285138de45ed2dda34546ef8547d74fb5d5922acd3624ea9e3b93f53ded04/hosts",​    "LogPath": "/var/lib/docker/containers/4bb285138de45ed2dda34546ef8547d74fb5d5922acd3624ea9e3b93f53ded04/4bb285138de45ed2dda34546ef8547d74fb5d5922acd3624ea9e3b93f53ded04-json.log",​    "Name": "/musing_ganguly",​    "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/e4e3e63ccccc35fdca2128c7744aec95e5d9781177edcc86d47b43f543f67ef2-init/diff:/var/lib/docker/overlay2/40b38560c9a02a744c2d0872ab2f4f93333ad65b400eb47b3fbb438b37aee7e1/diff",​        "MergedDir": "/var/lib/docker/overlay2/e4e3e63ccccc35fdca2128c7744aec95e5d9781177edcc86d47b43f543f67ef2/merged",​        "UpperDir": "/var/lib/docker/overlay2/e4e3e63ccccc35fdca2128c7744aec95e5d9781177edcc86d47b43f543f67ef2/diff",​        "WorkDir": "/var/lib/docker/overlay2/e4e3e63ccccc35fdca2128c7744aec95e5d9781177edcc86d47b43f543f67ef2/work"​      },​      "Name": "overlay2"​    },​    "Mounts": [],​    "Config": {​      "Hostname": "4bb285138de4",​      "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": "831691599b88",​      "Volumes": null,​      "WorkingDir": "",​      "Entrypoint": null,​      "OnBuild": null,​      "Labels": {​        "org.label-schema.build-date": "20200611",​        "org.label-schema.license": "GPLv2",​        "org.label-schema.name": "CentOS Base Image",​        "org.label-schema.schema-version": "1.0",​        "org.label-schema.vendor": "CentOS"​      }​    },​    "NetworkSettings": {​      "Bridge": "",​      "SandboxID": "6f0dae1a8a16719e2bda8f89811f3b71b43427286cd8b19cc7b65d5be420db15",​      "HairpinMode": false,​      "LinkLocalIPv6Address": "",​      "LinkLocalIPv6PrefixLen": 0,​      "Ports": {},​      "SandboxKey": "/var/run/docker/netns/6f0dae1a8a16",​      "SecondaryIPAddresses": null,​      "SecondaryIPv6Addresses": null,​      "EndpointID": "437e8b8ebf9b331a8ae0135dba22bb9d477bebff6ef8c52a2b6d7dcdd42bcd6e",​      "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": "2dc48a480bde9e7b163036eb12d8553dc6ed036754db8b16c9d9641631a51951",​          "EndpointID": "437e8b8ebf9b331a8ae0135dba22bb9d477bebff6ef8c52a2b6d7dcdd42bcd6e",​          "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

#测试

[root@docker ~]# docker psCONTAINER ID   IMAGE          COMMAND CREATED STATUS  PORTS        NAMES4bb285138de4  831691599b88    /bin/bash"     17 hours ago    Up15minutes musing_ganguly[root@docker ~]# docker exec -it 4bb285138de4 /bin/bash[root@4bb285138de4 /]# ps -efUID     PID  PPID  C STIME TTY      TIME CMDroot      1    0  0 02:36 pts/0   00:00:00 /bin/bashroot     14    0  0 02:51 pts/1   00:00:00 /bin/bashroot     28   14  0 02:52 pts/1   00:00:00 ps -ef

#方法二:

docker attach 容器id

#测试

[root@docker ~]# docker attach 4bb285138de4

[root@4bb285138de4 /]# ls

bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var

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

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

docker cp 容器id:容器内路径 目的主机路径
### #进入文件内部
[root@docker ~]# docker attach 4bb285138de4
\#在容器内新建一个文件
[root@4bb285138de4 home]# touch php
[root@4bb285138de4 home]# ls
php
[root@4bb285138de4 home]# exit
exit
[root@docker ~]# docker ps
CONTAINER ID     IMAGE        COMMAND       CREATED       STATUS        PORTS        NAMES\#将文件拷贝出来到主机上
[root@docker ~]# docker cp 4bb285138de4:/home/php /home/
[root@docker ~]# cd /home/
[root@docker home]# ll
total 0
-rw-r--r--. 1 root root 0 Jun 29 23:02 java
-rw-r--r--. 1 root root 0 Jun 29 23:03 php

小结命令:


实战练习(命令)

1. Docker安装nginx

#1.搜索镜像  search  可以去官网看帮助文档
#2.下载镜像 pull
#3.运行测试
[root@docker ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
684d9e6fe265        nginx               "/docker-entrypoint.…"   12 seconds ago      Up 11 seconds       80/tcp              nginx_02
ea6c5880e382        centos              "/bin/bash"              4 hours ago         Up 4 hours                              festive_curie
[root@docker ~]# docker stop 684d9e6fe265
684d9e6fe265
#   -d  后台运行
#   --name  给容器取名字
#   -p  宿主机端口:容器内部端口
[root@docker ~]# docker run -d --name nginx_03 -p 3333:80 nginx
ee42a7ca71c3abdac85d57c0dfb8628ad05ff04c97fef13ab3e0a1b03797d225
[root@docker ~]# curl localhost:3333<!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>
# 进入容器
[root@docker ~]# docker exec -it nginx_03 /bin/bash
root@ee42a7ca71c3:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@ee42a7ca71c3:/# cd /etc/nginx/
root@ee42a7ca71c3:/etc/nginx# ls
conf.d  fastcgi_params  koi-utf  koi-win  mime.types  modules  nginx.conf  scgi_params  uwsgi_params  win-utf

2. 安装tomcat

# 官方的使用
docker run -it --rm tomcat:9.0
#我们之前的启动都是后台,停止了之后,容器还是可以查到   docker run -it --rm,一般用来测试,用完就删除,有点像闪照,看了就删除照片那种# 下载启动
docker run -d -p 3355:8080 --name tomcat01 tomcat# 测试访问没有问题
[root@docker ~]# docker run -d -p 3355:8080 --name tomcat2 tomcat
027d4e9990ef8d5121de2830acd8a86a82827987aa32ad5b9a3868644c6d823e
[root@docker ~]# docker exec -it tomcat2 /bin/bash404
# 发现问题:1.Linux命令少了   2.没有webapps,阿里云镜像的原因,默认是最小的镜像,所以不必要的都剔除掉了
# 保证最小可运行环境!解决:将webapps.dist目录下的文件copy到webapps或者将webapps.dist改名为webapps

问题

[root@docker ~]# docker run -d -p 3355:8080 --name tomcat1 tomcat
f667afe1fd92ccc511a718c4b785ea0759aeb95320379d2eca94c2d78460d156
docker: Error response from daemon: driver failed programming external connectivity on endpoint tomcat1 (d1bf00f22f86648a1a301376da8b802eece1d8727c981d2a267a33febf357215):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 3355 -j DNAT --to-destination 172.17.0.3:8080 ! -i docker0: iptables: No chain/target/match

解决办法:自定义docker连接断掉了,重启一下docker服务

3. 部署ES+kibana

# es 暴露的端口很多!
# es    十分的耗内存
# es    数据一般需要放置到安全目录!挂载
--net somenetwork   ?    是一个网络配置#下载启动es
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2# 启动了 linux就卡住了 es是非常消耗内存的#查看cpu负载 docker stats  (图在下面)#   测试一下es是否成功[root@docker ~]# curl localhost:9200
{"name" : "d0334d25bbef","cluster_name" : "docker-cluster","cluster_uuid" : "ag11yTCjQQGzAlWFhEbpHQ","version" : {"number" : "7.6.2","build_flavor" : "default","build_type" : "docker","build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f","build_date" : "2020-03-26T06:34:37.794943Z","build_snapshot" : false,"lucene_version" : "8.4.0","minimum_wire_compatibility_version" : "6.8.0","minimum_index_compatibility_version" : "6.0.0-beta1"},"tagline" : "You Know, for Search"
}

# LIMIT:总共内存# MEN USAGE:容器占用内存,可以看到es是占用的非常高了# 增加内存的限制,修改配置文件 -e 环境配置修改
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPS="-Xms64m -Xmx512m" elasticsearch:7.6.2

作业:使用kibana连接es?思考网络是如何连接的?

可视化

portainer(先用这个)

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

Rancher(CI/CD再用)

什么是Portainer?

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

 docker run -d -p 8080:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer# 访问测试# 浏览器访问 192.168.0.104:8080

选择本地

Docker镜像

镜像是什么?

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

如何得到镜像

​ ·从远程仓库下载

​ ·朋友拷贝给你

​ ·自己制作一个镜像DockerFile

Docker镜像加载原理

UnioFS(联合文件系统)

我们下载的时候看到的一层层就是这个东西(layer层)!

Docker镜像加载原理

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS

bootfs主要包含bootloader(系统开机引导文件)kernel(内核)bootloader主要是引导加载kernel,Linux刚启动会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器的内核。当bootfs加载完成之后整个内核就都在内存中了,此时内存的使用权已经由bootfs转交给内核,此时系统也会卸载bootfs。

rootfs,在bootfs之上,包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件,rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等

对于精简的OS,rootfs可以很小,只需要报刊最基本的命令,工具和库就可以了,因为底层直接用Host的Kernel,自己只需要提供rootfs就可以了,由此课件对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以共用bootfs!!!

虚拟机是分钟级,容器是秒级启动!!!

层级:最底层是bootfs引导加载操作系统->rootfs加载操作系统发行版基础镜像(base image)->应用镜像(只读,多层)->容器层(可写)

分层理解

[root@docker ~]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
8559a31e96f4: Already exists
85a6a5c53ff0: Pull complete
b69876b7abed: Pull complete
a72d84b9df6a: Pull complete
5ce7b314b19c: Pull complete
04c4bfb0b023: Pull complete
Digest: sha256:800f2587bf3376cb01e6307afe599ddce9439deafbd4fb8562829da96085c9c5
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest

思考:为什么Docker要采用这种分层结构呢?

最大的好处,莫过于是资源共享了!比如有多个镜像都从相同的Base镜像构建出来,那么宿主机只需要在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样久可以为所有的容器服务了,而且镜像的每一次都可以被共享,

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

[root@docker ~]# docker inspect redis:latest//..."RootFS": {"Type": "layers","Layers": ["sha256:13cb14c2acd34e45446a50af25cb05095a17624678dbafbcc9e26086547c1d74","sha256:e6b49c7dcaac7a2ec2acc379da5f5b1bcc6a5d3badd72814fe945296216557bd","sha256:cdaf0fb0082b74223a224c39c2d2ea886c32f53b7e1d5b872d5354aae0df56b8","sha256:72d3a7e6fe022824ee2f852ca132030e22c644fbaf8287f4ea8044268abe40b7","sha256:67c707dbd847d8310d3b988c3e3d9d9eb53387ede0de472e36a15abbcb6c719c","sha256:7b9c5be81844318508f57a5b0574822dabaaed3dc25ee35d960feec3a9e941c4"]},

分层特点:

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

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

如何提交一个自己的镜像

commit镜像

docker commit 提交容器成为一个新的副本# 命令和git原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id   目标镜像名:[TAG]

实战测试:

# 1.启动一个默认的tomcat# 2.发现这个默认的tomcat是没用webapps应用,镜像的原因,官方的镜像默认webapps下面是没有文件的!# 3.我自己拷贝进去了基本的文件# 4.将我们操作过的容器通过commit提交为一个镜像!我们以后就是同我们修改过的镜像即可,这就是我们自己的镜像

如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们学习VM的时候,快照!

Docker进阶


容器数据卷

docker的理念回顾

将应用和环境打包成一个镜像!

**问题:**数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!

需求:数据可以持久化

Mysql,容器删了,删库跑路!需求:Mysql数据可以存储在本地!

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

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

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

使用数据卷

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

docker run -it -v 主机目录:容器内目录# 测试 绑定宿主机的/home/test与容器的/home目录
[root@docker home]# docker run -it -v /home/test:/home centos /bin/bash
# 容器中新建文件
[root@00cefe7f7e9d home]# touch test.java
[root@00cefe7f7e9d home]# ls
test.java
# 进入本地目录查看文件内容是否同步过来
[root@docker home]# cd test/
[root@docker ceshi]# ls
test.java

启动起来的时候我们可以通过命令:docker inspect 容器id 查看挂载情况

再来测试(本地修改文件,数据同步到容器中)!

1.停止容器

2.宿主机上修改文件内容

3.启动容器

4.容器内的数据依旧是同步的!!!

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

实战:安装MySql

#    获取镜像
[root@docker ~]# docker pull mysql:5.7#运行容器,需要做数据挂载! #   安装启动mysql,需要配置密码,这是注意要点!!!# 官方测试: docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag# 启动我们的mysql容器
-d 后台运行
-p  宿主机端口:容器端口  设置访问宿主机的段端口就能能访问到容器内的端口
-v  卷挂载
-e  环境配置    这里配置了mysql的密码
--name  容器的名字
[root@docker ~]# 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# 启动成功之后,我们在本地使用sqlyog来测试一下
#sqlyog-连接到服务器的3310 --- 3310和容器内的3306映射,这个时候我们就可以连接上了!# 在本地测试创建一个数据库,查看一下我们映射的路径是否ok!

假设我们将容器删除

发现,我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能!

具名和匿名挂载

# 匿名挂载
-v 容器内路径!   #这里不写主机的目录
docker run -it -d -P --name nginx_05 -v /etc/nginx nginx
-P 随机指定端口#查看所有volume的情况
[root@docker ~]# docker volume ls
DRIVER              VOLUME NAME
local               0bed872eb81e37b10092f6164471a50fdf84cc038bbc89801e7cb05b0a89535e
local               07de8b0bb6aaa72ff8b9c1cbe5552e6ecd4f54b0c9f5f2728c65d2463c1392bf# 这里发现,这种就是匿名挂载,我们在 -v 只写了容器内的路径,没有写容器外(宿主机)的路径!# 具名挂载 (通过  -v 卷名:容器内路径)
[root@docker ~]# docker run -d -it --name nginx_06 -P -v jvming-nginx:/etc/nginx nginx
# 列出所有的卷
[root@docker ~]# docker volume ls
DRIVER              VOLUME NAME
local               jvming-nginx# 查看一下这个卷详细信息

所有docker容器内的卷,没有指定目录情况下都是在 /var/lib/docker/volume/[卷名]/_data

我们通过具名挂载可以方便的找到我们的一个卷,大多数情况在使用具名挂载

# 如何却是具名挂载还是匿名挂载,还是指定路径挂载
-v  容器路径            #匿名挂载
-v  卷名:容器路径        #具名挂载 (数据存储在默认路径/var/lib/docker/volume/)
-v  /宿主机路径:容器内路径    #指定路径挂载

拓展:

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

初始DockerFile

DockerFile是用来构建docker镜像的构建文件!命令脚本!

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

# 创建一个dockerfile文件,名字可以随机 建议Dockerfile
#   文件中的内容  指令(大写)    参数
FROM centosVOLUME ["volume01","volume02"]CMD echo "-----end-----"
CMD /bin/bash# 这里的每个命令,就是镜像的一层!
docker build -f [Dockerfile文件路径] -t [镜像名称:tag] .

[root@docker docker-test-volume]# docker run -d -it bridge/centos:1.0 /bin/bash

查看一下卷挂载的路径 docker inspect 容器id

测试一下刚才的文件是否同步出去了

在容器挂载的目录volume01中添加文件test.txt

在本地的卷目录下查看文件是否同步

这种方法我们未来用的十分多,因为我们通常会构建自己的镜像!

假设构建镜像的时候没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径!

数据卷容器

是容器之间的挂载!!

思考:多个mysql同步数据实现共享

[root@docker ~]# docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name=mysql01 mysql:5.7[root@docker ~]# docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=mysql02 --volumes-from mysql01 mysql:5.7#这个时候,可以实现两个容器数据同步!

# 启动三个容器,通过我们自己写的镜像



# 测试:可以删除docker01,查看一下docker02和docker03是否还可以继续访问
# 测试依旧可以访问

结论:

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

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

DockerFile介绍

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

1.编写一个dockerfile文件

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

3.docker run运行镜像

4.docker push发布镜像(DockerHub.阿里云镜像仓库!)

很多官方镜像都是基础包,很多功能没有,我们通常会用自己搭建自己的镜像
官方既然可以制作镜像,那我们也可以!

DockerFile构建步骤

基础知识:

1.每个保留关键字(指令)都是必须是大写字母
2.执行从上到下顺序执行
3.# 表示注释
4.每一个指令都会创建提交一个新的镜像层,并提交!

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

Docker镜像逐渐成为了企业交付的标准

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

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

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

DockerFile的指令

FROM         #   基础镜像,一切从这里开始
MAINTAINER      #   镜像是谁写的,姓名+邮箱
RUN             #   镜像构建的时候运行的命令
ADD             #   步骤:tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR         #   镜像的工作目录,进入容器后的默认目录
VOLUME          #   挂载的目录
EXPOSE          #   暴露端口的位置
CMD             #   指定这个容器启动的时候要运行的命令,只有最后一个命令会生效,可被替代
ENTYRPOINT      #   指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD         #   当构建一个被继承Dockerfile这个时候就会运行ONBUILD的指令,出发指令
COPY            #   类似ADD,将我们文件拷贝到镜像中
ENV             #   构建的时候设置环境变量#下图EXPOESE 应为    EXPOSE

实战测试

Docker Hub中99%镜像都是从这个基础镜像过来的FROM scratch

创建一个自己的centos

# 构建一个适合自己的镜像
[root@docker dockerfile]# cat mydockerfile
FROM centos
MAINTAINER Bridge<master_cy@126.com>ENV MYPATH /usr/loacl
WORKDIR $MYPATHRUN yum -y install vim
RUN yum -y install net-toolsEXPOSE 80CMD echo $MYPATH
CMD echo "----end-----"
CMD /bin/bash# 使用构建的镜像来运行容器,千万别忘记最后的点
# 命令 docker build -f dockerfile文件路径 -t 镜像名:[tag] .
Successfully built 5cce4b4a2953
Successfully tagged mycentos:1.0# 测试运行 发现vim和ifconfig都可以使用了,工作目录更改为/usr/local
[root@docker dockerfile]# docker run -it mycentos:1.0
[root@3b0e4a7d2aeb loacl]# ls
[root@3b0e4a7d2aeb loacl]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 172.17.0.3  netmask 255.255.0.0  broadcast 172.17.255.255ether 02:42:ac:11:00:03  txqueuelen 0  (Ethernet)RX packets 7  bytes 586 (586.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 0  bytes 0 (0.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536inet 127.0.0.1  netmask 255.0.0.0loop  txqueuelen 1000  (Local Loopback)RX packets 0  bytes 0 (0.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 0  bytes 0 (0.0 B)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

我们可以列出本地镜像的变更历史 docker history 镜像id/名称:tag --查看镜像构建的过程

我们平时拿到一个镜像,可以研究它是怎么做的?

CMD和ENTRYPOINT的区别

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

测试CMD

#编写dockerfile文件
[root@docker home]# cat dockerfile1
FROM centos
CMD ["ls","-a"]# 构建镜像
[root@docker home]# docker build -f dockerfile1 -t mycentos:2.0 .
Sending build context to Docker daemon  207.1MB
Step 1/2 : FROM centos---> 831691599b88
Step 2/2 : CMD ["ls","-a"]---> Running in bcb31410ceed
Removing intermediate container bcb31410ceed---> 2522d09261a4
Successfully built 2522d09261a4
Successfully tagged mycentos:2.0
# 运行镜像,发现ls -a命令生效了
[root@docker home]# docker run -it mycentos:2.0
.   .dockerenv  dev  home  lib64       media  opt   root  sbin  sys  usr
..  bin     etc  lib   lost+found  mnt    proc  run   srv  tmp  var# 想追加一个命令 -l    ls -al
[root@docker home]# docker run 2522d09261a4 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\": executable file not found in $PATH": unknown.
ERRO[0000] error waiting for container: context canceled # cmd的情况下 -l参数 替换了CMD["ls","-a"]的命令,而-l 不算命令,所以报错!

测试ENTRYPOIN

# 我们追加命令,是直接拼接在外面的ENTRYPOINT命令的后面!
[root@docker home]# docker run mycentos:3.0 -l
total 0
drwxr-xr-x.   1 root root   6 Jul  2 15:32 .
drwxr-xr-x.   1 root root   6 Jul  2 15:32 ..
-rwxr-xr-x.   1 root root   0 Jul  2 15:32 .dockerenv
lrwxrwxrwx.   1 root root   7 May 11  2019 bin -> usr/bin
drwxr-xr-x.   5 root root 340 Jul  2 15:32 dev
drwxr-xr-x.   1 root root  66 Jul  2 15:32 etc
drwxr-xr-x.   2 root root   6 May 11  2019 home
lrwxrwxrwx.   1 root root   7 May 11  2019 lib -> usr/lib
lrwxrwxrwx.   1 root root   9 May 11  2019 lib64 -> usr/lib64
drwx------.   2 root root   6 Jun 11 02:35 lost+found
drwxr-xr-x.   2 root root   6 May 11  2019 media
drwxr-xr-x.   2 root root   6 May 11  2019 mnt
drwxr-xr-x.   2 root root   6 May 11  2019 opt
dr-xr-xr-x. 206 root root   0 Jul  2 15:32 proc
dr-xr-x---.   2 root root 162 Jun 11 02:35 root
drwxr-xr-x.  11 root root 163 Jun 11 02:35 run
lrwxrwxrwx.   1 root root   8 May 11  2019 sbin -> usr/sbin
drwxr-xr-x.   2 root root   6 May 11  2019 srv
dr-xr-xr-x.  13 root root   0 Jul  2 02:41 sys
drwxrwxrwt.   7 root root 145 Jun 11 02:35 tmp
drwxr-xr-x.  12 root root 144 Jun 11 02:35 usr
drwxr-xr-x.  20 root root 262 Jun 11 02:35 var

DockerFile中许多命令都十分的相似,我们需要了解他们的区别,我们最好的学习就是对比他们,然后测试效果!

实战测试2:Tomcat镜像

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

2.编写Dockerfiel文件,官方命令Dockerfile,build会自动构建这个文件

[root@docker tomcat]# vim Dockerfile
FROM centos
MAINTAINER Bridge<master_cy@126.com>COPY readme.txt /usr/local/readme/txtADD jdk-8u181-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.22.tar.gz /usr/local/RUN yum -y install vimENV MYPATH /usr/local
WORKDIR $MYPATHENV JAVA_HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/binEXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out

3.构建镜像

# docker build -t diytomcat .

4.启动镜像

# 项目挂载在本地/home/build/tomcat/test目录下,直接在test中做修改就可以直接发布。日志也挂载出来了,本地可以查看
# docker run -d -p 9090:8080 --name bridgetomcat -v /home/build/tomcat/test:/usr/local/apache-tomcat-9.0.22/webapps/test -v /home/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.22/logs diytomcat

5.测试访问

6.发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了)

发布自己的镜像

发布到Docker.Hub

Docker.Hub

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

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

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

[root@docker ~]# docker login --help
Usage:  docker login [OPTIONS] [SERVER]
Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.
Options:-p, --password string   Password--password-stdin    Take the password from stdin-u, --username string   Username

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

# push 自己的镜像到服务器上
[root@docker ~]# docker push dirtomcat03
The push refers to repository [docker.io/library/dirtomcat03]
6eabbc12bc8b: Preparing
efcfd5ec54aa: Preparing
f73de6d323b0: Preparing
bc4da657b4da: Preparing
eb29745b8228: Preparing
denied: requested access to the resource is denied  #拒绝# push镜像的问题?
[root@docker ~]# docker push dirtomcat03
The push refers to repository [docker.io/bridge/dirtomcat03]
An image does not exist locally with the tag: bridge/dirtomcat03#解决办法:增加一个tag,tag的意思是重新给镜像取个名字
# 想要上传的容器id(这里的容器id为dirtomcat03的,) chao123456e 为DockerHub账号,这里一定要和DockerHub上账号对应,不然不能上传 chao123456e/tomcat:2.0 为新镜像名称
[root@docker ~]# docker tag 2c30f06d63c3 chao123456e/tomcat:2.0# 表示正在上传,已经配置成功
[root@docker ~]# docker push chao123456e/tomcat:2.0
The push refers to repository [docker.io/chao123456e/tomcat]
6eabbc12bc8b: Pushing [===========================>                       ]  31.89MB/57.22MB
efcfd5ec54aa: Pushed
f73de6d323b0: Pushing [================>                                  ]  128.7MB/381.7MB
bc4da657b4da: Pushed
eb29745b8228: Pushing [==============================>                    ]  132.7MB/215.3MB
# 提交的时候可以看出也是按层级提交的

发布到阿里云镜像服务上

1.登录阿里云

2.找到容器镜像服务

3.创建命名空间

4.创建容器镜像

5.浏览阿里云

# push上去阿里云镜像
docker push chao123456e/tomcat:2.0

小结:

Docker 网络

理解Docker0

测试

三个网络

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

# [root@docker ~]# docker run -d -P --name tomcat01 tomcat# 查看容器的内部网络地址 ip addr
[root@docker ~]# docker exec -it tomcat01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
4: eth0@if5: <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 0inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever#Linux 可以ping通docker容器内部

原理:

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

再次测试:ip addr

2.再启动一个容器测试,发现又多了以一对网卡!

# 我们发现这个容器带来网卡,都是一堆堆的
# veth-pair 就是以低于的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连# 比如上图的本地机的 5:veth if    对应的就是tomcat01的 4:veth if5   所以说他们是成对出现,# 正因为有这个特性,veth-pair充当一个桥梁,连接各种虚拟网络设备的
# oPenStac ,Docker容器之间的连接,OVS的连接,都是使用veth-pair技术

3.测试tomcat01和tomcat02是否可以ping通!

[root@docker ~]# docker exec -it tomcat01 ping 172.17.0.2# 结论:容器和容器之间是可以互相ping通的

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

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

小结

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

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

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

思考

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

–Link

[root@docker ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known#如何解决上面的问题呢?
# 通过 --link 即可以解决了网络连通问题
[root@docker ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
[root@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.168 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.070 ms# 反向可以ping通吗?
[root@docker ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: No address associated with hostname

其实这个tomcat03就是在本地配置了tomcat02的配置?

[root@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 60b035aed160
172.17.0.4  bb26ed7d467d

本质探究:–link就是在我们hosts文件中配置了172.17.0.3 tomcat02 60b035aed160

wm 现在玩Docker已经不建议使用–link了!

自定义网络!不适用docker0!

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

自定义网络

查看所有的docker网络

[root@docker ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
c657cfee5244        bridge              bridge              local
afd6d3641e4f        host                host                local
edc909beaf2e        none                null                local

网络模式

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

none: 不配置网络

host: 和宿主机共享网络

container:容器网络联通!(用的少!让容器直接互联,局限性大!!)

# 我们直接启动的命令, --net bridge,而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name --net bridge tomcat#docker0特点:   默认,域名不能访问,--link可以连通# 我们可以自定义一个网络!
#   --driver 默认是bridge网络
# --subnet 192.168.0.0/16
# --gateway 192.168.0.1[root@docker ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
[root@docker ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
c657cfee5244        bridge              bridge              local
afd6d3641e4f        host                host                local
370471f6a056        mynet               bridge              local
edc909beaf2e        none                null                local

[root@docker ~]# docker run -d -P --name tomcat02 --network mynet tomcat
18c523b7a4f04e706175d72a7850339b442d6f562b492c497c4cd73cbc71bb58
[root@docker ~]# docker run -d -P --name tomcat03 --network mynet tomcat
59a7491cc124402428b25954528090316d16cbc2b8936b96478447f69be8ff29
[root@docker ~]# docker network inspect mynet
[{"Name": "mynet","Id": "370471f6a0566a37a8e698d6da6e7f3a7dfa8517363beb22cf6b9e46b8f14961","Created": "2020-07-06T21:32:34.873713447-04:00","Scope": "local","Driver": "bridge","EnableIPv6": false,"IPAM": {"Driver": "default","Options": {},"Config": [{"Subnet": "192.168.0.0/16","Gateway": "192.168.0.1"}]},"Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"ConfigOnly": false,"Containers": {"18c523b7a4f04e706175d72a7850339b442d6f562b492c497c4cd73cbc71bb58": {"Name": "tomcat02","EndpointID": "118c5e9b7ca2191dd31d1c05422845009b357b916e5a6acf42bd1e4333c9e747","MacAddress": "02:42:c0:a8:00:02","IPv4Address": "192.168.0.2/16","IPv6Address": ""},"59a7491cc124402428b25954528090316d16cbc2b8936b96478447f69be8ff29": {"Name": "tomcat03","EndpointID": "b00fcc708a073466f0844d7aaf308dafdee3c0d78f022a60a3ee69ef501ce249","MacAddress": "02:42:c0:a8:00:03","IPv4Address": "192.168.0.3/16","IPv6Address": ""}},"Options": {},"Labels": {}}
]# 再次测试ping连接
[root@docker ~]# docker exec -it tomcat02 ping tomcat03
PING tomcat03 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat03.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.173 ms
64 bytes from tomcat03.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.070 ms
^C
--- tomcat03 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1ms
rtt min/avg/max/mdev = 0.070/0.121/0.173/0.052 ms#现在不使用--link也可以ping名字了!
[root@docker ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat02.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.063 ms
64 bytes from tomcat02.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.067 ms
64 bytes from tomcat02.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.073 ms
^C
--- tomcat02 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2ms
rtt min/avg/max/mdev = 0.063/0.067/0.073/0.010 ms

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

好处:不同的集群使用不同的网络,保证集群是安全和健康的

网络连通

# 测试打通 tomcat01 - mynet    容器和网络来打通
[root@docker ~]# docker network connect mynet tomcat01# 连通之后就是将 tomcat01 放到了mynet网络下!# 一个容器两个ip地址!
# 阿里云服务: 公网ip        私网ip


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

实战:部署Redis集群

# 创建网卡
docker network create redis --subnet 172.38.0.0/16# 通过脚本创建六个redis配置
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
donedocker run -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --network redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

SpringBoot微服务打包Docker镜像

  1. 构建SpringBoot项目

  2. 打包install

  3. 编写Dockerfile文件

    FROM java:8MAINTAINER jacky(dapeng@163.com)COPY *.jar /app.jarCMD ["--server.port=8080"]EXPOSE 8080CMD ["java","-jar","app.jar"]
    
  4. 构建镜像(上传jar包和Dockerfile文件后)

    docker build -t jacky-springboot .
    
  5. 发布运行

docker run -d --name springboot-web -p 3300:8080 jacky-springboot# 测试访问
curl localhost:3300 --返回404页面curl localhost:3300/hello --访问hello接口,返回字符串

Docker概述及使用相关推荐

  1. 【1】Docker概述

    Docker概述 关键词 docker 是一个开源的应用容器引擎,是一个软件 打包应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的 Linux 机器上 容器性能开销极低 docker基 ...

  2. Docker学习篇(一)Docker概述、安装和常用命令

    Docker概述 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化.容器是完 ...

  3. Docker概述与基本使用

    Docker概述 一.介绍 1.1.Docker 介绍: Docker 是一个开源的应用容器引擎,基于 Go 语言并遵从Apache2.0协议开源,可以轻松的为任何应用创建一个轻量级的.可移植的.自给 ...

  4. Docker概述、安装及基础命令

    Docker概述.安装及基础命令 一.Docker概述 1. docker是什么 2. docker与虚拟机的区别 3. docker使用场景 4. docker核心概念 5. docker引擎 6. ...

  5. Docker概述(二)(标贝科技)

    标贝科技 https://ai.data-baker.com/#/?source=qwer12 填写邀请码fwwqgs,每日免费调用量还可以翻倍 Docker概述(二) 文章目录 Docker概述(二 ...

  6. 【docker】docker概述及基础入门

    docker概述及基础入门 前言: docker是近年来非常火的一个容器化技术,相比传统的vmware虚拟化技术有着非常大的优势,(vm:小伙子你不讲武德),对于开发人员.测试人员.运维人员,再往上走 ...

  7. Docker概述和安装部署

    概述 Docker产生的背景 一款产品从开发到上线,从操作系统,到运行环境,再到应用配置.作为开发+运维之间的协作我们需要关心很多东西,这也是很多互联网公司都不得不面对的问题,特别是各种版本的迭代之后 ...

  8. 搭建Docker环境---Docker概述

    Docker 包括三个基本概念: 镜像(Image) 容器(Container) 仓库(Repository) 这三部分组成了Docker的整个生命周期,如下图所示,容器是由镜像实例化而来的,这和我们 ...

  9. Docker之Docker概述

    Docker容器虚拟化平台 1. Docker 的概念 1.1 Docker 为什么会出现? 1.3 Docker 的作用 1.2 Docker 的历史 2. Docker 容器技术与虚拟机的区别 3 ...

最新文章

  1. linux 启动nacos报错_nacos在Linux上的搭建启动报错
  2. 3G手机Android应用开发视频教程_黎活明老师的视频(第三天课程)总共有八天课程...
  3. (17)System Verilog禁止类中所有变量随机属性
  4. 莫比乌斯反演习题总结
  5. java 全角半角符号转换_java 字符串全角半角转换
  6. 计算机的排除故障的方法,计算机产生故障的原因和排除故障的方法
  7. LINUX下Android NDK下载并配置
  8. 关于在IDEA中Tomcat乱码的解决办法
  9. 基于matlab的谐波处理及无功功率补偿源码,谐波抑制和无功功率补偿(第3版) pdf epub mobi txt 下载...
  10. Microsoft Office Word一打开文档就弹出样式小窗口
  11. IP 点分十进制表示法
  12. NS3使用Eclipse配置
  13. MathType批量修改公式字体和大小
  14. Unity Shader 学习笔记(33) 全局光照(GI)、反射探针、线性空间和伽马空间、高动态范围(HDR)
  15. 新入职如何快速的熟悉项目
  16. 小程序源码:修复登录接口仿抽奖助手-多玩法安装简单
  17. mysql zombodb_zombodb安装试用
  18. word两幅图并排并且插入题注不会乱
  19. 搜狗音乐盒1.2单文件
  20. java中workFlowEvent_关于WorkFlow的使用以及例子

热门文章

  1. 2021-02-24 Multisim 14.0 场效应管单按键开关电路
  2. Stream流的具体使用讲解
  3. 机器人运动学仿真笔记
  4. fixture 'xxx' not found
  5. Lua 错误之 attempt to index a function value
  6. 流媒体服务器(17)—— 流媒体开源服务 MediaSoup 初识
  7. 完美玩机 三星I9000解锁工具实测教程
  8. mgetnx redis_Redis几乎所有命令都在这了,还说你不会?
  9. 阿里云网盘内测申请表,阿里网盘内测资格申请
  10. 数据库课程设计--淘宝购物订单系统