栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

05SpringCloud-Docker

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

05SpringCloud-Docker

1.什么是Docker

项目部署问题:

大型项目组件非常多,特别是微服务项目。运行环境也很复杂。

每一个不同的组件应用,依赖不同的函数库。

  • 依赖关系复杂
  • 开发、测试、生成环境差异

Docker如何解决依赖的兼容问题的?

  • 将应用的Libs ( 函数库)、Deps (依赖)配置与应用一起打包

  • 将每个应用放到一个隔离容器去运行,避免互相干扰

Ubuntu和CentOS都是基于Linux内核,只是系统应用不同,提供的函数库有差异

Docker如何解决不同系统环境的问题?

  • Docker将用户程序与所需要调用的系统(比如Ubuntu)函数库一起打包
  • Docker运行到不同操作系统时,直接基于打包的库函数,借助于操作系统的Linux内核来运行

【Docker是一个快速交付应用、运行应用的技术】

1.可以将程序及其依赖、运行环境一 起打包为一个镜像,可以迁移到任意Linux操作系统
2.运行时利用沙箱机制形成隔离容器,各个应用互不干扰
3.启动、移除都可以通过一行命令完成,方便快捷

Docker初识:

Docker如何解决大型项目依赖关系复杂,不同组件依赖的兼容性问题?

  • Docker允许开发中将应用、依赖、函数库、配置一起打包,形成可移植镜像

  • Docker应用运行在容器中,使用沙箱机制,相互隔离

Docker如何解决开发、测试、生产环境有差异的问题(操作系统不一样)?

  • Docker镜像中包含完整运行环境,包括系统函数库,仅依赖系统的Linux内核,因此可以在任意Linux操作系统上运行
2.Docker和虚拟机的差别

虚拟机(virtual machine)是在操作系统中模拟硬件设备,然后运行另一个操作系统,比如在Windows系统里面运行Ubuntu系统,这样就可以运行任意的Ubuntu应用了。



Docker在执行时直接调用操作系统内核的,所以执行性能会比虚拟机快。

其他差异:

Docker只是封装了应用必须的函数库,体积往往比较小。容器都是MB级别,虚拟机至少几个G

总结:

Docker和虚拟机的差异:

  • docker是一 个系统进程;虚拟机是在操作系统中的操作系统
  • docker体积小、 启动速度快、性能好;虚拟机体积大、启动速度慢、性能一般
3.Docker架构 镜像和容器

镜像(Image):Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像。(镜像其实就是硬盘中的文件)

容器(Container): 镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器隔离,对外不可见。

镜像都是只读的,也就是说容器在运行过程中不能向镜像写东西。你可以基于镜像去创建容器,容器可以从里面读取数据但不能写。那我将来mysql数据往哪写呢?

很简单,你拷贝一份镜像数据到自己的container里面就行。

你在写数据写到自己空间里,不会对其他容器产生影响,也不会对镜像产生影响。

Docker和DockerHub

DockerHub是一个Docker镜像的托管平台。 这样的平台称为Docker Registry。

国内也有类似于DockerHub的公开服务,比如网易云镜像服务、阿里云镜像库等。

隐私问题,可以搭建私有云。

Docker是一个CS架构的程序,由两部分组成:

  1. 服务端(server):docker守护进程,负责处理docker指令,管理镜像、容器等
  2. 客户端(client):通过命令或restAPI向docker服务端发送指令。可以在本地或远程向服务端发送指令。

使用docker,主要就是向dockerserver发命令,想办法得到镜像,不管用那种方式,然后再把镜像创建成容器运行,完成部署就可以了。

总结:

  1. 镜像:将应用程序及其依赖、环境、配置打包在一-起
  2. 容器:镜像运行起来就是容器,一个镜像可以运行多个容器
  3. Docker结构
    1. 服务端:接收命令或远程请求,操作镜像或容器
    2. 客户端:发送命令或者请求到Docker服务端
  4. DockerHub:一个镜像托管的服务器,类似的还有阿里云镜像服务,统称为DockerRegistry
4.Docker的安装

安装Docker

企业部署一般都是采用Linux操作系统,而其中又数CentOS发行版占比最多,因此我们在CentOS下安装Docker。参考课前资料中的文档:


Docker 分为 CE 和 EE 两大版本。CE 即社区版(免费,支持周期 7 个月),EE 即企业版,强调安全,付费使用,支持周期 24 个月。

Docker CE 分为 stable test 和 nightly 三个更新频道。

官方网站上有各种环境下的 安装指南,这里主要介绍 Docker CE 在 CentOS上的安装。

1.CentOS安装Docker

Docker CE 支持 64 位版本 CentOS 7,并且要求内核版本不低于 3.10, CentOS 7 满足最低内核的要求,所以我们在CentOS 7安装Docker。

1.1.卸载(可选)

如果之前安装过旧版本的Docker,可以使用下面命令卸载:

yum remove docker 
                  docker-client 
                  docker-client-latest 
                  docker-common 
                  docker-latest 
                  docker-latest-logrotate 
                  docker-logrotate 
                  docker-selinux 
                  docker-engine-selinux 
                  docker-engine 
                  docker-ce

我的是之前都没有安装过,

1.2.安装docker

首先需要大家虚拟机联网,安装yum工具

yum install -y yum-utils 
           device-mapper-persistent-data 
           lvm2 --skip-broken

然后更新本地镜像源:

# 设置docker镜像源
yum-config-manager 
    --add-repo 
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
sed -i 's/download.docker.com/mirrors.aliyun.com/docker-ce/g' /etc/yum.repos.d/docker-ce.repo

yum makecache fast

然后输入命令:

yum install -y docker-ce

docker-ce为社区免费版本。稍等片刻,docker即可安装成功。

1.3.启动docker

Docker应用需要用到各种端口,逐一去修改防火墙设置。非常麻烦,因此建议大家直接关闭防火墙!

启动docker前,一定要关闭防火墙后!!

启动docker前,一定要关闭防火墙后!!

启动docker前,一定要关闭防火墙后!!

# 关闭
systemctl stop firewalld
# 禁止开机启动防火墙
systemctl disable firewalld
# 查看防火墙状态
systemctl status firewalld

通过命令启动docker:

systemctl start docker  # 启动docker服务

systemctl stop docker  # 停止docker服务

systemctl restart docker  # 重启docker服务

systemctl status docker # docker状态

然后输入命令,可以查看docker版本:

docker -v

如图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zKwWUG0w-1637048353451)(F:1黑马程序员SpringCloud3assetsimage-20210418154704436.png)]

1.4.配置镜像加速

docker官方镜像仓库网速较差,我们需要设置国内镜像服务:

参考阿里云的镜像加速文档:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

针对Docker客户端版本大于 1.10.0 的用户

您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器

sudo mkdir -p /etc/docker

# 这里直到EOF都要复制
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://opirc3cp.mirror.aliyuncs.com"]
}
EOF

sudo systemctl daemon-reload
sudo systemctl restart docker

镜像加速配置完成。

5.镜像命令

镜像名称一般分两部分组成: [repository]:[tag]

tag:版本,mysql:5.7 / mysql:5.6是两个不同的镜像

获取镜像的方式:

  1. 本地:dockerFile 通过docker build构建镜像

  2. 远程:Docker Registry 镜像服务器 通过 docker pull 从服务器拉取镜像

查看镜像 : docker images

删除镜像:docker rmi

推送镜像到服务:docker push

保存镜像为一个压缩包:docker save

加载压缩包为镜像:docker load

查看帮助文档 : docker --help

案例

从DockerHub中拉取一个nginx镜像并查看

  1. 首先去镜像仓库搜索nginx镜像,比如DockerHub:

  2. 拉取与查看

# 拉取nginx
docker pull nginx
# 查看镜像
docker images

# 镜像内容
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
nginx        latest    04661cdce581   6 days ago   141MB



利用docker save将nginx镜像导出磁盘,然后再通过load加载回来

步骤一: 利用docker xx --help命令查看docker save和docker load的语法
步骤二: 使用docker tag创建新镜像mynginx1.0
步骤三: 使用docker save导出镜像到磁盘

[root@hadoop100 ~]# docker save --help

Usage:  docker save [OPTIONS] IMAGE [IMAGE...]

Save one or more images to a tar archive (streamed to STDOUT by default)

Options:
  -o, --output string   Write to a file, instead of STDOUT

Save one or more images to a tar archive

将一个或多个图像保存到tar存档

docker save -o nginx.tar nginx:latest

[root@hadoop100 ~]# docker save -o nginx.tar nginx:latest
[root@hadoop100 ~]# ll
total 142484
-rw-------. 1 root root 145894912 Nov 15 18:09 nginx.tar

为了演示导入,先把nginx:latest镜像删除。

docker rmi nginx:latest

[root@hadoop100 ~]# docker rmi nginx:latest
Untagged: nginx:latest
Untagged: nginx@sha256:dfef797ddddfc01645503cef9036369f03ae920cac82d344d58b637ee861fda1
Deleted: sha256:04661cdce5812210bac48a8af672915d0719e745414b4c322719ff48c7da5b83
Deleted: sha256:89fa50132ae2bb56db192e9ab716c00d7af2af7cfd2e53d89d5d2fe5816cdbad
Deleted: sha256:0e18e237ed37ff83d795813dec5318934ea8ee0ad4dc63ed3027c8b690196500
Deleted: sha256:cadf0f41ad2a811bd450c929e3a51afe060fbc0f4c3dd0e98cb73b8023877c12
Deleted: sha256:4cd32ed8e5340b498b9992d324ded5c047cc0e7d631bffeca0d0fa0f8a0def33
Deleted: sha256:d46a23eaf6e327713efe12221a2b77f2ce3eec8f68df165727fc0afde62c4a6b
Deleted: sha256:e8b689711f21f9301c40bf2131ce1a1905c3aa09def1de5ec43cf0adf652576e

导入load命令的帮助

# 查看load命令帮助文档
docker load --help	

Usage:  docker load [OPTIONS]

Load an image from a tar archive or STDIN

Options:
  -i, --input string   Read from tar archive file, instead of STDIN
  -q, --quiet          Suppress the load output

导入命令

docker load -i nginx.tar

[root@hadoop100 ~]# docker load -i nginx.tar
e8b689711f21: Loading layer  83.86MB/83.86MB
ea56d6ebf7e5: Loading layer  61.99MB/61.99MB
38aec0f8e5ed: Loading layer  3.072kB/3.072kB
fc199aaed79a: Loading layer  4.096kB/4.096kB
921ee7f55927: Loading layer  3.584kB/3.584kB
280fbd619253: Loading layer  7.168kB/7.168kB
Loaded image: nginx:latest
镜像命令练习

去DockerHub搜索并拉取一个Redis镜像
1.去DockerHub搜 索Redis镜像
2.查看Redis镜像的名称和版本
3.利用docker pull命令拉取镜像
4.利用docker save命令将redis:latest打包为一个redis.tar包
5.利用docker rmi删除本地的redis:latest
6.利用docker load重新加载redis.tar文件

1.搜索

2,3.redis名称与版本、拉取

docker pull redis:latest

# 拉取最新版本redis
docker pull redis:latest


latest: Pulling from library/redis
7d63c13d9b9b: Already exists 
a2c3b174c5ad: Pull complete 
283a10257b0f: Pull complete 
7a08c63a873a: Pull complete 
0531663a7f55: Pull complete 
9bf50efb265c: Pull complete 
Digest: sha256:54ee15a0b0d2c661d46b9bfbf55b181f9a4e7ddf8bf693eec5703dac2c0f5546
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest

4.打包

[root@hadoop100 ~]# docker save -o redis.tar redis:latest
[root@hadoop100 ~]# ll
total 256064
-rw-------. 1 root root 145894912 Nov 15 18:09 nginx.tar
-rw-------. 1 root root 116304384 Nov 15 18:18 redis.tar

5.删除

[root@hadoop100 ~]# docker rmi redis:latest
Untagged: redis:latest
Untagged: redis@sha256:54ee15a0b0d2c661d46b9bfbf55b181f9a4e7ddf8bf693eec5703dac2c0f5546
Deleted: sha256:7faaec68323851b2265bddb239bd9476c7d4e4335e9fd88cbfcc1df374dded2f
Deleted: sha256:e6deb90762475cda72e21895911f830ed99fd1cc6d920d92873270be91235274
Deleted: sha256:2649acad13241d9c8d81e49357bc66cce459b352ded7f423d70ede7bd3bb7b89
Deleted: sha256:64007bba5fc220df4d3da33cecdc2d55dd6a73528c138b0fa1acd79fd6a9c217
Deleted: sha256:b2cc2f1bf8b1cca8ba7c19e1697f7b73755903ad8f880b83673fd6a697aca935
Deleted: sha256:fbd1283ab782925be4d990bd4bebe9ad5e5cf9a525abfb6fa87465e072da9d31

6.加载

[root@hadoop100 ~]# docker load -i redis.tar 
b43651130521: Loading layer  338.4kB/338.4kB
8b9770153666: Loading layer  4.274MB/4.274MB
6b01cc47a390: Loading layer   27.8MB/27.8MB
0bd13b42de4d: Loading layer  2.048kB/2.048kB
146262eb3841: Loading layer  3.584kB/3.584kB
Loaded image: redis:latest
[root@hadoop100 ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nginx        latest    04661cdce581   6 days ago    141MB
redis        latest    7faaec683238   4 weeks ago   113MB

6.容器命令介绍

容器的三个状态:运行、暂停、停止

如果容器进入暂停状态、操作系统会将容器内的进程挂起,容器关联的内存暂存起来。CPU不再执行这个进程。但是如果你把它恢复了内存空间恢复,程序接着被运行,那么这个容器就一直运行状态了。但是停止则不同,操作系统直接杀死,容器所占的内存回收,保留下来的仅剩容器的文件系统。一旦停止你是没办法恢复的。docker start 意味着生成一个全新的进程。

docker rm 彻底删除。

7.容器命令案例1 创建运行一个Nginx容器

1.去docker hub查看Nginx的容器运行命令

docker run --name containerName -p 80:80 -d nginx

docker run

–name : 容器名称

-p : 将宿主机端口与容器端口映射,冒号左侧是宿主机端口,右侧是容器端口

比方说我有一台centos的服务器,是192.168.150.101,在这台服务器上部署了一个nginx容器,端口是80.

我们的用户想要访问nginx容器,能不能访问?

肯定不能。

容器对外是隔离的。

所以我们要做一个端口映射。比方说我们宿主机有很多端口,其中一个端口是80,我们让宿主机的80和容器的80产生一个映射,这样以来,任何进入宿主机80的请求,就都会被转发到容器的80端口,这样就等于是Nginx处理了请求。所以这个时候如果我们的客户想要访问容器,你访问这台宿主机就行。比如说:http://192.168.150.101:80,宿主机一看80,统一放到Nginx容器里去,于是容器就处理了。

所以端口映射的作用是什么?

是把一个本来完全隔离的容器,暴露一个端口,让你透过它来访问。如果没有它任何人无法访问容器。

80:80

左侧是宿主机端口(是可以任意编写的),右侧是容器内端口(一般是不变的)

-d : 代表后台运行容器,不加则是前台运行。在后台运行,即不想在前面看到它,让他在后面默默执行。

nginx: 镜像名称,没有写标签,是最新版

[root@hadoop100 ~]# docker run --name mn -p 80:80 -d nginx
8837ea3e6c6d1a830dd048e800be5be730920a60fda98e3bf127b84b455e45ba #容器的唯一ID

查看容器运行状态

[root@hadoop100 ~]# docker ps
ConTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                               NAMES
8837ea3e6c6d   nginx     "/docker-entrypoint.…"   28 seconds ago   Up 27 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   mn

在宿主机访问一下,我这台centos虚拟机的ip地址是192.168.10.100,

我在window系统web访问的地址就应该是 http://192.168.10.100:80

容器部署成功

查看日志docker logs mn, mn是容器名

[root@hadoop100 ~]# docker logs mn
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/11/16 02:36:53 [notice] 1#1: using the "epoll" event method
2021/11/16 02:36:53 [notice] 1#1: nginx/1.21.4
2021/11/16 02:36:53 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6) 
2021/11/16 02:36:53 [notice] 1#1: OS: Linux 3.10.0-1160.el7.x86_64
2021/11/16 02:36:53 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/11/16 02:36:53 [notice] 1#1: start worker processes
2021/11/16 02:36:53 [notice] 1#1: start worker process 31
192.168.10.1 - - [16/Nov/2021:02:39:23 +0000] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36" "-"
2021/11/16 02:39:23 [error] 31#31: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.10.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "192.168.10.100", referrer: "http://192.168.10.100/"
192.168.10.1 - - [16/Nov/2021:02:39:23 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://192.168.10.100/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36" "-"

我想要持续监控日志怎么设置?

docker logs -f mn

可以一直跟踪日志

8.容器命令案例2

进入Nginx容器,修改HTML文件内容,添加信息

步骤一:进入容器。进入我们刚刚创建的nginx容器的命令为:

docker exec -it mn bash

# docker exec : 进入容器内部,执行一个命令
# -it : 给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互。
# mn : 容器名称
# bash : 进入容器后执行的命令,bash是一个linux终端交互命令。如果你有其他的命令要执行,这里也可以修改成你要执行的命令。

[root@hadoop100 ~]# docker exec -it mn bash
root@8837ea3e6c6d:/# 
root@8837ea3e6c6d:/# cd /usr/share/nginx/html/
root@8837ea3e6c6d:/usr/share/nginx/html# ls
50x.html  index.html

容器的内部其实会有自己的一套文件系统(阉割版)

sed -i 's#Welcome to nginx#哈哈哈哈哈#g' index.html
sed -i 's###g' index.html

exit 						# 退出容器
docker stop mn 				# 停止mn容器运行
docker ps -a 				# 查看所有包括停止的容器信息
docker start mn 			# 运行mn容器
docker rm -f mn 			# 强制删除mn

进入容器:

  • 命令是docker exec -it [容器名] [要执行的命令]
  • exec命令可以进入容器修改文件,但是在容器内修改文件是不推荐的I
9.容器命令练习

创建并运行一个redis容器,并且支持数据持久化
步骤一: 到DockerHub搜索Redis镜像
步骤二: 查看Redis镜像文档中的帮助信息
步骤三: 利用docker run命令运行一个Redis容器

docker run --name some-redis -d redis

# 用这个,配置好端口映射,myredis容器名
docker run --name myredis -p 6379:6379 -d redis redis-server --appendonly yes

[root@hadoop100 ~]# docker run --name myredis -d redis
833f9c68d82ff2e4f08f6ae6e173c4a0651be0ab401f27fd00a697e946f9f599


在我的windows拦截redis的地址应该是 192.168.10.100:6379

进入redis容器,并执行redis-cli客户端命令,存入num=666

docker exec -it myredis bash

# 直接进入redis-cli方式
docker exec -it myredis redis-cli

root@833f9c68d82f:/data# ls
root@833f9c68d82f:/data# redis-cli
127.0.0.1:6379> set mynum 666
OK
127.0.0.1:6379> get mynum
"666"
127.0.0.1:6379> 

10.数据卷命令

发现一个问题,容器和数据是耦合的,因此带来很多问题。

1.不便于修改:如我们该nginx的html需要进入容器内部修改

2.数据不可复用:容器内的修改对外是不可见的。所有修改对新创建的容器是不可复用的。

3.升级维护困难:数据在容器内,如果要升级容器必然删除旧容器,所有数据都跟着删除了。

数据卷(volume): 是一个虚拟目录,指向宿主机文件系统中的某个目录。

操作数据卷:

docker volume [command]

#create 创建volume
#inspect 	显示一个或多个volume信息
#ls 	列出所有的volume
#prune 	删除未使用的volume
#rm 	删除一个或多个指定的volume

案例:

创建一个数据卷,并查看数据卷在宿主机的目录位置

  1. 创建数据卷

    docker volume --help
    
    # 创建数据卷
    docker volume create html
    # 查看数据卷
    docker volume ls
    # 查看数据卷详细信息
    docker volume inspect html
    
    # 删除未使用的数据卷
    docker volume prune
    # 删除html这个数据卷
    docker volume rm html 
    

总结:

1.数据卷的作用:

  • 将容器与数据分离,解耦合,方便操作容器内数据保证数据安全。

2.数据卷操作

  • docker volume create
  • docker volume ls
  • docker volume inspect
  • docker volume rm
  • docker volume prune
11.数据卷挂载案例1

创建一个nginx容器,修改容器内的html目录内的index.html内容

需求说明:上个案例中,我们进入nginx容器内部,已经知道nginx的html目录所在位置/usr/share/ nginx/html,我们需要把这个目录挂载到html这个数据卷上,方便操作其中的内容。

提示: 运行容器时使用-V参数挂载数据卷

# 创建一个名为mn的nginx的容器,将镜像内/usr/share/nginx/html的内容挂载到html数据卷上
docker run --name mn -p 80:80 -v html:/usr/share/nginx/html -d nginx


docker ps
...
196bd4eaba5b   nginx     "/docker-entrypoint.…"   8 seconds ago    Up 7 seconds    0.0.0.0:80->80/tcp, :::80->80/tcp           mn

docker inspect html
[
    {
        "CreatedAt": "2021-11-15T19:22:34-08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/html/_data",
        "Name": "html",
        "Options": {},
        "Scope": "local"
    }
]



修改内容方式一

cd /var/lib/docker/volumes/html/_data
vim index.html

方式二,采用XFTP 直接改/var/lib/docker/volumes/html/_data 目录下的内容即可

修改后

现在直接可以在高级编辑工具里修改!

现在测试一下 数据卷是不存在的情况:

如果容器运行时volume不存在,会自动被创建出来!【所以我们没必要自己创建数据卷】

  1. 先删除刚运行的容器
docker rm -f mn
mn
[root@hadoop100 _data]# docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
html

Total reclaimed space: 1.144kB
[root@hadoop100 _data]# docker volume ls
DRIVER    VOLUME NAME
local     6a77edff06b613d92e73d319467ce40616ba6fb002774d2bdc227b4b03108181
[root@hadoop100 _data]# 

2.运行

docker run --name mn -p 80:80 -v html:/usr/share/nginx/html -d nginx

访问网页,可行!

如果我们数据卷不存在,docker会自动帮你把数据卷创建出来。

12.数据卷挂载案例2

创建并运行一个MySQL容器,将宿主机目录直接挂载到容器

提示:目录挂载与数据卷挂载的语法是类似的:
-V [宿主机目录]:[容器内目录]
-V [宿主机文件]:[容器内文件]

实现思路如下:

1.在将课前资料中的mysql.tar文件上传到虚拟机,通过load命令加载为镜像
2.创建目录/tmp/myql/data
3.创建目录/tmp/myql/conf,将课前资料提供的hmy.cnf文件上传到/tmp/mysql/conf
4.去DockerHub查阅资料, 创建并运行MySQL容器,要求:
①挂载/tmp/ myql/data到mysql容器内数据存储目录
②挂载/tmp/ myql/conf/hmy.cnf到mysql容器的配置文件
③设置MySQL密码

1.镜像导入

将mysql.tar导入到/opt/software目录

docker load -i mysql.tar

2. 创建目录
[root@hadoop100 software]# mkdir -p mysql/data
[root@hadoop100 software]# mkdir -p mysql/conf

/opt/software/mysql/conf下上传hmy.cnf

3.运行mysql容器
docker run 
--name mymysql 
-e MYSQL_ROOT_PASSWORD=123 
-p 3306:3306 
-v /opt/software/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf 
-v /opt/software/mysql/data:/var/lib/mysql 
-d mysql:5.7.25

前面是宿主机地址,后面是Mysql的地址

-v /opt/software/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf 配置文件

-v /opt/software/mysql/data:/var/lib/mysql 数据文件

所有的数据都挂载到了data目录下

测试用navicat连接一下

192.168.10.100:3306

总结

  1. docker run的命令中通过-V参数挂载文件或目录到容器中:
    ①-V volume名称:容器内目录
    ②-V 宿主机文件:容器内文件
    ③-V 宿主机目录:容器内目录
  2. 数据卷挂载与目录直接挂载的
    ①数据卷挂载耦合度低,由docker来管理目录,但是目录较深,不好找
    ②目录挂载耦合度高,需要我们自己管理目录,不过目录容易寻找查看
13.自定义镜像

Dockerfile自定义镜像,我们以后直接写的微服务就需要自己定义镜像。之前学习的都是官方的镜像

13.1 镜像结构

镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。

系统函数库、环境、配置、依赖,这就是镜像的组成,而我们说结构,还需要了解他们是怎么组成的。

这些的组成他们有没有相互的依赖关系或顺序呢?显然是有的,如果没有最底层的系统函数库,底层的文件系统,你怎么样去完成环境的配置?如果没有配置环境变量,你怎么做依赖的安装呢?如果没有依赖的安装,你怎么完成应用的安装呢?如果没有应用安装,你怎么做应用的配置呢?可见,镜像不仅仅是把这一堆的东西糅在一起。

接下来以mysql为例,将mysql镜像打散。

  1. 基础镜像:应用依赖的系统函数库,环境,配置,文件

  2. 层:在基础镜像基础上添加安装包、依赖、配置等,每次操作都形成新的一层。

    如果分层了,整完基础、配置、文件都分为独立一层,我现在想构建5.8,也就上面几层不想要了,下面几层还是可以用的,我可以基于他们往上构建,提供一定复用性。【我们自己构建镜像,也应该从基础开始,逐层构建】

  3. 入口:镜像运行入口,一般是程序启动的脚本和参数

总结:

镜像是分层结构,每一-层称为一个Layer

  1. baselmage层: 包含基本的系统函数库、环境变量、文件系统
  2. Entrypoint: 入口,是镜像中 应用启动的命令
  3. 其它: 在baselmage基础上添加依赖、安装程序、完成整个应用的安装和配置
13.2 Dockerfile

什么是Dockerfile

Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。

  1. FROM centos:6 表示基于centos6去构建基础镜像
  2. ENV key value 表示是键值对
  3. COPY ./mysql-5.7.rpm /tmp 本地拷贝到镜像里
  4. RUN 一般是安装命令
  5. EXPOSE 暴露端口,只是指定容器内监听的是什么端口,是给镜像使用者看,使用者一看是8080,那我-p参数:后面那一部分就必须写8080
    比如说这条命令:docker run --name containerName -p 80:80 -d nginx,冒号后面的值就必须写8080.(EXPOSE 加或者不加其实都可以,加的话,镜像使用者看了能够明白)
  6. ENTRYPOINT:启动命令

更新详细语法说明,请参考官网文档: https://docs.docker.com/engine/reference/builder

基于Ubuntu镜像构建一个新镜像, 运行一个java项目

步骤1:新建一个空文件夹docker-demo
步骤2:拷贝课前资料中的docker-demo.jar文件到docker-demo这个目录
步骤3:拷贝课前资料中的jdk8.tar.gz文件到docker-demo这个目录
步骤4:拷贝课前资料提供的Dockerfile到docker-demo这个目录
步骤5:进入docker-demo
步骤6:运行命令:docker build -t javaweb:1.0

我们观察一下Dockerfile文件

# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录
ENV JAVA_DIR=/usr/local

# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar

# 安装JDK
RUN cd $JAVA_DIR 
 && tar -xf ./jdk8.tar.gz 
 && mv ./jdk1.8.0_144 ./java8

# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin

# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar

打开xshell, 先在某个目录下创建dockerdemo,上传jdk,jar,dockerfile

执行如下命令,在docker-demo文件下。其中 -t 是 -tag的缩写,javaweb和1.0可以任意取。

【最后有一个点,代表dockerfile的位置】

docker build -t javaweb:1.0 .

运行

docker run --name web -p 8090:8090 -d javaweb:1.0

访问 http://192.168.10.100:8090/hello/count 能够访问。说明项目已经成功构建镜像,并部署到服务器了。

观察一下dockerfile,发现,除了copy指令,其他的指令都应该是可以复用的。那么能不能把其他除了部署jar的指令以外的指令,先行打包好称为一个镜像。后面直接部署jar呢?

基于java:8-alpine镜像,将一个Java项目构建为镜像

这个镜像已经帮我们把前n步给做完了。我们构建时以java:8-alpine 为基础时,就可以省去一大部分的安装JDK

修改后的Dockerfile文件

# 指定基础镜像
FROM java:8-alpine
COPY ./docker-demo.jar /tmp/app.jar
# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar

再次构建一次

    docker build -t javaweb:2.0 .
[root@hadoop100 docker-demo]# docker build -t javaweb:2.0 .
Sending build context to Docker daemon  211.1MB
Step 1/4 : FROM java:8-alpine
# 只需要4步就能拉取完成了!!!

实现思路如下:

①新建一个空的目录,然后在目录中新建一个文件,命名为Dockerfile

②拷贝课前资料提供的docker-demojar到这个目录中

③编写Dockerfile文件:

  1. 基于java:8-alpine作 为基础镜像
  2. 将app.jar拷 贝到镜像中
  3. 暴露端口
  4. 编写入口ENTRYPOINT

④使用docker build命令构建镜像

⑤使用docker run创建容器并运行

14.DockerCompose 14.1 初始化Compose

我们学了这么多,但是这些步骤都是我们手动一个个去部署的,在实际生产环境下,我们微服务的数量是非常多的。不可能一个个去构建!所以,我们必须要有一个集群部署的手段。 ——Compose

DockerCompose 是什么?

Docker Compose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动-一个个创建和运行容器!

【分布式应用部署的帮手】

Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。

就是将之前的docker run命令变成一种便于观察的yml格式

对比之前的书写

# mysql 容器
docker run 
--name mymysql 
-e MYSQL_ROOT_PASSWORD=123 
-p 3306:3306 
-v /opt/software/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf 
-v /opt/software/mysql/data:/var/lib/mysql 
-d mysql:5.7.25


# 构建镜像
docker build -t web:1.0
# 运行容器
docker build -t javaweb:2.0 .

模板

version: "3.8"

services:
	mysql:
		image: mysql:5.7.25
        environment:
        	MYSQL_ROOT_PASSWORD: 123
        volumes:
        - /opt/software/mysql/data:/var/lib/mysql
        - /opt/software/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf
    web:
    	build: .
    	ports:
    	- 8090:8090

mysql 仅仅是供给给集群内的服务用的,因此无需暴露端口,内部能访问就行了。

volumes 两个数据卷配置,具体配置内容是和之前完全一样的。

dockerCompose就是把docker run 各种参数转换成指令去执行的。

DockerCompose的详细语法参考官网: https://docs.docker.com/compose/compose-file/

将资料里的docker-compose,上传到/user/local/bin/目录

修改文件权限

chmod +x /usr/local/bin/docker-compose

base自动补全命令

# 补全命令
curl -L https://raw.githubusercontent.com/docker/compose/1.29.1/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose

如果这里出现错误,需要修改自己的hosts文件:

echo "199.232.68.133 raw.githubusercontent.com" >> /etc/hosts

总结:

DockerCompose有什么作用?

帮助我们快速部署分布式应用,无需-一个个微服务去构建镜像和部署。

14.2 初始化微服务集群

将之前学习的cloud-demo微服务集群利用DockerCompose部署

第一步

查看课前资料提供的cloud-demo文件夹,里面已经编写好了docker-compose文件

观察docker-compose.yml

version: "3.2"

services:
  nacos:
    image: nacos/nacos-server
    environment:
      MODE: standalone
    ports:
      - "8848:8848"
  mysql:
    image: mysql:5.7.25
    environment:
      MYSQL_ROOT_PASSWORD: 123
    volumes:
      - "$PWD/mysql/data:/var/lib/mysql"
      - "$PWD/mysql/conf:/etc/mysql/conf.d/"
  userservice:
    build: ./user-service
  orderservice:
    build: ./order-service
  gateway:
    build: ./gateway
    ports:
      - "10010:10010"

docker-compose在底层实现了服务间访问地址的转变,比如说,gateway想要访问orderservice服务,可以用服务名代替ip地址。我们之前在项目中用都是用localhost写的ip地址。我们需要去修改一下,改成服务名。

第二步

修改自己的cloud-demo项目,将数据库、nacos地址都命名为docker-compose中的服务名

改动1:

user-service / bootstrap.yml

server-addr: localhost:8848
server-addr: nacos:8848

改动2:

user-service / applicaiton.yml

    url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
    url: jdbc:mysql://mysql:3306/cloud_user?useSSL=false

改动3:

order-service / application.yml

url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
url: jdbc:mysql://mysql:3306/cloud_order?useSSL=false

server-addr: localhost:8848
server-addr: nacos:8848

改动4:

gateway / application.yml

server-addr: localhost:8848
server-addr: nacos:8848
第三步

使用maven打包工具,将项目中的每个微服务都打包为app.jar

观察 user-service 的pom.xml存在以下内容,打包文件名被设置为了app。并将这个配置复制到order-service,gateway


    app
    
        
            org.springframework.boot
            spring-boot-maven-plugin
        
    

将项目中打包生成的app.jar分别复制到cloud-demo各自的文件夹下

万事俱备!

第四步

将cloud-demo上传至虚拟机,利用docker-compose up -d来部署

docker-compose up -d

查看日志

docker-compose logs -f

报错

 Caused by: java.lang.reflect.UndeclaredThrowableException: null
gateway_1       | 	at org.springframework.util.ReflectionUtils.rethrowRuntimeException(ReflectionUtils.java:147) ~[spring-core-5.2.13.RELEASE.jar!/:5.2.13.RELEASE]
gateway_1       | 	at com.alibaba.cloud.nacos.registry.NacosServiceRegistry.register(NacosServiceRegistry.java:83) ~[spring-cloud-starter-alibaba-nacos-discovery-2.2.5.RELEASE.jar!/:2.2.5.RELEASE]

因先是userservice启动,往下才是nacos启动,nacos启动太慢。生成部署时,nacos环境应先部署,而后再去部署微服务

重启除了nacos外的微服务

docker-compose restart gateway userservice orderservice

访问报错,权限问题

 ### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Access denied for user 'root'@'172.18.0.2' (using password: YES)] with root cause

进入运行中的mysql容器,进入mysql

# 如果你需要修改mysql密码请执行,【password('这里是你的新密码')】
set password for root @localhost = password('root');

# by 'root' 中root是你的新密码
grant all privileges on *.* to root@'%' identified by 'root' with grant option;

# 刷新权限
flush privileges;

然后再访问地址:

http://192.168.10.100:10010/user/2?authorization=admin

访问成功

15.镜像仓库

镜像仓库( Docker Registry )有公共的和私有的两种形式:

公共仓库:例如Docker官方的Docker Hub,国内也有-些云服务商提供类似于Docker Hub的公开服务,比如网易云镜像服务、DaoCloud 镜像服务、阿里云镜像服务等。

除了使用公开仓库外,用户还可以在本地搭建私有Docker Registry。 企业自己的镜像最好是采用私有Docker
Registry来实现。

搭建私有镜像仓库

配置Docker信任地址

我们的私服采用的是http协议,默认不被Docker信任,所以需要做一个配置:

# 打开要修改的文件
vi /etc/docker/daemon.json
# 添加内容:
"insecure-registries":["http://192.168.10.100:8080"]
# 重加载
systemctl daemon-reload
# 重启docker
systemctl restart docker

新建个文件夹mkdir registry-ui

新建个文件 touch docker-compose.yml

将以下内容写入该文件

带有图形化界面版本

使用DockerCompose部署带有图象界面的DockerRegistry,命令如下:

version: '3.0'
services:
  registry:
    image: registry
    volumes:
      - ./registry-data:/var/lib/registry
  ui:
    image: joxit/docker-registry-ui:static
    ports:
      - 8080:80
    environment:
      - REGISTRY_TITLE=传智教育私有仓库
      - REGISTRY_URL=http://registry:5000
    depends_on:
      - registry

执行

docker-compose up -d

开始构建一个私有仓库

访问 http://192.168.10.100:8080

如何上传镜像到私有仓库?

打包

[root@hadoop100 registry-ui]# docker images
REPOSITORY                 TAG        IMAGE ID       CREATED          SIZE
cloud-demo_gateway         latest     b4732b29dd7a   47 minutes ago   185MB
cloud-demo_orderservice    latest     6e5ed0e753d3   48 minutes ago   187MB
cloud-demo_userservice     latest     818b29d17379   48 minutes ago   184MB
javaweb                    2.0        355e1a3a0444   2 hours ago      171MB
javaweb                    1.0        7bc0acdff822   2 hours ago      722MB
registry                   latest     b8604a3fe854   3 days ago       26.2MB
nginx                      latest     04661cdce581   6 days ago       141MB
redis                      latest     7faaec683238   4 weeks ago      113MB
ubuntu                     16.04      b6f507652425   2 months ago     135MB
nacos/nacos-server         latest     bdf60dc2ada3   3 months ago     1.05GB
joxit/docker-registry-ui   static     c97caf4d3877   6 months ago     24.5MB
mysql                      5.7.25     98455b9624a9   2 years ago      372MB
java                       8-alpine   3fd9dd82815c   4 years ago      145MB
[root@hadoop100 registry-ui]# docker tag nginx:latest 192.168.10.100:8080/nginx:1.0

ID都是一样的

192.168.10.100:8080/nginx   1.0        04661cdce581   6 days ago       141MB
nginx                       latest     04661cdce581   6 days ago       141MB

推送镜像

docker push 192.168.10.100:8080/nginx:1.0

拉取镜像

docker pull 192.168.10.100:8080/nginx:1.0

测试拉取之前先把本地的删除掉

docker rmi 192.168.10.100:8080/nginx:1.0
其他

简化版镜像仓库

Docker官方的Docker Registry是一个基础版本的Docker镜像仓库,具备仓库管理的完整功能,但是没有图形化界面。

搭建方式比较简单,命令如下:

docker run -d 
    --restart=always 
    --name registry	
    -p 5000:5000 
    -v registry-data:/var/lib/registry 
    registry

命令中挂载了一个数据卷registry-data到容器内的/var/lib/registry 目录,这是私有镜像库存放数据的目录。

访问http://YourIp:5000/v2/_catalog 可以查看当前私有镜像服务中包含的镜像

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/511997.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号