docker安装与入门

学习笔记记录自 [B站狂神说](

一、Docker 学习大纲

Docker 学习

  • Docker 概述
  • Docker 安装
  • Docker命令
    • 镜像命令
    • 容器命令
    • 操作命令
    • 命令总结
  • Docker 镜像
  • 容器数据卷
  • DockerFile
  • Docker 网络原理
  • IDEA 整合 Docker
  • Docker Compose
  • Docker Swarm
  • CNCD jenkins

二、Docker 概述 与 历史

篇幅较长,网上也有很多科普的文章,

vm linux centos 原生镜像,隔离,需要开启多个虚拟机, 几个 G,电脑
Docker 镜像(linux + mysql + jdk) 秒级启动

https://docs.docker.com/

https://hub.docker.com/

三、Docker 的安装

  • 你得有一台自己的云服务器,最近双十一有活动,新用户买一年的低配服务器(1核2G)只要 88 元。如果没有购买的可以看看 腾讯云服务器,配置起来相对比阿里云服务器,少一步安全组的操作.

现在是有 windows 的版本的了,可以直接下载安装的 传送门
在这里插入图片描述

一、Docker 的基本组成

3.1 镜像 image

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

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

  • 启动,停止,删除,基本命令!

  • 目前可以把这个容器理解为一个简易的 linux 系统(每次安装的时候,都会安装一个最小 Linux 子系统)

3.3 仓库 repository

仓库是存放镜像的地方!

仓库分为共有仓库私有仓库

Docker Hub(默认是国外的)

阿里云。。等等都有容器服务器

安装 Docker

环境准备

  1. Linux 基础
  2. CentOS 7
  3. 使用 xshell 链接远程服务器并操作!
# 系统内核
[root@VM_0_15_centos /]# uname -r
3.10.0-1062.18.1.el7.x86_64
[root@VM_0_15_centos /]# 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"

帮助文档(https://docs.docker.com/engine/install/centos/)

# 1. 卸载就得版本
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

# 2. 安装依赖环境
yum install -y yum-utils

# 3. 设置镜像的仓库
yum-config-manager
–add-repo
https://download.docker.com/linux/centos/docker-ce.repo # 默认是国外的!

yum-config-manager
–add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 推荐使用 阿里云镜像

# 4. 更新软件包的索引
yum makecache fast

# 5. 安装最新版的 docker 引擎, docker-ce 社区版 ee 企业版 (也可以指定安装不停的版本)
yum install docker-ce docker-ce-cli containerd.io

# 6. 启动 docker
systemctl start docker

# 7. 使用 docker version 查看是否启动成功
docker version

# 8. 启动一个镜像
docer run hello-world

[root@VM_0_15_centos /]# docer run hello-world
-bash: docer: command not found
[root@VM_0_15_centos /]# docker run hello-world
Unable to find image ‘hello-world:latest’ locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:8c5aeeb6a5f3ba4883347d3747a7249f491766ca1caa47e5da5dfcf6b9b717c0
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:

  1. The Docker client contacted the Docker daemon.
  2. The Docker daemon pulled the “hello-world” image from the Docker Hub.
    (amd64)
  3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
  4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/

For more examples and ideas, visit:
https://docs.docker.com/get-started/

# 9. 查看下载好的镜像
docker images

[root@VM_0_15_centos /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 9 months ago 13.3kB

设置镜像

[root@VM_0_15_centos /]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
Loaded plugins: fastestmirror, langpacks
Repository epel is listed more than once in the configuration
adding repo from: http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
grabbing file http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo

启动信息

[root@VM_0_15_centos /]# systemctl start docker
[root@VM_0_15_centos /]# docker version
Client: Docker Engine - Community
 Version:           19.03.13
 API version:       1.40
 Go version:        go1.13.15
 Git commit:        4484c46d9d
 Built:             Wed Sep 16 17:03:45 2020
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
Engine:
Version: 19.03.13
API version: 1.40 (minimum version 1.12)
Go version: go1.13.15
Git commit: 4484c46d9d
Built: Wed Sep 16 17:02:21 2020
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.3.7
GitCommit: 8fba4e9a7d01810a393d5d25a3621dc101981175
runc:
Version: 1.0.0-rc10
GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd
docker-init:
Version: 0.18.0
GitCommit: fec3683

卸载 docker

# 两个步骤完成卸载
Uninstall Docker Engine
Uninstall the Docker Engine, CLI, and Containerd packages:

1. 卸载 docker 一些依赖

yum remove docker-ce docker-ce-cli containerd.io

Images, containers, volumes, or customized configuration files on your host are not automatically removed. To delete all images, containers, and volumes:

2. 删除目录,卸载资源

rm -rf /var/lib/docker

3. docker 的默认工作路径

/var/lib/docker

You must delete any edited configuration files manually.

阿里云镜像加速

  1. 登录阿里云
  2. 找到容器镜像服务
  3. 配置镜像加速器

这里每个人的配置不一样,所以你填写我的是没有效果的

sudo mkdir -p /etc/docker

sudo tee /etc/docker/daemon.json <<-‘EOF’
{
“registry-mirrors”: [“https://opszdtgc.mirror.aliyuncs.com”]
}
EOF

sudo systemctl daemon-reload

sudo systemctl restart docker

回顾 helloworld 流程

开始 -> Docker 在本机寻找对象 -> 判断本机是否有这个镜像 -> 没有则去下载 Docker Hub 这个镜像 —> 找不到镜像就返回错误(否则就下载镜像到本地)

底层原理

Docker 是怎么工作的?

Docker 是一个 Client - Server 结构的系统,Docker 的守护进程运行在主机上,通过 Socket 从客户端访问,DockerServer 接收到一个 Docker-Client 的命令,就会执行命令

Docker 为什么比 VM 快

四、Docker 常用命令

4.1 帮助命令

docker version # 显示 docker 的版本信息

docker info # 显示 docker 的系统信息,包括镜像 和 容器的数量

docker 命令 --help # 帮助命令

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

4.2 镜像命令(搜索,下载,删除,查看)

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

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

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

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

docker search 搜索镜像

docker search --help # 查看使用方式,可以避免查询官方文档

# 可选项
–filter STARS=3000 # 搜索出来的镜像的

[root@VM_0_15_centos ~]# docker search mysql --filter STARS=300
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 10065 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3689 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 736 [OK]
percona Percona Server is a fork of the MySQL relati… 511 [OK]

docker pull 下载镜像

# 下载镜像 docker pull 镜像名[:tag]
[root@VM_0_15_centos ~]# docker pull mysql
Using default tag: latest  # 如果不写 tag:默认就是 latest
latest: Pulling from library/mysql
bb79b6b2107f: Pull complete   # 分层下载,docker image的核心,联合文件系统
49e22f6fb9f7: Pull complete 
842b1255668c: Pull complete 
9f48d1f43000: Pull complete 
c693f0615bce: Pull complete 
8a621b9dbed2: Pull complete 
0807d32aef13: Pull complete 
9eb4355ba450: Pull complete 
6879faad3b6c: Pull complete 
164ef92f3887: Pull complete 
6e4a6e666228: Pull complete 
d45dea7731ad: Pull complete 
Digest: sha256:86b7c83e24c824163927db1016d5ab153a9a04358951be8b236171286e3289a4 # 签名
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

[root@VM_0_15_centos ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
bb79b6b2107f: Already exists
49e22f6fb9f7: Already exists
842b1255668c: Already exists
9f48d1f43000: Already exists
c693f0615bce: Already exists
8a621b9dbed2: Already exists
0807d32aef13: Already exists
6d2fc69dfa35: Pull complete
56153548dd2c: Pull complete
3bb6ba940303: Pull complete
3e1888da91a7: Pull complete
Digest: sha256:b3dc8d10307ab7b9ca1a7981b1601a67e176408be618fc4216d137be37dae10b
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

docker rmi 删除镜像

# 根据 ID 删除,也可以同时指定多个 ID
docker rmi -f  IMAGE ID,IMAGE ID,IMAGE ID

# 递归删除所有镜像
docker rmi -f $(docker images -aq)

4.3 容器命令

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

# 下载 centOS 镜像
docker pull centos

新建容器并启动

docker run [可选参数] image

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

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

# 查看运行中的容器
docker ps

列出所有运行的容器

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

[root@VM_0_15_centos ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f3f9e8b9045f centos “/bin/bash” 3 minutes ago Exited (0) About a minute ago festive_hawking
44fe79a9cfc5 bf756fb1ae65 “/hello” 3 hours ago Exited (0) 3 hours ago romantic_pike

退出容器

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

删除容器

docer rm 容器ID 	# 删除指定的容器,不能删除正在运行的容器
docer rm -f ${docker ps -aq} # 删除所有的容器
docker ps -a -q |xargs docker rm # 删除所有容器

启动和停止容器

docker start 容器 id  # 启动容器
docker restart 容器id	# 
docker stop 容器id
docker kill 容器id

4.4 常用其他命令

后台启动容器

[root@VM_0_15_centos ~]# docker run -d centos
091ca119820ea987ca43ae2f608a628ce2c2af9cb364274a3eadfb65f93ffa8d
[root@VM_0_15_centos ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@VM_0_15_centos ~]# 

# 问题 docker ps,发现 centos 停止了

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

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

查看日志

docker logs -f -t --tail 容器,没有日志

# 自己编写一段 shell 脚本
docker ps

# 显示日志
-tf # 显示日志
–tail number # 显示日志的条数
docker logs -tf --tail 10 容器 ID

查看容器中进程的信息 ps

docker top

[root@VM_0_15_centos ~]# docker top 3e77e2715543
UID PID PPID C STIME TTY TIME CMD
root 31464 31448 0 15:28 pts/0 00:00:00 /bin/bash
[root@VM_0_15_centos ~]#

查看镜像的元数据

# 命令
docker inspect 容器id

# 测试
[
{
“Id”: “3e77e2715543f551edcdda1f0276e9602159b58d2c4f414792c23e9fa2f7b762”,
“Created”: “2020-10-17T07:28:43.374939473Z”,
“Path”: “/bin/bash”,
“Args”: [],
“State”: {
“Status”: “running”,
“Running”: true,
“Paused”: false,
“Restarting”: false,
“OOMKilled”: false,
“Dead”: false,
“Pid”: 31464,
“ExitCode”: 0,
“Error”: “”,
“StartedAt”: “2020-10-17T07:28:43.71609384Z”,
“FinishedAt”: “0001-01-01T00:00:00Z”
},
“Image”: “sha256:0d120b6ccaa8c5e149176798b3501d4dd1885f961922497cd0abef155c869566”,
“ResolvConfPath”: “/var/lib/docker/containers/3e77e2715543f551edcdda1f0276e9602159b58d2c4f414792c23e9fa2f7b762/resolv.conf”,
“HostnamePath”: “/var/lib/docker/containers/3e77e2715543f551edcdda1f0276e9602159b58d2c4f414792c23e9fa2f7b762/hostname”,
“HostsPath”: “/var/lib/docker/containers/3e77e2715543f551edcdda1f0276e9602159b58d2c4f414792c23e9fa2f7b762/hosts”,
“LogPath”: “/var/lib/docker/containers/3e77e2715543f551edcdda1f0276e9602159b58d2c4f414792c23e9fa2f7b762/3e77e2715543f551edcdda1f0276e9602159b58d2c4f414792c23e9fa2f7b762-json.log”,
“Name”: “/admiring_visvesvaraya”,
“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/f8794c646517a8e6206cc81948002a34d94b7a4b7ee68392a16829a840c6dd40-init/diff:/var/lib/docker/overlay2/f99f2fb61401e6e3d9e3fa4b33ae3f5f92bf5f574910e28b6509fac39636be19/diff”,
“MergedDir”: “/var/lib/docker/overlay2/f8794c646517a8e6206cc81948002a34d94b7a4b7ee68392a16829a840c6dd40/merged”,
“UpperDir”: “/var/lib/docker/overlay2/f8794c646517a8e6206cc81948002a34d94b7a4b7ee68392a16829a840c6dd40/diff”,
“WorkDir”: “/var/lib/docker/overlay2/f8794c646517a8e6206cc81948002a34d94b7a4b7ee68392a16829a840c6dd40/work”
},
“Name”: “overlay2”
},
“Mounts”: [],
“Config”: {
“Hostname”: “3e77e2715543”,
“Domainname”: “”,
“User”: “”,
“AttachStdin”: true,
“AttachStdout”: true,
“AttachStderr”: true,
“Tty”: true,
“OpenStdin”: true,
“StdinOnce”: true,
“Env”: [
“PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin”
],
“Cmd”: [
“/bin/bash”
],
“Image”: “centos”,
“Volumes”: null,
“WorkingDir”: “”,
“Entrypoint”: null,
“OnBuild”: null,
“Labels”: {
“org.label-schema.build-date”: “20200809”,
“org.label-schema.license”: “GPLv2”,
“org.label-schema.name”: “CentOS Base Image”,
“org.label-schema.schema-version”: “1.0”,
“org.label-schema.vendor”: “CentOS”
}
},
“NetworkSettings”: {
“Bridge”: “”,
“SandboxID”: “ff477eace5c8906f5fd01d86fc7737179f8fbf13cf4cae35499a1ebd98a070dd”,
“HairpinMode”: false,
“LinkLocalIPv6Address”: “”,
“LinkLocalIPv6PrefixLen”: 0,
“Ports”: { },
“SandboxKey”: “/var/run/docker/netns/ff477eace5c8”,
“SecondaryIPAddresses”: null,
“SecondaryIPv6Addresses”: null,
“EndpointID”: “5457cf149d34d8937295e72b2a8efb47830e18812a87c0afb2ff773f4d9be760”,
“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”: “457b5829b14f034c35472c80dd6ec2ab1b9666fac95bbbcdf41f23226918ac6a”,
“EndpointID”: “5457cf149d34d8937295e72b2a8efb47830e18812a87c0afb2ff773f4d9be760”,
“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
}
}
}
}
]

进入当前正在运行的容器 (exec)

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

# 命令
docker exec -it 容器id /bin/bash /sh

[root@VM_0_15_centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3e77e2715543 centos “/bin/bash” 12 minutes ago Up 12 minutes admiring_visvesvaraya

[root@VM_0_15_centos ~]# docker exec -it 3e77e2715543 /bin/bash
[root@3e77e2715543 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:28 pts/0 00:00:00 /bin/bash
root 19 0 0 07:41 pts/1 00:00:00 /bin/bash
root 32 19 0 07:41 pts/1 00:00:00 ps -ef

# 方式二
docker attach 容器Id # 进入当前正在进行的命令行

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

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

docker cp 容器id: 容器内路径 主机路径

[root@VM_0_15_centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ed828f6c65d8 centos “/bin/bash” 8 minutes ago Up 8 minutes beautiful_swanson
[root@VM_0_15_centos ~]# docker attach 3e77e2715543
You cannot attach to a stopped container, start it first
[root@VM_0_15_centos ~]# docker attach ed828f6c65d8
[root@ed828f6c65d8 home]# ls
a.java

# ctrl + p + q 后台运行
[root@VM_0_15_centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ed828f6c65d8 centos “/bin/bash” 9 minutes ago Up 9 minutes beautiful_swanson
[root@VM_0_15_centos ~]# cd /home/
[root@VM_0_15_centos home]# ls
apache-tomcat-9.0.30 java node Python-3.7.1 Python-3.7.1.tgz wget-log
[root@VM_0_15_centos home]# mkdir docker
[root@VM_0_15_centos home]# ls
apache-tomcat-9.0.30 docker java node Python-3.7.1 Python-3.7.1.tgz wget-log
[root@VM_0_15_centos ~]# docker cp ed828f6c65d8:/home/a.java /home/docker/
[root@VM_0_15_centos ~]# cd /home/
[root@VM_0_15_centos home]# cd docker/
[root@VM_0_15_centos docker]# ls
a.java

# 拷贝是一个手动过程,未来我们使用 -V 卷的技术,可以实现同步 /home

4.5 命令小结

五、Docker 常见环境

5.1 Docker 安装 Nginx

# 1. 搜索镜像 search, 建议去 docker 搜索,可以看到帮助文档
docker search nginx

# 2. 下载镜像
docker pull nginx

# 3. 启动 镜像, 运行测试
# -d 后台运行
# --name 给容器命名
# -p 宿主机端口,容器内部端口
docker run -d --name nginx01 -p 3344:80 nginx

PS C:\Users\伟\Desktop> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
ace069bcdcaa nginx “/docker-entrypoint.…” About a minute ago Up About a minute 0.0.0.0:3344->80/tcp nginx01

# 进入容器
PS C:\Users\伟\Desktop> docker exec -it nginx01 /bin/bash
root@ace069bcdcaa:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@ace069bcdcaa:/# cd /etc/nginx
root@ace069bcdcaa:/etc/nginx# ls
conf.d fastcgi_params koi-utf koi-win mime.types modules nginx.conf scgi_params uwsgi_params win-utf
root@ace069bcdcaa:/etc/nginx#

5.2 Docker安装 Tomcat

# 官方的用法,一次性,用完即删
docker run -it --rm tomcat:9.0

# 我们之前的启动的都是后台,停止了容器之后,容器还可以查到 docker run -it --rm, 一般用来测试,用完删除

# 下载tomcat
docker pull tomcat:9.0 tomcat

# 启动运行
docker run -d -p 3355:8080 --name tomcat01 tomcat

# 测试访问没有问题
curl localhost:3355

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

# 发现问题

  1. linux 命令少了
  2. 没有 webapps
  3. 阿里云镜像原因,默认是最小的镜像,所有的不必要的被剔除

[root@VM_0_15_centos ~]# docker exec -it tomcat01 /bin/bash
root@79dd7b818e4c:/usr/local/tomcat# ls
BUILDING.txt CONTRIBUTING.md LICENSE NOTICE README.md RELEASE-NOTES RUNNING.txt bin conf lib logs native-jni-lib temp webapps webapps.dist work
root@79dd7b818e4c:/usr/local/tomcat# cp webapps.dist/* webapps/
cp: -r not specified; omitting directory ‘webapps.dist/ROOT’
cp: -r not specified; omitting directory ‘webapps.dist/docs’
cp: -r not specified; omitting directory ‘webapps.dist/examples’
cp: -r not specified; omitting directory ‘webapps.dist/host-manager’
cp: -r not specified; omitting directory ‘webapps.dist/manager’
root@79dd7b818e4c:/usr/local/tomcat# cp -r webapps.dist/* webapps/
root@79dd7b818e4c:/usr/local/tomcat# cd webapps

以后部署项目,每次都要进入容器十分麻烦?是否可以在容器外部提供一个映射路径,达到在容器修改文件名 webapps,我们在外部防止项目,就自动同步到内部就好了

5.3 部署 es + kibna (16节跳过)

5.4 docker 安装 mysql

MySQL 数据持久化的问题
下载 5.7

# 1. 获取镜像
docker pull mysql:5.7

2. 启动 MYSQL

-d 后台运行
-p 端口映射 本地端口:docker内部端口
-v 卷挂载
-e 环境配置
name 容器名字
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root name mysql01 mysql:5.7

下载 8.0

docker pull mysql:8.0

docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root --name mysql8_use mysql:8.0
# 修改密码,mysql8 的编码问题,导致无法远程连接
docker exec -it 容器id /bin/bash

mysql -uroot -proot

ALTER USER ‘root’@’%’ IDENTIFIED WITH mysql_native_password BY ‘root’;

FLUSH PRIVILEGES;

然后就可以远程连接了

六、可视化软件

portainer (先用这个)

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

Rancher(CI/CD)

七、Docker 镜像讲解

7.1 镜像是什么

镜像是一种轻量级,可执行的独立软件包,用来打包软件运行环境 和 基于运行环境开发的软件

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

如何得到镜像:

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

7.3 Docker 镜像加载原理

UnionFS (联合文件系统)

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

虚拟机分钟级启动

容器是秒级启动

八、提交镜像

8.1 commit 镜像

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

实战测试

# 启动一个默认的 tomcat
# 发现这个默认的 tomcat 是没有 webapss应用, webapss 是没有文件的
# 我将文件进行了 拷贝
# 将我们操作过的容器通过 commit 提交作为一个镜像! 我们以后使用我没呢修改过的镜像即可
docker commit -a="Gorit" -m="add webapps" images ID 修改过的容器名称:1.0 

保存当前容器的状态,可以通过 commit 提交,获得一个镜像,就好比云服务器的快照

九、容器数据卷

9.1 容器数据卷的概念

docker 的理念:

  • 将应用于环境打包成一个镜像
  • 数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据持久化
  • MySQL,容易删除,删库跑路! 需求:MySQL 数据可以存储在本地!

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

这就是卷技术! 目录的挂载,将容器中的目录,挂载在 Linux 上面!

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

9.2 使用数据卷

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

docker run -it -v 主机目录: 容器内目录 
# 测试
docker run -it -v /home/ceshi:/home centos /bin/bash

容器之间的同步是双向的,我们以后只需要在本地修改即可,容器自动同步

9.3 MySQL 挂载实战

9.4 具名和匿名挂载

# 匿名挂载
docker run -d -P --name nginx01 -v /etc/nginx nginx
# 查看所有的 volumn 的情况
docker volume ls 
# 这里i发现,这种就是匿名的,我们在 -v 只写了容器内的路径,没有容器外的路径
# 具名挂载
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
docker volume ls
DRIVER		VOLUME	NAME
local		juming-nginx
# 通过 -v 卷名:容器内路径
# 查看一下这个卷
docker volume insepect juming-nginx
..

所有容器的卷,没有指定目录的情况下都是在: /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 -O --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
# ro 只要看到 ro接说明这个路径只能通过宿主机来操作,容器内部是无法操作的!

9.5 初识 Dockerfile

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

方式二:通过编写一个脚本,可以生成一个镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层!

touch dockerfile

# 创建一个 dockerfile 文件,名字随意,建议 dockerfile
# 文件的内容 指令(大写 参数
FROM centos
# 挂在卷
VOLUME ["volume01","volume02"]
CMD echo "-----end------"
CMD /bin/bash

构建 dockerfile

docker build -f ./dockerfile -t Gorit/centos:1.0 .
# 可以看到我们自己的镜像
docker images 

查看一下卷载的路径

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

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

9.6 数据卷容器

用法:–volumes-from 父容器名称

功能:实现容器间的数据共享

# 使用上面创建的自定义镜像
docker run -it --name docker01 Gorit/centos:1.0
docker run -it --name docker02 --volumes-from docker01 Gorit/centos:1.0
docker run -it --name docker03 --volumes-from docker01 Gorit/centos:1.0
# 然后进入任意一个环境
ls -l
# 进入数据卷目录
cd volunme01
touch aaa.txt
# 然后其他的就自动同步了

测试:可以删除 docker01,查看 docker02 和 docker03 是否还可以访问这些文件

测试文件依然可以访问

多个 mysql 实现数据共享

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
docker run -d -p 3310:3306  -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 mysql:5.7 --volumes-from mysql01 mysql:5.7
# 这个可以实现 两个容器数据同步

结论:

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

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

基于备份拷贝机制

十、DockerFile

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

10.1 创建第一个 Dockerfile (复习巩固)

构建步骤:

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

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

10.2 DockerFile 的构建过程

基本知识

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

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

步骤:开发,部署,上线运维 缺一不可

Docker 镜像已经逐渐成为企业交付的标准,必须掌握!!!

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

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

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

10.3 DockerFile 的指令

以前我们是使用别人的,现在知道这些指令后,我们来自己写一个镜像的!

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


10.4 实战测试

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

创建一个自己的 centOS

# 编写 dockerfile 的文件
FROM centos
MAINTAINER CodingGoirt<gorit@qq.com>

配置环境变量

ENV MYPATH /usr/local
WORKDIR $MYPATH

执行安装命令

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

EXPOSE 80

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

通过文件构建镜像

命令 docker build -f mydockerfile-centos -t mycemtos:0.1 .

#8 writing image sha256:d77323e0cfbddd8088a616b4005c0d2ee5d21bfa5cf771f776dbbb4e273f1835 done
#8 naming to docker.io/library/mycemtos:0.1 done
#8 DONE 0.6s

测试运行

docker run -it mycemtos:0.1

可以看到默认路径在 /usr/local

可以使用 vim 命令了

可以打开 ifconfig 了

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

  • docker history imageID

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

CMD 和 ENTIRPOINT 的区别

FROM centos
CMD ["ls","-a"]

FROM centos
ENTRYPOINT ["ls","-a"]

两者构建,在运行,效果是一样的

但是如果运行

docker run imageId -l # 前者原本的命令会被覆盖,后者是被追加在原有的命令

DockerFile 中很多命令都十分的相似,我们需要了解他们的区别,然后测试

10.5 实战 Tomcat 镜像

  1. 准备镜像文件 tomcat 压缩包,jdk 压缩包
  2. 编写 DockerFile 文件
  3. 访问镜像

10.6 发布镜像

DockerHub

  1. 地址 https://hub.docker.com/ ,并注册一个可以登录的账号
  2. 确认这个账号可以登录
  3. 在我们的服务器提交镜像
$ docker login --help
Log in to a Docker registry or cloud backend.
If no registry server is specified, the default is defined by the daemon.
Usage:
  docker login [OPTIONS] [SERVER] [flags]
  docker login [command]
Available Commands:
  azure       Log in to azure
Flags:
  -h, --help              help for login
  -p, --password string   password
      --password-stdin    Take the password from stdin
  -u, --username string   username
Global Flags:
      --config DIRECTORY   Location of the client config files DIRECTORY (default "C:\\Users\\伟\\.docker")
  -c, --context string     context
  -D, --debug              enable debug output in the logs
  -H, --host string        Daemon socket(s) to connect to
Use "docker login [command] --help" for more information about a command.
PS C:\Users\伟> docker login -ucodinggorit
Password:
Login Succeeded
docker push gorit/diytomcat:1.0
  1. 登录后可以提交镜像了
  2. docker push

阿里云镜像

  1. 登录阿里云
  2. 找到容器镜像服务
  3. 创建命名空间
  4. 创建容器镜像
  5. 根据 阿里云提供的方式拉取推

十一、Docker 网络

11.1 docker0

初始化 docker 环境

docker rmi -f $(docker images -aq)

Linux 下获取 ip地址

ip addr
# 随机启动一个
docker run -d -P --name tomcat01
PS C:\Users\伟> docker exec -it tomcat01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default qlen 1000
    link/tunnel6 :: brd ::
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
# 思考 ,linux 能不能 ping 通容器内部
#可以#
# linx 可以 ping 通 docker 容器内部

原理

  1. 我们每启动一个 docker 容器,docker 就会给 docker 容器分配个 ip,我们安装了docker,就会有个网卡 docker0,桥接模式,使用的技术是 evth-path技术!
  2. 在启动一个容器测试的时候,发现又多了一个网卡
# 我们发现这个容器带来的网卡,都是一对对的
# evth-path 就是一堆虚拟的设备接口,他们都是成对的出现,一段连着协议,一段彼此相连
# 正因为有这个特性,evth-path 充当一个桥梁,链接各种虚拟网络设备
# OpenStac,Docker 容器之间的连接,OVS 连接,都是使用 evth-pair 技术
  1. 测试 tomcat01 和 tomcat02 是否可以ping 通
    1. 容器和容器之间是可以互相 ping 通的

结论:

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

小结

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

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

11.2 – link

解决两个独立的 docker 项目不能互相 ping 的问题

docker run -d -P --name tomcat03 --link tomcat02 tomcat
docker exec -it tomcat03 ping tomcat02

# 反向可以 ping 通吗? 不可以,需要配置

可以通过 insepect 可以看到很多东西

11.3 自定义网络

查看所有 docker 网络

PS C:\Users\伟> docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
de74c8203497        bridge              bridge              local
550920e46e30        host                host                local
105ce7ef023f        none                null                local

网络模式:桥接 docker (默认)

none:不配置网络

host:和宿主机共享网络

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

测试

# 我们直接启动的命令 --net bridge,而这个就是我们的 docker0
docker run -d -P --name tomcat01 tomcat
docker -d -P --name tomcat01 --net bridge tomcat
# docker0 特点:默认域名不能访问, --link 可以打通连接
# --driver bridge 桥接
# --subnet 192.168.0.0/16
# --gateway 
PS C:\Users\伟> docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
# 我们的网络就创建好了
c81d519694cb79a3b84dda1e20b0ce76521fcd7dbd9f25ff9db38c4717dc4ec1
PS C:\Users\伟> docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
de74c8203497        bridge              bridge              local
550920e46e30        host                host                local
c81d519694cb        mynet               bridge              local
105ce7ef023f        none                null                local
# 启动
docker run -d -P --name tomcat-net-01 --net mynet tomcat
PS C:\Users\伟> docker run -d -P --name tomcat-net-01 --net mynet tomcat
29efa1bcdb47c157b3737caa313aba619ef7c521f75babe6fff606443d7b0af5
PS C:\Users\伟> docker run -d -P --name tomcat-net-02 --net mynet tomcat
29c71809d2ba670ea7ccc9d64e64a784b813458273187584aca030d6cc7af0cc
PS C:\Users\伟> 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.115 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.108 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.067 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=4 ttl=64 time=0.088 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=5 ttl=64 time=0.077 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=6 ttl=64 time=0.046 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=7 ttl=64 time=0.052 ms

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

好处:

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

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

网络连通

# 测试连通
docker netword connect mynet tomcat01
# 连通之后,就是将 tomcat01 放了 mynet 网络下
# 一个容器两个 ip 地址
# 云服务器:公网 ip  私有 ip
# 01 连通
docker exec -it tomcat01 ping tomcat-net-01
# 02 是依然打不通的
docker exec -it tomcat02 ping tomcat-net-01

结论:

  • 假设要跨王楼操作别人,就需要使用 docker network connect 连通!

11.4 实战 部署 redis 集群

  1. 创建一个网卡
# 通过脚本创建六个 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
done
# 开启一个服务
docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
# 。。。
# 创建集群
redis-cli --cluster create 172.38.0.11:6379  172.38.0.12:6379 ... --cluster-replicas 1

11.5 SpringBoot 微服务打包

1、构建 SpringBoot 项目

2、打包应用

  • 将打包出来的应用放在 项目根路径

3、编写 dockerFile

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

4、构建镜像

$ docker build -t gorit-docker-springboot .
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 159B done
#1 DONE 0.0s
#2 [internal] load .dockerignore
#2 transferring context: 2B done
#2 DONE 0.1s
#3 [internal] load metadata for docker.io/library/java:8
#3 DONE 5.7s
#4 [1/2] FROM docker.io/library/java:8@sha256:c1ff613e8ba25833d2e1940da0940...
#4 DONE 0.0s
#5 [internal] load build context
#5 transferring context: 45B
#5 transferring context: 47B done
#5 DONE 0.0s
#6 [2/2] COPY *.jar /app.jar
#6 CACHED
#7 exporting to image
#7 exporting layers done
#7 writing image sha256:79a6d059fd2b32a8f79e8c1466ffa2c610f03c42059ea591b80beb3c5b2a1ef1 done
#7 naming to docker.io/library/gorit-docker-springboot done
#7 DONE 0.0s

5、发布运行

PS C:\Users\伟\Desktop\docker\idea> docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
gorit-docker-springboot   latest              79a6d059fd2b        6 minutes ago       660MB
mytomcat01                1.0                 833d7bcc1b04        10 hours ago        653MB
tomcat                    latest              625b734f984e        41 hours ago        648MB
C:\Users\伟>docker ps
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS              PORTS                     NAMES
83badbffcc4d        gorit-docker-springboot   "java -jar /app.jar …"   12 seconds ago      Up 11 seconds       0.0.0.0:32768->8080/tcp   docker-springboot-web

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xQouAWHr-1603596651206)(G:\编程学习\电子书\数据结构与算法之美PDF版本\note\image-20201025112827701.png)]

十二、进阶内容

企业实战

Docker Compose

Docker Swarm

CI/CD jekins lin

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值