
# 制作实例镜像
#### 下载依赖包
1. 下载JRE：<https://download.java.net/openjdk/jdk11/ri/openjdk-11+28_linux-x64_bin.tar.gz>。
2. 下载Apache Kafka二进制包：<https://archive.apache.org/dist/kafka/2.7.0/kafka_2.13-2.7.0.tgz>。
3. 下载Kafka监控指标上报库：<https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.15.0/jmx_prometheus_javaagent-0.15.0.jar>。
 
#### 创建配置文件
1. 创建初始化ZooKeeper的配置启动参数脚本zkGenConfig.sh。
   ```
   #!/bin/bash
   ZK_CONF_DIR=${ZK_CONF_DIR:-"/opt/kafka_2.13-2.7.0/config"}
   ZK_CONFIG_FILE="$ZK_CONF_DIR/zookeeper.properties"
   ZK_DATA_DIR=${ZK_DATA_DIR:-"/var/lib/zookeeper/zk/${NAMESPACE}/${INSTANCE}/${POD_NAME}/data"}
   ID_FILE="$ZK_DATA_DIR/myid"
   ZK_REPLICAS=${ZK_REPLICAS:-"3"}
   ZK_CLIENT_PORT=${ZK_CLIENT_PORT:-2181}
   ZK_SERVER_PORT=${ZK_SERVER_PORT:-2888}
   ZK_ELECTION_PORT=${ZK_ELECTION_PORT:-3888}
   # 1. 生成 myid
   echo "Generate myid"
   HOST=$(hostname -s)
   DOMAIN=$(hostname -d)
   if [[ $HOST =~ (.*)-([0-9]+)$ ]]; then
     NAME=${BASH_REMATCH[1]}
     ORD=${BASH_REMATCH[2]}
   else
     echo "Failed to extract ordinal from hostname $HOST"
     exit 1
   fi
   MY_ID=$((ORD + 1))
   echo "MY_ID=$MY_ID"
   mkdir -p $ZK_DATA_DIR
   rm -f $ID_FILE
   if [ ! -f $ID_FILE ]; then
     echo $MY_ID >>$ID_FILE
   fi
   # 2. 副本数量
   if [ -z $ZK_REPLICAS ]; then
     echo "The environment variable ZK_REPLICAS is not exist."
     exit 1
   fi
   echo "ZK_REPLICAS=$ZK_REPLICAS"
   # 3. 创建配置文件
   rm -f $ZK_CONFIG_FILE
   echo "tickTime=2000" >>$ZK_CONFIG_FILE
   echo "initLimit=5" >>$ZK_CONFIG_FILE
   echo "syncLimit=2" >>$ZK_CONFIG_FILE
   echo "dataDir=$ZK_DATA_DIR" >>$ZK_CONFIG_FILE
   echo "clientPort=$ZK_CLIENT_PORT" >>$ZK_CONFIG_FILE
   for ((i = 1; i <= $ZK_REPLICAS; i++)); do
     echo "server.$i=$NAME-$((i - 1)).$DOMAIN:$ZK_SERVER_PORT:$ZK_ELECTION_PORT" >> $ZK_CONFIG_FILE
   done
   ```
   
2. 创建监控指标上报配置文件metrics-config.yaml。
   ```
   startDelaySeconds: 0
   lowercaseOutputName: false
   lowercaseOutputLabelNames: false
   rules:
     - pattern: kafka.controller<type=KafkaController, name=GlobalTopicCount><>Value
       name: kafka_controller_KafkaController_Value
       type: GAUGE
       labels:
         name: GlobalTopicCount
     - pattern: kafka.controller<type=KafkaController, name=GlobalPartitionCount><>Value
       name: kafka_controller_KafkaController_Value
       type: GAUGE
       labels:
         name: GlobalPartitionCount
     - pattern: kafka.server<type=ReplicaManager, name=LeaderCount><>Value
       name: kafka_server_ReplicaManager_Value
       type: GAUGE
       labels:
         name: LeaderCount
     - pattern: kafka.server<type=ReplicaManager, name=PartitionCount><>Value
       name: kafka_server_ReplicaManager_Value
       type: GAUGE
       labels:
         name: PartitionCount
     - pattern: kafka.server<type=BrokerTopicMetrics, name=BytesInPerSec><>Count
       name: kafka_server_BrokerTopicMetrics_Count
       type: GAUGE
       labels:
         name: BytesInPerSec
     - pattern: kafka.server<type=BrokerTopicMetrics, name=BytesOutPerSec><>Count
       name: kafka_server_BrokerTopicMetrics_Count
       type: GAUGE
       labels:
         name: BytesOutPerSec
     - pattern: kafka.server<type=BrokerTopicMetrics, name=MessagesInPerSec><>Count
       name: kafka_server_BrokerTopicMetrics_Count
       type: GAUGE
       labels:
         name: MessagesInPerSec
     - pattern: kafka.server<type=BrokerTopicMetrics, name=TotalProduceRequestsPerSec><>Count
       name: kafka_server_BrokerTopicMetrics_Count
       type: GAUGE
       labels:
         name: TotalProduceRequestsPerSec
     - pattern: kafka.server<type=BrokerTopicMetrics, name=TotalFetchRequestsPerSec><>Count
       name: kafka_server_BrokerTopicMetrics_Count
       type: GAUGE
       labels:
         name: TotalFetchRequestsPerSec
     - pattern: kafka.server<type=BrokerTopicMetrics, name=BytesInPerSec><>OneMinuteRate
       name: kafka_server_BrokerTopicMetrics_OneMinuteRate
       type: GAUGE
       labels:
         name: BytesInPerSec
     - pattern: kafka.server<type=BrokerTopicMetrics, name=BytesOutPerSec><>OneMinuteRate
       name: kafka_server_BrokerTopicMetrics_OneMinuteRate
       type: GAUGE
       labels:
         name: BytesOutPerSec
     - pattern: kafka.server<type=BrokerTopicMetrics, name=MessagesInPerSec><>OneMinuteRate
       name: kafka_server_BrokerTopicMetrics_OneMinuteRate
       type: GAUGE
       labels:
         name: MessagesInPerSec
     - pattern: kafka.server<type=BrokerTopicMetrics, name=TotalProduceRequestsPerSec><>OneMinuteRate
       name: kafka_server_BrokerTopicMetrics_OneMinuteRate
       type: GAUGE
       labels:
         name: TotalProduceRequestsPerSec
     - pattern: kafka.server<type=BrokerTopicMetrics, name=TotalFetchRequestsPerSec><>OneMinuteRate
       name: kafka_server_BrokerTopicMetrics_OneMinuteRate
       type: GAUGE
       labels:
         name: TotalFetchRequestsPerSec
     - pattern: kafka.server<type=BrokerTopicMetrics, name=BytesInPerSec, topic=(.+)><>Count
       name: kafka_server_BrokerTopicMetrics_Count
       type: GAUGE
       labels:
         name: BytesInPerSec
         topic: "$1"
     - pattern: kafka.server<type=BrokerTopicMetrics, name=BytesOutPerSec, topic=(.+)><>Count
       name: kafka_server_BrokerTopicMetrics_Count
       type: GAUGE
       labels:
         name: BytesOutPerSec
         topic: "$1"
     - pattern: kafka.server<type=BrokerTopicMetrics, name=MessagesInPerSec, topic=(.+)><>Count
       name: kafka_server_BrokerTopicMetrics_Count
       type: GAUGE
       labels:
         name: MessagesInPerSec
         topic: "$1"
     - pattern: kafka.server<type=BrokerTopicMetrics, name=TotalProduceRequestsPerSec, topic=(.+)><>Count
       name: kafka_server_BrokerTopicMetrics_Count
       type: GAUGE
       labels:
         name: TotalProduceRequestsPerSec
         topic: "$1"
     - pattern: kafka.server<type=BrokerTopicMetrics, name=TotalFetchRequestsPerSec, topic=(.+)><>Count
       name: kafka_server_BrokerTopicMetrics_Count
       type: GAUGE
       labels:
         name: TotalFetchRequestsPerSec
         topic: "$1"
     - pattern: kafka.server<type=BrokerTopicMetrics, name=BytesInPerSec, topic=(.+)><>OneMinuteRate
       name: kafka_server_BrokerTopicMetrics_OneMinuteRate
       type: GAUGE
       labels:
         name: BytesInPerSec
         topic: "$1"
     - pattern: kafka.server<type=BrokerTopicMetrics, name=BytesOutPerSec, topic=(.+)><>OneMinuteRate
       name: kafka_server_BrokerTopicMetrics_OneMinuteRate
       type: GAUGE
       labels:
         name: BytesOutPerSec
         topic: "$1"
     - pattern: kafka.server<type=BrokerTopicMetrics, name=MessagesInPerSec, topic=(.+)><>OneMinuteRate
       name: kafka_server_BrokerTopicMetrics_OneMinuteRate
       type: GAUGE
       labels:
         name: MessagesInPerSec
         topic: "$1"
     - pattern: kafka.server<type=BrokerTopicMetrics, name=TotalProduceRequestsPerSec, topic=(.+)><>OneMinuteRate
       name: kafka_server_BrokerTopicMetrics_OneMinuteRate
       type: GAUGE
       labels:
         name: TotalProduceRequestsPerSec
         topic: "$1"
     - pattern: kafka.server<type=BrokerTopicMetrics, name=TotalFetchRequestsPerSec, topic=(.+)><>OneMinuteRate
       name: kafka_server_BrokerTopicMetrics_OneMinuteRate
       type: GAUGE
       labels:
         name: TotalFetchRequestsPerSec
         topic: "$1"
     - pattern: kafka.log<type=Log, name=(.+), topic=(.+), partition=(.+)><>Value
       name: kafka_log_Log_Value
       type: GAUGE
       labels:
         name: "$1"
         topic: "$2"
         partition: "$3"
     - pattern: java.lang<type=OperatingSystem><>SystemCpuLoad
       name: os_SystemCpuLoad
       type: GAUGE
       valueFactor: 100
     - pattern: java.lang<type=OperatingSystem><>ProcessCpuLoad
       name: os_ProcessCpuLoad
       type: GAUGE
       valueFactor: 100
     - pattern: java.lang<type=OperatingSystem><>TotalPhysicalMemorySize
       name: os_TotalPhysicalMemorySize
       type: GAUGE
     - pattern: java.lang<type=OperatingSystem><>FreePhysicalMemorySize
       name: os_FreePhysicalMemorySize
       type: GAUGE
   ```
   
3. 创建Dockerfile。
   ```
   FROM centos:latest
   ENV PATH="/opt/jre-11.0.11/bin:${PATH}" \
       KAFKA_HOME="/opt/kafka_2.13-2.7.0"
   ADD openjdk-11+28_linux-x64_bin.tar.gz /opt/
   ADD kafka_2.13-2.7.0.tgz /opt/
   ADD zkGenConfig.sh ${KAFKA_HOME}/bin
   ADD jmx_prometheus_javaagent-0.15.0.jar ${KAFKA_HOME}/libs
   ADD metrics-config.yaml ${KAFKA_HOME}/config
   RUN ln -s ${KAFKA_HOME} /opt/kafka \
       && chmod u+x ${KAFKA_HOME}/bin/zkGenConfig.sh \
       && sed -i "/kafka-run-class.sh/i\\export JMX_PORT=9999" ${KAFKA_HOME}/bin/kafka-server-start.sh \
       && sed -i "/kafka-run-class.sh/i\\export KAFKA_OPTS=\"\${KAFKA_OPTS} -javaagent:\$base_dir\/\.\.\/libs/jmx_prometheus_javaagent-0.15.0.jar=9404:\$base_dir\/\.\.\/config\/metrics-config.yaml\"" ${KAFKA_HOME}/bin/kafka-server-start.sh
   WORKDIR $KAFKA_HOME
   ```
   
 
#### 制作容器镜像
构建容器镜像命令如下：
```
$ docker build -t kafka:v2.7.0 .
```
