在kubernetes集群中創建redis主從多實例


在kubernetes集群中創建redis主從多實例

繼續使用上次實驗環境 https://www.58jb.com/html/180.html ,因為環境中已經配置好flannel網絡了,接下要就是慢慢在此環境中創建一些實例。因為只是搭建簡單的環境是比較容易上手,隨便網上一搜可能就出來了。但是要自己去從頭一步一步跑起項目,還是基於真實的項目來跑的話還是需要自己多研究,當然目前還是止於使用階段,要深入還得多看資料。

本次要記錄的是自己從創建鏡像到實現redis主從示例,為什么要自己制作鏡像呢?其實就是為了自己可以學多點,畢竟網上的都人別人做好的,你自己沒做過根本不知道制作過程中會遇到什么。為什么有些鏡像大,有些鏡像比較小。這都是在哪里做的優化?
本次直接使用alpine基礎鏡像,因為它小,加上個redis也就11M左右的鏡像,如果使用centos可能就大點了,這里先不做存儲的方便,只是簡單的實現redis-master和redis-slave之間的自動發現。
為了自己好區分我直接制作兩個鏡像,一個為redis-master專門用來跑master服務的,一個為redis-slave專門跑slave實例的。其實可以只用一個,只需分兩個配置文件或者是兩個不同的啟動方法,這里不做這個介紹。

redis-slave鏡像制作

需要二個文件:Dockerfile、run.sh

Dockerfile內容如下:

FROM alpine:3.4  
RUN apk add --no-cache redis sed bash  
COPY run.sh /run.sh  
CMD [ "/run.sh" ]  
ENTRYPOINT [ "bash" ]  

其實默認可以不使用redis.conf文件的,如果需要就在上面的Dockerfile文件也加入,這里目前也處於測試,先不加配置。

run.sh啟動腳本,也就是一行文件。

[root@k8s-node1 slave]# cat run.sh 
#/bin/sh 
redis-server --slaveof ${REDIS_MASTER_SERVICE_HOST} ${REDIS_MASTER_SERVICE_PORT} 

打包成鏡像傳到內網倉庫:

docker build -t redis-slave . 
docker tag redis-slave reg.docker.tb/harbor/redis-slave 
docker push reg.docker.tb/harbor/redis-slave 

redis-master鏡像制作

跟上面的配置差不多一樣,只是啟動時的命令有點不而已。
Dockerfile內容如下:

FROM alpine:3.4  
RUN apk add --no-cache redis sed bash  
COPY run.sh /run.sh  
CMD [ "/run.sh" ]  
ENTRYPOINT [ "bash" ]  

其實默認可以不使用redis.conf文件的,如果需要就在上面的Dockerfile文件也加入,這里目前也處於測試,先不加配置。

run.sh啟動腳本,也就是一行文件。

[root@k8s-node1 master]# cat run.sh 
#/bin/sh 
redis-server

打包成鏡像傳到內網倉庫:

docker build -t redis-master . 
docker tag redis-master reg.docker.tb/harbor/redis-master 
docker push reg.docker.tb/harbor/redis-master 

創建kube的配置文件yaml

創建一個master-service.yaml 來統一Master的入口,同時會自動關聯到labels為redis-master的所有Pod,這里要注意Service要優於pod啟動,不然無法通過環境變量把配置信息寫入到pod中。

apiVersion: v1 
kind: Service 
metadata: 
  name: redis-master 
  labels: 
    name: redis-master 
spec: 
  ports: 
  - port: 6379 
    targetPort: 6379 
  selector: 
    name: redis-master 

redis-master.yaml 以rc的方式來創建一個master容器,它會保證容器的副本數量。

apiVersion: v1 
kind: ReplicationController 
metadata: 
  name: redis-master 
  labels: 
    name: redis-master 
spec: 
  replicas: 1 
  selector: 
    name: redis-master 
  template: 
    metadata: 
      labels: 
        name: redis-master 
    spec: 
      containers: 
      - name: master 
        image: reg.docker.tb/harbor/redis-master 
        ports: 
        - containerPort: 6379 

redis-slave-service.yaml跟上面的Service一樣,都是管理redis-slave所有容器的,此服務創建后會把所有的slave實例的容器分配一個集群IP.

apiVersion: v1 
kind: Service 
metadata: 
  name: redis-slave 
  labels: 
    name: redis-slave 
spec: 
  ports: 
  - port: 6379 
  selector: 
    name: redis-slave 

redis-slave.yaml 同樣是以RC的方式來創建redis-slave實例,這里的數量為兩個。需要注意的是Image這里指定是剛才打包的鏡像名。

apiVersion: v1 
kind: ReplicationController 
metadata: 
  name: redis-slave 
  labels: 
    name: redis-slave 
spec: 
  replicas: 2 
  selector: 
    name: redis-slave 
  template: 
    metadata: 
      labels: 
        name: redis-slave 
    spec: 
      containers: 
      - name: worker 
        image: reg.docker.tb/harbor/redis-slave 
        env: 
        - name: GET_HOSTS_FROM 
          value: env 
#value: dns
        ports: 
        - containerPort: 6379 

注意:要實現master和slave服務自動發現,需要配置它們之間的對應關系。Kubernetes有兩種方法就是環境變量ENV和DNS記錄解析,因為我的實驗環境沒有使用這個DNS來解析,所以只能使用ENV環境變量。

上面的redis-slave.yaml 就是使用了env環境變量。

接下來創建實例吧:

master: 
kubectl create -f redis-service.yaml 
kubectl create -f redis-master.yaml 

slave: 
kubectl create -f redis-slave-service.yaml 
kubectl create -f redis-slave.yaml 

查看啟動的效果:

[root@k8s-master redis-pod]# kubectl get all -o wide 
NAME                    READY     STATUS    RESTARTS   AGE       IP           NODE 
po/redis-master-qpzlh   1/1       Running   0          1h        172.21.2.2   k8s-node1 
po/redis-slave-2rwk5    1/1       Running   0          1h        172.21.2.3   k8s-node1 
po/redis-slave-6tf2f    1/1       Running   0          1h        172.21.8.3   k8s-node2 

NAME              DESIRED   CURRENT   READY     AGE       CONTAINERS   IMAGES                              SELECTOR 
rc/redis-master   1         1         1         1h        master       reg.docker.tb/harbor/redis-master   name=redis-master 
rc/redis-slave    2         2         2         1h        worker       reg.docker.tb/harbor/redis-slave    name=redis-slave 

NAME               TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE       SELECTOR 
svc/kubernetes     ClusterIP   10.254.0.1       <none>        443/TCP    3d        <none> 
svc/redis-master   ClusterIP   10.254.152.116   <none>        6379/TCP   1h        name=redis-master 
svc/redis-slave    ClusterIP   10.254.188.60    <none>        6379/TCP   1h        name=redis-slave 

簡單的測試master和slave是否可以同步數據:
連接master容器,可以看到有兩個Replication中有兩個connected_slaves就是從實例,后面跟着的就是IP地址。

[root@k8s-master redis-pod]# kubectl exec -it redis-master-qpzlh -- /bin/bash 
bash-4.3# redis-cli                                                                                                                                          
127.0.0.1:6379> info 
# Server 
redis_version:3.2.11 
redis_git_sha1:535782f7 
redis_git_dirty:0 
redis_build_id:80ce8a1f388ac530 
redis_mode:standalone 
os:Linux 4.4.113-1.el7.elrepo.x86_64 x86_64 
arch_bits:64 
multiplexing_api:epoll 
gcc_version:5.3.0 
process_id:5 
run_id:6629f021c2e5bd972fff05c84566cc92c7e59be0 
tcp_port:6379 
uptime_in_seconds:7105 
uptime_in_days:0 

...... 
# Clients 
connected_clients:2 
client_longest_output_list:0 
client_biggest_input_buf:0 
blocked_clients:0 
...... 

# Replication 
role:master 
connected_slaves:2 
slave0:ip=172.21.2.3,port=6379,state=online,offset=5276,lag=1 
slave1:ip=172.21.8.0,port=6379,state=online,offset=5276,lag=1 
master_repl_offset:5276 
repl_backlog_active:1 
repl_backlog_size:1048576 
repl_backlog_first_byte_offset:2 
repl_backlog_histlen:5275 

連接一個slave容器查看信息,可以看到Replication中role:slave為從實例,master的IP和端口等信息。

[root@k8s-master ~]# kubectl exec -it redis-slave-2rwk5 -- /bin/bash 
bash-4.3# redis-cli                                                                                                                                          
127.0.0.1:6379> info 
# Server 
redis_version:3.2.11 
redis_git_sha1:535782f7 
redis_git_dirty:0 
redis_build_id:80ce8a1f388ac530 
redis_mode:standalone 
os:Linux 4.4.113-1.el7.elrepo.x86_64 x86_64 
arch_bits:64 
multiplexing_api:epoll 
gcc_version:5.3.0 
process_id:5 
run_id:d48c42ea0a83babda663837ed5a6f9ef5a3ff9bf 
tcp_port:6379 
uptime_in_seconds:3957 
uptime_in_days:0 

...... 
# Replication 
role:slave 
master_host:10.254.152.116 
master_port:6379 
master_link_status:up 
master_last_io_seconds_ago:7 
master_sync_in_progress:0 
slave_repl_offset:5542 
slave_priority:100 
slave_read_only:1 
connected_slaves:0 
master_repl_offset:0 
repl_backlog_active:0 
repl_backlog_size:1048576 
repl_backlog_first_byte_offset:0 
repl_backlog_histlen:0 

此時在Master上創建一個key, 在slave上立馬就可以獲取到了。

master: 
127.0.0.1:6379> set name swper 
OK 

slave: 
127.0.0.1:6379> get name 
"swper" 

slave上只讀: 
127.0.0.1:6379> set test 1 
(error) READONLY You can't write against a read only slave. 

這樣就實現了一主多從的效果了,集群的IP現在是外部無法訪問的,kubernetes節點中可以相互連通。
其實原本是很簡單的實驗,我居然在傳遞參數的時候少了個$號導致一直獲取不到


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM