• Docker高级(完结)


    一、DockerFile

    DockerFile简介

    Docker是用来构建Docker镜像文件,由一条条docker指令和参数构成的脚本。
    在这里插入图片描述

    DockerFile构建过程

    在这里插入图片描述

    小总结

    在这里插入图片描述
    从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,

    • Dockerfile是软件的原材料

    • Docker镜像是软件的交付品

    • Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例

    Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。

    在这里插入图片描述
    1 Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;

    2 Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时会真正开始提供服务;

    3 Docker容器,容器是直接提供服务的

    docker保留字

    vim Dockerfile

    FROM centos
    MAINTAINER zzyy<zzyybs@126.com>
     
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
     
    #安装vim编辑器
    RUN yum -y install vim
    #安装ifconfig命令查看网络IP
    RUN yum -y install net-tools
    #安装java8及lib库
    RUN yum -y install glibc.i686
    RUN mkdir /usr/local/java
    #ADD 是相对路径jar,把jdk-8u171-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置
    ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/
    #配置java环境变量
    ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
    ENV JRE_HOME $JAVA_HOME/jre
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
    ENV PATH $JAVA_HOME/bin:$PATH
     
    EXPOSE 80
     
    CMD echo $MYPATH
    CMD echo "success--------------ok"
    CMD /bin/bash
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    docker run -it 新镜像名字:TAG .(当前目录)
    docker run -it centosjava8:1.5 /bin/bash

    虚悬镜像

    虚悬镜像:仓库名、标签名都是 的镜像,称为 dangling images(虚悬镜像)。

    在构建或者删除镜像时可能由于一些错误导致出现虚悬镜像。

    列出docker中的虚悬镜像:

    docker image ls -f dangling=true
    
    • 1

    虚悬镜像一般是因为一些错误而出现的,没有存在价值,可以删除:

    # 删除所有的虚悬镜像
    docker image prune
    
    • 1
    • 2

    Docker发布微服务

    搭建一个简单的SpringBoot项目:
    1、 创建maven工程,pom为:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.5.6</version>
        </parent>
    
        <groupId>org.study</groupId>
        <artifactId>test-docker</artifactId>
        <packaging>pom</packaging>
        <version>1.0-SNAPSHOT</version>
        <modules>
            <module>docker_boot</module>
        </modules>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
    </project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    2、 新建Module,pom为:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>test-docker</artifactId>
            <groupId>org.study</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>docker_boot</artifactId>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    3、编写一个配置文件

    server:
      port: 6001
    
    • 1
    • 2

    4、 编写主启动类

    package com.study;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * @author tengyer 2022/05/06 16:34
     */
    @SpringBootApplication
    public class DockerBootApplication {
        public static void main(String[] args) {
            SpringApplication.run(DockerBootApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    5、 编写一个Controller

    package com.study.controller;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.UUID;
    
    /**
     * @author tengyer 2022/05/06 16:35
     */
    @RestController
    public class OrderController {
        @Value("${server.port}")
        private String port;
    
        @RequestMapping("/order/docker")
        public String helloDocker() {
            return "hello world \t" + port + "\t" + UUID.randomUUID().toString();
        }
    
        @RequestMapping(value = "/order/index", method = RequestMethod.GET)
        public String index() {
            return "服务端口号:" + "\t" + port + "\t" + UUID.randomUUID().toString();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在Idea中运行没有问题时,将其使用maven的package打成jar包。

    发布微服务项目到Docker容器

    1. 将项目jar包上传到服务器
    2. 编写Dockerfile
    FROM openjdk:8-oracle
    MAINTAINER lee
    
    # 在主机 /var/lib/docker目录下创建一个临时文件,并链接到容器的 /tmp
    VOLUME /tmp
    
    # 将jar包添加到容器中,并命名为 springboot_docker.jar
    ADD docker_boot-1.0-SNAPSHOT.jar /springboot_docker.jar
    # 运行jar包
    RUN bash -c 'touch /springboot_docker.jar'
    ENTRYPOINT ["java", "-jar", "/springboot_docker.jar"]
    
    # SpringBoot项目配置的端口号为6001,需要将6001暴露出去
    EXPOSE 6001
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3、构建镜像

    docker build -t springboot_docker:1.0 .
    
    • 1

    4、 启动容器:

    docker run -d -p 6001:6001 --name springboot springboot_docker:1.0
    
    • 1

    二、Docker网络

    简介

    docker安装并启动服务后,会在宿主机中添加一个虚拟网卡。

    在Docker服务启动前,使用 ifconfig 或 ip addr 查看网卡信息:

    ● ens33或eth0:本机网卡
    ● lo:本机回环网络网卡
    ● 可能有virbr0(CentOS安装时如果选择的有相关虚拟化服务,就会多一个以网桥连接的私网地址的virbr0网卡,作用是为连接虚拟网卡提供NAT访问外网的功能。如果要移除该服务,可以使用 yum remove libvirt-libs.x86_64)

    使用 systemctl start docker启动Docker服务后,会多出一个 docker0 网卡。

    作用:

    ● 容器间的互联和通信以及端口映射
    ● 容器IP变动时候可以通过服务名直接网络通信而不受到影响

    Docker容器的网络隔离,是通过Linux内核特性 namespace和 cgroup 实现的。

    在这里插入图片描述

    Docker网络命令

    查看Docker网络模式:

    docker network ls
    
    • 1

    在这里插入图片描述
    添加Docker网络:

    docker network create xxx
    
    • 1

    删除Docker网络:

    docker network rm xxx
    
    • 1

    查看网络元数据:

    docker network inspect xxx
    
    • 1

    删除所有无效的网络:

    docker network prune
    
    • 1

    能干嘛

    在这里插入图片描述

    docker网络模式

    在这里插入图片描述
    查看某个容器的网络模式:

    # 通过inspect获取容器信息,最后20行即为容器的网络模式信息
    docker inspect 容器ID | tail -n 20
    
    • 1
    • 2

    bridge模式

    Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),该桥接网络的名称为docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信。

    docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配。

    在这里插入图片描述

    host模式

    直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行 NAT 转换。
    在这里插入图片描述
    如果在 docker run 命令中同时使用了 --network host 和 -p端口映射,例如:

    docker run -p 8082:8080 --network host tomcat
    
    • 1

    那么会出现一个警告:

    WARNING: Published ports are discarded when using host network mode
    
    • 1

    因为此时已经使用了host模式,本身就是直接使用的宿主机的IP和端口,此时的-p端口映射就没有了意义,也不会生效,端口号还是会以主机端口号为主。

    正确做法是:不再进行-p端口映射,或者改用bridge模式

    container模式

    新建的容器和已经存在的一个容器共享网络IP配置,而不是和宿主机共享。

    新创建的容器不会创建自己的网卡、IP,而是和一个指定的容器共享IP、端口范围。两个容器除了网络共享,其他的如文件系统、进程列表依然是隔离的。
    在这里插入图片描述

    docker run -it --name alpine1 alpine /bin/sh
    
    # 指定和 alpine1 容器共享网络
    docker run -it --netrowk container:alpine1 --name alpine2 alpine /bin/sh
    
    • 1
    • 2
    • 3
    • 4

    此时使用 ip addr查看两台容器的网络,会发现两台容器的eth0网卡内的IP等信息完全相同。

    如果关掉了alpine1容器,因为alpine2的网络使用的alpine1共享网络,所以关掉alpin1后,alpine2的eth0网卡也随之消失了。

    自定义网络

    容器间的互联和通信以及端口映射。

    容器 IP 变动时候可以通过服务名直接网络通信而不受影响。(类似Eureka,通过服务名直接互相通信,而不是写死IP地址)。
    自定义桥接网络(自定义网络默认使用的是桥接网络 bridge):

    1、 新建自定义网络

    docker network create tomcat_network
    
    • 1

    2、 查看网络列表

    docker network ls
    
    • 1

    3、 创建容器时,指定加入我们自定义的网络中

    docker run -d -p 8081:8080 --network tomcat_network --name tomcat1 tomcat:8.5-jdk8-corretto
    
    docker run -d -p 8082:8080 --network tomcat_network --name tomcat2 tomcat:8.5-jdk8-corretto
    
    • 1
    • 2
    • 3

    4、此时进入tomcat1中,使用ping命令测试连接tomcat2容器名,发现可以正常连通

    # 安装ifconfig命令
    yum install -y net-tools
    # 安装ip addr命令
    yum install -y iproute
    # 安装ping命令
    yum install -y iputils
    
    # 直接ping容器名,不需要ping IP地址
    ping tomcat2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    三、Docker-compose容器编排

    简介

    Docker-Compose 是 Docker 官方的开源项目,负责实现对Docker容器集群的快速编排。

    Docker-Compose可以管理多个Docker容器组成一个应用。需要定义一个yaml格式的配置文件 docker-compose.yml,配置好多个容器之间的调用关系,然后只需要一个命令就能同时启动/关闭这些容器。

    在这里插入图片描述

    下载

    curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    
    • 1
    chmod +x /usr/local/bin/docker-compose
    
    • 1
    docker-compose --version
    
    • 1

    在这里插入图片描述

    compose编排实例

    示例:

    # docker-compose文件版本号
    version: "3"
    
    # 配置各个容器服务
    services:
      microService:
        image: springboot_docker:1.0
        container_name: ms01  # 容器名称,如果不指定,会生成一个服务名加上前缀的容器名
        ports:
          - "6001:6001"
        volumes:
          - /app/microService:/data
        networks:
          - springboot_network
        depends_on:  # 配置该容器服务所依赖的容器服务
          - redis
          - mysql
    
      redis:
        image: redis:6.0.8
        ports:
          - "6379:6379"
        volumes:
          - /app/redis/redis.conf:/etc/redis/redis.conf
          - /app/redis/data:data
        networks:
          - springboot_network
        command: redis-server /etc/redis/redis.conf
    
      mysql:
        image: mysql:5.7
        environment:
          MYSQL_ROOT_PASSWORD: '123456'
          MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
          MYSQL_DATABASE: 'db_springboot'
          MYSQL_USER: 'springboot'
          MYSQL_PASSWORD: 'springboot'
        ports:
          - "3306:3306"
        volumes:
          - /app/mysql/db:/var/lib/mysql
          - /app/mysql/conf/my.cnf:/etc/my.cnf
          - /app/mysql/init:/docker-entrypoint-initdb.d
        networks:
          - springboot_network
        command: --default-authentication-plugin=mysql_native_password # 解决外部无法访问
    
    networks:
      # 创建 springboot_network 网桥网络
      springboot_network:
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    编写完成docker-compose.yml后,进行语法检查:

    # 进行语法检查
    docker-compose config -q
    
    • 1
    • 2

    如果语法检查没有任何问题,进行创建、启动:

    docker-compose up -d
    
    • 1
  • 相关阅读:
    用Python在XML和Excel表格之间实现互转
    OSINT技术情报精选·2024年6月第1周
    Android Socket通讯 之 表情列表优化、业务逻辑优化
    C#实现观察者模式
    最长公共子串LCS
    Openwrt_树莓派B+_Wifi中继
    【spark】第二章——SparkCore之运行架构及核心编程
    一种退避序列实现
    c++ 编译过程杂记等
    MySQL的基础(一)
  • 原文地址:https://blog.csdn.net/qq_57818853/article/details/130678255