参考

【狂神说Java】Docker最新超详细版教程通俗易懂
Docker 启动报错

前言

记录下笔记, 之后好复习

Docker安装

Docker的基本组成

镜像(image):

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

容器(container):

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

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

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

仓库(repository):

仓库就是存放镜像的地方

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

Docker Hub(默认是国外的)

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

Docker安装

官方文档链接

# 1.卸载旧版本
sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine# 2.需要的安装包
sudo yum install -y yum-utils# 3.设置镜像仓库
sudo yum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.repo # 默认从国外, 很慢sudo yum-config-manager \--add-repo \http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 推荐阿里云# 4.更新yum软件索引 (optional)
sudo yum makecache fast # centos7
sudo yum makecache # centos8
# centos 7 没问题, centos 8 j会报错# 5. 安装docker引擎 docker-ce 社区版本 ee 企业版
#                  核心        客户端        容器
sudo yum install docker-ce docker-ce-cli containerd.io# 6. 查看docker版本

# 7. 启动docker
sudo systemctl start docker# 8. 验证docker engine是否安装成功
sudo docker run hello-world# 9. 查看下载的hello-world镜像
sudo docker images

Docker 卸载

# 1. 卸载安装包
sudo yum remove docker-ce docker-ce-cli containerd.io# 2. 卸载资源sudo rm -rf /var/lib/docker     # docker的默认工作路径sudo rm -rf /var/lib/containerd

配置阿里云镜像加速

  1. 找到阿里云加速地址

  2. 配置使用

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

回顾Hello-world流程

底层原理

Docker是什么工作的?

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

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

Docker为什么比VM快?

  1. Docker 有着比虚拟机更少的抽象层
  2. Docker 利用的是宿主机的内核, VM需要Guest OS

Docker的常用命令

帮助命令

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

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

镜像命令

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

[root@zb zhoubin]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED      SIZE
hello-world   latest    feb5d9fea6a5   3 days ago   13.3kB# 解释
REPOSITORY  镜像的仓库源
TAG         镜像的标签
IMAGE ID    镜像的id
CREATED     镜像的创建时间
SIZE        镜像的大小# 可选项-a, --all             Show all images (default hides intermediate images)--digests         Show digests-f, --filter filter   Filter output based on conditions provided--format string   Pretty-print images using a Go template--no-trunc        Don't truncate output-q, --quiet           # 只显示镜像的id

docker search 搜索镜像

[root@zb zhoubin]# docker search mysql
NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                             MySQL is a widely used, open-source relation…   11473     [OK]
mariadb                           MariaDB Server is a high performing open sou…   4356      [OK]     # 可选项-f, --filter filter   Filter output based on conditions provided--format string   Pretty-print search using a Go template--limit int       Max number of search results (default 25)--no-trunc        Don't truncate output# 例子docker search mysql -f=STARS=3000   # 搜索星星大于3000

docker pull 下载镜像

# 下载镜像 docker pull 镜像名[:tag]
[root@zb zhoubin]# docker pull mysql
Using default tag: latest # 如果不写tag, 默认就是latest
latest: Pulling from library/mysql
a330b6cecb98: Pull complete     # 分层下载, docker image的核心 联合文件系统
9c8f656c32b8: Pull complete
88e473c3f553: Pull complete
062463ea5d2f: Pull complete
daf7e3bdf4b6: Pull complete
1839c0b7aac9: Pull complete
cf0a0cfee6d0: Pull complete
1b42041bb11e: Pull complete
10459d86c7e6: Pull complete
b7199599d5f9: Pull complete
1d6f51e17d45: Pull complete
50e0789bacad: Pull complete
Digest: sha256:99e0989e7e3797cfbdb8d51a19d32c8d286dd8862794d01a547651a896bcf00c # 签名 防伪标志
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest  # 真实地址# 两个等价
docker pull mysql
docker pull docker.io/library/mysql:latest# 下载版本的镜像
docker pull mysql:5.7


docker rmi 删除镜像

[root@zb zhoubin]# docker rmi -f 镜像id   # 删除指定的镜像
[root@zb zhoubin]# docker rmi -f 镜像id 镜像id 镜像id 镜像id   # 删除多个镜像
[root@zb zhoubin]# docker rmi -f $(docker images -aq)  # 删除全部的镜像# 可选的-f, --force      Force removal of the image--no-prune   Do not delete untagged parents

容器命令

有了镜像才可以创建容器, 下载一个centos镜像来测试学习

docker pull centos

docker run 新建容器并启动

docker run [可选参数] image# 可选的
--name="Name"    容器名字, 用来区分容器
-d              后台方式运行
-it             使用交互方式运行, 进入容器查看内容
-p              指定容器的端口 -p 8080:8080-p ip:主机端口:容器端口-p 主机端口:容器端口(常用)-p 容器端口容器端口
-P              随机指定端口# 例子
# 启动并进入容器
[root@zb zhoubin]# docker run -it centos /bin/bash
[root@af490be56050 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var# 从容器中退出
[root@af490be56050 /]# exit
exit
[root@zb /]# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  zhoubin

docker ps 列出所有运行的容器

[root@zb /]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@zb /]# docker ps -a
CONTAINER ID   IMAGE          COMMAND       CREATED         STATUS                     PORTS     NAMES
af490be56050   centos         "/bin/bash"   4 minutes ago   Exited (0) 3 minutes ago             infallible_mccarthy
f9456648c272   feb5d9fea6a5   "/hello"      2 hours ago     Exited (0) 2 hours ago               hungry_curran# 可选的-a, --all             Show all containers (default shows just running), 包括历史运行的-f, --filter filter   Filter output based on conditions provided--format string   Pretty-print containers using a Go template-n, --last int        Show n last created containers (includes all states) (default -1)-l, --latest          Show the latest created container (includes all states)--no-trunc        Don't truncate output-q, --quiet           # 只显示容器的编号-s, --size            Display total file sizes

退出容器

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

docker rm 删除容器

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

启动和停止容器的操作

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

常用的其他命令

后台启动容器

# 命令 docker run -d 镜像名
[root@zb /]# docker run -d centos
# 问题docker ps, 发现centos停止了
# 常见的坑: docker 容器使用后台运行, 就必须要有一个前台进程, docker发现没有引用, 会自动停止
# centos 容器启动后, 发现自己没有提供服务, 就会立刻停止

docker logs 查看日志

docker logs [可选参数] 容器# 可选的--details        Show extra details provided to logs-f, --follow         Follow log output--since string   Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)-n, --tail string    Number of lines to show from the end of the logs (default "all")-t, --timestamps     Show timestamps--until string   Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)

docker top 常看容器中进程信息

# 命令 docker top 容器id
[root@zb /]# docker top fdcb4ce7d32c
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                2049439             2049419             0                   17:35               pts/0               00:00:00            /bin/bash

docker inspect 查看镜像的源数据

# 命令 docker inspect 容器id[root@zb /]# docker inspect fdcb4ce7d32c
[{"Id": "fdcb4ce7d32ce6d1c0024b8616b4cb7bd346458b7adf1e4be5364edd5033ee74","Created": "2021-09-27T09:35:55.474260558Z","Path": "/bin/bash","Args": [],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 2049439,"ExitCode": 0,"Error": "","StartedAt": "2021-09-27T09:35:55.740878875Z","FinishedAt": "0001-01-01T00:00:00Z"},"Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6","ResolvConfPath": "/var/lib/docker/containers/fdcb4ce7d32ce6d1c0024b8616b4cb7bd346458b7adf1e4be5364edd5033ee74/resolv.conf","HostnamePath": "/var/lib/docker/containers/fdcb4ce7d32ce6d1c0024b8616b4cb7bd346458b7adf1e4be5364edd5033ee74/hostname","HostsPath": "/var/lib/docker/containers/fdcb4ce7d32ce6d1c0024b8616b4cb7bd346458b7adf1e4be5364edd5033ee74/hosts","LogPath": "/var/lib/docker/containers/fdcb4ce7d32ce6d1c0024b8616b4cb7bd346458b7adf1e4be5364edd5033ee74/fdcb4ce7d32ce6d1c0024b8616b4cb7bd346458b7adf1e4be5364edd5033ee74-json.log","Name": "/cranky_elbakyan","RestartCount": 0,"Driver": "overlay2","Platform": "linux","MountLabel": "","ProcessLabel": "","AppArmorProfile": "","ExecIDs": null,"HostConfig": {"Binds": null,"ContainerIDFile": "","LogConfig": {"Type": "json-file","Config": {}},"NetworkMode": "default","PortBindings": {},"RestartPolicy": {"Name": "no","MaximumRetryCount": 0},"AutoRemove": false,"VolumeDriver": "","VolumesFrom": null,"CapAdd": null,"CapDrop": null,"CgroupnsMode": "host","Dns": [],"DnsOptions": [],"DnsSearch": [],"ExtraHosts": null,"GroupAdd": null,"IpcMode": "private","Cgroup": "","Links": null,"OomScoreAdj": 0,"PidMode": "","Privileged": false,"PublishAllPorts": false,"ReadonlyRootfs": false,"SecurityOpt": null,"UTSMode": "","UsernsMode": "","ShmSize": 67108864,"Runtime": "runc","ConsoleSize": [0,0],"Isolation": "","CpuShares": 0,"Memory": 0,"NanoCpus": 0,"CgroupParent": "","BlkioWeight": 0,"BlkioWeightDevice": [],"BlkioDeviceReadBps": null,"BlkioDeviceWriteBps": null,"BlkioDeviceReadIOps": null,"BlkioDeviceWriteIOps": null,"CpuPeriod": 0,"CpuQuota": 0,"CpuRealtimePeriod": 0,"CpuRealtimeRuntime": 0,"CpusetCpus": "","CpusetMems": "","Devices": [],"DeviceCgroupRules": null,"DeviceRequests": null,"KernelMemory": 0,"KernelMemoryTCP": 0,"MemoryReservation": 0,"MemorySwap": 0,"MemorySwappiness": null,"OomKillDisable": false,"PidsLimit": null,"Ulimits": null,"CpuCount": 0,"CpuPercent": 0,"IOMaximumIOps": 0,"IOMaximumBandwidth": 0,"MaskedPaths": ["/proc/asound","/proc/acpi","/proc/kcore","/proc/keys","/proc/latency_stats","/proc/timer_list","/proc/timer_stats","/proc/sched_debug","/proc/scsi","/sys/firmware"],"ReadonlyPaths": ["/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]},"GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/2546a273abe99c7335fbb03d67f8d380f743d91b6a47647231a4548967e23832-init/diff:/var/lib/docker/overlay2/ae442db66d110d0f4da98712944be8533e5c129299d4378bd8b50157e1715767/diff","MergedDir": "/var/lib/docker/overlay2/2546a273abe99c7335fbb03d67f8d380f743d91b6a47647231a4548967e23832/merged","UpperDir": "/var/lib/docker/overlay2/2546a273abe99c7335fbb03d67f8d380f743d91b6a47647231a4548967e23832/diff","WorkDir": "/var/lib/docker/overlay2/2546a273abe99c7335fbb03d67f8d380f743d91b6a47647231a4548967e23832/work"},"Name": "overlay2"},"Mounts": [],"Config": {"Hostname": "fdcb4ce7d32c","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": "20210915","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": "7949bffe1d061e2cf0ea576114c80fc61f593d9ac8b33cc3b65823af443dc449","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {},"SandboxKey": "/var/run/docker/netns/7949bffe1d06","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "1e0662f10c7915bee627d362cf5ec94a9a460a88ac4d17d7ce856e3fc2c5c94a","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": "aa59f89e5467987caa069f8a0de56691ac5d953cdafb7b842287b0c8b3bc6d1e","EndpointID": "1e0662f10c7915bee627d362cf5ec94a9a460a88ac4d17d7ce856e3fc2c5c94a","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}}}}
]

进入当前正在运行的容器

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

方式1:

# 命令
docker exec -it 容器id bashShell# 例子
[root@zb /]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
fdcb4ce7d32c   centos    "/bin/bash"   11 minutes ago   Up 11 minutes             cranky_elbakyan
[root@zb /]# docker exec -it fdcb4ce7d32c /bin/bash
[root@fdcb4ce7d32c /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@fdcb4ce7d32c /]# ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 09:35 pts/0    00:00:00 /bin/bash
root          15       0  0 09:47 pts/1    00:00:00 /bin/bash
root          30      15  0 09:47 pts/1    00:00:00 ps -ef

方式2:

# 命令
docker attach 容器id
# 例子
[root@zb /]# docker attach fdcb4ce7d32c
正在执行当前的代码...

区别:

docker exec : 进入容器后开启一个新的终端, 可以在里面操作(常用)

docker attach: 进入容器正在执行的终端, 不会启动新的进程

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

#命令 docker cp 容器id:容器内路径 目标主机路径[root@zb home]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
806a97d603e4   centos    "/bin/bash"   3 minutes ago   Up 2 minutes             mystifying_leakey
[root@zb home]# docker exec -it 806a97d603e4 /bin/bash
[root@806a97d603e4 /]# cd /home
[root@806a97d603e4 home]# ls
[root@806a97d603e4 home]# touch text.cpp
[root@806a97d603e4 home]# read escape sequence
[root@zb home]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
806a97d603e4   centos    "/bin/bash"   3 minutes ago   Up 3 minutes             mystifying_leakey
[root@zb home]# ls
test.java
[root@zb home]# docker cp 806a97d603e4:/home/text.cpp /home
[root@zb home]# ls
test.java  text.cpp# 拷贝是一个手动过程, 未来我们使用 -v 卷的技术, 可以实现自动同步

小结

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  # 创建一个新的容器, 同run, 但不启动容器
diff    Inspect changes to files or directories on a container’s filesystem     # 查看docker容器变化
events  Get real time events from the server    # 从docker服务获取容器实时事件
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包中的内容创建一个新的文件系统映像[对应export]
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                                 # 注册或者登陆一个 docker 源服务器
logout  Log out from a Docker registry                              # 从当前的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               # 从docker镜像源服务器拉去指定镜像或者库镜像
push    Push an image or a repository to a registry                 # 推送指定镜像或者库镜像至docker源服务器
rename  Rename a container
restart Restart one or more containers                              # 重启运行容器
rm      Remove one or more containers                               # 移除一个或者多个容器
rmi     Remove one or more images                                   # 移除一个或多个镜像[无容器使用该镜像才可删除, 否则需删除相关容器才可继续或 -f 强制删除]
run     Run a command in a new container                            # 创建一个新的容器并运行一个命令
save    Save one or more images to a tar archive (streamed to STDOUT by default) # 保存一个镜像为一个 tar 包[对应 load]
search  Search the Docker Hub for images                                        # 在 docker hub 中搜索镜像
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                                     # 查看docker 版本号
wait    Block until one or more containers stop, then print their exit codes    # 截取容器停止时的退出状态值

可视化

  • portainer(先用这个)

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

什么是portainer?

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

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

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

Docker镜像讲解

镜像是什么

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

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

如何得到镜像

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

Docker镜像加载原理

UnionFS(联合文件系统)

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

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

Docker镜像加载原理

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

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

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

平时我们安装进虚拟机的CentOS都是好几个G,为什么Docker 这里才200M?

对于一个精简的OS, rootfs可以很小, 只需要包含最基础的命令, 工具和程序库就可以了, 因为底层直接用Host的kernel, 自己只需要提供rootfs就可以了, 由此可见对于不同的linux发行版, bootf基本是一直的, rootfs会有差别, 因为不同的发行版可以公有bootfs

分层理解

分层的镜像

我们可以去下载一个镜像, 可以看到是一层一层的再下载的

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

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

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

[root@zb zhoubin]# docker image inspect redis:latest
[// ....."RootFS": {"Type": "layers","Layers": ["sha256:d000633a56813933cb0ac5ee3246cf7a4c0205db6290018a169d7cb096581046","sha256:bdad86443e47c5665683ac41c1f24f28479d830d7e3cc47d0a337ee5166c7714","sha256:6a7992ac480029d82b7dbb757d16fe5d023aa283ed32b52267cd1fe9e6b73c49","sha256:be43d2475cf809c0f2ec31950e849d0f888f3121970fd99196a11a903f8c3820","sha256:be5818ef2907adfe19be14bf66647b5fb5a2029143f9297f8ce1ff1fd1d35753","sha256:c54e0c16ea22fa873c12f6a7f3fb4e021bb58d67c292156a6ce6e08637458b7c"]},"Metadata": {"LastTagTime": "0001-01-01T00:00:00Z"}}
]

理解:

所有的Docker 镜像都起始于一个基础镜像层, 当进行修改或增加新的内容时, 就会在当前镜像层之上, 创建新的镜像层

举个简单的例子, 例如基于Ubuntu Linux 16.04创建一个新的镜像, 这就是新镜像的第一层, 如果在该镜像中添加Python包, 就会在基础镜像层之上创建第二个镜像层, 如果继续添加一个安全补丁, 就会创建第三个镜像层

该镜像当前已经包含3个镜像层

在添加额外的镜像层的同时, 镜像始终保持是当前所有镜像的组合, 理解这一点非常重要, 下图举了一个简单的例子,每个镜像层包含3个文件, 而镜像包含了两个镜像层的6个文件

上图中的镜像层跟之前图的略有区别, 主要目的是便于展示文件

下图中展示了一个稍微复杂的三层镜像, 在外部看来整个镜像只有6个文件, 这是因为最上层的文件7是文件5的一个更新版本

这种情况下, 上层镜像层中的文件覆盖了底层镜像层的文件, 这样就使得文件的更新八本作为一个新的镜像层添加到镜像当中去

Docker 通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈, 并保证多镜像层对外展示为统一的文件系统

Linux 上可用的存储引擎有AUFS, Overlay2, Device Mapper, Btrfs 以及 ZFS, 顾名思义, 每种存储引擎都基于Linux中对应的文件系统或者块设备技术, 并且每种存储引擎都有其独有的性能特点

Docker在Windows上仅支持windowfilter一种存储引擎, 改引擎基于NTFS文件系统之上实现分层和Cow[1]

下图展示了与系统相同的三层镜像, 所有镜像层堆叠并合并, 对外提供统一的视图

特点

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

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

Commit镜像

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

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

实战测试

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

容器数据卷

什么是容器数据卷

Docker的理念回顾

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

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

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

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

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

总结: 容器的持久化和同步操作, 容器间也可以数据共享

使用数据卷

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

docker run -it -v 主机目录:容器内目录# 测试
[root@zb home]# docker run -it -v /home/test:/home centos /bin/bash# 启动后通过docker inspect 容器id

好处: 之后修改只需要本地修改即可

实战: 安装mysql

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

# 获取镜像
[root@zb test]# docker pull mysql:5.7# 运行容器, 需要做数据挂载 # 安装启动mysql, 需要配置密码
# 官方测试: docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag# 启动mysql
[root@zb test]# 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

具名和匿名挂载

# 匿名挂载
-v 容器内路径
[root@zb data]# docker run -d -P --name nginx01 -v /etc/nginx/ nginx
de24b43780f17972c33f104d377c6fe19c9cdcf5b7a8f4db78f8f0596d76e304# 查看所有的volume 的情况
[root@zb data]# docker volume ls
DRIVER    VOLUME NAME
local     19be477cd4e0b3b2822f7d00e18fd5179198d5e0dcd37354c8d8af26a32cb5b7
local     a4f93cf8eb95af73bd61ac16ec45d0d69d7e240b368bbdd9e1c536d68e6a7aa0# 这种就是匿名挂载, 在-v只写了容器内的路径, 没有写容器外的路径# 具名挂载
[root@zb data]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
35663552faf1b1a7661bb84a854f67c2e2e514d8daab79191f6cd331b13edb2e
[root@zb data]# docker volume ls
DRIVER    VOLUME NAME
local     19be477cd4e0b3b2822f7d00e18fd5179198d5e0dcd37354c8d8af26a32cb5b7
local     a4f93cf8eb95af73bd61ac16ec45d0d69d7e240b368bbdd9e1c536d68e6a7aa0
local     juming-nginx# 通过 -v 卷名:容器内路径
# 查看一下这个卷
[root@zb data]# docker volume inspect juming-nginx
[{"CreatedAt": "2021-09-29T10:01:57+08:00","Driver": "local","Labels": null,"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data","Name": "juming-nginx","Options": null,"Scope": "local"}
]

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

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

# 如何确定是具名挂载还是匿名挂载, 还是指定路径挂载
-v 容器内路径            # 匿名挂载
-v 卷名:容器内路径        # 具名挂载
-v /宿主机路径:容器内路径  # 指定路径挂载

拓展:

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

初识Dockerfile

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

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

# 创建一个dockerfile 文件,建议 Dockerfile
# 文件中的内容 指令(大写) 参数
FROM centos
VOLUME ["volume01", "volume02"]CMD echo "---------end--------"
CMD /bin/bash#这里的每个命令, 就是镜像的一层

这个卷和外部一定有一个同步的目录

查看卷挂载的路径

未来使用的十分多, 通过会构建自己的镜像

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

数据卷容器

多个mysql 同步数据

# 启动3个容器




# 测试, 删除centos01, 查看centos02 和 centos03 是否还可以访问这个文件
# 测试依旧可以访问

多个mysql 实现数据共享

[root@zb test]# 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[root@zb test]# docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 --volumes-from mysql01 mysql:5.7# 实现两个容器数据同步

结论:

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

一旦持久化到了本地, 本地的数据不会删除

DockerFile

Docker构建介绍

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

构建步骤:

  1. 编写一个dockerfile 文件
  2. docker build 构建称为一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(DockerHub, 阿里云镜像仓库)

DockerFile构建过程

基础知识:

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

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

  3. /# 表示注释

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

dockerfile 是面向开发的, 要发布项目, 做镜像

步骤: 开发, 部署, 运营

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

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

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

DockerFile的指令

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

实战测试

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

创建一个自己的centos

# 1.编写Dockerfile的文件
[root@zb docker-file]# cat mydockerfile
FROM centos
MAINTAINER zb<421830611@qq.com>ENV MYPATH /usr/local
WORKDIR $MYPATHRUN yum -y install vim
RUN yum -y install net-toolsEXPOSE 80CMD echo $MYPATH
CMD echo "-----end---"
CMD /bin/bash# 2. 通过这个文件构建镜像
# 命令 docker build -f dockerfile文件路径 -t 镜像名:[tag] .
[root@zb docker-file]# docker build -f mydockerfile -t mycentos:0.1 .# 3. 测试运行

对比: 之前的原生的centos

我们增加之后的景象

可以列出本地进行的变更历史

CMD 和 ENTRYPOINT 区别

ENTRYPOINT   # 指定这个容器启动的时候要运行的名利, 可以追加命令
COPY        # 类似ADD, 将我们文件拷贝到镜像中

测试cmd

# 编写dockerfile 文件
[root@zb docker-file]# vim dockerfile-cmd-test
FROM centos
CMD ["ls", "-a"]# 构建镜像
[root@zb docker-file]# docker build -f dockerfile-cmd-test -t cmdtest .# run运行, 发现ls -a 命令生效
[root@zb docker-file]# docker run 04f016b4925e
.
..
.dockerenv
bin# 想追加一个命令 -l,想要有la -al效果
[root@zb docker-file]# docker run 04f016b4925e -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled # cmd的清理下 -l 替换了 CMD["ls", "-a"]命令, -l 不是命令, 报错

测试 ENTRYPOINT

# 编写dockerfile 文件
[root@zb docker-file]# vim dockefile-cmd-entrypoint
FROM centos
ENTRYPOINT ["ls", "-a"]# 构建镜像
[root@zb docker-file]# docker build -f dockefile-cmd-entrypoint -t entorypoint-test .
Sending build context to Docker daemon  4.096kB
Step 1/2 : FROM centos---> 5d0da3dc9764
Step 2/2 : ENTRYPOINT ["ls", "-a"]---> Running in ba2c39e2bfe3
Removing intermediate container ba2c39e2bfe3---> 488df2cac5a4
Successfully built 488df2cac5a4
Successfully tagged entorypoint-test:latest[root@zb docker-file]# docker run 488df2cac5a4
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var# 追加命令是直接拼接在ENTRYPOINT后面的
[root@zb docker-file]# docker run 488df2cac5a4 -l
total 0
drwxr-xr-x   1 root root   6 Sep 29 07:19 .
drwxr-xr-x   1 root root   6 Sep 29 07:19 ..
-rwxr-xr-x   1 root root   0 Sep 29 07:19 .dockerenv
lrwxrwxrwx   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root 340 Sep 29 07:19 dev
drwxr-xr-x   1 root root  66 Sep 29 07:19 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 Sep 15 14:17 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 147 root root   0 Sep 29 07:19 proc
dr-xr-x---   2 root root 162 Sep 15 14:17 root
drwxr-xr-x  11 root root 163 Sep 15 14:17 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 Sep 29 07:19 sys
drwxrwxrwt   7 root root 171 Sep 15 14:17 tmp
drwxr-xr-x  12 root root 144 Sep 15 14:17 usr
drwxr-xr-x  20 root root 262 Sep 15 14:17 var

实战: tomcat 镜像

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

  2. 编写dockerfile 文件, 官方命名Dockerfile , build 会自动寻找这个文件, 不需要-f 指定

    MAINTAINET zb<421830611@qq.com>COPY readme.txt /usr/local/readme.txt
    ADD jdk-8u11-linux-x64.tar.gz /usr/local/
    ADD apache-tomcat-9.0.22.tar.gz /usr/local/RUN yum -y install 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 CATLINA_HOME /usr/local/apache-tomcat-9.0.22
    ENV CATLINA_PASH /usr/local/apache-tomcat-9.0.22
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/binEXPOSE 8080CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/logs/catalina.out
  3. 构建镜像

    # docker build -t zbtomcat .
    
  4. 启动镜像

    [root@zb tomcat]# docker run -it -p 9090:8080 --name zbtomcat -v /tmp/tomcat/test:/usr/local/apache-tomcat-9.0.22/webapps/test -v /tmp/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.22/logs zbtomcat
    
  5. 访问测试

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

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    </web-app>
    
    <%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>hello</title>
    </head>
    <body>
    Hello World!<br/>
    <%
    System.out.println("------my test web logs -----");
    %></body>
    </html>
    

发布自己的镜像

DockerHub

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

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

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

    [root@zb zhoubin]# docker login --helpUsage:  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[root@zb zhoubin]# docker login -u zzbbzb
    Password:
    WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded
    
  4. 登录完毕后就可以提交镜像, 就是一步docker push

    # push 自己的镜像到服务器上
    [root@zb zhoubin]# docker push zbtomcat
    Using default tag: latest
    The push refers to repository [docker.io/library/zbtomcat]
    606a9fcc1aa2: Preparing
    2580ff04a607: Preparing
    255d8e8398a5: Preparing
    e7d27dc20f3e: Preparing
    74ddd0ec08fa: Preparing
    denied: requested access to the resource is denied # 拒绝# 镜像问题?
    [root@zb zhoubin]# docker push zb/zbtomcat:1.0
    The push refers to repository [docker.io/zb/zbtomcat]
    An image does not exist locally with the tag: zb/zbtomcat# 处理, 增加tag, tag 要用户名/镜像名:tag
    [root@zb tomcat]# docker tag a42188e7ed03 zzbbzb/zbtomcat:1.0
    [root@zb tomcat]# docker images
    REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
    zbtomcat              latest    a42188e7ed03   2 minutes ago   643MB
    zzbbzb/zbtomcat       1.0       a42188e7ed03   2 minutes ago   643MB
    entorypoint-test      latest    488df2cac5a4   31 hours ago    231MB
    cmdtest               latest    04f016b4925e   31 hours ago    231MB
    mycentos              0.1       c14351513f8f   32 hours ago    336MB
    zb/centos             1.0       85db2884db4a   36 hours ago    231MB
    tomcat_zb             1.0       56ec5de67d3c   2 days ago      684MB
    mysql                 5.7       9f35042c6a98   2 days ago      448MB
    centos                latest    5d0da3dc9764   2 weeks ago     231MB
    tomcat                9.0       62146f8bda84   2 weeks ago     680MB
    tomcat                latest    bb832de23021   2 weeks ago     680MB
    nginx                 latest    ad4c705f24d3   2 weeks ago     133MB
    redis                 latest    02c7f2054405   3 weeks ago     105MB
    portainer/portainer   latest    580c0e4e98b0   6 months ago    79.1MB# docker push 上去
    [root@zb tomcat]# docker push zzbbzb/zbtomcat:1.0
    The push refers to repository [docker.io/zzbbzb/zbtomcat]
    d2d29553047a: Pushing [=>                                                 ]   1.66MB/72.56MB
    beb0f6e2950e: Pushing [====>                                              ]  1.361MB/15.41MB
    1c2f3be1f20c: Pushing [>                                                  ]  1.594MB/324MB
    4b5e8fca88ed: Pushed
    74ddd0ec08fa: Pushing [>                                                  ]  2.196MB/231.3MB

阿里云镜像上

  1. 登录阿里云

  2. 找到容器镜像服务

  3. 创建命名空间

  4. 创建容器镜像

  5. 浏览阿里云文档

小结

Docker 网络(铺垫 容器编排 集群部署)

理解Docker0

清空所有images和容器

测试

三个网络

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

# [root@zb /]# docker run -d -P --name tomcat01 tomcat# 查看容器内部网络地址 ip addr, 发现容器启动的时候会得到一个  eth0@if116 ip地址, docker分配的
[root@zb tomcat]# 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
115: eth0@if116: <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通 容器内部
[root@zb tomcat]# 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.084 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.039 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.047 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.044 ms# linux可以ping通docker容器内部

原理

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

再次测试ip addr

  1. 再启动一个测试, 发现又多了一个网卡
# 我们发现这个容器带来的网卡, 都是一对对的
# veth-pair 就是一对的虚拟设备接口, 都是成对出现的, 一段连着协议, 一段彼此相连
# 有这个特性, veth-pair 充当一个桥梁,链接各种虚拟网络设备
# OpenStac, Docker 容器之间的链接, ovs的链接, 都是使用 veth-pair技术
  1. 测试tomcat01 和 tomcat02 是否可以ping通

    [root@zb tomcat]# docker exec -it tomcat02 ping 172.17.0.1
    PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
    64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.075 ms
    64 bytes from 172.17.0.1: icmp_seq=2 ttl=64 time=0.051 ms# 结论: 容器和容器之间是可以互相ping通
    

绘制一个网络模型图:

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

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

小结

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

Docker中的所有的网络接口都是虚拟的, 虚拟的转发效率高

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

–link

思考一个场景, 项目不重启, 数据库ip换掉了, 可以通过名字来访问容器

[root@zb tomcat]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known# 如何解决
# 通过--link可以解决了网络连通问题
[root@zb tomcat]# docker run -d -P --name tomcat03 --link tomcat02  mytomcat
a513374a099c59c789df5c3a5cd2c65a4a3558ff0b4e2fc93ce02ed5bf9f9ce5
[root@zb tomcat]# 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.076 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.071 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.076 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=4 ttl=64 time=0.057 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=5 ttl=64 time=0.045 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=6 ttl=64 time=0.057 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=7 ttl=64 time=0.055 ms
--- tomcat02 ping statistics ---
7 packets transmitted, 7 received, 0% packet loss, time 6121ms
rtt min/avg/max/mdev = 0.045/0.062/0.076/0.013 ms# 方向可以ping通嘛
[root@zb tomcat]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known

探究: inspect

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

# 查看host配置
[root@zb tomcat]# 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 94488e4e8bb6
172.17.0.4      a513374a099c

本质探究: --link 就是在hosts配置中增加了172.17.0.3 tomcat02 94488e4e8bb6

现在玩Docker 不建议的–link

自定义网络, 不使用docker0

docker0问题: 不支持容器名链接访问

自定义网络

查看所有的docker 网络

网络模式

bridge: 桥接模式 docker0 搭桥(默认, 自己创建也适用birdge模式)

none: 不配置网络

host: 和宿主机共享网络

container: 容器网络连通(用的少)

测试

# 我们直接启动的命令 --net bridge, 这个就是我们的docker0
docker run -d -P --name tomcat01 mytomcat
docker run -d -P --name tomcat01 --net bridge mytomcat# docker0特点: 默认域名不能访问, --link 可以打通连接
# 自定义一个网络
# --driver bridge
# --subnet 192.168.0.0/16 192.168.0.2 192.168.255.255
# --gateway 192.168.0.1
[root@zb tomcat]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
84219c18de814d86d92b12f51a3c5df4786ee92531c7c26f0516574c8e002648
[root@zb tomcat]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
609a25ab1e11   bridge    bridge    local
d0a1cdd793b6   host      host      local
84219c18de81   mynet     bridge    local

自己的网络就创建好了

[root@zb tomcat]# docker network inspect mynet
[{"Name": "mynet","Id": "84219c18de814d86d92b12f51a3c5df4786ee92531c7c26f0516574c8e002648","Created": "2021-10-01T19:49:51.739326047+08: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": {"88451c50139b7134879879aba1c29fc10c52b5aaa2828bc8050591375e9a7a17": {"Name": "tomcat_net_02","EndpointID": "5ef468aca35753f6ed899e817adbe1ccd6cc1376224208028f77585ef2ec09aa","MacAddress": "02:42:c0:a8:00:03","IPv4Address": "192.168.0.3/16","IPv6Address": ""},"9caf86f431f3fa336f5da303c4c6d2ae48d579b779457f8b282d1d5abbaa459b": {"Name": "tomcat_net_01","EndpointID": "8b55ac78dd05ee2832932a3fe512985c33545c665016d12db102bace6ac6f964","MacAddress": "02:42:c0:a8:00:02","IPv4Address": "192.168.0.2/16","IPv6Address": ""}},"Options": {},"Labels": {}# 再次测试ping链接
[root@zb tomcat]# docker exec -it tomcat_net_01 ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.107 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.072 ms
--- 192.168.0.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1041ms
rtt min/avg/max/mdev = 0.072/0.089/0.107/0.019 ms# 现在不使用--link 也可以ping名字
[root@zb tomcat]# docker exec -it tomcat_net_01 ping tomcat_net_02
PING tomcat_net_02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat_net_02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.050 ms
64 bytes from tomcat_net_02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.059 ms
64 bytes from tomcat_net_02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.064 ms
--- tomcat_net_02 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2037ms
rtt min/avg/max/mdev = 0.050/0.057/0.064/0.010 ms

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

好处:

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

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

网络连通


# 测试打通 tomcat01 - mynet
[root@zb tomcat]# docker network connect mynet tomcat01# 连通之后就是将tomcat01 放到了mynet网络下
# 一个容器两个ip地址
# 类似于阿里云一个公网, 一个私网

# 01链接ok
[root@zb tomcat]# docker exec -it tomcat01 ping tomcat_net_01
PING tomcat_net_01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat_net_01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from tomcat_net_01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.052 ms# 02 是依旧打不通的
[root@zb tomcat]# docker exec -it tomcat02 ping tomcat_net_01
ping: tomcat_net_01: Name or service not known

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

作业

Docker 安装 Nginx

# 1. 搜索镜像
[root@zb home]# docker search nginx
# 2. 下载镜像
[root@zb home]# docker pull nginx
# 3. 运行测试
[root@zb home]# docker run -d --name nginx01 -p 3389:80 nginx
[root@zb home]# curl localhost:3389

端口暴露的概念

Docker 安装tomacat

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

部署es + kibana

# es 暴露的端口很多
# es 十分的耗内存
# es 的数据一般需要放置到安全目录, 挂载# 启动 elasticsearch
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2# 启动linux就很卡 docker stats查看 cpu的状态# 增加内存限制, 修改配置文件 -e 环境配置修改
docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2

使用kinana连接es? 思考网络如果才能连接过去

Docker 基础入门相关推荐

  1. Docker基础入门(基本命令)

    Docker基础入门(基本命令) 一.Docker概述 1.Docker为什么会出现? 一款产品: 开发–上线 两套环境!应用环境,应用配置! 开发 - 运维. 问题:我在我的电脑上可以允许!版本更新 ...

  2. Docker基础入门及示例

    Docker近几年的发展可谓一日千里,特别从是2013年随着一个基于LXC的高级容器引擎开源,到现在,其在linux和windows上都有了很好的支持,并且已经有很多公司将docker用于实际的生产环 ...

  3. Docker基础入门详解

    一.产生背景 在传统软件开发流程中,研发程序员将功能代码研发完成后,交由测试人员进行测试,最后通过运维人员部署上线.但是在这个过程中,常常因为环境问题.配置问题.软件版本问题等等诸多因素,造成一些问题 ...

  4. 老男孩Docker基础入门培训视频Docker核心原理解(完整版)

    课程介绍: Dokcer比较初级的培训视频教程,很适合零基础的朋友们来学习,没有复杂的原理,初入门推荐的Docker培训视频 课程目录: L021-01-Docker介绍.avi L021-02-Do ...

  5. docker基础入门和docker compose实战

    Docker运维部署 docker官网:https://www.docker.com/ 文档:https://docs.docker.com/ Docker的文档是超级详细的! 仓库:https:// ...

  6. Docker 基础入门篇(上)

    为什么需要docker 主流虚拟化技术分析 Docker的安装与部署 Docker的完整架构图 1.为什么需要docker 系统运行环境变更,软件版本升级,操作系统不一致等等问题都会导致本来一个很简单 ...

  7. Docker基础入门总结

    一.什么是Docker 官方文档描述:"Docker is an open platform for developing, shipping, and running applicatio ...

  8. Docker基础入门getting started

    系列文章目录 Docker 概述 Docker getting started 文章目录 系列文章目录 前言 一.容器及镜像的概念 二.容器化一个应用 三.更新应用 四.分享应用 五.持久化数据存储 ...

  9. docker基础入门一:docker安装镜像下载根据镜像创建容器

    一.安装准备: #卸载旧的版本: yum list installed |grep docker yum -y remove  ... #卸载后将保留/var/lib/docker的内容(镜像.容器等 ...

最新文章

  1. tar常见文件解压法
  2. asp.net中使用窗体身份验证
  3. 在redhat9上安装firefox
  4. 打开黑色_表哥出差带回来一箱苹果,打开后发现是黑色的,大家表示都没见过...
  5. 在Linux虚拟机中添加多个ip地址
  6. 使用Storm实现实时大数据分析!
  7. js 匿名函数_编写高质量箭头函数的5个最佳做法
  8. 用c语言输出1 n平方自然数魔方阵,用C语言求:打印出由1到n平方的自然数的魔方阵...
  9. MCGS 无限配方数据存储及U盘导入导出-第二集
  10. .net 反编译_向.net/Unity 程序员推荐一个十分因吹斯听的网站:sharplab.io
  11. webpack常用知识点
  12. linux知识点查阅
  13. 纪念贴:历史会证明今天是不是开创新历史的一天
  14. 【人脸表情识别】基于matlab GUI LBP+SVM脸部动态特征人脸表情识别【含Matlab源码 1369期】
  15. ai人工智能的数据服务_可解释的AI-它对数据科学家有何影响?
  16. matlab 梁代码,方舟生存进化梁龙鞍怎么做 梁龙鞍代码材料一览
  17. sharepoint如何解锁被用户锁定的文件?
  18. 东南大学计算机学院保研比例,江苏省高校保研率排行榜,南京大学第1,保研率超过1/3...
  19. 【JZOJ 5421】【NOIP2017提高A组集训10.25】嘟嘟噜
  20. ios越狱python插件_人生苦短,我用Python – 越狱后如何在IOS设备上玩Python编程,2018-07-11 – 算法网...

热门文章

  1. 跨境卖家必看系列:沃尔玛美国站入驻教程
  2. 如何查看和修改Windows远程桌面端口
  3. vs2013 下配置OpenGL(超级宝典第五版)开发环境
  4. 春秋云镜-Time-Writeup
  5. UNIX系统实现中的限制
  6. 勒索病毒频发下如何防勒索病毒
  7. 网络攻防实战--ARP欺骗
  8. 超强1000个jquery极品插件(。。)
  9. Ubuntu 16.04/18.04 安装和使用QQ和微信最简洁的方式(2019.10.28更新)
  10. OpenWrt内核模块开发(六)-通过linux netfilter框架实现mac地址过滤