当前位置: 首页 > news >正文

【微服务】Docker 容器化

一、初识Docker

1. 为什么需要 Docker

大型项目组件较多,运行环境也较为复杂,部署时会遇到一些问题:

  • 依赖关系复杂,容易出现兼容性的问题
  • 开发、测试、生产环境有差异

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

  • 将应用的Libs(函数库)、Deps(依赖)、配置与应用一起打包
  • 将每个应用放到一个隔离容器去运行,避免互相干扰

不同环境的操作系统不同,Docker如何解决?我们先来了解下操作系统结构

  • 开发人员基于函数库开发。程序调用函数库,函数库调用内核指令,内核指令调用硬件。

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

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

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

2. Docker 与虚拟机

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

虚拟机运行时会先运行虚拟机自身的操作系统,再由 Hypervisor 调用外部的操作系统(安装了虚拟机的操作系统)。

Docker 与 虚拟机的性能比较

镜像和容器

  • 镜像(ImageDocker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像。
  • 容器(Container:镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器做隔离,对外不可见

 DockerDockerHub

  • DockerHub:DockerHub是一个Docker镜像的托管平台。这样的平台称为Docker Registry
  • 国内也有类似于DockerHub 的公开服务比如 网易云镜像服务阿里云镜像库等。

3. Docker架构

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

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

4. 小结

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

1. 将程序及其依赖、运行环境一起打包为一个镜像,可以迁移到任意Linux操作系统

2. 运行时利用沙箱机制形成隔离容器,各个应用互不干扰

3. 启动、移除都可以通过一行命令完成,方便快捷


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

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

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


Docker如何解决开发、测试、生产环境有差异的问题

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


Docker和虚拟机的差异:

docker是一个系统进程;虚拟机是在操作系统中的操作系统

docker体积小、启动速度快、性能好;虚拟机体积大、启动速度慢、性能一般


镜像

将应用程序及其依赖、环境、配置打包在一起

容器

镜像运行起来就是容器,一个镜像可以运行多个容器

Docker结构

服务端:接收命令或远程请求,操作镜像或容器

客户端:发送命令或者请求到Docker服务端

DockerHub

一个镜像托管的服务器,类似的还有阿里云镜像服务,统称为DockerRegistry

Docker工作流

构建自定义镜像或者从DockerRegistry拉取镜像; 根据镜像创建容器,并运行

二、Docker的基本操作

1. 安装 Docker

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

卸载:

如果之前安装过旧版本的 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. 首先需要大家虚拟机联网,安装yum工具

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

 2. 然后更新本地镜像源:

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

3. 安装 Docker

yum install -y docker-ce

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

systemctl stop firewalld     # 关闭防火墙systemctl disable firewalld  # 禁止防火墙自启动systemctl status firewalld  # 查看防火墙状态
systemctl start docker  # 启动docker服务systemctl stop docker  # 停止docker服务systemctl restart docker  # 重启docker服务systemctl enable docker  # 开启自动开启docker服务systemctl status docker # docker服务的状态

5. 可以查看docker版本: 

docker -v   

至此 Docker 按照上述步骤就可以了,但是 docker官方镜像仓库网速较差,我们需要设置国内镜像服务:参考阿里云镜像加速文档

 2. 镜像操作

2.1 镜像名称的组成

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

在没有指定tag时,默认是latest,代表最新版本的镜像

上图展示的 mysql 是 repository,5.7是tag,合并在一起就是镜像名称,代表5.7版本的MySQL镜像。

2.2 常见镜像命令

  • docker --help 查看所有的命令
docker --help
  • docker **  --help 命令查看指定的指令用法。如查看 images 的命令
docker images --help

2.3 案例

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

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

2. 通过命令拉取自己需要的镜像:docker pull nginx

3. 查看拉取到的镜像: docker images 【nginx】

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

1. 利用docker xx --help命令查看docker savedocker load的语法

2. 使用docker save导出镜像到磁盘

docker save -o [保存的目标文件名称] [镜像名称]

例如:docker save -o nginx.tar nginx:latest。这条命令分解解释:

docker save  保存命令

-o 写出文件

nginx.tar  将文件写出到 nginx.tar 这个文件中

nginx: latest  镜像名称


3. 使用docker load加载镜像

加载之前删除之前拉取的nignx 镜像

docker rmi nginx:latest

加载本地文件

docker load -i nginx.tar

-i 是 input  的简写 

查看镜像

docker images

3. 容器操作

3.1 容器命令

docker exec 进入容器执行命令

docker logs 查看容器运行日志,添加 -f 参数可以持续查看日志, 

cocker logs -f  日志名

docker ps 查看所有运行的容器及状态, 添加 -a 参数查看所有转台的容器,

如 docker ps -a

docker rm 容器名 删除指定容器,不能删除正在运行的容器,除非添加 -f 参数,

如 docker rm 容器名 -f 

docker commit 容器id 镜像名称:版本号        // 容器转镜像

docker save -o 压缩文件名称 镜像名称:版本号              // 打包成压缩文件

docker load -i 压缩文件名称              // 压缩文件转镜像

暂停:进程暂停,CPU不再运行,并不释放内存

停止:进程终止,回收进程占用的内存、CPU等资源

3.2 创建并运行容器

docker run --name 容器名 -p 80:80 -d nginx

命令解读:

docker run :创建并运行一个容器

--name : 给容器起一个名字,比如叫做mn

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

-d:后台运行容器

nginx:镜像名称

如下图,因为容器有个沙箱隔离机制,所有外部的请求访问这个容器时是访问不了的。因此,需要对宿主主机端口号与容器端口进行映射,请求直接访问宿主主机端口80,由宿主主机访问容器端口80。

3.3 案例

 案例一 :进入Nginx容器,修改HTML文件内容,添加“传智教育欢迎您”

1. 进入容器。进入我们上面创建的nginx容器的命令:

docker exec -it [容器名] [要执行的命令]

例如:docker exec -it mn bash  

命令解读

docker exec  进入容器内部

-it        给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互

mn      要进入的容器的名称

bash   进入容器后执行的命令,bash是一个linux终端交互命令,可替换为其它命令

容器内部会模拟一个独立的Linux文件系统,看起来如同一个linux服务器一样,nginx 的环境、配置、运行文件都在这里。

2. 进入nginxHTML所在目录 /usr/share/nginx/html

cd /usr/share/nginx/html

3. 修改index.html的内容,由于容器内没有 vi 命令,无法直接修改,只能借助下面命令修改

sed -i 's#Welcome to nginx#传智教育欢迎您#g' index.html
sed -i 's#<head>#<head><meta charset="utf-8">#g' index.html

 4. 在浏览器访问自己的虚拟机 ip 加上端口即可访问

4. 数据卷

4.1 为什么需要数据卷

  • 修改 nginx 的html页面时,需要进入到nginx 内部;
  • 并且没有编辑器,修改文件不方便;
  • 如果删除容器后在容器内的所有修改都不会保留。

如果使用数据卷,可以把容器和数据分离,降低耦合度,操作方便,便于维护,保证数据安全。

4.2 什么是数据卷

数据卷(volume)是一个虚拟目录,指向宿主机文件系统中的某个目录。一个数据卷可以同时被多个容器挂载

如图,容器中的conf 、html 两个文件夹,指向了宿主机 volumes 目录下的 conf、html文件夹。一旦完成数据卷挂载,对容器的操作就会作用在数据卷对应的宿主主机上。同时,宿主主机和容器形成了双向绑定,这就就可以不进入容器修改数据了。

4.3 数据卷命令

docker volume [COMMAND]

docker volume命令是数据卷操作,根据命令后跟随的command来确定下一步的操作:

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

1. 创建数据卷

docker volume create [数据卷名字]
# 如
docker volume create html

2. 查看所有数据

docker volume ls

3. 查看数据卷详细信息

docker volume inspect [数据卷名字]
# 例
docker volume inspect html

4. 挂载数据卷

通过 -v 参数来挂载一个数据卷到某个容器内目录,命令格式如下

docker run \--name mn \-v html:/root/html \-p 8080:80nginx \

命令解析 

docker run: 创建并运行容器

--name mn  给容器取名为 mn

-v html:/root/html:  把html数据卷挂载到容器内的/root/html这个目录中

-p 8080:80  把宿主机的8080端口映射到容器的80端口

nginx 镜像名称

5. 挂载本地目录 

容器不仅仅可以挂载数据卷,也可以直接挂载到宿主机目录上。关联关系如下:

带数据卷模式:宿主机目录 --> 数据卷 —> 容器内目录
直接挂载模式:宿主机目录 —> 容器内目录

目录挂载与数据卷挂载的语法是类似的:

-v [宿主机目录]:[容器内目录]
-v [宿主机文件]:[容器内文件]

数据卷挂载与本地直接挂载的对比:

  • 数据卷挂载耦合度低,由docker来管理目录,但是目录较深,不好找
  • 目录挂载耦合度高,需要我们自己管理目录,不过目录容易寻找查看 

4.4 挂载数据卷案例1

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

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

1. 创建容器并挂载数据卷到容器内的HTML目录

# -d : 后台运行   nginx 是镜像名称
docker run --name mn -v html:/usr/share/nginx/html -p 80:80 -d nginx

2. 进入HTML数据卷所在位置,并修改HTML内容

# 查看html数据卷的位置
docker volume inspect html
# 进入该目录
cd /var/lib/docker/volumes/html/_data
# 修改文件,自定义内容
vi index.html
# 修改后按ESC,再输入:wq回车即可退出

 4.5 挂在数据卷案例2

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

实现思路:

  1. 在DockerHub 中拉取 mysql 镜像
  2. 在本机上创建目录 /tmp/mysql/data  和 /tmp/mysql/conf
  3. 将自己的配置文件 hmy.cnf 上传到 /tmp/mysql/conf
  4. 在DockerHub查阅资料,创建并运行MySQL容器,要求:
  • 挂载/tmp/mysql/data到mysql容器内数据存储目录
  • 挂载/tmp/mysql/conf/hmy.cnf到mysql容器的配置文件
  • 设置MySQL密码
docker run \
--name mysql  \
-e MYSQL_ROOT_PASSWORD=123 \
-p 3307:3306 \
-v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf  \
-v /tmp/mysql/data:/var/lib/mysql  \ 
-d \
mysql:5.7.25

-e 表示环境变量,-d 表示后台运行, -p 端口 

三、Dockerfile自定义镜像

常见的镜像在DockerHub就能找到,但是我们自己写的项目就必须自己构建镜像了。知己知彼方能百战百胜,自己构建镜像首先要了解镜像的结构。

1. 镜像结构

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

下图是 mysql 的组成结构:

镜像就是在系统函数库、运行环境基础上,添加应用程序文件、配置文件、依赖文件等组合,然后编写好启动脚本打包在一起形成的文件。

我们要构建镜像,其实就是实现上述打包的过程。

2. Dockerfile

Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction)用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。第一行必须是FROM,从一个基础镜像来构建。基础镜像可以是基本操作系统,如Ubuntu。也可以是其他人制作好的镜像,例如:java:8-alpine

 更新详细语法说明,请参考官网文档: Dockerfile reference | Docker Docs 

构建自定义的镜像时,并不需要一个个文件去拷贝,打包。只需要告诉Docker,我们的镜像的组成,需要哪些BaseImage、需要拷贝什么文件、需要安装什么依赖、启动脚本是什么,将来Docker会帮助我们构建镜像。

3. 案例

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

步骤1:在电脑上新建一个空文件夹docker-demo

步骤2:拷贝资料中的docker-demo.jar文件到docker-demo这个目录

步骤3:拷贝资料中的jdk8.tar.gz文件到docker-demo这个目录

步骤4:拷贝资料提供的Dockerfile到docker-demo这个目录

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

步骤5:将上述准备好的docker-demo上传到虚拟机任意目录,然后进入docker-demo目录下

步骤6:构建镜像:

# docker build -t 镜像名:镜像版本号 .
docker build -t javaweb:1.0 .

-t 全称是 tag,  点(.)表示当前目录

步骤7:创建容器并运行

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

最后访问 http://192.168.150.101:8090/hello/count,其中的ip改成自己的ip 

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

虽然可以基于Ubuntu基础镜像, 添加任意自己需要的安装包构建镜像,但是却比较麻烦。所以大多数情况下,我们都可以在一些安装了部分软件的基础镜像上做改造。

例如,构建java项目的镜像,可以在已经准备了JDK的基础镜像基础上构建。

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

实现思路:

  1. 新建一个空的目录,在目录中新建一个名为Dockerfile的文件
  2. 拷贝上述资料提供的docker-demo.jar到这个目录中

  3. 编写Dockerfile文件步骤如下:

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

   编写Dockerfile文件入口内容如下:

FROM java:8-alpine
COPY ./app.jar /tmp/app.jar
EXPOSE 8090
ENTRYPOINT java -jar /tmp/app.jar

 4. 使用docker build命令构建镜像

docker build -t javaweb:1.0 .

5. 使用docker run创建容器并运行

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

  最后访问 http://192.168.150.101:8090/hello/count 

四、Docker-Compose

Docker Compose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。详细语法参考官网 DockerCompose

1. 初识 Docker-Compose

Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。可以看做是将多个docker run命令写在一个文件里,只是语法微有差异。格式如下所示:

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

 上面包含了 mysql 和 web 两个容器:

  • mysql: 基于 mysql:5.7.25 镜像构建的镜像挂载了两个目录
  • web: 基于docker build 临时构建的镜像容器,映射端口是8090

2. 安装

1. 下载:在Linux环境下需要通过命令下载:

# 安装
curl -L https://github.com/docker/compose/releases/download/1.23.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

2. 修改文件权限:修改文件权限,让其变成可执行文件

# 修改权限
chmod +x /usr/local/bin/docker-compose

+x 表示给予它执行权 

3. 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

 

3. 部署微服务集群

需求:将资料中的cloud-demo微服务集群利用DockerCompose部署

实现思路

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

 

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

使用 maven 打包工具,将项目中的每个微服务都打包为 app.jar
④将打包好的app.jar拷贝到cloud-demo中的每一个对应的子目录中
⑤ 将cloud-demo上传至虚拟机,利用 docker-compose up -d 来部署
  • 下面我们来看看 docker-compose.yml里面的内容
version: "3.2"services:nacos:image: nacos/nacos-serverenvironment:MODE: standaloneports:- "8848:8848"mysql:image: mysql:5.7.25environment:MYSQL_ROOT_PASSWORD: 123volumes:- "$PWD/mysql/data:/var/lib/mysql"- "$PWD/mysql/conf:/etc/mysql/conf.d/"userservice:build: ./user-serviceorderservice:build: ./order-servicegateway:build: ./gatewayports:- "10010:10010"

可以看到里面包含5个service服务:

nacos:作为注册中心和配置中心
        image: nacos/nacos-server: 基于nacos/nacos-server镜像构建
        environment:环境变量
        MODE: standalone:单点模式启动
        ports:端口映射,这里暴露了8848端口
mysql:数据库
        image: mysql:5.7.25:镜像版本是 5.7.25
        environment:环境变量
        MYSQL_ROOT_PASSWORD: 123:设置数据库root账户的密码为123
        volumes:数据卷挂载,这里挂载了mysql的data、conf目录, 使用 $PWD 是因为
userservice、orderservice、gateway:都是基于Dockerfile临时构建的

  •  查看mysql目录,可以看到其中已经准备好了cloud_order、cloud_user表:

  • 查看微服务模块(order-service和user-service),可以看到都包含Dockerfile文件: 

 

 

上述的 Dockerfile 内容如下:

FROM java:8-alpine
COPY ./app.jar /tmp/app.jar
ENTRYPOINT java -jar /tmp/app.jar
  • 修改微服务配置

因为微服务将来要部署为docker容器,而容器之间是通过容器名互联,而不是通过ip地址互联。所有需要将order-service、user-service、gateway服务的mysql、nacos地址都修改为基于容器名的访问。

  • 打包为jar包 

接下来需要将我们的每个微服务都打包为jar。因为之前查看到Dockerfile中的jar包名称都是app.jar,因此我们的每个微服务都需要用这个名称。

可以通过修改pom.xml中的打包名称来实现,每个微服务都需要修改:

<build><!-- 服务打包的最终名称 --><finalName>app</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>
  • 拷贝jar包到部署目录

打包好的 jar 包存放在各个微服务模块的 target 目录下的 test-classes 目录中,复制编译打包好的app.jar文件,放到Dockerfile的同级目录中。

注意:每个微服务的app.jar放到与服务名称对应的目录。

 

  • 部署

我们需要将文件整个cloud-demo文件夹上传到虚拟机中任意目录中,通过DockerCompose部署。

进入cloud-demo目录,然后运行下面的命令即可:

docker-compose up -d

五、Docker镜像仓库

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

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

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

官网地址:https://hub.docker.com/_/registry

1. 搭建私有镜像仓库

1.1 无图形化界面版

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 目录,这是私有镜像仓库存放数据的目录。

1.2 图形化界面版

  • 使用DockerCompose部署带有图象界面的DockerRegistry,命令如下:
version: '3.0'
services:registry:image: registryvolumes:- ./registry-data:/var/lib/registryui:image: joxit/docker-registry-ui:staticports:- 8080:80environment:- REGISTRY_TITLE=私有仓库- REGISTRY_URL=http://registry:5000depends_on:- registry

因为5000端口没有暴露,是供服务内部访问的 

  • 新建 yml 配置文件写入上述内容,上传服务器后,在当前目录执行如下命令:
docker-compose up -d

之后就能在浏览器访问,如:http://192.168.150.101:8080

1.3 配置 Docker 信任地址

  • 我们的私服采用的http协议,默认不被Docker信任,所以需要做一个配置:
# 打开要修改的文件
vi /etc/docker/daemon.json
# 添加内容,改成自己服务器ip:
"insecure-registries":["http://192.168.150.101:8080"]
# 重加载
systemctl daemon-reload
# 重启docker
systemctl restart docker

2.  推送、拉取镜像

推送本地镜像到私有镜像服务必须重命名(docker tag)镜像,步骤如下:

1. 重新tag本地镜像,名称前缀为私有仓库的地址:192.168.150.101:8080/

docker tag nginx:latest 192.168.150.101:8080/nginx:1.0 

把nginx:latest 重命名为 nginx:1.0 

2. 推送镜像

镜像仓库推送前需要把仓库地址配置到docker服务的daemon.json文件中,被docker信任

docker push 192.168.150.101:8080/nginx:1.0 

3. 拉取镜像

docker pull 192.168.150.101:8080/nginx:1.0 

3. 小结

1.推送本地镜像到仓库前都必须重命名(docker tag)镜像,以镜像仓库地址为前缀

2.镜像仓库推送前需要把仓库地址配置到docker服务的daemon.json文件中,被docker信任

3.推送使用docker push命令

4.拉取使用docker pull命令

相关文章:

【微服务】Docker 容器化

一、初识Docker 1. 为什么需要 Docker 大型项目组件较多&#xff0c;运行环境也较为复杂&#xff0c;部署时会遇到一些问题&#xff1a; 依赖关系复杂&#xff0c;容易出现兼容性的问题开发、测试、生产环境有差异 Docker 如何解决依赖的兼容问题 将应用的Libs&#xff08;…...

[前端] 为网站侧边栏添加搜索引擎模块

前言 最近想给我的个人网站侧边栏添加一个搜索引擎模块&#xff0c;可以引导用户帮助本站SEO优化&#xff08;让用户可以通过点击搜索按钮完成一次对本人网站的搜索&#xff0c;从而实现对网站的搜索引擎优化&#xff09;。 最开始&#xff0c;我只是想实现一个简单的百度搜索…...

解决CORS (跨源资源共享) 错误

问题引入 前端代码 <template><div id"hello-vue" class"demo">{{ message }}</div><el-button type"primary" click"handleClick">我是一个按钮</el-button></template><script setup>//加…...

Redis 实现分布式缓存

一、引言 在当今互联网时代&#xff0c;随着业务的不断发展和用户量的持续增长&#xff0c;系统的性能和可扩展性成为了关键挑战。分布式缓存作为一种重要的技术手段&#xff0c;能够有效地缓解数据库压力、提高系统响应速度、增强系统的可扩展性。Redis 作为一种高性能的内存数…...

Chrome与火狐哪个浏览器的移动版本更流畅

在当今的数字化时代&#xff0c;移动设备已经成为我们生活中不可或缺的一部分。而浏览器作为我们访问互联网的重要工具&#xff0c;其性能和用户体验直接影响到我们的使用感受。本文将对比Chrome和火狐&#xff08;Firefox&#xff09;两款主流浏览器的移动版本&#xff0c;探讨…...

7篇Python爬虫实例,直接代码可运行,全网最全,注释超详细(适合收藏)——2、爬取图片信息。

7篇Python爬虫实例&#xff0c;可直接运行&#xff0c;适合收藏 python爬虫7篇实例&#xff0c;分七个文章进行发布&#xff1b;第二篇&#xff1a;爬取图片信息。 爬取图片信息&#xff0c;并将每张图片都下载下来。 爬虫主要三部分&#xff1a; 1、获取数据 2、数据解析 3、…...

25.停车场管理系统(基于web的Java项目)

目录 1.系统的受众说明 2.相关技术与方法 3.系统分析 3.1 可行性分析 3.1.1 技术可行性 3.1.2 经济可行性 3.1.3 操作可行性 3.2 需求分析 3.2.1 系统功能描述 3.2.2 用例图分析 4. 系统设计 4.1 系统类分析 5. 系统详细设计与实现 5.1 用户登录 5.2 系统信…...

展览搭建公司怎么跟展会主办打好交道

与展会主办打好交道的重要性 首先&#xff0c;我们得明白&#xff0c;展览搭建公司为何要跟展会主办打交道。简单地说&#xff0c;展会主办拥有大量的参展商信息。这些参展商是展览搭建公司潜在的客户群体&#xff0c;与主办打好交道&#xff0c;就等于拿到了通向这些客户的 “…...

软件开发方法

软件开发方法是一种用于指导软件开发过程的系统性方法,它涵盖了从需求分析、设计、编码、测试到维护的整个软件生命周期。软件开发方法通常包括一系列的步骤、技术和工具,以确保软件的质量、可维护性和可扩展性。 常见的软件开发方法有瀑布模型、敏捷开发、螺旋模型等。这些…...

「Mac畅玩鸿蒙与硬件24」UI互动应用篇1 - 灯光控制小项目

本篇将带领你实现一个互动性十足的灯光控制小项目&#xff0c;用户可以通过点击按钮来控制灯光的开关。该项目将涉及状态管理、动态图片加载以及按钮交互&#xff0c;是学习鸿蒙应用开发的重要基础。 关键词 UI互动应用状态管理动态图片加载用户交互 一、功能说明 在这个灯光…...

十二:java web(4)-- Spring核心基础

目录 创建项目 Spring 核心基础 Spring 容器 Spring 容器的作用 Spring 容器的工作流程 Bean Bean 的生命周期 IOC&#xff08;控制反转&#xff09;与依赖注入&#xff08;DI&#xff09; 控制反转的概念 依赖注入的几种方式&#xff08;构造器注入、Setter 注入、接…...

new和malloc有什么区别,他们的用法是什么?malloc分配失败会导致什么问题

1) new和malloc的区别&#xff0c;和他们的用法 new 和 malloc 主要有以下区别&#xff1a; 一、性质和来源 new &#xff1a;是 C 的运算符&#xff0c;在操作时会调用构造函数进行对象的初始化。它是 C 语言层面的操作&#xff0c;能更好地与 C 的面向对象特性结合。 malloc …...

了解SQLExpress数据库

SQLExpress&#xff08;Microsoft SQL Server Express&#xff09;是由微软公司开发的一款免费且轻量级的数据库管理系统。以下是关于SQLExpress的详细解释&#xff1a; 一、定义与特点 定义&#xff1a; SQLExpress是Microsoft SQL Server的一个缩减版或基础版&#xff0c;旨在…...

geoserver创建一个根据属性显示不同形状的点样式

geoserver创建一个根据属性显示不同形状的点样式 三角形 -triangle 圆形 - circle 正方形 - square 星形 - star 十字形 - cross 菱形 -diamond 代码&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <StyledLayerDescriptor version"…...

中国遗传学会2024全国学术研讨会在长沙成功召开

2024年11月3日至6日&#xff0c;备受瞩目的中国遗传学会2024全国学术研讨会在长沙盛大召开&#xff0c;此次盛会由中国遗传学会携手湖南省遗传学会共同主办&#xff0c;中南大学与南华大学共同承办。大会以“遗传学&#xff1a;前沿与交叉”为主题&#xff0c;吸引了来自全国各…...

Android Studio 多工程公用module引用

在Android Studio中&#xff0c;如果有多个工程需要共享同一个module&#xff0c;你可以通过以下步骤来实现module的公用&#xff1a; 1.将你想共享的module移动到一个单独的目录&#xff0c;比如一个新建的"libraries"文件夹。 2.修改module的build.gradle文件&am…...

(实战)WebApi第9讲:EFCore性能优化(IQueryable延迟查询、取消跟踪机制)

一、例子是第8讲的四、6&#xff08;EFCore的静态化处理 &#xff09;&#xff1a;分析ToList() ToList()在下图绿色框内。 二、在没有最终取数据的时候&#xff0c;使用 IQueryable<T> 延迟执行查询 &#xff08;1&#xff09;在没有最终取数据的时候&#xff0c;不要使…...

Java实现pdf转图片

第一步 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.32</version> <!-- 请检查最新版本 --> </dependency> 第二步 package com.example.demo.file.pdf;import or…...

健身房管理新纪元:SpringBoot技术应用

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…...

Java之字符串分割转换List

Java之字符串分割转换List 字符串分割成数组然后转换成List有多种方式&#xff0c;以下是每种方式的示例&#xff0c;推荐Java8的新特性Stream。 使用Java8的新特性Stream API String str "aaa,bbb,ccc"; // 使用Arrays.stream() List<String> list1 …...

RabbitMQ如何保证发送的消息可靠(RabbitMQ的Confirm模式和2.Return模式)

RabbitMQ如何保证发送的消息可靠&#xff08;RabbitMQ的Confirm模式和2.Return模式&#xff09; 1、RabbitMQ消息Confirm模式&#xff08;保证从生产者到交换机的消息可靠&#xff09;1.1、Confirm模式简介1.2、具体代码实现1.2.1、application.yml 开启确认模式1.2.2、生产者方…...

适配器模式:类适配器与对象适配器

适配器模式是一种结构性设计模式&#xff0c;旨在将一个接口转换成客户端所期望的另一种接口。它通常用于解决由于接口不兼容而导致的类之间的通信问题。适配器模式主要有两种实现方式&#xff1a;类适配器和对象适配器。下面&#xff0c;我们将详细探讨这两种方式的优缺点及适…...

volatile原理

volatile原理 volatile的底层实现原理是内存屏障,Memory Barrier(Memory Fence) 对volatile变量的写指令后会加入写屏障 对volatile变量的读指令前会加入读屏障 如何保证可见性 写屏障保证在该屏障之前的,对共享变量的改动,都同步到主存当中 public void actor2(I_Resu…...

【AI神器】SD(Stable Diffusion)一键安装包

是否还在无法使用Stable Diffusion 而烦恼&#xff0c;今天就给大家带来sd的私有化部署&#xff0c;一键安装包 https://pan.quark.cn/s/c16aa752ac6a 当然对电脑配置略微有些要求&#xff1a; 首先&#xff0c;本地安装对电脑配置有一些基本要求&#xff0c; 本地电脑安装…...

lanqiaoOJ 1112:小王子双链表 ← STL list

【题目来源】https://www.lanqiao.cn/problems/1112/learning/【题目描述】 小王子有一天迷上了排队的游戏&#xff0c;桌子上有标号为 1-10 的 10 个玩具&#xff0c;现在小王子将他们排成一列&#xff0c;可小王子还是太小了&#xff0c;他不确定他到底想把那个玩具摆在哪里&…...

C#WPF之快速理解MVVM模式

MVVM是一种设计模式&#xff0c;特别适用于WPF等XAML-based的应用程序开发。MVVM模式主要包含三个部分&#xff1a;Model&#xff08;模型&#xff09;、View&#xff08;视图&#xff09;和ViewModel&#xff08;视图模型&#xff09;。 Model&#xff08;模型&#xff09;&a…...

微积分[1]|微积分的底层逻辑——解析几何、不等式与极限(含博主推荐的数理阅读教材共计21本书籍)

原创首发于CSDN&#xff0c;禁止转载&#xff0c;谢谢&#xff01; 文章目录 微积分的底层逻辑探究一篇网络文章《数学分析的核心——不等式》高中数学与大学数学的脱节&#xff5c;脱节的实质含义&#xff5c;高中与大学的衔接数理书籍推荐 我个人所认为的数学分析的根基更新时…...

1-磁盘建立空闲分区

学习目标&#xff1a; 掌握磁盘分区的基本知识和操作技能&#xff0c;能够独立创建和管理磁盘空闲分区&#xff0c;以优化存储空间和提高系统性能&#xff0c;为后续的系统安装和数据管理打下基础。 学习内容&#xff1a; 1 选择一个适合的磁盘分区软件。推荐DiskGenius、Par…...

使用SearXNG-搭建个人搜索引擎(附国内可用Docker镜像源)

介绍 SearXNG是聚合了七十多种搜索服务的开源搜索工具。我们可以匿名浏览页面&#xff0c;不会被记录和追踪。作为开发者&#xff0c;SearXNG也提供了清晰的API接口以及完整的开发文档。 部署 我们可以很方便地使用Docker和Docker compose部署SearXNG。下面给出Docker部署Se…...

InnoDB 存储引擎<五>undo log, redo log,以及双写缓冲区

目录 撤销⽇志 - Undo Log 双写缓冲区 - Doublewrite Buffer 重做⽇志 - Redo Log 本篇是继承自上篇InnoDB存储引擎的磁盘文件 上篇链接&#xff1a;InnoDB 存储引擎&#xff1c;四&#xff1e;磁盘文件一 撤销⽇志 - Undo Log 1.什么是撤销⽇志&#xff1f; 解答问题&a…...