docker

docker

Docker 是一个开源平台,旨在自动化应用程序的部署、扩展和管理。它利用容器技术提供了一种轻量级的虚拟化方式,使得开发者能够将他们的应用及其依赖项打包成一个可移植的容器,这样无论在什么环境中,应用都能以相同的方式运行。

docker官网地址:https://www.docker.com/

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows操作系统的机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

image-20231022113149765

补充:

1、docker 基于go语言。

2、利用同一个镜像创建的容器,可以运行在不同的平台,确保应用在不同的平台具有一致的运行效果,减少因环境差异引起的问题。

3、隔离性、移植性、伸缩性。

docker架构

Docker采用的是Client/Server 架构,客户端向服务器发送请求,服务器负责构建、运行和分发容器。

客户端和服务器可以运行在同一个Host 上。

image-20230717092740969

Docker 客户端:Client

Docker 服务器:Docker daemon

Docker 镜像:Image

Registry:镜像仓库

Docker 容器:Container

docker核心组件

  • 容器 (Container): 容器是一个轻量级、可移植的执行环境,可以独立于主机操作系统运行。每个容器都是从 Docker 镜像创建的,包含了应用程序及其运行所需的所有依赖项。
  • 镜像 (Image): 镜像是一个只读的模板,包含了运行某个应用所需的一切内容。镜像可以通过 Dockerfile 构建,Dockerfile 是一个用来描述如何构建镜像的文本文件。
  • Docker Hub: 这是 Docker 的官方公共镜像仓库,用户可以在这里共享和下载镜像。

Registry是存放Docker镜像的仓库,Registry分私有和公有两种。

Docker Hub是默认的Registry(Docker Hub Container Image Library | App Containerization),由Docker公司维护,上面有数以万计的镜像,用户可以自由下载和使用。

image-20230420095756720

  • Docker Compose: 这是一个工具,用于定义和运行多容器 Docker 应用程序。用户可以通过一个配置文件(docker-compose.yml)来配置应用的服务、网络和卷等。
  • Docker Swarm: 这是 Docker 的原生集群管理工具,可以将多个 Docker 引擎作为一个单一的虚拟主机进行管理,从而实现负载均衡和高可用性。

镜像和容器

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

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

docker镜像操作

搜索镜像

可以使用命令搜索也可以在docker hub 搜索镜像。

相关命令如下所示:

# 命令:
docker search 镜像关键字

# 示例:搜索镜像名称中包含redis关键字的镜像
docker search redis

执行效果如下所示:

image-20230717095934771

列介绍:

1、name: 镜像仓库源名称

2、description: 镜像的描述

3、official: 是否 docker 官方发布

4、stars: 镜像的收藏数,收藏数越多表示此镜像的受欢迎程度越高

5、automated: 是否自动构建

拉取镜像

相关命令如下所示:

# tag表示的镜像的标签,也可以理解为就是镜像的版本
docker pull 镜像名称[:tag]

# 示例1: 默认拉取的是最新的redis镜像
docker pull redis	等价于 docker pull redis:latest	

# 示例2: 拉取redis7.0.10镜像,一个镜像到底存在哪些标签,需要上docker hub中进行查看
docker pull redis:7.0.10

执行效果如下所示:

image-20230717100251996

推送镜像

# 将本地镜像推送到Docker Hub或私有仓库:
docker push <镜像名>:<标签>  
# 例如:
docker push myapp:latest  

构建自定义镜像

# 使用Dockerfile构建镜像:
docker build -t <镜像名>:<标签> <Dockerfile所在目录>  
# 例如:
docker build -t myapp:latest .  

标记镜像

docker tag <源镜像>:<源标签> <目标镜像>:<目标标签>

# 例如,将镜像标记为新版本:
docker tag ubuntu:latest ubuntu:myversion  

导出镜像

# 将镜像导出为.tar文件:
docker save -o <文件名>.tar <镜像名>:<标签>  
# 例如:
docker save -o ubuntu.tar ubuntu:latest  

导入镜像

# 从.tar文件中导入镜像:
docker load -i <文件名>.tar  
# 例如:
docker load -i ubuntu.tar  

查看本地镜像

相关命令如下所示:

# 命令: 
docker images

执行效果如下所示:

image-20230717100416721

列介绍:

1、repository: 镜像来源仓库名称

2、tag: 镜像标签

3、image id: 镜像id

4、created: 创建时间

5、size: 镜像的大小

删除本地镜像

相关命令如下所示:

#根据镜像名称:tag删除
docker rmi 	镜像名称:镜像tag

#根据镜像id删除
docker rmi 镜像id

注意:如果一个镜像存在对应的容器,此时这个镜像是无法进行删除的,需要先删除镜像,再删除容器。

docker容器操作

  • 容器分类:

    1、交互型容器:具有和用户交互的输入和输出终端,容器创建后自动进入容器中,退出容器后,容器自动关闭。

    image-20231022133704412

    2、守护型容器:没有和用户交互终端,需要使用docker exec进入容器,退出后,容器不会关闭。

image-20231022134220421

创建容器

下载java镜像:

docker pull java

创建守护式和交互式容器

交互式
docker run -it --name java02 java:latest /bin/bash

守护式
docker run -id --name java01 java:latest 

注意:如果从一个交互式容器中退出,此时容器的状态变成 Exited 关机状态

查询容器

相关命令如下所示:

# 查看本地正在运行的容器
docker ps 
# 查询所有的容器包含未运行的容器
docker ps -a
# 查看所有正在运行的容器的id号
docker ps -q

执行效果如下所示:

image-20230717101615569

列介绍:

1、container id: 容器名称

2、image: 镜像名称

3、command: 容器启动时所执行的命令

4、created: 创建时间

5、status: 容器状态

6、ports: 端口映射情况

7、names: 容器的名称

容器管理(关闭/启动/重启)

容器管理的相关命令如下所示:

docker stop 	容器名称/容器id											# 关闭容器
docker start  	容器名称/容器id											# 启动容器
docker restart 	容器名称/容器id											# 重启容器

删除容器

docker rm      容器名称/容器的id  #删除一个已停止的容器
docker rm -f   容器名称/容器的id  #强制删除一个正在运行的容器
docker rm -f $(docker ps -qa)  #强制删除所有容器

注意:上述的命令只能删除已经关闭的容器,如果想删除正在运行的容器,可以通过添加 -f 参数进行实现。

进入容器

进入容器命令如下所示:

docker exec -it java02 /bin/bash				# 进入到容器中同时打开一个shell窗口

image-20231022134601483

查看容器日志

查询容器内进程日志,-f 参数表示实时监控日志信息。

docker logs -f 容器名称/容器的id

启动一个容器后,发现容器无法正常使用,那一定要使用这个命令去查看容器的日志,检查是否有报错日志。

查看容器ip

注意:查看的ip无法远程去访问,相当于局域网内的ip,在win本地无法去远程连接。但是容器与容器之间可以使用ip去互联。

docker inspect 容器名称/容器的id

拷贝

宿主机和容器之间可以互相拷贝文件/目录。

docker cp ./a.txt redis01:/root/	 	#把宿主机中当前目录下的a.txt文件拷贝到redis01的root目录中
docker cp redis01:/root/a.txt ./ 		#把容器中的root目录下的a.txt文件拷贝到宿主机中当前目录中

备份与迁移

迁移到另一个服务器中

把A服务器上的某个容器迁移到B服务器上。

image-20230420152250969

涉及的docker命令:

# 把docker容器保存成一个镜像
docker commit   容器名称/容器的id   镜像名称

# 把镜像保存为tar文件,传输到另一台docker服务器,对方通过该压缩包恢复成镜像。
docker save -o  xxxx.tar  镜像名称/镜像id

# 把tar文件恢复成为一个镜像
docker load -i 	xxxx.tar

迁移到阿里云服务器中

image-20241023094205338

首先在阿里云上创建好镜像仓库

image-20241023094454488

后面根据阿里云提示一步步操作即可。

容器自动启动

创建好一个容器,希望下次服务器开机后,自动启动起来,使用 --restart=always

docker run -id --name nginx -p 80:80 --restart=always nginx:latest

将一个已存在的容器设置自启动:

docker update --restart=always 容器名

端口映射

访问容器中的应用时,不能直接通过容器ip进行访问,要通过宿主机ip和宿主机port进行访问。

创建容器时,需要指定端口映射 -p 宿主机端口:容器中应用的端口

一定注意宿主机端口可以随意,但是要保证没有被占用。

例如:

docker run -id --name nginx -p 80:80 nginx:latest

docker run -id --name spzx_redis --restart=always -p 6377:6379 redis:latest

docker数据卷操作

容器内程序的文件、配置等都在容器的内部,要读写容器内的文件非常不方便。如何解决?数据卷。

数据卷(volume)是一个虚拟目录,是容器内目录宿主机目录之间映射的桥梁。

以Nginx为例,有两个关键的目录:

  • html:放置一些静态资源;
  • conf:放置配置文件;

利用数据卷将两个目录与宿主机目录关联,操作宿主机的目录内容就相当于操作容器内的目录内容,方便我们操作。

image-20231215165415131

查看数据卷

命令如下所示:

docker volume ls

创建数据卷

命令如下所示:

docker volume create # 数据卷名称

查询数据卷详情

命令如下所示:

docker volume inspect # 数据卷名称

删除数据卷

命令如下所示:

docker volume rm 数据卷名称  # 删除指定的数据卷

数据卷挂载(nginx演示)

#下载nginx镜像
docker pull nginx

#创建nginx容器,并且指定数据卷挂载和端口映射
docker run -id --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx

#查看html数据卷的实际目录
docker inspect html 

#创建hello.html,部署到html数据卷目录下,会自动同步到容器中
#测试访问 http://宿主机ip:宿主机port/hello.html

目录挂载

数据卷的目录结构较深,如果我们去操作数据卷目录会不太方便。

数据卷的缺点:数据卷对应的宿主机实际目录,是默认指定的,不是我们自己自定义的。

目录挂载:就是随意指定宿主机上的任意目录和容器中的任意目录进行挂载。

格式: -v 宿主机目录:容器目录

示例:
docker run -id --name nginx2 -p 82:80 -v /html:/usr/share/nginx/html nginx

注意:目录挂载时,先将宿主机目录下的内容同步到容器中去(和数据卷挂载正好相反)

除了目录挂载,也可以单独指定宿主的一个文件和容器中的某个文件进行挂载。

docker run -id --name nginx2 -p 82:80
-v /html:/usr/share/nginx/html      
-v /nginx.conf:/usr/share/nginx/conf/nginx.conf
nginx

mysql容器

docker run -id --name=spzx_mysql 
-p 3309:3306 
--restart=always  
--privileged=true 
-e MYSQL_ROOT_PASSWORD=1234 
mysql:latest

当使用--privileged=true选项运行容器时,Docker会赋予容器几乎与主机相同的权限,例如允许容器访问主机的所有设备。

注意:如果在进行远程连接时,出现如下报错:

image-20240412180834692

在MySQL 8.0中,caching_sha2_password是默认的身份验证插件,而不是mysql_native_password.

解决办法:升级sqlyog的版本 或者 修改mysql默认身份验证插件。

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '1234';
FLUSH PRIVILEGES;

dockerfile(自定义镜像)

前面我们所使用的镜像都是别人构建好的,但是别人构建好的镜像不一定能满足我们的需求。

如何构建自定义镜像?使用dockerfile。

dockerfile就是一个文本文件,在这个文件中可以使用docker所提供的一些指令来指定我们构建镜像的细节。

常用命令

指令 用法 作用
FROM FROM image_name:tag 指定一个构建镜像的基础源镜像,如果本地没有就会从公共库中拉取,没有指定镜像的标签会使用默认的latest标签,可以出现多次,如果需要在一个dockerfile中构建多个镜像。
MAINTAINER MAINTAINER user_name 描述镜像的创建者,名称和邮箱
RUN RUN "command" "param1" "param2" 用来执行一些命令,可以写多条
ENV ENV key value 设置容器的环境变量,可以写多条。
ADD ADD source_dir/file 将宿主机的文件复制到容器内,如果是压缩文件,则复制后自动解压
ENTRYPOINT ENTRYPOINT "command" "param1" "param2" 用来指定容器启动时所执行的命令
WORKDIR WORKDIR /app 设置当前工作目录。后续的指令将在这个目录下执行
COPY COPY . . 将本地文件或目录复制到镜像中的指定路径。
EXPOSE EXPOSE 5000 声明应用程序所使用端口

自定义jdk17镜像

需求:使用dockerfile来构建一个包含Jdk17的centos7镜像

分析:

1、基础的镜像的应该选择centos:7

2、在自己所构建的镜像中需要包含Jdk17,就需要把Jdk17添加到centos:7的基础镜像中

3、为了方便的去使用自己构建的镜像中的Jdk17,就需要去配置环境变量

4、因为Jdk17仅仅是一个开发工具,并不是一个服务进程,因此在启动容器的时候可以不指定任何的执行命令

实现步骤:

1、将Jdk17的安装包上传到linux服务器的指定目录下

2、在Jdk17所在的目录下创建一个dockerfile文件

3、使用docker build命令构建镜像

4、使用docker images查看镜像构建情况

5、使用自己所构建的镜像创建容器,测试Jdk17的安装情况

具体步骤:

# 1、创建目录
mkdir –p /usr/local/dockerfilejdk17
cd /usr/local/dockerfilejdk17
  
# 2、下载jdk-17_linux-x64_bin.tar.gz并上传到服务器(虚拟机)中的/usr/local/dockerfilejdk17目录
# 3、在/usr/local/dockerfilejdk17目录下创建dockerfile文件,文件内容如下:
vim dockerfile

#FROM:指定基础源镜像
#ADD:将宿主机的文件复制到容器内,如果是压缩文件,则复制后自动解压
#ENV:设置容器的环境变量
FROM centos:7
MAINTAINER chs
RUN mkdir -p /usr/local/java
ADD jdk-17.0.7_linux-x64_bin.tar.gz /usr/local/java/
ENV JAVA_HOME=/usr/local/java/jdk-17.0.7
ENV PATH=$PATH:$JAVA_HOME/bin

# 4、执行命令构建镜像;不要忘了后面的那个 .
docker build -t centos7-jdk17 .

# 5、查看镜像是否建立完成
docker images

# 6、创建容器
docker run -it --name chs-centos centos7-jdk17 /bin/bash

# 7、进入容器
docker exec -it chs-centos /bin/bash
输入命令:java -version

SpringBoot项目构建镜像

将一个springboot应用以docker的方式进行部署,也就是构建一个springboot应用的docker镜像。

image-20241023165134551

项目打包上传

首先把jar包上传到linux服务器上 /myapp 目录,提前创建/myapp目录

jar名称:ebuy-docker-1.0-SNAPSHOT.jar

创建/myapp/dockerfile

#构建新镜像使用的基础镜像,由于springboot工程使用java17环境,所以基本镜像选择我们自己构建的java17镜像
FROM centos7-jdk17

#声明作者
MAINTAINER chs

#声明应用程序所使用端口
EXPOSE 8081

#将jar包复制到基础镜像 “/” 代表镜像的根地址
ADD ebuy-docker-1.0-SNAPSHOT.jar /ebuy-docker-1.0-SNAPSHOT.jar

#设置工作目录
WORKDIR /

#利用新镜像创建容器时,容器内自动执行java -jar  ebuy-docker-1.0-SNAPSHOT.jar
ENTRYPOINT ["java" , "-jar" , "ebuy-docker-1.0-SNAPSHOT.jar"]

创建好容器后,执行 docker logs -f 容器名 , 查看容器内应用程序的日志,检查容器内应用程序是否启动成功。

注意:容器创建成功,不意味着容器内应用程序启动成功。

执行构建命令

在/myapp 目录下执行命令:

docker build -t ebuy-docker:v1.0 .

这里的 “.” 表示 使用当前目录下的dockerfile构建一个自定义镜像,镜像名为ebuy-docker:v1.0

创建容器

使用镜像创建容器:

docker run -id --name ebuy-docker -p 8081:8081 ebuy-docker:v1.0

访问测试: http://宿主机ip:8081

maven插件

docker-maven-plugin这个插件可以实现在idea本地项目进行package时,自动构建镜像到docker服务器。

docker开启远程访问

#修改该文件
vim /lib/systemd/system/docker.service

#找到ExecStart行,修改成如下内容
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H fd:// --containerd=/run/containerd/containerd.sock

systemctl daemon-reload				#重启守护进程
systemctl restart docker			#重启docker

注意:要关闭防火墙。

在pom.xml添加插件

<plugin>
                
    <groupId>com.spotify</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>1.2.2</version>

    <!--将插件绑定在某个phase执行-->
    <executions>
        <execution>
            <id>build-image</id>
            <!--将插件绑定在package这个phase(阶段)上。也就是说,用户只需执行mvn package,就会自动执行mvn docker:build-->
            <phase>package</phase>
            <goals>
                <goal>build</goal>
            </goals>
        </execution>
    </executions>

    <configuration>

        <!--指定生成的镜像名-->
        <imageName>${project.artifactId}</imageName>

        <!--指定标签,也就是版本号,可以自定义-->
        <imageTags>
            <imageTag>latest</imageTag>
        </imageTags>
        
        <!--指定远程 docker api地址 也就是服务器ip+docker的端口号-->
        <dockerHost>http://192.168.188.128:2375</dockerHost>

        <!-- 指定 dockerfile 路径-->
        <dockerDirectory>${project.basedir}</dockerDirectory>
        
        <!-- 是否跳过docker构建 -->
        <skipdockerBuild>false</skipdockerBuild>

    </configuration>

</plugin>

创建dockerfile文件

在当前工程的根目录下(pom.xml同级目录)创建dockerfile

FROM centos7-jdk17
MAINTAINER chs
EXPOSE 8081
ADD target/ebuy-docker-1.0-SNAPSHOT.jar /ebuy-docker-1.0-SNAPSHOT.jar
WORKDIR /
ENTRYPOINT ["java" , "-jar" , "ebuy-docker-1.0-SNAPSHOT.jar"]

执行maven的打包命令

在项目根目录下执行打包命令,同时利用打好的jar包在docker服务器构建镜像。

mvn clean package -DskipTests								# 打包跳过测试

在docker服务器执行docker images查询是否出现了该镜像。

docker compose(创建容器)

1、Docker Compose是一个工具,用于定义和运行多容器应用程序的工具;

2、Docker Compose通过yml文件定义多容器的docker应用;

3、Docker Compose通过一条命令根据yml文件的定义去创建或管理多容器;

Docker Compose 是用来做Docker 的多容器控制,有了 Docker Compose 你可以把所有繁复的 Docker 操作全都一条命令,自动化的完成。

官网地址:https://docs.docker.com/compose/install/linux/

下载与安装

下载与安装:

# 创建指定目录存储docker compose
mkdir -p /usr/local/lib/docker/cli-plugins

# 下载并移动
curl -SL 
https://github.com/docker/compose/releases/download/v2.14.2/docker-compose-linux-x86_64 
-o /usr/local/lib/docker/cli-plugins/docker-compose

# 给docker-compose文件赋予可执行权限
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose

# 查看docker compose的版本
docker compose version

入门案例

需求:使用docker compose部署redis

docker-compose.yml文件的内容如下所示:

services:
  redis:
    image: redis:latest
    container_name: redis
    ports:
      - "6377:6379"
    volumes:
      - redis-data:/data
  mysql:
    container_name: mysql
    image: mysql:8.0.30
    ports:
      - "3309:3306"
    volumes:
      - mysql_data:/var/lib/mysql
      - mysql_conf:/etc/mysql
    privileged: true
    environment:
      - "MYSQL_ROOT_PASSWORD=1234"   # 数据库root的密码1234
volumes:
  redis-data: {}
  mysql_data: {}
  mysql_conf: {}

docker compose相关命令:

# 启动容器(如果不存在容器就创建、存在则修改)
docker compose -f docker-compose.yml  -p spzx  up -d  #守护线程式创建

# 删除所有容器
docker compose -f docker-compose.yml down

# 停止所有容器
docker compose -f docker-compose.yml stop

# 启动所有容器
docker compose -f docker-compose.yml start

# 重启所有容器
docker compose -f docker-compose.yml restart

docker compose文件中其他的常见指令参考官方文档:https://docs.docker.com/compose/compose-file/05-services/

参考案例:https://www.cnblogs.com/acatsmiling/p/18474458

创建容器nginx+gateway+service+mysql+redis

创建容器nacos、minio、sentinel

创建nacos容器:

docker run -id \
-e MODE=standalone \
-p 18848:8848 \
-p 19848:9848 \
-p 19849:9849 \
--name test_spzx_nacos2.1.1 \
--restart=always \
nacos/nacos-server:v2.1.1



创建sentinel容器:

docker run -id --name=test_sentinel --restart=always -p 18858:8858  bladex/sentinel-dashboard:latest



创建minio容器:

docker run \
-p 19000:9000 \
-p 19001:9001 \
--name=test_minio \
-id --restart=always \
-e "MINIO_ROOT_USER=admin" \
-e "MINIO_ROOT_PASSWORD=admin123456" \
-v spzx_minio-data:/data \
-v spzx_minio-config:/root/.minio \
minio/minio  \
server /data --console-address ":9001"


minio容器中的/data 目录作为存储数据的目录和宿主机的spzx_minio-data数据卷做了挂载,当容器中的data目录下产生新的数据会同步到宿主机的数据卷目录下。
posted @   CH_song  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示