menu 冷 の Codeworld
search self_improvement
目录

Docker 快速入门

冷环渊
冷环渊 2022年04月03日  ·  阅读 433

Docker

Docker

docker是什么,docker的用处,以前是必须会spring,现在高级的工程师需要掌握docker

如何学习docker

  • Docker概述
  • docker安装
  • docker命令
    • 镜像命令
    • 容器命令
    • 操作命令
    • 等等
  • docker镜像
  • 容器数据卷
  • dockerfile
  • docker网络原理
  • docker整合idea
  • docker compose
  • docker swarm
  • DI/CD jenkins

知道的越多,不知道的越多

docker概述

docker为什么出现?

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

开发 和 运维 问题:在我的电脑上可以运行,版本更新,导致服务不可用!对于运维来说,考验十分的大

开发即是运维的情况下更是如此,每一个机器都要部署环境,浪费时间和人力,容器化,项目带着环境来打包,配置很麻烦,也有部分不能跨平台比如开发win,打包到linux

传统思想 : 开发jar 运维来做

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

为什么docker厉害?

java --apk --发布 --- 张三使用 apk --- 安装即可用!

java ---jar ---打包项目带上环境(镜像) --- (docker仓库镜像)--下载开发人员上传的镜像 -- 直接就可以运行

docker根据以上的问题给出了解决方案

docker的思想来自于集装箱

image-20211006142006627

JRE - -多个应用---原来是交叉的

docker的核心思想 : 隔离,打包装箱,每个箱子都是互相隔离的

Docker通过隔离机制,让服务器更好的发挥

本质 : 所有的技术都是出现了问题,我们需要去解决

Docker的历史和作用

2010,几个搞it的年轻人,最开始的时候并不叫 Docker dotcloud

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

他们将自己的技术(容器化技术)同一的命名为 Docker

应为刚诞生所以没什么基础,于是乎领导人们选择了将Docker的源码开放

开源之后的Docker一瞬间就火了

为什么Docker火起来了,应为相比虚拟机,Docker要更加的轻量

虚拟机 :

​ 一般都是再win中安装Vmware 通过这个技术我们可以虚拟出来一台电脑或者是多台电脑,但是占用过大,随便一个镜像就是十几个g,十分的笨重

image-20211006143537787

虚拟机技术的缺点:

  1. 资源占用十分多
  2. 开机关机需要时间
  3. 运行完整的操作系统,还要安装运行软件

Docker :

​ 相比之下Docker就显得格外的小巧。隔离,镜像(核心的环境4m+jdk+mysql)需要的时候我们只需要去运行镜像就可以了,大大提升了灵活性

image-20211006143627502

Docker技术 :

  1. 运行在操作系统之上,容器没有内核,也不用虚拟硬件
  2. 每个容器是互相隔离的,又属于自己的文件系统,不会互相的影响

了解了Docker的作用,可以知道我们程序员掌握Docker是十分的必要的

社区文档

Docker的社区文档是十分的详细的

文档连接 : https://docs.docker.com/

image-20211006143117018

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

DevOps(开发和运维)

他的宗旨是什么

应用更快速的交付和部署

  • 传统 : 一堆帮助文档,安装程序
  • Docker:打包镜像发布测试,一键运行

更便捷的升级和扩容

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

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

更简单的系统运维

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

更高效的计算资源利用

Docker是内核级别的虚拟化,可以在一个物理机上运行很多的容器实例

Docker安装

Docker的组成结构

查看源图像

镜像:

Docker的镜像就像是一个模板,可以荣国这个模板来创建容器服务

例子:

tomcat ====》run ===》tomcat01容器(提供服务)

我们可以同过镜像创建多个容器(最终服务运行或者是项目运行都是在容器中的)

容器:

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

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

目前我们可以把容器理解为一个建议的linux系统,项目都是跑在系统上的

仓库:

仓库就是存放镜像的地方

有私有的有共有的

DockerHub

阿里云等等厂商都有镜像服务

安装Docker

环境准备

  1. 需要会一点点linx的基础
  2. linux : CentOS7
  3. 使用连接工具连接服务器操作

确认系统环境

[root@iZwz90ps06ioyada63oiwiZ ~]# uname -r
3.10.0-957.21.3.el7.x86_64

[root@iZwz90ps06ioyada63oiwiZ ~]# cat /etc/os-release 
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

官方文档可以看到要求:

image-20211006145800662

我们如果是用的linxu系统是 CentOS 那么必须是 7 版本以上才支持的

如果安装装过的话,建议删除之前的旧版本的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 \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

#4 安装docker相关的内容
 yum install docker-ce docker-ce-cli containerd.io
 
#5 安装之后测试是否安装成功
systemctl start docker

#6查看docker的版本号
docker version

之后查看我们docker的版本即可

image-20211006150606651

#7 运行docker的helloword
docker run hello-world

image-20211006150917425

# 8 如何查看docker下载的镜像呢?
docker images
# 就可以查看docker下载的位置了

image-20211006150957136

了解 如何卸载docker

#1 卸载docker的相关内容
yum remove docker-ce docker-ce-cli containerd.io
#2 卸载docker的和我们下载容器
 sudo rm -rf /var/lib/docker
 sudo rm -rf /var/lib/containerd
# /var/lib/docker 是 docker的默认工作路径

提升效率

阿里云的容器加速

  1. 登录阿里云找到容器服务

    image-20211006151353748

  2. 找到镜像加速地址

    image-20211006151407490

  3. 配置使用

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

回顾hello world 的完整过程

image-20211006163940871

run 的过程分析图

image-20211006163925489

底层原理

docker是做什么工作的?

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

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

image-20211006164315668

Docker为什么比虚拟机快

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

    image-20211006164353290

  2. Docker利用的是主机的内核,vm需要的是Guset OS

  3. 所以说新建一个容器的时候,docker不需要想虚拟机一样重新加一个操作系统的内核,避免引导,

  4. 虚拟机是加载 Guest OS 分钟级别的,

  5. 而docker是利用主机的操作系统,省略了这个复杂的加载过程,秒级别

image-20211006164648744

现在的docker是都支持的

不只支持 linux,Mac OS, windows都支持

之后又docker的使用经验之后我们回过头来再看理论,就会理解的很清晰了

Docker的常用命令

帮助命令

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

帮助文档的地址 :

https://docs.docker.com/engine/reference/run/

镜像命令

Docker imeages #查看所有本地的主机上有的镜像

[root@iZwz90ps06ioyada63oiwiZ ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
hello-world   latest    feb5d9fea6a5   12 days ago   13.3kB

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

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

Docker pull 下载

#下载内容 ,默认的tag 是 latest
#可以按照版本号 ,也可以直接用mysql下载版本
[root@iZwz90ps06ioyada63oiwiZ ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
07aded7c29c6: Already exists  #分段的下载,联合文件系统,不用重复下载,可以共用重复的部分
f68b8cbd22de: Already exists 
30c1754a28c4: Already exists 
1b7cb4d6fe05: Already exists 
79a41dc56b9a: Already exists 
00a75e3842fb: Already exists 
b36a6919c217: Already exists 
5e11fe494f45: Pull complete 
9c7de1f889a7: Pull complete 
cf6a13d05a76: Pull complete 
fc5aa81f393a: Pull complete 
Digest: sha256:360c7488c2b5d112804a74cd272d1070d264eef4812d9a9cc6b8ed68c3546189
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

image-20211006225936295

删除命令

docker rmi -f 9f35042c6a98 #根据 镜像id 删除docker镜像
docker rmi -f images id images id images id #批量删除docker镜像
docker rmi -f $(docker images -aq) # 删除全部镜像

image-20211006230329893

容器命令

说明:我们有了镜像才可以创建容器,以linux为例子,创造一个CentOS的容器

来测试学习

docker pull centos

新建容器并且启动

docker run [可选参数] image

#参数说明

--name = "name" 容器名字, tomcat 1 ,tomcat 2来区分容器
-d              后台的方式运行
-it             使用交互方式运行 ,进入容器查看内容
-p              指定容器的端口 -p 8080:8080
	-p ip :主机端口:容器端口
	-p  主机端口 : 容器端口(常用)
	-p  容器端口
-p               随机指定端口

#测试,并且启动进入容器
[root@iZwz90ps06ioyada63oiwiZ ~]# docker run -it centos /bin/bash
[root@aa1a02ed3f51 /]# ls
bin  etc   lib	  lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr

#推出容器查看
[root@iZwz90ps06ioyada63oiwiZ /]# ls
bin   dev  home  lib64       media  mynacos  nginxWebdata  patch  project  run   srv  tmp  var
boot  etc  lib   lost+found  mnt    myredis  opt           proc   root     sbin  sys  usr  www


	

列出所有运行的容器

docker ps
#列出当前正在运行的容器
-a  #列出当前正在运行的容器+带出历史运行过的内容
-n = ? #显示最近创建的容器
-q    #只显示容器的编号
#可以看到我们之前使用的 helloworld 和 centos 容器
[root@iZwz90ps06ioyada63oiwiZ /]#  docker ps -a
CONTAINER ID   IMAGE          COMMAND       CREATED         STATUS                     PORTS     NAMES
aa1a02ed3f51   centos         "/bin/bash"   3 minutes ago   Exited (0) 2 minutes ago             upbeat_matsumoto
0341862ece26   feb5d9fea6a5   "/hello"      8 hours ago     Exited (0) 8 hours ago               clever_jennings


退出容器

exit #直接容器停止并且推出
Ctrl + p + q #容器不停止 推出

删除容器

docker rm 容器id  # 删除指定容器,不能删除正在运行的容器
docker rm -f $(docker ps -aq) #删除所有的容器
docker ps -a|xargs docker rm #也可以删除所有的容器

[root@iZwz90ps06ioyada63oiwiZ /]# docker rm -f $(docker ps -aq)
aa1a02ed3f51
0341862ece26

启动和停止容器

docker start 容器id     #启动容器
docker restart 容器id   #重启容器
docker stop 容器id	  #关闭容器
docker kill 容器id	  #强制关闭当前的容器

常用的其他命令

后台启动容器

#命令 docker run -d 镜像!
#问题 docker ps 发现centos停止了
#常见的坑 docker 容器使用后台运行,就必须要有一个前台的进程,docker发现没有前台的应用,就会自动停止
#nginx 容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了


查看日志

docker logs -f -t --tail 容器 

#自己编写一段shell脚本
while true; do echo hyc;sleep 1;done

#查看运行是否成功
[root@iZwz90ps06ioyada63oiwiZ /]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS                     PORTS     NAMES
754a5ea93b0c   centos    "/bin/sh -c 'while t…"   5 seconds ago   Exited (1) 5 seconds ago             sad_morse

#显示日志
docker logs  
显示全部日志
docker logs -tf cb8836c6fe21

按条件显示日志,之后一直显示
docker logs -tf --tail 10  cb8836c6fe2

--tf   #显示日志
--tail number #显示日志的条数

查看容器中的进程信息

[root@iZwz90ps06ioyada63oiwiZ /]# docker top cb8836c6fe21
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                3490                3472                0                   23:32               ?                   00:00:00            /bin/sh -c while true;do echo hyc;sleep 1;done
root                4994                3490                0                   23:39               ?                   00:00:00            /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1

查看镜像的元数据

#命令 查看 docker inspect cb8836c6fe21
[
    {
        "Id": "cb8836c6fe217ecab4ba2c0fa5f3d83ecd298c09f26aed3f2024062b0191bfcf",
        "Created": "2021-10-06T15:32:31.74201481Z",
        "Path": "/bin/sh",
        "Args": [
            "-c",
            "while true;do echo hyc;sleep 1;done"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 3490,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-10-06T15:32:32.049192513Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
        "ResolvConfPath": "/var/lib/docker/containers/cb8836c6fe217ecab4ba2c0fa5f3d83ecd298c09f26aed3f2024062b0191bfcf/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/cb8836c6fe217ecab4ba2c0fa5f3d83ecd298c09f26aed3f2024062b0191bfcf/hostname",
        "HostsPath": "/var/lib/docker/containers/cb8836c6fe217ecab4ba2c0fa5f3d83ecd298c09f26aed3f2024062b0191bfcf/hosts",
        "LogPath": "/var/lib/docker/containers/cb8836c6fe217ecab4ba2c0fa5f3d83ecd298c09f26aed3f2024062b0191bfcf/cb8836c6fe217ecab4ba2c0fa5f3d83ecd298c09f26aed3f2024062b0191bfcf-json.log",
        "Name": "/wizardly_hopper",
        "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/db5602f161d4930ca2f6f2d70eaddf29fb5daf635fa1307c9f3f9ee559ca7c50-init/diff:/var/lib/docker/overlay2/c57ecea0403cf58cf7c21ca1f4db2a1a84dadf594ceccd5560466191cfc22ec8/diff",
                "MergedDir": "/var/lib/docker/overlay2/db5602f161d4930ca2f6f2d70eaddf29fb5daf635fa1307c9f3f9ee559ca7c50/merged",
                "UpperDir": "/var/lib/docker/overlay2/db5602f161d4930ca2f6f2d70eaddf29fb5daf635fa1307c9f3f9ee559ca7c50/diff",
                "WorkDir": "/var/lib/docker/overlay2/db5602f161d4930ca2f6f2d70eaddf29fb5daf635fa1307c9f3f9ee559ca7c50/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "cb8836c6fe21",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "while true;do echo hyc;sleep 1;done"
            ],
            "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": "7e30f1e5819c55f424a9444110159f16e04b63b5e5a4e53146eece8e4a8df0f3",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/7e30f1e5819c",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "3e938d5faea175bc21e47cbc812e2157a9853ade29723ce12b6114c99637bb86",
            "Gateway": "172.18.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.18.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:12:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "cedc24b7c89ecc2306b4f241d9a60b0a1b1246a8ce98c9013432c67af21785f6",
                    "EndpointID": "3e938d5faea175bc21e47cbc812e2157a9853ade29723ce12b6114c99637bb86",
                    "Gateway": "172.18.0.1",
                    "IPAddress": "172.18.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:12:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

进入容器之后,修改一些配置

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

#命令
[root@iZwz90ps06ioyada63oiwiZ /]# docker ps -a #新建一个交互命令行
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
cb8836c6fe21   centos    "/bin/sh -c 'while t…"   13 minutes ago   Up 13 minutes             wizardly_hopper
[root@iZwz90ps06ioyada63oiwiZ /]# docker exec -it cb8836c6fe21 /bin/bash
[root@cb8836c6fe21 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 15:32 ?        00:00:00 /bin/sh -c while true;do echo hyc;sleep 1;done
root       986     0  0 15:48 pts/0    00:00:00 /bin/bash
root      1014     1  0 15:48 ?        00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin
root      1015   986  0 15:48 pts/0    00:00:00 ps -ef
[root@cb8836c6fe21 /]# 

#方式二
docker attach 容器id
#测试
进入之后会显示正在执行的 代码

#docker exec 进入容器开启一个新的终端。可以再里面操作(常用)
#docker attach 进入容器正砸执行的终端

从docker中取出文件

#创建文件
[root@iZwz90ps06ioyada63oiwiZ dockerTest]# touch athyc.java
[root@iZwz90ps06ioyada63oiwiZ dockerTest]# ls
athyc.java  hyc.java  test.java
[root@iZwz90ps06ioyada63oiwiZ dockerTest]# docker attach bcf5c1ea447c
You cannot attach to a stopped container, start it first
[root@iZwz90ps06ioyada63oiwiZ dockerTest]# docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                     PORTS     NAMES
bcf5c1ea447c   centos    "/bin/bash"   5 minutes ago   Exited (0) 4 minutes ago             cool_ishizaka
63184e5cad4d   centos    "/bin/bash"   8 minutes ago   Exited (0) 6 minutes ago             jovial_cori
#启动容器
[root@iZwz90ps06ioyada63oiwiZ dockerTest]# docker start bcf5c1ea447c
bcf5c1ea447c
[root@iZwz90ps06ioyada63oiwiZ dockerTest]# docker start bcf5c1ea447c /bin/bash
bcf5c1ea447c
Error response from daemon: No such container: bin/bash
Error: failed to start containers: /bin/bash

#进入命令行
[root@iZwz90ps06ioyada63oiwiZ dockerTest]# docker attach bcf5c1ea447c
[root@bcf5c1ea447c /]# ls
bin  etc   lib	  lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr
[root@bcf5c1ea447c /]# cd /home

#创建文件
[root@bcf5c1ea447c home]# touch someone.java
[root@bcf5c1ea447c home]# ls
someone.java  test.java
[root@bcf5c1ea447c home]# exit
exit
#从docker中复制文件到主机文件夹
[root@iZwz90ps06ioyada63oiwiZ dockerTest]# docker cp bcf5c1ea447c:/home/someone.java /dockerTest/
[root@iZwz90ps06ioyada63oiwiZ dockerTest]# ls
athyc.java  hyc.java  someone.java  test.java

小结

image-20211007001746033

日常使用命令大全

attach      Attach local standard input, output, and error streams to a running container
  #当前shell下 attach连接指定运行的镜像
  build       Build an image from a Dockerfile # 通过Dockerfile定制镜像
  commit      Create a new image from a container's changes #提交当前容器为新的镜像
  cp          Copy files/folders between a container and the local filesystem #拷贝文件
  create      Create a new container #创建一个新的容器
  diff        Inspect changes to files or directories on a container's filesystem #查看docker容器的变化
  events      Get real time events from the server # 从服务获取容器实时时间
  exec        Run a command in a running container # 在运行中的容器上运行命令
  export      Export a container's filesystem as a tar archive #导出容器文件系统作为一个tar归档文件[对应import]
  history     Show the history of an image # 展示一个镜像形成历史
  images      List images #列出系统当前的镜像
  import      Import the contents from a tarball to create a filesystem image #从tar包中导入内容创建一个文件系统镜像
  info        Display system-wide information # 显示全系统信息
  inspect     Return low-level information on Docker objects #查看容器详细信息
  kill        Kill one or more running containers # kill指定docker容器
  load        Load an image from a tar archive or STDIN #从一个tar包或标准输入中加载一个镜像[对应save]
  login       Log in to a Docker registry #
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

练习

nginx

docker安装nginx

#1, 搜索镜像 search 建议去docker hub 上搜索可以看到详细信息
docker search nginx
#2  拉取镜像 pull 下载镜像
docker pull nginx 
#3  运行测试
#使用参数
#-d 后台运行
# --name 给容器名字
# -p 宿主机端口:容器端口
[root@iZwz90ps06ioyada63oiwiZ ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@iZwz90ps06ioyada63oiwiZ ~]# docker run -d --name nginx01 -p 3344:80 nginx
30361d53c7276f50adecbef37a56865b9858a0b553efa7f33689c8c9f16d927e
[root@iZwz90ps06ioyada63oiwiZ ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                  NAMES
30361d53c727   nginx     "/docker-entrypoint.…"   30 seconds ago   Up 30 seconds   0.0.0.0:3344->80/tcp   nginx01
[root@iZwz90ps06ioyada63oiwiZ ~]# curl localhost:3344

#测试通过,进入查看配置,之后停止容器
[root@iZwz90ps06ioyada63oiwiZ ~]# curl localhost:3344
<!DOCTYPE html>
<html>
<head>
#成功
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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@iZwz90ps06ioyada63oiwiZ ~]# docker exec -it nginx01 /bin/bash
root@30361d53c727:/# ls
bin  boot  dev	docker-entrypoint.d  docker-entrypoint.sh  etc	home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@30361d53c727:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@30361d53c727:/# cd /etc/nginx
root@30361d53c727:/etc/nginx# ls
conf.d	fastcgi_params	mime.types  modules  nginx.conf  scgi_params  uwsgi_params
root@30361d53c727:/etc/nginx# exit
exit
[root@iZwz90ps06ioyada63oiwiZ ~]# ls
install.sh
[root@iZwz90ps06ioyada63oiwiZ ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                  NAMES
30361d53c727   nginx     "/docker-entrypoint.…"   7 minutes ago   Up 7 minutes   0.0.0.0:3344->80/tcp   nginx01
[root@iZwz90ps06ioyada63oiwiZ ~]# docker stop 30361d53c727 
30361d53c727

端口暴露的概念

image-20211007113424795

思考:是不是我们每次创建一个nginx容器部署点东西,都需要去修改配置,这显然很耗时间,那么我们 需要怎么做呢, -v 数据卷容器,可以解决,

tomcat

docker 安装 tomcat

#官方的实例 用完就会删除,
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

#发现可以访问但是没有内容,这是为什么呢,应为下载的tomcat是阉割版本,webapps下是空的所有没有
root@3fba46045c12:/usr/local/tomcat# ls
BUILDING.txt	 LICENSE  README.md	 RUNNING.txt  conf  logs	    temp     webapps.dist
CONTRIBUTING.md  NOTICE   RELEASE-NOTES  bin	      lib   native-jni-lib  webapps  work
root@3fba46045c12:/usr/local/tomcat# cd webapps
root@3fba46045c12:/usr/local/tomcat/webapps# 

#问题 linux命令少了,webapps是空的,为什么? 应为阿里云的镜像是最小的,把不必要的都剔除掉了,保证最小的运行

#webapps.dist 我们之前webapps的东西都在这个dist里面,只需要复制内容到webapps中就可以完成访问了

image-20211007133450899

思考:每次开一个tomcat的容器,就得去复制一次dist文件,要是我部署了项目岂不是每次都会消失,没有持久化,那还得了。这个还只是tomcat。要是mysql容器删除了,那岂不是直接数据全部丢失。

可视化

  • portainer(先使用这个)

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

什么是portainer

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

之后就可以通过它访问了

http://120.79.14.203:8088/#/init/admin

进入之后会要先注册一个账号

image-20211007151140339

之后选择本地的

image-20211007151211509

之后就可以看到docker的内容了

image-20211007151405290

比如有多少镜像阿,多少容器阿,可以点进去操作命令

Docker镜像讲解

镜像是什么

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

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

如何获得镜像:

  • 从远程仓库下载
  • 朋友拷贝
  • 自己制作镜像dockerfile

Docker镜像加载原理

UnionFS 联合文件系统

image-20211007152543164

Docker镜像加载的原理

image-20211007152852449

分层理解

分层的镜像

我们可以去下载一个镜像,注意观察下载的日志输出,可以看到一层层的下载,

image-20211007153412138

我们会发只会下载一些新的,之前老的都是可以复用的

Docker的分层

每个操作系统都有自己的储存方式

docker上我们的操作可以是再镜像层面的基础上新加了一层,

image-20211007154232293

docker镜像的特点

docker的镜像一般都是只读状态的,我们run起来的容器,都是再容器层面,新写的层面会被加到顶部。

所以我们的所有操作都是基于容器的,容器基于一个基本的镜像,

image-20211007154640895

理解了这些我们再去提交一个属于自己的镜像

COMMIT镜像

docker commit 提交哦让其成为一个新的副本

#命令和git的原理类似
docker commit -m = “提交的描述i星系” -a =“作者” 容器id 目标的镜像名字:【tag】

实战测试:打包一个webapps下有文件的 tocmat上去

#1 启动一个tomcat 

#2 之前发现的问题,我们的tomcat下默认是没有文件的,都放在 webapps.dist虚下,每次我们都需要去将这个文件夹中的东西去复制到webapps中,十分的麻烦。

#3我自己将文件拷贝到了基本文件

#4 我自己拷贝的镜像我提交了。这个比较好用,我直接提交上去用我提交的我觉得舒服的镜像

到了这里就算是入门Docker

容器数据卷

什么是容器的数据卷

docker的理念回顾

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

数据 如果数据在容器中,我们容器删除的话,数据也会跟着消失 ==需求 :需要持久化==

MySql 容器删除=删库跑路 ==需求:MySql数据可以存储到本地!==

容器之间可以有一个数据空想的技术,docker容器中产生的数据,同步到本地

删除容器数据不会消失,这个就是卷技术

目录的挂载,将我们的容器内的目录,挂在到linux上!

image-20211007162143064

容器需要持久化和同步操作,容器间也可以数据共享

使用数据卷

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

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

#挂载测试
docker run -it -v /dockerTest/ceshi/:/home centos /bin/bash

#查看容器元数据
docker inspcet 容器id

image-20211007162919462

可以看到卷的挂载信息

绑定信息确认之后,我们来试试是不是真的成功了

image-20211007163222265

绑定成功,之后我们测试,就是是不是容器停止下来数据还能有数据嘛?

我们这里在服务器的testjava文件中写点内容

image-20211007163529383

之后去启动容器看看是否 同步

同步成功!!!

image-20211007163639956

到这里我们就实现了数据卷的数据持久化操作,只要容器不消失,关闭之后再次打开也是可以看更改的内容的。

实战安装mysql

mysql持久话的问题

#拉去mysql的镜像 
docker pull mysql:5.7

#启动挂载mysql的容器 mysql是必须要有密码的
#官方的测试
 docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
 # -e 我们这里可以看到,我们需要配置环境的时候,就可以用-e来配置
 
docker run -d -p 3310:3306 
-v /dockerTest/mysql/conf:/etc/mysql/conf.d
-v /dockerTest/mysql/data:/var/lib/mysql 
-e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

#-d 是后台挂在
#-p 映射端口
#-v 卷挂载
#--name 容器名字
#--e 配置环境,mysql密码

#启动成功之后打开数据库连接工具连接docker的mysql
#navicat 连接 服务器的3310(映射的docker 3306)连接成功
#测试本地创建数据库,查看是否data的内容映射到成功

哪怕我们将容器删除,我们挂载到本地的数据是不会丢失的,这就实现了容器持久化。

具名挂载和匿名挂载

#匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx

#查看卷(volume)的信息
docker volume ls

#这里发现数据都是没有名字的,这里我们没有设置本机的路径,-v只写了容器内的路径,这个就是匿名挂载

#具名挂载
docker run -d -P -v juming-nginx:/etc/nginx nginx
查看卷信息
docker volume ls
local     10f1524cc8295a9e7dfd75c88dab113395da11959756738bf121b5733ac2be70
local     24439de8b83f5493f971314bc3e5ca0e8f60d14a338ee19c7e35910403ade730
local     juming-nginx

可以看到我们刚才的设置的
#通过 -v 卷名 : 容器内路径
#查看一下这个卷

image-20211008161005185

所有的docker容器内的卷,,没有指定目录,就都会放在/var/lic/docker/volumes/xxx/_data

我们通过具名挂载可以很轻松拿出来配置。大多数的时候我们都是具名挂载

image-20211008161214811

#如何区分具名挂载,匿名挂载,和绝对路径挂载
-v 容器内路径  #匿名挂载
-v 卷名 :容器内路径 #具名挂载
-v /宿主机路径:容器路径 #指定路径挂载

拓展

#通过 -v 容器内的路径ro ow改变读写权限
ro readonly #只读
rw redwrite #可读可写

#一旦设置了容器权限,容器对我们挂载出来的内容就有限顶了
#ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作的

初识dockerfile

dockerfile 就是通过构建docker 镜像的构建文件,命令脚本,

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

#创建一个dockerfile 的文件,名字可以随意,建议dockerfile
#文件中的内容 大写
FROM centos
VOLUME ["volume01","volume02"]

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

#这里的每个指令就是镜像的一层

image-20211008170701378

启动i自己的容器

image-20211008171210378

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

这个是匿名挂载

我们要找的话一定是一段很长的乱码

找到卷挂载的命令

image-20211008171418747

容器同步成功

image-20211008171600981

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

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

数据卷容器

容器之间同步数据

image-20211008171856431

我们要打开三个容器,启动第一个:可以看到我们挂载的两个容器

image-20211008172215072

这里我们跑起来容器

docker run -it --name docker02 --volumes-from docker01 2dd933a342b1

挂载我们的docker01

image-20211008173147275

我们可以看到docker02的里面也有之前两个挂载的容器

我们在docker01新增volume01新建个文件夹 docker01,在docker02中也可以看见

image-20211008173242330

这里是docker02查看volume1 的内容

image-20211008173235639

可以看出已经很明显了,挂载成功,这个时候我们docker01就是数据卷容器同时也是docker01容器

只要还有容器在挂载数据就不会丢失

image-20211008173533997

多个mysql实现数据共享

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

#mysql02挂载mysql01
docker run -d -p 3310:3306 
-e MYSQL_ROOT_PASSWORD=123456 --name mysql01 --volumes-from mysql01  mysql:5.7

结论:

容器之间配置信息,数据卷容器的生命周期一直持续到没有容器位置

但是一旦持久化到了本地, 就不会消失

dockerfile

dockerfile介绍

用来构建docker 镜像的

构建步骤:

  • 编写一个docker file 文件
  • docker build 构建成一个镜像
  • docker run 运行镜像
  • docker push 发布镜像(Docker hub 阿里云镜像)

我们来看看官方是怎么做的

image-20211106170721576

image-20211106172154705

很多官方的镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像

官方可以制作镜像,那我们也可以

DockerFile构建过程

基础知识

  • 每个保留关键字,指令都必须是大写字母
  • 执行从上到下执行
  • #表示注释
  • 每个指令都会创建提交一个新的镜像层

image-20211106172456651

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

我们要掌握dockerfile 就基本可以掌握常用的docker镜像企业交付了

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

dockerimages:通过dockerfile生成的镜像,最终发布和运行的产品

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

Dockerfile的指令

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

image-20211106172810755

实战测试

创建一个自己的centos

FROM centos
MAINTAINER hyc<3132774018@qq,com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80

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

# 2. 通过这个文件构建镜像
# 命令 docker build -f dockerfile文件路径 -t 镜像名:[tag] .
 
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker build -f mydockerfile-centos -t mycentos:0.1 .
 
Successfully built d2d9f0ea8cb2
Successfully tagged mycentos:0.1

#测试运行

对比之前原生的centos

image-20211106180200362

我们增加了 vim 和 net-tools

我们可以查看一下镜像的变更历史

docker history <imagesid>

image-20211106180537787

我们平时拿到一个镜像可以研究他是怎么构建的

CMD 和ENTRYPOINT区别

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

测试CMD

# 1. 编写dockerfile文件

[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# vim dockerfile-cmd-test 
FROM centos
CMD ["ls", "-a"]

# 2. 构建镜像

[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest .

# 3. run运行, 发现我们的ls -a 命令生效

[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run ebe6a52bb125
.
..
.dockerenv
bin
dev
etc
home
lib
lib64

# 想追加一个命令 -l 变成 ls -al

[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run ebe6a52bb125 -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.
[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run ebe6a52bb125 ls -l

# cmd的情况下 -l替换了CMD["ls", "-a"]命令, -l不是命令,所以报错了

测试ENTRYPOINT

# 1. 编写dockerfile文件

[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# vim dockerfile-entrypoint-test 
FROM centos
ENTRYPOINT ["ls", "-a"]

# 2. 构建文件

[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker build -f dockerfile-entrypoint-test -t entrypoint-test .

# 3. run运行 发现我们的ls -a 命令同样生效

[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run entrypoint-test
.
..
.dockerenv
bin
dev
etc
home
lib

# 4. 我们的追加命令, 是直接拼接到ENTRYPOINT命令的后面的!

[root@iZ2zeg4ytp0whqtmxbsqiiZ dockerfile]# docker run entrypoint-test -l
total 56
drwxr-xr-x  1 root root 4096 Aug 13 07:52 .
drwxr-xr-x  1 root root 4096 Aug 13 07:52 ..
-rwxr-xr-x  1 root root    0 Aug 13 07:52 .dockerenv
lrwxrwxrwx  1 root root    7 May 11  2019 bin -> usr/bin
drwxr-xr-x  5 root root  340 Aug 13 07:52 dev
drwxr-xr-x  1 root root 4096 Aug 13 07:52 etc
drwxr-xr-x  2 root root 4096 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 4096 Aug  9 21:40 lost+found

实战 tomcat

这里我们先准备好 需要用到的 安装包

  • apache-tomcat-9.0.54.tar.gz
  • jdk-8u311-linux-x64.tar.gz
  1. 准备镜像文件 tomcat压缩包,jdk的压缩包!

    在这里插入图片描述

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

    [root@iZwz90ps06ioyada63oiwiZ dockerfiletomcat]# cat Dockerfile
    FROM centos
    MAINTAINER hyc<3132774018@qq.com>
    
    COPY readme.txt /usr/local/readme.txt
    
    ADD jdk-8u311-linux-x64.tar.gz /usr/local/
    ADD apache-tomcat-9.0.54.tar.gz /usr/local/
    
    RUN yum -y install vim
    
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    
    ENV JAVA_HOME /usr/local/jdk1.8.0_311
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.54
    ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.54
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
    
    EXPOSE 8080
    
    CMD /usr/local/apache-tomcat-9.0.54/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.54/bin/logs/catalina.out
    
    
  3. 启动并且挂载

    docker run -d -p 3344:8080 --name hyctomcat11 -v /dockerTest/dockerfiletomcat/test:/usr/local/apache-tomcat-9.0.54/webapps/test -v /dockerTest/dockerfiletomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.54/logs diytomcat
    
  4. 访问 3344端口

成功

image-20211106212344365

发布

注册docker hub 账号

image-20211107171256066

到服务器命令行登陆

[root@iZwz90ps06ioyada63oiwiZ ~]# docker login -u doomwatcher
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-store

Login Succeeded

登陆自己的docker账户

登录成我们就可以push到 自己的仓库了

之后我们要给之前我们自己写的tocmat 规范命名 docker tag dockerhub用户名/镜像名:版本号

[root@iZwz90ps06ioyada63oiwiZ ~]# docker tag diytomcat  doomwatcher/diytomcat:1.0

image-20211107172125161

之后我们用 docker push 到我们的docker上

image-20211107172219696

image-20211107172248100

docker网络

认识docker网络

测试 ip addr 查看

image-20211107193400215

我们可以测试一下,容器和容器之间 能不能ping通

image-20211107193505174

# 跑一个tomcat 
docker run -d -P --name tomcat01 tomcat
# 获取ip
ip addr

# 我们可以用查看元数据的方式查看 容器的ip地址

image-20211107194843093

# 之后用宿主机 linux 去ping容器
 ping 172.18.0.2
 
 # 能通

image-20211107194927467

原理

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

image-20211107195156421

我们新启动的容器就会多一个新的网卡

我们发现,这些容器的网卡都是一对一对的

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

image-20211107195532158

我们新建一个 tomcat 尝试容器之间是否能够ping通

结论:容器与容器之间是可以相互ping通的!

绘制一个网络模型图

在这里插入图片描述

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

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

小结

在这里插入图片描述

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

在这里插入图片描述

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

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

思考一个场景,我们编写了一个微服务,database url =ip; 项目不重启,数据ip换掉了,我们希望可以处理这个问题,可以按名字来进行访问容器

[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
 
# 如何可以解决呢?
# 通过--link既可以解决网络连通问题
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker run -d -P  --name tomcat03 --link tomcat02 tomcat
3a2bcaba804c5980d94d168457c436fbd139820be2ee77246888f1744e6bb473
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
3a2bcaba804c        tomcat              "catalina.sh run"   4 seconds ago       Up 3 seconds        0.0.0.0:32772->8080/tcp   tomcat03
f22ed47ed1be        tomcat              "catalina.sh run"   57 minutes ago      Up 57 minutes       0.0.0.0:32771->8080/tcp   tomcat02
9d97f93401a0        tomcat              "catalina.sh run"   About an hour ago   Up About an hour    0.0.0.0:32770->8080/tcp   tomcat01
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# 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.129 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.100 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.110 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=4 ttl=64 time=0.107 ms
 
# 反向可以ping通吗?
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
 

探究:inspect!

在这里插入图片描述

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

[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# 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 f22ed47ed1be
172.17.0.4  3a2bcaba804c

本质探究:--link 就是我们在hosts配置中增加了一个172.17.0.3 tomcat02 f22ed47ed1be

我们现在玩Docker已经不建议使用--link了!

自定义网络!不使用Docker0!

Docker0的问题:它不支持容器名链接访问!

自定义网络

查看所有的docker网络

在这里插入图片描述

网络模式

bridge: 桥接模式,桥接 docker 默认,自己创建的也是用brdge模式

none: 不配置网络

host: 和宿主机共享网络

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

测试

# 我们直接启动的命令默认有一个 --net bridge,而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat
 
# docker0特点,默认,容器名不能访问, --link可以打通连接!
# 我们可以自定义一个网络!
# --driver bridge
# --subnet 192.168.0.0/16 可以支持255*255个网络 192.168.0.2 ~ 192.168.255.254
# --gateway 192.168.0.1
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
26a5afdf4805d7ee0a660b82244929a4226470d99a179355558dca35a2b983ec
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
30d601788862        bridge              bridge              local
226019b14d91        host                host                local
26a5afdf4805        mynet               bridge              local
7496c014f74b        none                null                local

我们自己创建的网络就ok了!

在这里插入图片描述

在自己创建的网络里面启动两个容器

[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
0e85ebe6279fd23379d39b27b5f47c1e18f23ba7838637802973bf6449e22f5c
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
c6e462809ccdcebb51a4078b1ac8fdec33f1112e9e416406b606d0c9fb6f21b5
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "26a5afdf4805d7ee0a660b82244929a4226470d99a179355558dca35a2b983ec",
        "Created": "2020-08-14T11:12:40.553433163+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": {
            "0e85ebe6279fd23379d39b27b5f47c1e18f23ba7838637802973bf6449e22f5c": {
                "Name": "tomcat-net-01",
                "EndpointID": "576ce5c0f5860a5aab5e487a805da9d72f41a409c460f983c0bd341dd75d83ac",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "c6e462809ccdcebb51a4078b1ac8fdec33f1112e9e416406b606d0c9fb6f21b5": {
                "Name": "tomcat-net-02",
                "EndpointID": "81ecbc4fe26e49855fe374f2d7c00d517b11107cc91a174d383ff6be37d25a30",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

# 再次拼连接

[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# 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.113 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.093 ms
^C
--- 192.168.0.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.093/0.103/0.113/0.010 ms

# 现在不使用 --link也可以ping名字了!

[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# 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.068 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.096 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.094 ms

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

好处:

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

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

网络连通

在这里插入图片描述

测试打通tomcat01 和mynet

在这里插入图片描述

# 连通ok
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# 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.100 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.085 ms
^C
--- tomcat-net-01 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.085/0.092/0.100/0.012 ms
# 依旧无法连通,没有connect
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker exec -it tomcat02 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known
 

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

springboot打包微服务项目上docker

  1. 构建springboot项目

    我们这里新建一个 deockerbootDemo

    image-20211107211729453

    写一个controller 返回一个 hello 即可

    之后去安装一个docker的插件,可以用idea 发布到docker

  2. 打包应用

  3. 编写dockerFile

    FROM java:8
    COPY *.jar /app.jar
    
    CMD["------serverprot:8080"]
    EXPOSE 8080
    
    ENTRYPOINT ["java","-jar","/app.jar"]
    
  4. 构建镜像

    将文件上传到 服务器的 dockertest/diea 文件夹中

    运行dokcer bulid -t name .即可构建镜像

    image-20211107213720789

  5. 发布运行

之后我们创建容器

 docker run -d -P --name hyc-springboot-web hycboot

image-20211107213537801

以后我们就只需要,给别人一个镜像即可,

要是我们要很多个镜像,我们该怎么用?

docker进阶预告 :

  1. Docker compose
  2. Docker Swarm
  3. CI/DI jenkins
分类: