精华内容
下载资源
问答
  • 2020-01-12 00:35:05

    本次搭建zk集群为了方便,以docker容器的方式来演示

    1.创建三个docker实例并按装jdk8

    docker run --privileged -dit --name zk1 --hostname zk1 docker.io/centos:7.6.1810 /usr/sbin/init
    docker run --privileged -dit --name zk2 --hostname zk2 docker.io/centos:7.6.1810 /usr/sbin/init
    docker run --privileged -dit --name zk3 --hostname zk3 docker.io/centos:7.6.1810 /usr/sbin/init
    #为了方便这里直接使用yum安装
    docker exec -ti zk1 /bin/bash -c "yum -y install java-1.8.0-openjdk.x86_64"
    docker exec -ti zk2 /bin/bash -c "yum -y install java-1.8.0-openjdk.x86_64"
    docker exec -ti zk3 /bin/bash -c "yum -y install java-1.8.0-openjdk.x86_64"
    

    2.查出每个docker的ip(在创建时指定ip也可以)

    [root@wfw zk]# docker inspect -f='{{.NetworkSettings.IPAddress}} {{.Config.Hostname}}' $(sudo docker ps -a -q) > hostname
    [root@wfw zk]# ll
    total 4
    -rw-r--r-- 1 root root 45 Jan 11 23:30 hostname
    [root@wfw zk]# cat hostname 
    172.17.0.4 zk3
    172.17.0.3 zk2
    172.17.0.2 zk1
    

    3.配置每个docker的hosts

    #将hostname文件拷贝到各个docker中的home路径下
    docker cp hostname zk1:/home/hostname
    docker cp hostname zk2:/home/hostname
    docker cp hostname zk3:/home/hostname
    
    #将hostname内容写入hosts文件
    docker exec -ti zk1 /bin/bash -c "cat /home/hostname >> /etc/hosts"
    docker exec -ti zk2 /bin/bash -c "cat /home/hostname >> /etc/hosts"
    docker exec -ti zk3 /bin/bash -c "cat /home/hostname >> /etc/hosts"
    

    4.下载zk并复制到各个docker

    wget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.10/zookeeper-3.4.10.tar.gz
    
    #将zk复制到各个docker的home路径下
    docker cp zookeeper-3.4.10.tar.gz zk1:/home/zookeeper-3.4.10.tar.gz
    docker cp zookeeper-3.4.10.tar.gz zk2:/home/zookeeper-3.4.10.tar.gz
    docker cp zookeeper-3.4.10.tar.gz zk3:/home/zookeeper-3.4.10.tar.gz
    
    #解压所有docker上的zk包
    docker exec -ti zk1 /bin/bash -c "tar zxvf /home/zookeeper-3.4.10.tar.gz -C /home"
    docker exec -ti zk2 /bin/bash -c "tar zxvf /home/zookeeper-3.4.10.tar.gz -C /home"
    docker exec -ti zk3 /bin/bash -c "tar zxvf /home/zookeeper-3.4.10.tar.gz -C /home"
    

    5.登陆zk1,配置zk的配置文件zoo.cfg

    [root@zk1 home]# cd /home/zookeeper-3.4.10/conf/
    [root@zk1 conf]# touch zoo.cfg
    [root@zk1 conf]# vi zoo.cfg 
    [root@zk1 conf]# cat zoo.cfg 
    tickTime=2000
    initLimit=10
    syncLimit=5
    dataLogDir=/opt/zookeeper/logs
    dataDir=/opt/zookeeper/data
    clientPort=2181
    autopurge.snapRetainCount=500
    autopurge.purgeInterval=24
    server.1=zk1:2888:3888
    server.2=zk2:2888:3888 
    server.3=zk3:2888:3888
    

    6.拷贝zoo.cfg到其他两个docker的同路径下,为了方便也可以在宿主机中创建该文件像上述方法拷贝到所有docker

    docker cp zoo.cfg zk1:/home/zookeeper-3.4.10/conf/zoo.cfg
    docker cp zoo.cfg zk2:/home/zookeeper-3.4.10/conf/zoo.cfg
    docker cp zoo.cfg zk3:/home/zookeeper-3.4.10/conf/zoo.cfg
    

    7.创建data路径及myid文件

    docker exec -ti zk1 /bin/bash -c "mkdir -p /opt/zookeeper/{logs,data}; echo "1" > /opt/zookeeper/data/myid"
    docker exec -ti zk2 /bin/bash -c "mkdir -p /opt/zookeeper/{logs,data}; echo "2" > /opt/zookeeper/data/myid"
    docker exec -ti zk3 /bin/bash -c "mkdir -p /opt/zookeeper/{logs,data}; echo "3" > /opt/zookeeper/data/myid"
    

    8.启动每个docker中的zk进程

    [root@wfw zk]# docker exec -ti zk3 /bin/bash -c "/home/zookeeper-3.4.10/bin/zkServer.sh start"
    ZooKeeper JMX enabled by default
    Using config: /home/zookeeper-3.4.10/bin/../conf/zoo.cfg
    Starting zookeeper ... STARTED
    [root@wfw zk]# docker exec -ti zk2 /bin/bash -c "/home/zookeeper-3.4.10/bin/zkServer.sh start"
    ZooKeeper JMX enabled by default
    Using config: /home/zookeeper-3.4.10/bin/../conf/zoo.cfg
    Starting zookeeper ... STARTED
    [root@wfw zk]# docker exec -ti zk1 /bin/bash -c "/home/zookeeper-3.4.10/bin/zkServer.sh start"
    ZooKeeper JMX enabled by default
    Using config: /home/zookeeper-3.4.10/bin/../conf/zoo.cfg
    Starting zookeeper ... STARTED
    

    9.查询zk状态

    [root@wfw zk]# docker exec -ti zk3 /bin/bash -c "/home/zookeeper-3.4.10/bin/zkServer.sh status"
    ZooKeeper JMX enabled by default
    Using config: /home/zookeeper-3.4.10/bin/../conf/zoo.cfg
    Mode: follower
    [root@wfw zk]# docker exec -ti zk2 /bin/bash -c "/home/zookeeper-3.4.10/bin/zkServer.sh status"
    ZooKeeper JMX enabled by default
    Using config: /home/zookeeper-3.4.10/bin/../conf/zoo.cfg
    Mode: leader
    [root@wfw zk]# docker exec -ti zk1 /bin/bash -c "/home/zookeeper-3.4.10/bin/zkServer.sh status"
    ZooKeeper JMX enabled by default
    Using config: /home/zookeeper-3.4.10/bin/../conf/zoo.cfg
    Mode: follower
    

    附:

    如果三个docker已经配置了ssh免密登陆,还可以只在一个docker启动左右集群的zk进程

    #!/bin/bash
    usage="Usage: zkRun.sh [start|stop|status|restart]"
    if [ $# -ne 1 ]; then
      echo $usage
      exit 1
    fi
    case $1 in
      (start)
        cmd="start"
      ;;
      (stop)
        cmd="stop"
      ;;
      (status)
        cmd="status"
      ;;
      (restart)
        cmd="restart"
      ;;
      (*)
        echo $usage
        exit 1
        ;;
    esac
    docker_hostname=$(cat ./hostname|awk '{print $2}')
    for salve in $docker_hostname ; do
        ssh $docker_hostname "/home/zookeeper-3.4.10/bin/zkServer.sh $cmd"
    done
    

    在一开始生成hostname文件时就是直接通过查询docker容器列表详情获得的,也可以通过脚本形式来生成zk的zoo.cfg配置文件,过程也不复杂

    #!/bin/bash
    # zoo_gen.sh
    # generate zoo.cfg
    echo "tickTime=2000" >> zoo.cfg
    echo "initLimit=10" >> zoo.cfg
    echo "syncLimit=5" >> zoo.cfg
    echo "dataLogDir=/opt/zookeeper/logs" >> zoo.cfg
    echo "dataDir=/opt/zookeeper/data" >> zoo.cfg
    echo "clientPort=2181" >> zoo.cfg
    echo "autopurge.snapRetainCount=500" >> zoo.cfg
    echo "autopurge.purgeInterval=24" >> zoo.cfg
    
    id=0
    for hostname in $(cat ./hostname|awk '{print $2}')
      do
        ((id++))
        echo "server.$id=$hostname:2888:3888" >> zoo.cfg
      done
    

    myid文件的自动生成和推送其实也不是难做,只不过需要ssh免密登陆,稍微复杂一些,这里就略过了,感兴趣的可以自己试着写写,方法思路有很多种

    zk_auto.sh

    #!/bin/sh
    #docker pull openjdk:8u242-jdk
    #wget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.10/zookeeper-3.4.10.tar.gz
    
    docker stop zk1 && docker rm zk1
    docker stop zk2 && docker rm zk2
    docker stop zk3 && docker rm zk3
    
    #创建docker
    image=mamohr/centos-java:latest
    docker run --privileged -dit --name zk3 --hostname zk3 ${image} /usr/sbin/init
    docker run --privileged -dit --name zk2 --hostname zk2 ${image} /usr/sbin/init
    docker run --privileged -dit --name zk1 --hostname zk1 ${image} /usr/sbin/init
    
    #生成hostname
    docker inspect -f='{{.NetworkSettings.IPAddress}} {{.Config.Hostname}}' $(sudo docker ps -a -q) | grep zk > hostname
    
    #将hostname文件拷贝到各个docker中的home路径下
    docker cp hostname zk1:/home/hostname
    docker cp hostname zk2:/home/hostname
    docker cp hostname zk3:/home/hostname
    
    #将hostname内容写入hosts文件
    docker exec -ti zk1 /bin/bash -c "cat /home/hostname >> /etc/hosts"
    docker exec -ti zk2 /bin/bash -c "cat /home/hostname >> /etc/hosts"
    docker exec -ti zk3 /bin/bash -c "cat /home/hostname >> /etc/hosts"
    
    #将zk复制到各个docker的home路径下
    docker cp zookeeper-3.4.10.tar.gz zk1:/home/zookeeper-3.4.10.tar.gz
    docker cp zookeeper-3.4.10.tar.gz zk2:/home/zookeeper-3.4.10.tar.gz
    docker cp zookeeper-3.4.10.tar.gz zk3:/home/zookeeper-3.4.10.tar.gz
    
    #解压所有docker上的zk包
    docker exec -ti zk1 /bin/bash -c "tar zxf /home/zookeeper-3.4.10.tar.gz -C /home"
    docker exec -ti zk2 /bin/bash -c "tar zxf /home/zookeeper-3.4.10.tar.gz -C /home"
    docker exec -ti zk3 /bin/bash -c "tar zxf /home/zookeeper-3.4.10.tar.gz -C /home"
    
    #生成zoo.cfg
    echo "tickTime=2000" > zoo.cfg
    echo "initLimit=10" >> zoo.cfg
    echo "syncLimit=5" >> zoo.cfg
    echo "dataLogDir=/opt/zookeeper/logs" >> zoo.cfg
    echo "dataDir=/opt/zookeeper/data" >> zoo.cfg
    echo "clientPort=2181" >> zoo.cfg
    echo "autopurge.snapRetainCount=500" >> zoo.cfg
    echo "autopurge.purgeInterval=24" >> zoo.cfg
    
    id=0
    for hostname in $(cat ./hostname|awk '{print $2}')
      do
        ((id++))
        echo "server.$id=$hostname:2888:3888" >> zoo.cfg
      done
    
    docker cp zoo.cfg zk1:/home/zookeeper-3.4.10/conf/zoo.cfg
    docker cp zoo.cfg zk2:/home/zookeeper-3.4.10/conf/zoo.cfg
    docker cp zoo.cfg zk3:/home/zookeeper-3.4.10/conf/zoo.cfg
    
    docker exec -ti zk1 /bin/bash -c "mkdir -p /opt/zookeeper/{logs,data}; echo "1" > /opt/zookeeper/data/myid"
    docker exec -ti zk2 /bin/bash -c "mkdir -p /opt/zookeeper/{logs,data}; echo "2" > /opt/zookeeper/data/myid"
    docker exec -ti zk3 /bin/bash -c "mkdir -p /opt/zookeeper/{logs,data}; echo "3" > /opt/zookeeper/data/myid"
    
    docker exec -ti zk1 /bin/bash -c "/home/zookeeper-3.4.10/bin/zkServer.sh start"
    docker exec -ti zk2 /bin/bash -c "/home/zookeeper-3.4.10/bin/zkServer.sh start"
    docker exec -ti zk3 /bin/bash -c "/home/zookeeper-3.4.10/bin/zkServer.sh start"
    
    docker exec -ti zk1 /bin/bash -c "/home/zookeeper-3.4.10/bin/zkServer.sh status" 
    docker exec -ti zk2 /bin/bash -c "/home/zookeeper-3.4.10/bin/zkServer.sh status"
    docker exec -ti zk3 /bin/bash -c "/home/zookeeper-3.4.10/bin/zkServer.sh status"
    
    
    更多相关内容
  • 下面将介绍使用三台云服务器,用docker部署zookeeper+kafka+kafka-connect-ui集群。(如果大家掌握基础Linux命令、docker常用命令以及DockerCompose基础知识的话应该可以顺利完成部署)

    Docker容器化部署zookeeper+kafka集群详细步骤

    一、前言

    写在前面:下面将介绍使用三台云服务器,用docker部署zookeeper+kafka+kafka-connect-ui集群。(如果大家掌握基础Linux命令、docker常用命令以及DockerCompose基础知识的话应该可以顺利完成部署)

    背景介绍:为了测试使用kafka connect插件读取Oracle数据库日志从而达到实时获取Oracle数据库数据变化的目的,而搭建的三个节点的zookeeper+kafka集群,顺便将自己的步骤记录下来加深印象也希望能对大家有些许的帮助。

    最后我还是没能找到一个稳定监控Oracle数据库的kafka connect插件,如果大佬们有好的方案,希望能告诉我一下,有任何问题也可在下方评论,大家一起讨论一起学习一起进步。

    二、准备三台云服务器

    这里我用的是三台云服务器,大家可以白嫖三家的云服务器新用户优惠,也可以通过流量付费的方式购买三个配置高一些的服务器,当然也可以使用虚拟机。

    这里我以kafka01、kafka02、kafka03代指三台服务器

    以下操作默认使用root权限

    三、安装Docker

    1 卸载旧版本Docker

    yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-engine
    

    2 安装yum工具包

    yum install -y yum-utils
    

    3 设置阿里云镜像

    yum-config-manager \
        --add-repo \
        http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    

    4 安装Docker

    yum install docker-ce docker-ce-cli containerd.io  #安装最新版本 docker-ce 社区版  docker-ce 企业版
    
    yum list docker-ce --showduplicates | sort -r #显示docker历史版本
    yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io #安装指定版本docker
    

    5 启动Docker

    systemctl start docker
    

    查看docker是否安装成功

    docker version
    

    6 Docker命令

    官方命令文档

    四、下载Docker-compose

    sudo 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 777 docker-compose # chmod 777 给文件授权 可读可写可执行
    

    五、拉取zookeeper和kafka相关镜像

    我这里用的是zookeeper、wurstmeister/kafka和landoop/kafka-connect-ui镜像
    这个也可以先不拉取,后续启动docker-compose文件时会自动下载

    docker pull zookeeper
    
    docker pull wurstmeister/kafka
    
    docker pull landoop/kafka-connect-ui
    

    查看docker已有镜像

    docker images
    

    六、给各服务器开启相关端口

    如果使用的是云服务器一定要在控制台安全组中打开所需要的端口,如果使用的虚拟机的话可以直接关闭防火墙

    systemctl stop firewalld ## 关闭防火墙
    systemctl status firewalld ## 查看防火墙状态
    systemctl start firewalld ## 打开防火墙
    

    七、编写compose文件

    如果大家有对zookeeper和kafka的部署或者其中配置有问题的话可以参考这篇Canal监控MySQL数据到Kafka详细步骤(jdk+zookeeper+kafka+canal+mysql),其中对部分参数有所解释,步骤也较为详细,或者大家也可以在下方评论交流。

    1 在/home/docker目录创建docker-compose.yml以及zoo.cfg文件

    2 编写第一个节点的compose文件以及zoo.cfg文件

    compose文件

    version: '1.1'
    services:
      zookeeper:
        image: 'zookeeper:latest'
        restart: always
        environment:
          ZOO_MY_ID: 1
        volumes:
          - /home/docker/zoo.cfg:/conf/zoo.cfg
        ports:
          - 2181:2181
          - 2888:2888
          - 3888:3888
        container_name: 'zookeeper01'
      kafka01:
        image: wurstmeister/kafka
        ports:
          - "9092:9092"
          - "8083:8083"
        environment:
          KAFKA_ADVERTISED_HOST_NAME: kafka01ip
          KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka01ip:9092
          KAFKA_ZOOKEEPER_CONNECT: "kafka01ip:2181,kafka02ip:2181,kafka03ip:2181"
          KAFKA_ADVERTISED_PORT: 9092
          KAFKA_BROKER_ID: 1
          KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
        depends_on:
          - zookeeper
        container_name: kafka01
      kafkaconnectui:
        image: landoop/kafka-connect-ui
        ports:
          - "8000:8000"
        environment:
          CONNECT_URL: kafka01ip:8083
        container_name: kafkaconnectui
        depends_on:
          - kafka01
    

    zoo.cfg文件

    tickTime=2000
    initLimit=10
    syncLimit=5
    dataDir=/data
    dataLogDir=/data
    clientPort=2181
    audit.enable=true
    server.1=0.0.0.0:2888:3888
    server.2=kafka02ip:2888:3888
    server.3=kafka03ip:2888:3888
    

    3 编写第二个节点的compose文件以及zoo.cfg文件

    compose文件

    version: '1.1'
    services:
      zookeeper:
        image: 'zookeeper:latest'
        restart: always
        environment:
          ZOO_MY_ID: 2
        volumes:
          - /home/docker/zoo.cfg:/conf/zoo.cfg
        ports:
          - 2181:2181
          - 2888:2888
          - 3888:3888
        container_name: 'zookeeper02'
      kafka02:
        image: wurstmeister/kafka
        ports:
          - "9092:9092"
          - "8083:8083"
        environment:
          KAFKA_ADVERTISED_HOST_NAME: kafka02ip
          KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka02ip:9092
          KAFKA_ZOOKEEPER_CONNECT: "kafka01ip:2181,kafka02ip:2181,kafka03ip:2181"
          KAFKA_ADVERTISED_PORT: 9092
          KAFKA_BROKER_ID: 2
          KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
        depends_on:
          - zookeeper
        container_name: kafka02
      kafkaconnectui:
        image: landoop/kafka-connect-ui
        ports:
          - "8000:8000"
        environment:
          CONNECT_URL: kafka02ip:8083
        container_name: kafkaconnectui
        depends_on:
          - kafka02
    

    zoo.cfg文件

    tickTime=2000
    initLimit=10
    syncLimit=5
    dataDir=/data
    dataLogDir=/data
    clientPort=2181
    audit.enable=true
    server.1=kafka01ip:2888:3888
    server.2=0.0.0.0:2888:3888
    server.3=kafka03ip:2888:3888
    

    4 编写第三个节点的compose文件以及zoo.cfg文件

    compose文件

    version: '1.1'
    services:
      zookeeper:
        image: 'zookeeper:latest'
        restart: always
        environment:
          ZOO_MY_ID: 3
        volumes:
          - /home/docker/zoo.cfg:/conf/zoo.cfg
        ports:
          - 2181:2181
          - 2888:2888
          - 3888:3888
        container_name: 'zookeeper03'
      kafka03:
        image: wurstmeister/kafka
        ports:
          - "9092:9092"
          - "8083:8083"
        environment:
          KAFKA_ADVERTISED_HOST_NAME: kafka03ip
          KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka03ip:9092
          KAFKA_ZOOKEEPER_CONNECT: "kafka01ip:2181,kafka02ip:2181,kafka03ip:2181"
          KAFKA_ADVERTISED_PORT: 9092
          KAFKA_BROKER_ID: 3
          KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
        depends_on:
          - zookeeper
        container_name: kafka03
      kafkaconnectui:
        image: landoop/kafka-connect-ui
        ports:
          - "8000:8000"
        environment:
          CONNECT_URL: kafka03ip:8083
        container_name: kafkaconnectui
        depends_on:
          - kafka03
    

    zoo.cfg文件

    tickTime=2000
    initLimit=10
    syncLimit=5
    dataDir=/data
    dataLogDir=/data
    clientPort=2181
    audit.enable=true
    server.1=kafka01ip:2888:3888
    server.2=kafka02ip:2888:3888
    server.3=0.0.0.0:2888:3888
    

    八、启动docker-compose

    cd到/home/docker文件夹下,此时当前目录下有一个docker-compose.yml文件以及zoo.cfg文件

    docker-compose up  ## 启动
    docker-compose stop  ## 停止
    

    三个节点都启动后查看每个节点正在运行的镜像

    docker ps
    

    九、启动kafka-connect

    镜像都正常启动后,进入各个kafka容器中启动kafka-connect

    docker exec -it kafka01 bash  ## 进入kafka01容器
    
    cd /opt/kafka_2.13-2.8.1/bin/  ## 进入到bin目录下
    
    connect-distributed.sh -daemon /opt/kafka_2.13-2.8.1/config/connect-distributed.properties  
    ## 启动connect
    

    十、在浏览器输入kafka01ip:8000进入kafka ui界面

    kafka-ui界面

    十一、结语

    至此,已经完成所有操作,可以通过kafka来进行一些测试了。以上应该有很多可以更加简便的操作或者不对的地方,如有发现还行大家指正,不胜感激。大家有什么问题也可以在下方评论或者私信我,我会尽力帮大家解答。如果这篇文章对大家还算有所帮助,希望帮忙点个赞支持一下。最后祝大家工作顺利,心想事成!

    展开全文
  • 文章目录项目背景最终效果启动 zk 集群启动 nacos 服务如何实现技术栈构建基础镜像Compose 配置实现细节s6mysql 初始时执行 sql源替换扩展: 后面还可以做什么参考资料 项目 如果你想直接看代码,可以直接看我的 ...

    项目

    如果你想直接看代码,可以直接看我的 git-docker-centos 项目地址,最近发布了 v1.2.0 版本,readme 已经非常详细了,包括项目的使用方式 和 需求规划

    本机环境基本只依赖 Docker 的安装,Docker Desktop 的安装教程可参考我之前的博客-Docker Desktop 安装方式和开发镜像分享,当然,更详细的教程网上一搜有一堆

    本篇文章的个人博客地址
    公众号文章地址

    背景

    之前已经大致将自己平时开发用到的服务和环境,都打包到了 Dockerfile 中,可在本机进行开发环境和基础组件的一键部署。后续自己也进行一些改进,减少了仓库中的shell 脚本文件,整体安装逻辑会更加直观

    关于我为什么要封装自己的 Dockerfile

    这个项目当时做到这里就感觉算是完成了一个不小的目标,但随着自己用这个项目的深入,总感觉还差点意思,比如 zk 只能部署一个节点,集群的话需要写三个(对应三个节点)很长的 docker run 指令,加一堆参数(主要是注入 zk 本身的配置),根本没法记,只能放到电脑笔记中,每次拷贝粘贴,非常不方便

    给人的感觉,有点像微信的公众号,本来机制是很好的,实时的新闻也有,沉淀下来的技术博客也很多,但是用着用着就感觉没那么好用了,自己不想看的东西越来越多,想要的文章自己又看不到。好的工具却不能提升学习的效率,类似这种感觉

    另外还有一个小小的痛点: nacos 作为阿里开源的配置管理服务,官方仓库确实已经很完善了,代码在 nacos 仓库,容器化部署相关的配置文件放到 nacos-docker,分得很细。但是官方提供的 standalone-mysql-5.7.yaml 单机部署配置文件中使用的 nacos 和 mysql 镜像不兼容 Mac M1 系统。官方也有对应的 issue,但是到发这篇博客的时候,官方还未解决

    直到有一天通过 k8s 接触到了 其他管理容器集群的工具,其中 swarm 就是通过 compose 管理集群的,突然意识到 docker-compose 这个工具应该是比较切合我的需求

    主要的原因,就是 对比 Kubernetes 来说:k8s 自成一套体系,也牵扯到很多其他技术栈,对初学者来说需要花很多时间去掌握。但是 Compose 其实还是基于 Docker 的基本指令,它对应的配置文件,其实就对应了 Docker 的指令或者参数,对熟悉 Docker 指令的同学来说肯定非常好上手

    那还多说什么呢?直接参考官方文档,实践起来

    最终效果

    Compose 这块实现了 zk 集群 和 nacos 服务(依赖 mysql),直接看效果

    启动 zk 集群

    # 构建操作系统基础镜像
    make build_base
    
    # 构建 java 开发镜像
    make build_dev_java
    
    # 构建 zookeeper 镜像
    make build_zookeeper
    
    # 启动 zk 集群
    ## 前面构建镜像都是一次性的,后面启动 zk 集群、启动 nacos 都不需要再重复构建
    make run_zookeeper_cluster
    

    zookeeper cluster start

    启动 nacos 服务

    # 构建 nacos 镜像
    make build_nacos
    
    # 启动 nacos 服务
    make run_nacos_mysql
    

    nacos start
    nacos web
    其中,nacos 服务启动 需要先构建 centos_base、centos_java、centos_nacos 和 centos_mysql 镜像,zk 集群启动需要先构建 centos_java、centos_zookeeper 镜像

    第一次构建镜像的话,确实需要总的大概十几分钟的时间,比如 java 的基础镜像,需要先下载几百M 的 JDK,zookeeper 镜像的构建需要编译 zk,但是之后的开发过程就非常顺滑了,启动服务只需要几秒钟。这在之前直接使用 Docker 指令启动 zk 集群 还需要粘贴一堆指令,是无法想象的

    如何实现

    技术栈

    容器技术:Docker、Docker Compose

    • 熟悉 Docker 指令
    • 了解和Docker 相关的术语,比如容器、镜像、Dockerfile 他们的用法
    • 了解 Compose 基本用法

    后台开发:Java 语言,Zookeeper、Nacos、MySQL 等中间件

    • OpenJDK 安装
    • 中间件安装

    脚本

    • shell 基本语法

    构建基础镜像

    在通过 Compose 启动服务之前,我们需要把基础镜像先构建好
    这里基础镜像可以分为三部分:

    • 操作系统基础镜像(centos_base)
    • 开发环境基础镜像(如 Java 开发镜像)
    • 组件镜像(centos_zookeeper)

    你可以理解为这是一个金字塔三角的结构,就好像你在电脑上安装各种软件,他们是最上层的服务(对应组件),然后软件需要运行在一些系统提供的基础环境中(比如红警在 win10 上跑就需要设置兼容性),最下面一层是操作系统

    关于每个镜像里面安装的组件,我在项目的 Readme 文档中有具体说明

    readme

    Compose 配置

    这里需要对 Compose 的使用方式有基本了解,对于熟悉 docker 的同学来说不会太难

    举个例子:nacos+mysql 的 Compose 配置

    version: "3.9"
    # 定义需要启动的服务,nacos 依赖 mysql, 因此需要定义nacos和mysql 两个服务
    services:
      nacos:
        # 镜像名
        image: centos_nacos
        # 启动容器的环境变量,对 nacos 来说,主要需要注入 mysql 的配置
        environment:
          - MYSQL_HOST=mysql
          - MYSQL_PORT=3306
          - MYSQL_DB=d_nacos
          - MYSQL_USER=root
          - MYSQL_PASSWORD=root_NACOS_123
        # 暴露到主机的端口
        ports:
          - "8848:8848"
        # 先启动 mysql 服务,再启动 nacos
        depends_on:
          - mysql
      mysql:
        image: centos_mysql
        # 设置 mysql 登录密码,以及创建一个非默认DB
        environment:
          - ROOT_PASSWORD=root_NACOS_123
          - USER_DB=d_nacos
        # 将当前路径挂载到 mysql 容器里面的特定目录(init_sql)
        # 这里有一个小功能实现: 让 mysql 在初始化的时候查找 init_sql 目录下所有 sql 文件 并 执行,为什么要这么实现在后面实现细节中会讲到
        volumes:
          - "./:/home/modules/mysql/init_sql"
    # 创建一个 nacos 和 mysql 服务共用的网络环境
    networks:
      my-nacos:
    

    实现细节

    s6

    s6 是为了适配容器化场景,针对各个芯片指令集平台都做了适配的 服务管理器,类似 systemctl

    为什么要引入 s6,主要原因还是 systemctl 在 Mac M1 上不兼容,这个在git 上很多项目都有讨论,其中使用 s6 就是一种解决方案,只是需要稍微做点适配

    比如 mysql,不能使用 service mysql start 指令启动的情况下,就需要把服务启动指令以 s6 支持的方式,写好启动脚本,并在 Dockerfile 中增加注入 启动脚本 的逻辑了

    # centos_base.Dockerfile
    ## 设置系统启动后执行 /init 以启动 s6 进程
    ENTRYPOINT ["/init"]
    
    # mysql.Dockerfile
    COPY s6/ /etc/
    
    # s6/services.d/mysql/run
    #!/bin/bash
    /usr/sbin/mysqld --user=root
    

    mysql 初始化时执行 sql

    场景: 一开始我对 mysql Dockerfile 实现的功能只是一键启动,但是后面发现对 nacos 一键部署的场景,还需要支持 初始化时导入 nacos sql ,否则 nacos 无法正常启动

    这其实也是 nacos 官方的 compose 配置所使用的 mysql 镜像是 nacos 官方仓库中的镜像的原因。mysql 官方 Dockerfile 并不支持在初始化时执行 sql

    所以这里对 mysql Dockerfile 实现了一个 加载并执行 指定目录下的 sql 文件的功能

    # init-mysql.sh
    ......
    ## execute init sql
    sql_files=`ls -l {mysql_init_sql_home} | grep -E "\.sql$" | sed "s/.* //g" | tr '\n' ' '`
    for current_sql_file in ${sql_files[@]}
    do
        mysql -uroot -p"${ROOT_PASSWORD}" -f -D${USER_DB} < {mysql_init_sql_home}/${current_sql_file}
    done
    ......
    

    源替换

    在国内网络条件下进行开发你需要解决的一个很基础的问题,就是代理服务器的问题,否则因为下载速度效率会非常低, 这里分两种场景:
    对 yum 源、OpenJDK 下载等可以找到国内源 替换 国外地址 的话,直接替换下载地址就可以了

    # env_java.sh
    ## 使用清华源 mirrors.tuna.tsinghua.edu.cn,还是挺全的
    jdk_11_repo="https://mirrors.tuna.tsinghua.edu.cn/AdoptOpenJDK/11/jdk/x64/linux"
    ......
    
    jdk_8_repo="https://mirrors.tuna.tsinghua.edu.cn/AdoptOpenJDK/8/jdk/x64/linux"
    ......
    

    对不能找到国内源替换的情况,那就只能加快下载速度了,这里我本地有个代理,需要在镜像构建的时候配置到 环境变量 http_proxy 中去
    默认 Docker 启动容器的网络模式(driver)下,内部识别到主机的代理地址一般是 host.docker.internal(Mac)或 172.26.16.1(Win10),对应容器内部网络的网关地址
    所以做了一个循环逻辑,依次检测指定几个代理端口是否能通,通的话直接配置proxy的逻辑

    # init-system-proxy.sh, 构建 centos_base 镜像时会调用
    for proxy_host in ${proxy_host_array[@]}
    do
        for proxy_port in ${proxy_port_array[@]}
        do
            ## telnet 一个通的地址很快,这里设置超时 1s
            telnet_output=`timeout 1 telnet $proxy_host $proxy_port 2>&1` || true
            telnet_refused_msg=`echo $telnet_output | grep "Connection refused" || true`
            telnet_host_unknown_msg=`echo $telnet_output | grep "Unknown host" || true`
            if [ -n "$telnet_output" ] && [ -z "$telnet_refused_msg" ] && [ -z "$telnet_host_unknown_msg" ]; then
                echo "export http_proxy=http://$proxy_host:$proxy_port" >> /etc/profile
                echo "export https_proxy=http://$proxy_host:$proxy_port" >> /etc/profile
                break
            fi
        done
        current_proxy=`cat /etc/profile | grep http_proxy || true`
        if [ -n "$current_proxy" ]; then
            break
        fi
    done
    

    扩展: 后面还可以做什么

    1、横向扩展
    支持更多服务的本地化集群

    大部分后台中间件,我们在公司里面实践的时候都会遇到部署集群和维护的场景。如果想在自己电脑上研究,当然是能够快速部署集群方便一点。

    不过,要能够通过我上面所说的思路去搭集群,并不是容易事,你需要先设想 镜像如何构建,需要把哪些配置作为容器启动参数提供出来,这两步可能会花费大部分时间。不过如果能把这两步搞定,后面 compose 配置的编写就是顺理成章的事了

    2、纵向扩展
    学习 K8S

    Compose 毕竟只是通过启动多个容器节点来实现集群 部署的效果,还不涉及到容器编排技术,资源调度这些。想要了解更多技术上的细节,还是最好通过 swarm、k8s 这类工具来实践

    当然,想精通这两个工具,就没这么简单了,有时候做好长时间啃一门技术的心里准备,比学习方法更重要

    参考资料

    Compose 官方文档

    国内源替换仓库

    s6 使用教程(基本是 git 官方 readme 的翻译版,不过作为入门教程还是不错)

    nacos issue

    展开全文
  • docker 搭建zk集群/单机

    2022-05-29 11:26:54
    文章目录前言目录结构docker-...zk1,2,3 组成集群 zk0 为单机 docker-compose.yml 如下 # cd zk/ docker-compose up . version: '3.8' networks: zknet: name: zk-net services: zk1: image: zookeeper:l

    前言

    1. 基于docker环境和docker-compose
    2. 当前zk 3.7.0

    目录结构

    在这里插入图片描述

    zk1,2,3 组成集群
    zk0 为单机
    

    docker-compose.yml 如下

    # cd zk/ 
    docker compose up .
    
    version: '3.8'
    networks:
      zknet:
        name: zk-net
    
    services:
      zk1:
        image: zookeeper:latest
        restart: always
        hostname: zk1
        container_name: zk1
        environment:
          - ZOO_MY_ID=1
          - ZOO_SERVERS=server.1=0.0.0.0:2888:3888 server.2=zk2:2888:3888 server.3=zk3:2888:3888;2181
        volumes:
          - ./zoo1/data:/data
          - ./zoo1/datalog:/datalog
        ports:
          - 2181:2181
          - 18081:8080
        networks:
          - zknet
    
      zk2:
        image: zookeeper:latest
        hostname: zk2
        container_name: zk2
        environment:
          - ZOO_MY_ID=2
          - ZOO_SERVERS=server.1=zk1:2888:3888 server.2=0.0.0.0:2888:3888 server.3=zk3:2888:3888;2181
        volumes:
          - ./zoo2/data:/data
          - ./zoo2/datalog:/datalog
        ports:
          - 2182:2181
          - 18082:8080
        networks:
          - zknet
    
      zk3:
        image: zookeeper:latest
        hostname: zk3
        container_name: zk3
        environment:
          - ZOO_MY_ID=3
          - ZOO_SERVERS=server.1=zk1:2888:3888 server.2=zk2:2888:3888 server.3=0.0.0.0:2888:3888;2181
        volumes:
          - ./zoo3/data:/data
          - ./zoo3/datalog:/datalog
        ports:
          - 2183:2181
          - 18083:8080
        networks:
          - zknet
      
      # 单机
      zk0:  
        image: zookeeper:latest
        hostname: zk0
        container_name: zk0
        volumes:
          - ./zoo0/data:/data
          - ./zoo0/datalog:/datalog
        ports:
          - 2184:2181
          - 18084:8080
        networks:
          - zknet
    

    golang测试代码

    package main
    
    import (
    	"fmt"
    	"github.com/samuel/go-zookeeper/zk"
    	"time"
    )
    
    func main() {
    	//var hosts = []string{"localhost:2181", "localhost:2182", "localhost:2183"} //server端host
    	var hosts = []string{"localhost:2184"} //server端host
    	option := zk.WithEventCallback(callback)
    
    	conn, _, err := zk.Connect(hosts, time.Second*5, option)
    	defer conn.Close()
    	if err != nil {
    		panic(err)
    	}
    
    	flag, err := conn.Create("/TEST", []byte("123123"), zk.FlagEphemeral, zk.WorldACL(zk.PermAll))
    	if err != nil {
    		panic(err)
    	}
    
    	_, _, ch, err := conn.ExistsW("/TEST")
    	if err != nil {
    		panic(err)
    	}
    	go watchCreataNode(ch)
    
    	bytes, _, err := conn.Get("/TEST")
    	if err != nil {
    		panic(err)
    	}
    	println(string(bytes))
    
    	flag, err = conn.Create("/TEST", []byte("123123"), zk.FlagSequence, zk.WorldACL(zk.PermAll))
    	if err != nil {
    		panic(err)
    	}
    	println(string(flag))
    
    	time.Sleep(5*time.Second)
    }
    
    func callback(event zk.Event) {
    	fmt.Println("*******************")
    	fmt.Println("path:", event.Path)
    	fmt.Println("type:", event.Type.String())
    	fmt.Println("state:", event.State.String())
    	fmt.Println("-------------------")
    }
    
    
    func watchCreataNode(ech <-chan zk.Event){
    	event:=<-ech
    	fmt.Println("*******************")
    	fmt.Println("path:", event.Path)
    	fmt.Println("type:", event.Type.String())
    	fmt.Println("state:", event.State.String())
    	fmt.Println("-------------------")
    }
    
    /*
    GOROOT=/Users/zyj/go/go1.16 #gosetup
    GOPATH=/Users/zyj/go #gosetup
    /Users/zyj/go/go1.16/bin/go build -o /private/var/folders/18/c2k36qyx3hl6d3dg8ccs876r0000gn/T/___go_build_lib_demo_zk lib_demo/zk #gosetup
    /private/var/folders/18/c2k36qyx3hl6d3dg8ccs876r0000gn/T/___go_build_lib_demo_zk #gosetup
    *******************
    path: 
    type: EventSession
    state: StateConnecting
    -------------------
    *******************
    path: 
    type: EventSession
    state: StateConnected
    -------------------
    2022/05/29 11:53:05 Connected to 127.0.0.1:2184
    *******************
    path: 
    type: EventSession
    state: StateHasSession
    -------------------
    2022/05/29 11:53:05 authenticated: id=72057602412707841, timeout=5000
    2022/05/29 11:53:05 re-submitting `0` credentials after reconnect
    123123
    /TEST0000000006
    *******************
    path: /TEST
    type: EventNodeDeleted
    state: unknown state
    -------------------
    2022/05/29 11:53:10 recv loop terminated: err=EOF
    2022/05/29 11:53:10 send loop terminated: err=<nil>
    *******************
    path: /TEST
    type: EventNodeDeleted
    state: unknown state
    -------------------
    *******************
    path: 
    type: EventSession
    state: StateDisconnected
    -------------------
    
    Process finished with exit code 0
    
    */
    
    展开全文
  • springboot+dubbo+zk集群搭建

    千次阅读 2019-05-11 10:30:15
    zookeeper的集群搭建在上一编已经说过,不会的可以查看。 下面开始搭建springboot+dubbo+zk注册中心的demo 生产者工程目录如图 一、创建dubbo-provider父工程 父pom.xml <?xml version="1.0" encoding=...
  • 云原生比较????,但是之前从未接触过,最近的项目就是上云上云再上云,再...搭建ZK集群 一、购买机器(ZK) k8s不可以选择跨Region(地区)的机器,但是支持跨可用区,为了稳定可靠,每个可用区都要有机器 先上购买ECS
  • zk+kafka集群

    千次阅读 2021-11-22 20:53:19
    docker服务编排 yml文件 安装:yum install docker-compose version: '3.1' services: zoo1: image: wurstmeister/zookeeper ... - 2184:2181 将zk1,主机映射到容器上 volumes:关联卷路径 - /d
  • 福利网址:261.67.48709.%68ost/7/33/5.05 下载Docker:yum -y install docker 启动命令:...docker-compose stop #停止集群容器 docker-compose restart #重启集群容器 docker ps 检查zk集群、kafka集群是否启动成功
  • docker搭建kafka集群+ZK

    2021-11-22 14:58:10
    在写kafka之前,docker搭建一套kafka集群环境,用的腾讯云,这里真的不得不吐槽一下腾讯云的体验比阿里云强,阿里云要不你反思反思? 1、创建子网,管理方便一点 docker network create --subnet 172.19.0.0/16 -...
  • 部署zookeeper4.1 安装JDK 1.84.2 安装ZK[11,12,21]4.3 配置DNS解析4.4 启动zk 1. 微服务 1.1 介绍 微服务 (Microservices) 是一种软件架构风格,它是以专注于单一责任与功能的小型功能区块 (Small Building Blocks...
  • Zookeeper集群搭建

    千次阅读 2022-04-18 22:59:01
    7.zk集群原理 1.什么是zookeeper zookeeper(动物园管理者)简称zk,一个分布式,开放源码的分布式应用程序协调服务,是谷歌的Chubby一个源码的实现,是Hadoop和Hbase的重要组件,zk使用java编写,支持java和c两...
  • Docker-compose一键部署zk集群+dubbo-admin

    千次阅读 2019-07-31 17:42:22
    Compose 通过一个配置文件来管理多个Docker容器,在配置文件中,所有的容器通过services来定义,然后使用docker-compose脚本来启动,停止和重启应用,和应用中的服务以及所有依赖服务的容器,非常适合组合使用多个...
  • 准备zk需要的zoo.cfg 和 myid 文件 [root@10.0.0.11 root]# cd templates/kafka/ [root@10.0.0.11 root]# ls myid1 myid2 myid3 zoo.cfg 1.编辑主角色文件 vim install-zk.yml --- - hosts: '{{ target }}' vars: ...
  • 前面我们已经介绍了canal的admin、server、adapter三个部分的容器化以及在k8s集群下的搭建过程。在创建canal-server的时候,k8s环境下,容器重启会造成ip地址的变动给我们带来了一些问题,我们通过在创建canal-...
  • Zookeeper集群安装部署教程
  • 首先确保hadoop集群正常运行,还需要确认hadoop和hbase的适配版本,我的hadoop是3.3.2,hbase下的是2.4.11。 hadoop3集群部署 背景: 我的机子:10.0.2.4是node1(master),10.0.2.15是node2(slave),10.0.2.5是...
  • 简单记录一下使用 Docker 搭建 ZK 集群的一些步骤。 1、镜像下载 如果下载太慢可以使用阿里源解决 docker pull zookeeper:3.4.11 2、ZK 集群的搭建 首先创建一个名为 docker-compose.yml 的文件 version: '2' ...
  • HOST1: centos7.5 :172.16.217.135 zk1 HOST2: centos7.5 :172.16.217.136 zk2 HOST3: centos7.5 :172.16.217.137 zk3 先把防火墙开放三个端口 sudo firewall-cmd --zone=public --add-port=2181/tcp --permanent ...
  • Docker搭建kafka集群Ø需求说明:公司目前有三个环境,生产环境,测试和演示环境,再包括开发人员还有开发的环境,服务器上造成了一定的资源浪费,因为环境需要依赖zookeeper和kafka,redis这些服务,只要搭一个环境...
  • k8s部署kafka集群zk

    2021-03-24 15:08:03
    storageClassName: "gluster-heketi-2" # resources: # requests: # storage: 2Gi 3、这里没有持久化zk数据到nfs,执行 kubectl apply kafka-namespace.yaml kubectl apply zookeeper-headless.yaml 部署kafka集群 ...
  • 本文简要说明了如何在Docker容器中启动和配置Zookeeper。 1 准备工作 1.1 下载zookeeper镜像 $ docker pull zookeeper:3.4 1.2 单点模式 安装Docker CE 1.3 集群模式 安装Docker EE 创建一个名为zk-overlay的...
  • docker搭建zk+kafka集群

    2020-07-08 15:58:42
    1 搭建zookeeper集群(本文使用的是docker,创建三个容器) 1.1 下载zookeeper,可以直接在官网下载,也可以通过wget的方式下在 官网1:https://zookeeper.apache.org/ 官网2:...
  • v /home/docker/zookeeper/node2/logs:/logs \ zookeeper 4.4、集群状态 # 在容器 zookeeper-master 中开启一个交互模式的终端 docker exec -it zookeeper-master /bin/bash # 查看 zookeeper 状态 bin/zkServer.sh ...
  • kafka 1. 入门简介 kafka https://www.cnblogs.com/likehua/p/3999538.html zookeeper ... 2. 使用docker安装zk docker run -d --name zookeeper -p 2181:2...
  • Docker部署Zookeeper集群 详细步骤

    千次阅读 2020-12-04 01:33:01
    Docker部署Zookeeper集群 详细步骤 自定义镜像mycentos 前往查看步骤——自定义mycentos镜像 将Dockerfile文件 修改 EXPOSE 2181 如下图则完成自定义镜像。 启动3个mycentos容器,分别命名centos01、centos02、...
  • 本文来自网易云社区作者:孙婷婷背景在前文《测试环境docker—基于ndp部署模式的docker基础镜像制作》中已经详述了docker镜像制作及模块部署的过程,按照上述做法已可以搭建测试环境。但是在实践过程中发现存在很...
  • docker部署zookeeper集群

    2021-09-07 23:21:24
    配置单机Zookeeper的时候我们建立了/docker/developer/zookeeper目录,类比一下,我们部署zookeeper集群需要至少zookeeper容器,所以建立三个目录: /docker/developer/zookeeper01 /docker/developer/zookeeper02 ...
  • 基于docker的ZK集群的搭建

    千次阅读 2018-08-14 20:43:23
    最近在研究docker网络方面的应用,也在参考其他楼主的文章,今天在本机成功搭建了基于docker的ZK集群,记录下来,以备以后使用,也希望能给各位提供借借鉴。  使用docker搭建集群环境,主要在网络方面使用host主机...
  • docker 搭建 zookeeper 集群

    千次阅读 2022-04-19 18:43:58
    文章目录下载官方zookeeper镜像搜索官方镜像下载官方镜像查看镜像元数据创建docker网络新建bridge网络创建挂载路径创建容器并加入网络查看节点状态参考文献 下载官方zookeeper镜像 搜索官方镜像 $ docker search ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,658
精华内容 4,263
关键字:

容器化zk集群