使用 Docker 構(gòu)建 Zookeeper 服務
1. 前言
在我們使用 Zookeeper 來進行各種功能的開發(fā)時,為了節(jié)約開發(fā)成本,我們通常使用的是 Zookeeper 的單機模式或者偽集群模式,但是在測試環(huán)境和生成環(huán)境中,我們需要的就是高可用高性能的 Zookeeper 服務來對我們的應用提供支持了。
那么如何搭建一個高可用高性能的 Zookeeper 服務集群呢?其實在 Zookeeper 集群模式這一節(jié)的內(nèi)容中我們就搭建過集群數(shù)量為 3 的 Zookeeper 服務。在本節(jié)內(nèi)容中,我們會使用另外一種更高效的方式來搭建我們的 Zookeeper 集群,這種方式就是使用容器引擎 Docker 來進行 Zookeeper 集群的構(gòu)建。接下來我們來簡單的了解一下 Docker,然后再使用 Docker 來安裝 Zookeeper 。
2. Docker 介紹
Docker 是一個開源的應用容器引擎,讓開發(fā)者可以打包他們的應用以及依賴包到一個可移植的容器中,然后發(fā)布到任何流行的 Linux 系統(tǒng)或 Windows 系統(tǒng)上,也可以實現(xiàn)虛擬化,容器是完全使用沙箱機制,相互之間不會有任何接口。
首先我們來簡單了解一下 Docker 的組成。在 Docker 中有 4 個基本組成:
- Docker Image 鏡像
- Docker Container 容器
- Docker Client 客戶端
- Docker Daemon 守護進程
Docker 和 Zookeeper 同樣是 C/S 的架構(gòu),Docker 服務端通過 Docker Daemon 守護進程來維持長時間的運行,Docker Client 客戶端通過 CLI 的 API 來對 Docker 服務端的 Docker Image 鏡像和 Docker Container 容器來進行操作。我們通過 API 去 Docker Hub 的官網(wǎng)拉取 Image 鏡像,然后通過 Image 鏡像來創(chuàng)建 Container 容器。
在我們使用 Docker 來搭建 Zookeeper 集群的時候,也同樣的先去 Docker Hub 的官網(wǎng)拉取 Zookeeper 的鏡像,然后通過這個 Zookeeper 鏡像就能創(chuàng)建 Zookeeper 的容器實例了。這個 Zookeeper 的容器實例就是一個 Zookeeper 服務,我們就可以通過 Zookeeper 客戶端來進行連接和操作了。
簡單了介紹了 Docker ,接下來我們介紹如何安裝 Docker。
3. Docker 安裝
在不同的操作系統(tǒng)中都可以安裝 Docker ,本節(jié)內(nèi)容中只演示 Ubuntu 環(huán)境下的 Docker 安裝。本次安裝演示的 Ubuntu 版本為 Ubuntu 20.04.1 LTS 。
- apt 更換國內(nèi)源
在安裝應用之前,我們需要把 apt 更換為國內(nèi)源,這里我們選擇阿里云的 mirros.aliyun.com。
# 備份 apt 源列表文件
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
# 更換源為 mirros.aliyun.com
sudo sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
# 更新源
sudo apt-get clean
sudo apt-get update
更換完畢后,我們還需要安裝 apt 的一些工具,如 https,curl 等。
- 安裝 apt 依賴包
sudo apt-get -y install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
- 獲取 GPG 密鑰證書
我們這里使用阿里云的鏡像來獲取 GPG 密鑰:
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
獲取成功會返回 OK ,我們使用 apt-key finger 命令查看:
apt-key finger
# 輸出密鑰信息
/etc/apt/trusted.gpg
--------------------
pub rsa4096 2017-02-22 [SCEA]
9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid [ unknown] Docker Release (CE deb) <docker@docker.com>
sub rsa4096 2017-02-22 [S]
密鑰添加成功后,我們就可以開始后續(xù)的安裝了。
- 添加 Docker 源
為了更快速的安裝 Docker,這里我們添加阿里云的 Docker 源,首先我們先使用 lsb_release -a 命令獲取當前系統(tǒng)的 Codename:
lsb_release -a
# 輸出系統(tǒng)信息
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.1 LTS
Release: 20.04
Codename: focal
本系統(tǒng)的 Codename 也就是版本代碼為 focal,我們在添加 Docker 源的時候就會使用這個版本:
# 添加 docker-ce 源,系統(tǒng)為 ubuntu,系統(tǒng)版本為 focal, stable 為 docker 穩(wěn)定版。
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu focal stable"
執(zhí)行完畢后,我們需要更新 apt 源:
sudo apt-get update
- Docker 安裝
更新完源后,我們就可以開始安裝 Docker 組件了:
sudo apt-get install docker-ce docker-ce-cli containerd.io
執(zhí)行這一行命令需要一點時間,稍等片刻。完成后我們就可以來查看 Docker 是否安裝成功了。
- 查看 Docker 版本
使用 docker -v 來查看 Docker 版本:
docker -v
# 輸出 docker 版本信息
Docker version 19.03.13, build 4484c46d9d
看到版本信息輸出就說明我們的 Docker 源安裝成功了。
Tips: 如果安裝失敗,需要注意系統(tǒng)的版本和添加的 Docker 源是否能使用。
安裝成功后,我們來添加 Docker Image 鏡像源。
- 添加 Docker Image 鏡像源
使用阿里云的 Docker Image 鏡像源,需要登錄阿里云官網(wǎng)開啟 容器鏡像服務:
添加 Docker Image 鏡像源為阿里云鏡像,這里同學們使用自己賬號的加速器地址即可:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxxxx.mirror.aliyuncs.com"]
}
EOF
添加完畢后,我們就可以啟動我們的 Docker 服務了。
- 啟動 Docker
service docker start
# 輸出啟動信息
* Starting Docker: docker
啟動完成,接下來我們進行測試。
- Docker 測試
執(zhí)行測試命令:
docker run hello-world
輸出:
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:4cf9c47f86df71d48364001ede3a4fcd85ae80ce02ebad74156906caff5378bc
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
我們看到這段信息就說明,我們的 Docker 測試成功了。
那么接下來,我們就可以使用 Docker 來安裝 Zookeeper 服務。
4. Docker 安裝 Zookeeper
- 查詢鏡像
我們可以去 Docker Hub 的官網(wǎng)查看 Zookeeper 的鏡像:https://hub.docker.com/_/zookeeper
也可以使用 search 命令來查詢 Zookeeper 鏡像:
# 查詢 zookeeper 鏡像
docker search zookeeper
執(zhí)行這條命令會輸出很多 zookeeper 鏡像,這里我們可以看到第一條就是官方的 zookeeper 鏡像。
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
zookeeper Apache ZooKeeper is an open-source... 936 [OK]
- 拉取鏡像
接下來我們開始拉取 Zookeeper 鏡像:
# 拉取 zookeeper 鏡像,默認是 latest
docker pull zookeeper
# 選擇版本拉取就在后面跟上版本信息
docker pull zookeeper:3.6
這里我們選擇 latest 版的鏡像,執(zhí)行 docker pull zookeeper 后開始拉取鏡像:
Using default tag: latest
latest: Pulling from library/zookeeper
d121f8d1c412: Pull complete
75deccc0fc24: Pull complete
690f480f5f48: Pull complete
b20f9556d3e0: Pull complete
30b60f0b1627: Pull complete
a774eb30ae9a: Pull complete
99abe5102984: Pull complete
f0154f2759c0: Pull complete
Digest: sha256:6c051390cfae7958ff427834937c353fc6c34484f6a84b3e4bc8c512b53a16f6
Status: Downloaded newer image for zookeeper:latest
docker.io/library/zookeeper:latest
- 查看本地鏡像
拉取鏡像完畢后,我們使用 images 命令來查看鏡像:
# 查看鏡像
docker images
# 輸出信息
REPOSITORY TAG IMAGE ID CREATED SIZE
zookeeper latest 36b7f3aa2340 10 days ago 252MB
- 啟動鏡像
接下來我們就可以啟動 zookeeper 鏡像了。
# run 啟動,-d 后臺運行,--name 別名,-p 端口映射(可以寫多個), 容器名稱:版本(不寫默認latest)
docker run -d --name=zookeeper -p 2181:2181 zookeeper
啟動成功后會輸出當前容器的 ID:
6e191d07172187ec27c2227ae99760177b2fe7dbca25061af35586dd7ee0d1cb
- 查看容器
這里我們可以使用 container 命令來查看容器:
# 查看所有的容器
docker container ls -a
輸出容器列表,我們可以看見剛才啟動的 zookeeper 容器:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6e191d071721 zookeeper "/docker-entrypoint.…" 3 minutes ago Up 3 minutes zookeeper
- 進入容器
使用 exec 命令我們就可以進入已經(jīng)啟動的 zookeeper 容器:
docker exec -it zookeeper /bin/bash
進入容器后我們使用 ls
命令來查看 文件列表:
LICENSE.txt NOTICE.txt README.md README_packaging.md bin conf docs lib
Zookeeper 的命令就在 bin 目錄中,我們可以使用 zkCli.sh 連接 Zookeeper 服務端,也可以使用宿主機的客戶端加映射的端口來連接 Docker 容器內(nèi)的 Zookeeper 服務端。
想要退出容器的話使用 exit
命令即可。
- 關(guān)閉容器
如果我們想要關(guān)閉容器,在容器外使用以下命令:
docker container stop zookeeper
如果這樣來啟動多個容器,然后一個一個配置的話,也是一件繁瑣的事情。那么有沒有一次性能啟動多個 Zookeeper 的方式呢?接下來我們就使用 Docker Compose 來構(gòu)建 Zookeeper 集群。
5. Docker Compose
Docker Compose 的定位是:定義和運行多個 Docker 容器的應用(Defining and running multi-container Docker applications)。
Docker Compose 中有兩個重要的概念:
- 服務 service :一個應用的容器,實際上可以包括多個運行相同鏡像的容器實例。
- 項目 project :由一組關(guān)聯(lián)的應用容器組成的一個完整業(yè)務單元,在 docker-compose.yml 文件中定義。
通過 Docker Compose,我們可以使用 docker-compose.yml 文件來配置應用程序需要的所有服務,然后使用 up
命令,就可以從 docker-compose.yml 文件配置中創(chuàng)建并啟動所有服務。
首先我們來安裝 Docker Compose。
5.1 Docker Compose 安裝
我們可以直接從 Docker 官方 GitHub Release 上直接拉取編譯好的二進制文件:
# 拉取 compose
curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# 添加 docker-compose 命令
chmod +x /usr/local/bin/docker-compose
# 補全命令
curl -L https://raw.githubusercontent.com/docker/compose/1.8.0/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
執(zhí)行完畢后,我們來查看 docker-compose 的版本:
docker-compose -v
# 輸出版本信息
docker-compose version 1.27.4, build 40524192
5.2 構(gòu)建 Zookeeper 集群
接下來我們就來使用 docker-compose.yml 文件,構(gòu)建 Zookeeper 集群。
- 創(chuàng)建 docker-compose.yml
首先我們在 /usr/local 目錄下創(chuàng)建 zookeeper 文件夾,在 zookeeper 文件夾中創(chuàng)建 docker-compose.yml 文件:
mkdir /usr/local/zookeeper
touch /usr/local/zookeeper/docker-compose.yml
創(chuàng)建完成后,我們開始編寫 docker-compose.yml 文件:
vi /usr/local/zookeeper/docker-compose.yml
# Zookeeper 版本
version: '3.6'
# 服務組
services:
# 服務1
zoo1:
# 鏡像:zookeeper
image: zookeeper
# 總是啟動
restart: always
# 地址別名 zoo1
hostname: zoo1
# 端口暴露
ports:
- 2181:2181
# 環(huán)境配置
environment:
# myid 文件值
ZOO_MY_ID: 1
# 集群服務列表
ZOO_SERVERS: server.1=0.0.0.0:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
# 服務2
zoo2:
image: zookeeper
restart: always
hostname: zoo2
ports:
- 2182:2181
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=0.0.0.0:2888:3888;2181 server.3=zoo3:2888:3888;2181
# 服務3
zoo3:
image: zookeeper
restart: always
hostname: zoo3
ports:
- 2183:2181
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=0.0.0.0:2888:3888;2181
- 啟動
編寫完成后,在 docker-compose.yml 的目錄使用 docker-compose up 命令啟動:
# 進入 docker-compose.yml 所在目錄
cd /usr/local/zookeeper/
# 后臺啟動
docker-compose up -d
# 輸出啟動信息
Starting zookeeper_zoo1_1 ... done
Starting zookeeper_zoo3_1 ... done
Starting zookeeper_zoo2_1 ... done
啟動成功后,我們可以使用 docker container ls -a 查看容器列表,我們也可以使用 ps 命令來查看 docker-compose 構(gòu)建的容器:
docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------------------------------------------
zookeeper_zoo1_1 /docker-entrypoint.sh zkSe ... Up 0.0.0.0:2181->2181/tcp, 2888/tcp, 3888/tcp, 8080/tcp
zookeeper_zoo2_1 /docker-entrypoint.sh zkSe ... Up 0.0.0.0:2182->2181/tcp, 2888/tcp, 3888/tcp, 8080/tcp
zookeeper_zoo3_1 /docker-entrypoint.sh zkSe ... Up 0.0.0.0:2183->2181/tcp, 2888/tcp, 3888/tcp, 8080/tcp
構(gòu)建完成后,我們就可以使用 客戶端來連接 Zookeeper 了。
- 連接 Zookeeper 服務端
首先我們使用 exec 命令進入容器:
docker exec -it zookeeper_zoo1_1 /bin/bash
再使用 zkCli.sh 來連接 Zookeeper 服務端:
zkCli.sh -server localhost:2181,localhost:2182,localhost:2183
這樣我們通過一個文件就構(gòu)建了一個數(shù)量為 3 的 Zookeeper 集群,方便構(gòu)建而且易于管理。
6. 總結(jié)
在本節(jié)內(nèi)容中,我們學習了使用 Docker 來構(gòu)建 Zookeeper 服務,還使用了 Docker Compose 構(gòu)建了 Zookeeper 集群。以下是本節(jié)內(nèi)容總結(jié):
- Docker 安裝。
- 使用 Docker 安裝 Zookeeper 。
- 使用 Docker Compose 構(gòu)建 Zookeeper 集群。