1. 程式人生 > >從docker入門到使用docker搭建redis哨兵叢集(待整理)

從docker入門到使用docker搭建redis哨兵叢集(待整理)

安裝docker

#檢視版本
uname -r
#Docker 執行在 CentOS 7 上,要求系統為64位、系統核心版本為 3.10 以上。
#Docker 執行在 CentOS-6.5 或更高的版本的 CentOS 上,要求系統為64位、系統核心版本為 2.6.32-431 或者更高版本。

rpm -iUvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

yum -y install docker-io
service docker start

#yum下載的docker版本可能比較低
#方法1:
vim /usr/bin/yum-config-manager #確定使用的yum是py2版本 yum remove docker-io 參考: https://docs.docker.com/engine/installation/linux/docker-ce/centos/#install-docker-ce-1 systemctl start docker #方法2 #下載最新的 wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-17.12.0.ce-1.el7.centos.x86_64.rpm

升級核心步驟

一、安裝elrepo的yum源--http://elrepo.org/tiki/tiki-index.php
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
#如果出現問題:curl: (60) SSL certificate problem: unable to get local issuer certificate
#wget http://mirror.centos.org/centos/6/os/x86_64/Packages/ca-certificates-2016.2.10-65.4.el6.noarch.rpm
#rpm2cpio ca-certificates-2016.2.10-65.4.el6.noarch.rpm | cpio -idmv
#cp -pi ./etc/pki/tls/certs/ca-bundle.* /etc/pki/tls/certs/ #yum reinstall ca-certificates #yum reinstall openssl #如果還是不行,直接不用rpm安裝 #wget --no-check-certificate https://www.elrepo.org/RPM-GPG-KEY-elrepo.org #rpm --import RPM-GPG-KEY-elrepo.org rpm -Uvh http://www.elrepo.org/elrepo-release-6-6.el6.elrepo.noarch.rpm 二、升級核心 #在yum的elrepo源中有ml和lt兩種核心,其中ml(mainline)為最新版本的核心,lt為長期支援的核心。 #如果要安裝ml核心,使用如下命令: yum --enablerepo=elrepo-kernel -y install kernel-ml #如果要安裝lt核心,使用如下命令: yum --enablerepo=elrepo-kernel -y install kernel-lt 三、修改grub.conf檔案 vim /etc/grub.conf default=0

docker相關操作

docker search centos

#使用docker執行centos後輸出,會自殺,因為docker認為沒什麼事情可以做了
docker pull centos /bin/echo "Hello world"
#docker build -t csphere/centos:7.1 .

#後臺執行docker
docker run -dit centos

#檢視容器列表
docker ps
docker ps -a

#進入容器
docker attach 44fc0f0582d9   # 使用了exit命令,容器就會退出後臺執行
docker exec -it 44fc0f0582d9 /bin/sh #不會退出

#在宿主機器檢視docker的cpu 記憶體使用狀態
docker stats 44fc0f0582d9

構建一個容器

參考

vim Dockerfile
# 將官方 Python 執行時用作父映象
FROM python:2.7-slim

# 將工作目錄設定為 /app。指定RUN、CMD與ENTRYPOINT命令的工作目錄
WORKDIR /app

# 將當前目錄內容複製到位於 /app 中的容器中。複製檔案指令。它有兩個引數<source>和<destination>。destination是容器內的路徑。source可以是URL或者是啟動配置上下文中的一個檔案
ADD . /app

# 安裝 requirements.txt 中指定的任何所需軟體包。在shell或者exec的環境下執行的命令
RUN pip install -r requirements.txt

# 使埠 80 可供此容器外的環境使用
EXPOSE 80

# 定義環境變數
ENV NAME World

# 在容器啟動時執行 app.py。提供了容器預設的執行命令。 Dockerfile只允許使用一次CMD指令。 使用多個CMD會抵消之前所有的指令,只有最後一個指令生效。
CMD ["python", "app.py"]
vim requirements.txt
Flask
Redis
app.py
from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
    try:
        visits = redis.incr("counter")
    except RedisError:
        visits = "<i>cannot connect to Redis, counter disabled</i>"

    html = "<h3>Hello {name}!</h3>" \
           "<b>Hostname:</b> {hostname}<br/>" \
           "<b>Visits:</b> {visits}"
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)
docker build -t friendlyhello .

#檢視構建的映象
docker images

#執行構建的映象(將本機的4000對映到docker的80埠)
docker run -p 4000:80 friendlyhello

curl http://localhost:4000

輸出:
輸出結果

#登入 jhcoder 19901108 [email protected]
docker login
#標記
docker tag friendlyhello jhcoder/get-started:part1
docker images
#REPOSITORY            TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
#friendlyhello         latest              bb72871e4fe5        14 hours ago        149.1 MB
#jhcoder/get-started   part1               bb72871e4fe5        14 hours ago        149.1 MB

#push上去倉庫
docker push jhcoder/get-started:part1

#可以在任何地方執行這個映象
docker run -p 4000:80 jhcoder/get-started:part1

#檢視日誌
docker logs -f sentry_redis_6301

指示容器的行為(yml)

vim docker-compose.yml

#####檔案注意空格      ## mapping values are not allowed in this context
version: "3"
services:
  web:
    # 將 username/repo:tag 替換為您的名稱和映象詳細資訊
    image: jhcoder/get-started:part1
    deploy:
      replicas:5
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "80:80"
    networks:
      - webnet
networks:
  webnet:
  • 從映象庫中拉取我們在步驟 2 中上傳的映象。
  • 將該映象的五個例項作為服務 web 執行,並將每個例項限制為最多使用 10% 的 CPU(在所有核心中)以及 50MB RAM。
  • 如果某個容器發生故障,立即重啟容器。
  • 將主機上的埠 80 對映到 web 的埠 80。
  • 指示 web 容器通過負載均衡的網路 webnet 共享埠 80。(在內部,容器自身將在臨時埠釋出到 web 的埠 80。)
  • 使用預設設定定義 webnet 網路(此為負載均衡的 overlay 網路)。
docker swarm init

#部署
docker stack deploy -c docker-compose.yml getstartedlab

#檢視
docker stack ps getstartedlab

#刪除
docker stack rm getstartedlab

構建Redis

docker pull hub.c.163.com/library/redis:latest

docker run --name redis-6379 -p 16379:6379 -d hub.c.163.com/library/redis

docker ps

使用redis構建哨兵叢集

  • 生成6份配置
vim redis-6301.conf
vim redis-6302.conf
vim redis-6303.conf

vim sentry-16301.conf
vim sentry-16302.conf
vim sentry-16303.conf
// redis-6301.conf
daemonize yes
pidfile /var/run/redis-6301.pid
port 6301
requirepass jhcoder

// sentry-16301.conf
port 16301
dir /data
sentinel monitor mymaster 192.168.1.10 6301 2
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
sentinel auth-pass mymaster jhcoder

// redis-6302.conf
daemonize yes
pidfile /var/run/redis-6302.pid
port 6302
requirepass jhcoder
slaveof 192.168.1.10 6301
masterauth jhcoder

// sentry-16302.conf
port 16302
dir /data
sentinel monitor mymaster 192.168.1.10 6301 2
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
sentinel auth-pass mymaster jhcoder

// redis-6303.conf
daemonize yes
pidfile /var/run/redis-6303.pid
port 6303
requirepass jhcoder
slaveof 192.168.1.10 6301
masterauth jhcoder

### sentry-16303.conf ###
port 16303
dir /data
sentinel monitor mymaster 192.168.1.10 6301 2
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
sentinel auth-pass mymaster jhcoder

使用shell指令碼生成配置檔案

#!/bin/sh
redis6301="
daemonize yes \n
pidfile /var/run/redis-6301.pid \n
port 6301 \n
requirepass jhcoder \n"
sentry16301="
port 16301 \n
dir /data \n
sentinel monitor mymaster 192.168.1.10 6301 2 \n
sentinel down-after-milliseconds mymaster 30000 \n
sentinel failover-timeout mymaster 60000 \n
sentinel parallel-syncs mymaster 1 \n
sentinel auth-pass mymaster jhcoder \n
sentinel announce-ip 192.168.1.10 \n
sentinel announce-port 16301"
redis6302="
daemonize yes \n
pidfile /var/run/redis-6302.pid \n
port 6302 \n
requirepass jhcoder \n
slaveof 192.168.1.10 6301 \n
slave-announce-ip 192.168.1.10 \n
slave-announce-port 6302 \n
masterauth jhcoder \n"
sentry16302="
port 16302 \n
dir /data \n
sentinel monitor mymaster 192.168.1.10 6301 2 \n
sentinel down-after-milliseconds mymaster 30000 \n
sentinel failover-timeout mymaster 60000 \n
sentinel parallel-syncs mymaster 1 \n
sentinel auth-pass mymaster jhcoder \n
sentinel announce-ip 192.168.1.10 \n
sentinel announce-port 16302"
redis6303="
daemonize yes \n
pidfile /var/run/redis-6303.pid \n
port 6303 \n
requirepass jhcoder \n
slaveof 192.168.1.10 6301 \n
slave-announce-ip 192.168.1.10 \n
slave-announce-port 6303 \n
masterauth jhcoder \n"
sentry16303="
port 16303 \n
dir /data \n
sentinel monitor mymaster 192.168.1.10 6301 2 \n
sentinel down-after-milliseconds mymaster 30000 \n
sentinel failover-timeout mymaster 60000 \n
sentinel parallel-syncs mymaster 1 \n
sentinel auth-pass mymaster jhcoder \n
sentinel announce-ip 192.168.1.10 \n
sentinel announce-port 16303"

echo -e ${redis6301} > ../config.d/redis-6301.conf
echo -e ${redis6302} > ../config.d/redis-6302.conf
echo -e ${redis6303} > ../config.d/redis-6303.conf
echo -e ${sentry16301} > ../config.d/sentry-16301.conf
echo -e ${sentry16302} > ../config.d/sentry-16302.conf
echo -e ${sentry16303} > ../config.d/sentry-16303.conf
這裡的配置相比之前改的都是ip的配置
1、docker宿主現在使用host模式。
2、配置貌似不識別域名!!!!!!!!!!!
3、從機標明主機的通訊ip和port,這個配置會自動生成在配置檔案中,最後redisson使用這個ip和port,所以需要注意
  slave-announce-ip 宿主ip \n
  slave-announce-port 6303 \n
  • 最終成功命令
docker run -d -ti \
-p 6301:6301 -p 16301:16301 \
-v /data/docker-redis/sentry/config.d/redis-6301.conf:/etc/redis/redis-6301.conf \
-v /data/docker-redis/sentry/config.d/sentry-16301.conf:/etc/redis/sentry-16301.conf \
-v /data/docker-redis/sentry/data/6301:/data \
-m 1024m \
--cpuset-cpus="0" \
--network="host" \
--dns="223.5.5.5" \
--name sentry_redis_6301 \
--sysctl net.core.somaxconn=511 \
hub.c.163.com/library/redis \
/bin/sh -c \
'redis-server /etc/redis/redis-6301.conf && redis-sentinel /etc/redis/sentry-16301.conf'

docker run -d -ti \
-p 6302:6302 -p 16302:16302 \
-v /data/docker-redis/sentry/config.d/redis-6302.conf:/etc/redis/redis-6302.conf \
-v /data/docker-redis/sentry/config.d/sentry-16302.conf:/etc/redis/sentry-16302.conf \
-v /data/docker-redis/sentry/data/6302:/data \
-m 1024m \
--cpuset-cpus="1" \
--network="host" \
--dns="223.5.5.5" \
--name sentry_redis_6302 \
--sysctl net.core.somaxconn=511 \
hub.c.163.com/library/redis \
/bin/sh -c \
'redis-server /etc/redis/redis-6302.conf && redis-sentinel /etc/redis/sentry-16302.conf'

docker run -d -ti \
-p 6303:6303 -p 16303:16303 \
-v /data/docker-redis/sentry/config.d/redis-6303.conf:/etc/redis/redis-6303.conf \
-v /data/docker-redis/sentry/config.d/sentry-16303.conf:/etc/redis/sentry-16303.conf \
-v /data/docker-redis/sentry/data/6303:/data \
-m 1024m \
--cpuset-cpus="2" \
--network="host" \
--name sentry_redis_6303 \
--sysctl net.core.somaxconn=511 \
hub.c.163.com/library/redis \
/bin/sh -c \
'redis-server /etc/redis/redis-6303.conf && redis-sentinel /etc/redis/sentry-16303.conf'
  • 測試
redis-cli -p 6301 -a jhcoder
#在主機進行hset, 在從機進行hget

#啟動日誌檢視
docker logs -f sentry_redis_6302
#進入主機 docker ps
docker exec -ti b4ee02d90d18 /bin/sh
# kill 主機redis-server
ps -ef | grep redis
kill -9 xxx
#檢視日誌輸出
#進入哨兵客戶端
redis-cli -p 16301 -a jhcoder
redis-cli -p 16302 -a jhcoder
#檢視
SENTINEL masters


#java客戶端可以通過自己寫命令支援哨兵

以上的做法通過客戶端是可以連線上的, 但是通過redisson連線不上,因為redisson需要連線哨兵的6302,但是這裡提供的是內網的ip,外網不能直接訪問到,所以嘗試吧哨兵放在宿主機器上執行。

docker run -d -ti \
-p 6301:6301 \
-v /data/docker-redis/sentry/config.d/redis-6301.conf:/etc/redis/redis-6301.conf \
-v /data/docker-redis/sentry/data/6301:/data \
-m 1024m \
--cpuset-cpus="0" \
--name sentry_redis_6301 \
--sysctl net.core.somaxconn=511 \
hub.c.163.com/library/redis \
/bin/sh -c \
'redis-server /etc/redis/redis-6301.conf'

docker run -d -ti \
-p 6302:6302 \
-v /data/docker-redis/sentry/config.d/redis-6302.conf:/etc/redis/redis-6302.conf \
-v /data/docker-redis/sentry/data/6302:/data \
-m 1024m \
--cpuset-cpus="1" \
--name sentry_redis_6302 \
--sysctl net.core.somaxconn=511 \
hub.c.163.com/library/redis \
/bin/sh -c \
'redis-server /etc/redis/redis-6302.conf'

docker run -d -ti \
-p 6303:6303 \
-v /data/docker-redis/sentry/config.d/redis-6303.conf:/etc/redis/redis-6303.conf \
-v /data/docker-redis/sentry/data/6303:/data \
-m 1024m \
--cpuset-cpus="2" \
--name sentry_redis_6303 \
--sysctl net.core.somaxconn=511 \
hub.c.163.com/library/redis \
/bin/sh -c \
'redis-server /etc/redis/redis-6303.conf'

搭建redis官方叢集

  • 生成6份配置檔名

vim /data/docker-redis/official/config.d/redis-6401.conf ……

port 6401 # 6402 6403 6404 6405 6406
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
docker run -d -ti \
-p 6401:6401 -p 16401:16401 \
-v /data/docker-redis/official/config.d/redis-6401.conf:/etc/redis/redis-6401.conf \
-v /data/docker-redis/official/data/6401:/data \
--name official_redis_6401 \
--sysctl net.core.somaxconn=511 \
hub.c.163.com/library/redis \
/bin/sh -c \
'redis-server /etc/redis/redis-6401.conf'

docker run -d -ti \
-p 6402:6402 -p 16402:16402 \
-v /data/docker-redis/official/config.d/redis-6402.conf:/etc/redis/redis-6402.conf \
-v /data/docker-redis/official/data/6402:/data \
--name official_redis_6402 \
--sysctl net.core.somaxconn=511 \
hub.c.163.com/library/redis \
/bin/sh -c \
'redis-server /etc/redis/redis-6402.conf'

docker run -d -ti \
-p 6403:6403 -p 16403:16403 \
-v /data/docker-redis/official/config.d/redis-6403.conf:/etc/redis/redis-6403.conf \
-v /data/docker-redis/official/data/6403:/data \
--name official_redis_6403 \
--sysctl net.core.somaxconn=511 \
hub.c.163.com/library/redis \
/bin/sh -c \
'redis-server /etc/redis/redis-6403.conf'

docker run -d -ti \
-p 6404:6404 -p 16404:16404 \
-v /data/docker-redis/official/config.d/redis-6404.conf:/etc/redis/redis-6404.conf \
-v /data/docker-redis/official/data/6404:/data \
--name official_redis_6404 \
--sysctl net.core.somaxconn=511 \
hub.c.163.com/library/redis \
/bin/sh -c \
'redis-server /etc/redis/redis-6404.conf'

docker run -d -ti \
-p 6405:6405 -p 16405:16405 \
-v /data/docker-redis/official/config.d/redis-6405.conf:/etc/redis/redis-6405.conf \
-v /data/docker-redis/official/data/6405:/data \
--name official_redis_6405 \
--sysctl net.core.somaxconn=511 \
hub.c.163.com/library/redis \
/bin/sh -c \
'redis-server /etc/redis/redis-6405.conf'

docker run -d -ti \
-p 6406:6406 -p 16406:16406 \
-v /data/docker-redis/official/config.d/redis-6406.conf:/etc/redis/redis-6406.conf \
-v /data/docker-redis/official/data/6406:/data \
--name official_redis_6406 \
--sysctl net.core.somaxconn=511 \
hub.c.163.com/library/redis \
/bin/sh -c \
'redis-server /etc/redis/redis-6406.conf'

安裝ruby

//安裝大於2.2.2ruby,然後安裝redis模組
gem install redis

// !!!!! 不要用127.0.0.1,這裡使用的是宿主機器的ip
//這裡的目的是使用redis官方自帶的ruby工具構建起叢集間的通訊
./redis-trib.rb create --replicas 1 172.18.0.1:6401 172.18.0.1:6402 \
172.18.0.1:6403 172.18.0.1:6404 172.18.0.1:6405 172.18.0.1:6406

成功介面