相关文章推荐
高大的茄子  ·  Android/Automotive ...·  4 月前    · 
酷酷的羊肉串  ·  macos - Mac OS X ...·  1 年前    · 

编写redis的docker-compose.yml配置文件,参数含义参考注释

不同的编排文件建议放到单独的文件夹中,比如单独新建一个redis目录,mysql的就创建mysql目录,依次类推

# 原始命令:
# docker run -d --name redis -p 6379:6379 -v  \
#   - /root/docker/compose/redis/redis.conf:/etc/redis/redis.conf \
#   - /root/docker/compose/redis/data:/data \
#   --network my_network redis:latest redis-server /etc/redis/redis.conf  
# 版本号
version: "3"
# 服务列表,命令:docker run
services:
  # 服务名称,任意,不重复即可
  redis:
    # 指定服务名称,命令:--name redis
    # 如果不指定,则将默认用docker-compose.yml所在文件夹名_服务名称_n命名
    container_name: redis
    # 指定镜像:命令 redis:latest
    image: redis:latest
    # 指定端口:命令 -p 主机端口:容器端口
    ports:
      - "6379:6379"
    # 数据容器卷
    volumes:
      - /root/docker/compose/redis/redis.conf:/etc/redis/redis.conf
      - /root/docker/compose/redis/data:/data
    # 加入指定网络,容器间必须要处于同一个网络才能通过容器名称进行调用
    networks:
      - my_network
    # 运行命令
    command: redis-server /etc/redis/redis.conf  
# 创建网络      
networks:
  # 默认将会创建为 docker-compose.yml所在 文件夹名_my_network 网络名称
  my_network:

2.2 运行配置文件

  • 在docker-compose.yml所在文件夹通过docker-compose up运行,也可以添加-d参数在后台运行
  • 此处docker-compose.yml所在文件夹:/root/docker/compose
  • # docker-compose up
    Creating network "compose_my_network" with the default driver
    Creating redis ... done
    Attaching to redis
    redis    | 1:C 24 Mar 2022 00:13:38.331 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
    redis    | 1:C 24 Mar 2022 00:13:38.331 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
    redis    | 1:C 24 Mar 2022 00:13:38.332 # Configuration loaded
    redis    | 1:M 24 Mar 2022 00:13:38.332 * monotonic clock: POSIX clock_gettime
    
  • 查看docker实例
  • 进入容器内部,可以执行redis的客户端工具
  • # docker-compose exec redis bash
    root@f5865bc42306:/data# redis-cli
    
  • 查看网络,发现compose会自动创建在编排文件中的配置文件
  • # docker network ls
    NETWORK ID     NAME                 DRIVER    SCOPE
    012d4d17c012   bridge               bridge    local
    # 默认将会创建为 docker-compose.yml所在文件夹名_my_network 网络名称
    88c54133c87a   compose_my_network   bridge    local
    1524da0505ee   host                 host      local
    f4cbc4779eaf   none                 null      local
    
  • 查看网络细节
  • docker network inspect compose_my_network
  • "Name": "compose_my_network", "Id": "88c54133c87a04cc8c86a55c240d2ccafb9bfb456b8e7d185a9a246b5d274025", "Created": "2022-03-24T00:13:37.623603357Z", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ "Subnet": "172.20.0.0/16", "Gateway": "172.20.0.1" "Internal": false, "Attachable": true, "Ingress": false, "ConfigFrom": { "Network": "" "ConfigOnly": false, "Containers": { "f5865bc42306380b1bd72690d6f67d8abdd46a240a96ea5f9bcfee412fe76c17": { "Name": "redis", "EndpointID": "8638b4c9850e533778d331bfd916b120f8a1ac59a9f547763c5e352df93ed897", "MacAddress": "02:42:ac:14:00:02", "IPv4Address": "172.20.0.2/16", "IPv6Address": "" "Options": {}, "Labels": { # 内部实际名称还是my_network "com.docker.compose.network": "my_network", # 容器编排项目名称 "com.docker.compose.project": "compose", "com.docker.compose.version": "1.29.2"
  • docker-compose stop:停止但不删除
  • docker-compose down:停止并且删除网络等一些列配置
  • # docker-compose down
    Removing redis ... done
    Removing network compose_my_network
    

    三、MySQL编排

    3.1 编写配置文件

    注意这里只贴出了compose的构建配置,等同的docker命令参考redis部分,只是内容变了,但是等级等价的命令并没有太大差异

    version: "3"
    services:
      mysql:
        container_name: mysql
        image: mysql:5.7
        ports:
          - "33306:3306"
        environment:
          # 等同于 -e MYSQL_ROOT_PASSWORD指定root的登录密码
          MYSQL_ROOT_PASSWORD: 'tianxin'
          MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
          # 这里这个指令compose启动成功后会自动创建名为docker的数据库
          MYSQL_DATABASE: 'docker'
          # 此处就是相当于 mysql create user,创建了数据库的登录用户
          MYSQL_USER: 'docker'
          MYSQL_PASSWORD: '123456'  
        volumes:
          - /root/docker/compose/mysql/data:/var/lib/mysql
          # 这里的my.cnf可以从原来的安装的MySQL里面找,如果没有不配置也不影响,只是为了方便外部更改
          - /root/docker/compose/mysql/conf/my.cnf:/etc/my.cnf
          - /root/docker/compose/mysql/init:/docker-entrypoint-initdb.d
        networks:
          # 注意加入同一个网络
          - my_network
        # 解决外部无法访问
        command: --default-authentication-plugin=mysql_native_password
    networks:
      my_network:
    

    3.2 运行配置文件

  • 在mysql docker-compose.yml所在文件夹通过docker-compose up运行,也可以添加-d参数在后台运行
  • 运行之后养成随手就是 docker ps 查看容器是否启动的好习惯
  • 进入容器内容,通过指定的密码登录
  • # docker-compose exec mysql bash
    root@6cb40ff45da5:/# mysql -uroot -ptianxin
    mysql: [Warning] Using a password on the command line interface can be insecure.
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 2
    Server version: 5.7.36 MySQL Community Server (GPL)
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    # 这里可以看到,自动创建了docker数据库
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | docker             |
    | mysql              |
    | performance_schema |
    | sys                |
    +--------------------+
    5 rows in set (0.00 sec)
    mysql> use docker;
    Database changed
    mysql> show tables;
    Empty set (0.00 sec)
    

    四、微服务编排

    tip:MySQL和Redis相对于独立,但是对于服务而言,依赖于Redis和MySQL,所以在服务启动前需要先启动Redis和MySQL,如果依赖服务较多,人工管理是一件比较麻烦的事情。通过docker-compose的编排可以指定依赖关系等等

    4.1 编写服务

  • 创建SpringBoot服务,采用SpringBoot+MyBatis+MySQL+Redis完成简单的SpringBoot应用
  • maven的pom.xml依赖如下
  • <?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.4.3</version>
            <relativePath/>
        </parent>
        <groupId>com.codecoord</groupId>
        <artifactId>docker</artifactId>
        <version>1.0</version>
        <properties>
            <java.version>1.8</java.version>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.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-data-redis</artifactId>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.5.1</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.2.5</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    
  • 应用配置文件
  • 特别说明:服务依赖的容器服务,使用容器服务名称,比如 jdbc:mysql://mysql:3306/docker,不要通过IP。端口号是容器内部端口,不是外部端口号!比如 -p 13306:3306,13306是对外端口,3306才是容器内部服务端口,服务依赖时不要指定为外部端口,生产中也不建议除了服务外的容器直接对外提供访问

    server:
      port: 80
    spring:
      redis:
        port: 6379
        # redis:依赖的服务
        host: redis
      datasource:
        # mysql:依赖的服务,注意端口是容器端口,非宿主机端口
        url: jdbc:mysql://mysql:3306/docker?userSSL=false
        username: root
        password: tianxin
        driver-class-name: com.mysql.cj.jdbc.Driver
        type: com.alibaba.druid.pool.DruidDataSource
    
    import com.codecoord.docker.domain.User;
    import com.codecoord.docker.service.UserService;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import javax.annotation.Resource;
    import java.util.*;
    @RestController
    @RequestMapping("/docker")
    public class DockerController {
        @Resource
        private UserService userService;
        @Resource
        private RedisTemplate<String, Object> redisTemplate;
        @RequestMapping("/list")
        public List<User> list() {
            return userService.list();
        @RequestMapping("/add")
        public boolean add() {
            return userService.save(new User() {{
                setName(UUID.randomUUID().toString());
        @RequestMapping("/get/{id}")
        public Object get(@PathVariable("id") Long id) {
            Map<String, Object> returnMap = new HashMap<>();
            Object cache = redisTemplate.opsForValue().get(id);
            if (Objects.nonNull(cache)) {
                returnMap.put("data", cache);
                returnMap.put("cache", "缓存命中");
                return returnMap;
            User user = userService.getById(id);
            returnMap.put("data", user);
            returnMap.put("cache", "缓存未命中");
            redisTemplate.opsForValue().set(id.toString(), user);
            return returnMap;
    
  • 其他DAO层的按照MP格式搭建接口,注意实体类需要序列化
  • Redis的序列化按照自己的需要配置
  • 4.2 服务构建

    先安装java:8镜像,参考Docker-高级篇(1)-Dockerfile(核心&构建Redis&构建JDK8) - 掘金 (juejin.cn)

  • 编写Dockerfile,将服务项目打成jar包(普通的springboot使用maven package打包后的jar包)之后和Dockerfile放于同一个文件文件夹下
  • # 基础镜像使用java8,需要先构建
    FROM java:8
    MAINTAINER tianxincoord@163.com
    # 容器卷,指定临时文件的目录为/tmp
    VOLUME /tmp
    # 指定工作目录
    WORKDIR /tmp
    # 重命名可选操作,方便docker ps查看
    add docker-1.0.jar core_service.jar
    # 运行jar包
    ENTRYPOINT ["java", "-jar", "core_service.jar"]
    # 暴露30001端口作为服务端口
    EXPOSE 30001
    
    # 构建镜像
    # docker build -t core_service:1.0 .
    Sending build context to Docker daemon  245.5MB
    Step 1/7 : FROM java:8
     ---> 95064f52c03b
    Step 2/7 : MAINTAINER tianxincoord@163.com
     ---> Running in 4e2fe1672499
    Removing intermediate container 4e2fe1672499
     ---> e17943871098
    Step 3/7 : VOLUME /tmp
     ---> Running in b7f7d56bc0cf
    Removing intermediate container b7f7d56bc0cf
     ---> 7b67adbb7378
    Step 4/7 : WORKDIR /tmp
     ---> Running in 973e07d965cb
    Removing intermediate container 973e07d965cb
     ---> 70f5211073eb
    Step 5/7 : add docker-1.0.jar core_service.jar
     ---> 5015d0feafeb
    Step 6/7 : ENTRYPOINT ["java", "-jar", "core_service.jar"]
     ---> Running in a8b45a171493
    Removing intermediate container a8b45a171493
     ---> 0e9ea7fb43c7
    Step 7/7 : EXPOSE 30001
     ---> Running in 01e5efc042a6
    Removing intermediate container 01e5efc042a6
     ---> af170edd9100
    Successfully built af170edd9100
    Successfully tagged core_service:1.0
    
  • 查看构建完成后的镜像
  • # docker images
    REPOSITORY     TAG       IMAGE ID       CREATED          SIZE
    core_service   1.0       af170edd9100   58 seconds ago   648MB
    java           8         95064f52c03b   8 minutes ago    610MB
    centos         7         eeb6ee3f44bd   6 months ago     204MB
    

    4.3 服务编排(redis&mysql&服务)

  • 编写compose配置文件
  • version: "3"
    services:
      macro_server:
        image: core_service:1.0
        container_name: core_service
        ports:
          - "80:80"
        volumes:
          - /root/docker/compose/app:/data
        # 指定网络,这一步必须要和以来的服务处于统一网络
        networks:
          - my_network
        # 依赖于redis和mysql,在启动本服务之前会先启动依赖的服务
        depends_on:
          - redis
          - mysql
      # Redis服务
      redis:
        container_name: redis
        image: redis:latest
        ports:
          - "6379:6379"
        volumes:
          - /root/docker/compose/redis/redis.conf:/etc/redis/redis.conf
          - /root/docker/compose/redis/data:/data
        networks:
          - my_network
        command: redis-server /etc/redis/redis.conf
      # MySQL服务,上面的构建服务直接拷贝下来即可
      mysql:
        container_name: mysql
        image: mysql:5.7
        ports:
          - "3306:3306"
        environment:
          MYSQL_ROOT_PASSWORD: 'tianxin'
          MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
          MYSQL_DATABASE: 'docker'
          MYSQL_USER: 'docker'
          MYSQL_PASSWORD: '123456'
        volumes:
          - /root/docker/compose/mysql/data:/var/lib/mysql
          - /root/docker/compose/mysql/conf/my.cnf:/etc/my.cnf
          - /root/docker/compose/mysql/init:/docker-entrypoint-initdb.d
        networks:
          - my_network
        command: --default-authentication-plugin=mysql_native_password
    networks:
      my_network:
    
  • 启动compose
  • # docker-compose up
    Creating network "compose_my_network" with the default driver
    Creating redis ... done
    Creating mysql ... done
    Creating core_service ... done
    
  • 进入服务内部,ping一下服务名,看一下是否网络连接成功,只有这里ping得通,服务才会调用得通
  • 4.5 服务测试

  • 进入MySQL服务中,创建对应的库和表
  • docker exec -it mysql bash
    
    use docker;
    create table user
        id          int primary key auto_increment,
        name        varchar(50),
        create_time datetime not null default current_timestamp,
        modify_time datetime not null default current_timestamp on update current_timestamp
    
  • 访问接口是否正常
  • http://192.168.33.10:80/docker:未配置的路径,正常抛出404
  • 5.1 自愈性

  • 服务容器化之后可以比普通jar部署方式拥有更高自愈性,比如原来普通jar部署当服务挂了之后,必须要重新处理启动服务,此时也可以通过一个看门狗程序当发现进程挂了之后自动重启,但是当服务多了,管理起来是一个比较麻烦的时候
  • 而对于容器来说,就是docker kill/stop和docker run就可以快速淘汰老的服务启动新服务
  • 5.2 调度性

  • 传统jar部署方式最大的问题在于环境的一致性,比如现在A服务器上的服务能力不够了,需要在B服务器上部署一个新服务,那么安装环境是一个很麻烦的事情,特别是对于配置项目较多的服务来说进行大规模的快速调度基本上是一个很麻烦且费力的操作
  • 对于容器化服务来说,所有的依赖服务在一个镜像完成后就可以以此进行为模板快速docker run很多很多的相同配置环境的服务
  • 那么在弹性扩缩容上,通过容器可以很方便达到这个目标,服务容器话是一个服务用户到了一定规模之后不得不考虑的问题
  • TianXinCoord TianXinCoord
    粉丝