Docker高级(完结)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS SQL Server,独享型 2核4GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: Docker高级(完结)

一、DockerFile

DockerFile简介

Docker是用来构建Docker镜像文件,由一条条docker指令和参数构成的脚本。

image.png


DockerFile构建过程


image.png

小总结

image.png

从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,


Dockerfile是软件的原材料


Docker镜像是软件的交付品


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


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

image.png


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
docker run -it 新镜像名字:TAG .(当前目录)
docker run -it centosjava8:1.5 /bin/bash


虚悬镜像

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


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


列出docker中的虚悬镜像:


docker image ls -f dangling=true


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



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


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>



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>


3、编写一个配置文件

server:
  port: 6001



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);
    }
}


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();
    }
}


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


发布微服务项目到Docker容器


将项目jar包上传到服务器

编写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


3、构建镜像


docker build -t springboot_docker:1.0 .


4、 启动容器:


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


二、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 实现的。

image.png



Docker网络命令

查看Docker网络模式:


docker network ls

image.png

添加Docker网络:


docker network create xxx


删除Docker网络:


docker network rm xxx


查看网络元数据:


docker network inspect xxx


删除所有无效的网络:


docker network prune


能干嘛

image.png


docker网络模式

image.png

查看某个容器的网络模式:


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


bridge模式

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


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

image.png



host模式

直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行 NAT 转换。


如果在 docker run 命令中同时使用了 --network host 和 -p端口映射,例如:


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


那么会出现一个警告:


WARNING: Published ports are discarded when using host network mode


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


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


container模式

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


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

image.png


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


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


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


自定义网络

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


容器 IP 变动时候可以通过服务名直接网络通信而不受影响。(类似Eureka,通过服务名直接互相通信,而不是写死IP地址)。

自定义桥接网络(自定义网络默认使用的是桥接网络 bridge):


1、 新建自定义网络


docker network create tomcat_network


2、 查看网络列表


docker network ls

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


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


三、Docker-compose容器编排

简介

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


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


image.png


下载

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



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:




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


# 进行语法检查

docker-compose config -q


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


docker-compose up -d


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
6月前
|
NoSQL Java Redis
Docker【Java 高级】4
Docker【Java 高级】4
84 0
|
6月前
|
Java Linux 网络架构
Docker【Java 高级】3
Docker【Java 高级】3
56 0
|
6月前
|
Java 应用服务中间件 Docker
Docker【Java 高级】2
Docker【Java 高级】2
547 0
|
6月前
|
数据可视化 Java 应用服务中间件
Docker【Java 高级】1
Docker【Java 高级】1
82 0
|
7月前
|
Ubuntu 网络协议 Linux
Docker高级网络实践
Docker中libnetwork提供的4种驱动,它们各有千秋,但实际上每一种方式都有一定的局限性。
129 0
|
7月前
|
存储 SpringCloudAlibaba 运维
docker高级篇:镜像原理和Dockerfile
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件
100 0
docker高级篇:镜像原理和Dockerfile
|
存储 安全 Linux
docker的冷门高级玩法(2)
docker的冷门高级玩法(2)
|
存储 应用服务中间件 Shell
docker的冷门高级玩法(1)
docker的冷门高级玩法(1)
|
消息中间件 Docker 容器
|
运维 前端开发 jenkins
Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成——部署方案优化
之前我们做的方案部署都是只能选择一个微服务部署并只有一台生产服务器,每个微服务只有一个实例,容错率低 如何去解决?
Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成——部署方案优化

相关产品

  • 云迁移中心