Docker高级(完结)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 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
相关文章
|
7月前
|
存储 运维 Linux
Docker详解(六)——Docker高级控制命令
Docker详解(六)——Docker高级控制命令
66 2
|
7月前
|
存储 监控 Docker
《Docker 简易速速上手小册》第7章 高级容器管理(2024 最新版)
《Docker 简易速速上手小册》第7章 高级容器管理(2024 最新版)
69 0
|
存储 SpringCloudAlibaba 运维
docker高级篇:镜像原理和Dockerfile
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件
218 0
docker高级篇:镜像原理和Dockerfile
|
Ubuntu 网络协议 网络安全
|
NoSQL Java Redis
Docker【Java 高级】4
Docker【Java 高级】4
118 0
|
Java Linux 网络架构
Docker【Java 高级】3
Docker【Java 高级】3
87 0
|
Java 应用服务中间件 Docker
Docker【Java 高级】2
Docker【Java 高级】2
933 0
|
数据可视化 Java 应用服务中间件
Docker【Java 高级】1
Docker【Java 高级】1
105 0
|
Ubuntu 网络协议 Linux
Docker高级网络实践
Docker中libnetwork提供的4种驱动,它们各有千秋,但实际上每一种方式都有一定的局限性。
214 0
|
消息中间件 Docker 容器
下一篇
DataWorks