基于Kubernetes和Docke实现留言簿案例

一、介绍

本案例基于Kubernetes和Docker,其中包括
1、web前端
2、redis master
3、redis slave
其中web前端通过javascript redis api和redis master交互

kubernetes体系架构

二、配置

0、先决条件
Kubernetes 集群

1、启动redis master
使用replication controller确保只有一个pod在运行(当某个节点down了,rc会在另一个健康的node启动redis master),但可能会有数据丢失。

[root@centos1 example]# kubectl create -f redis-master-controller.json
replicationcontrollers/redis-master
[root@centos1 example]# kubectl get rc
CONTROLLER   CONTAINER(S)  IMAGE(S)  SELECTOR      REPLICAS
redis-master  master     redis   name=redis-master  1

验证master运行成功,如下展示了pod运行在centos2/192.168.1.112这台机器上

[root@centos1 example]# kubectl get pods
POD         IP      CONTAINER(S)  IMAGE(S)  HOST          LABELS       STATUS  CREATED   MESSAGE
redis-master-svar7  172.17.0.9               centos2/192.168.1.112  name=redis-master  Running  55 seconds
                 master     redis                         Running  55 seconds

SSH到centos2/192.168.1.112查看docker状态

[root@centos2 yum.repos.d]# docker ps
CONTAINER ID    IMAGE                 COMMAND        CREATED       STATUS       PORTS        NAMES
91689ce56668    redis:latest              "/entrypoint.sh redi  3 minutes ago    Up 3 minutes              k8s_master.52732b08_redis-master-svar7_default_5b6d5485-1894-11e5-b3ad-000c293c8c19_97e79b7b
38c3180813c3    gcr.io/google_containers/pause:0.8.0  "/pause"        3 minutes ago    Up 3 minutes              k8s_POD.49eee8c2_redis-master-svar7_default_5b6d5485-1894-11e5-b3ad-000c293c8c19_298e038f

注意:kubectl create执行后,如果镜像不存在,会执行docker pull,根据网络情况,下载中的pods 在kubertnetes UI上会显示pending状态

2、启动master service
一个kubernetes service会对一个或多个container进行负载均衡,这是通过我们上面redis-master中定义的labels元数据实现的,值得注意的是,在redis中只有一个master,但是我们依然为它创建一个service,这是因为这样我们就能使用一个elastic IP来路由到具体某一个master。
kubernetes集群中的service是通过container中的环境变量实现服务发现的,service基于pod label实现container的负载均衡。
在第一步中创建的pod包含了一个label“name=redis-master”,service的selector字段决定了service将流量转发给哪个pod,port和targetPort信息定义了service proxy运行在什么端口。

[root@centos1 example]# kubectl create -f redis-master-service.json
services/redis-master
[root@centos1 example]# kubectl get services
NAME      LABELS                  SELECTOR      IP(S)      PORT(S)
redis-master  name=redis-master             name=redis-master  10.254.154.90  6379/TCP

上面的运行成功后,所有pods都能发现redis master运行在6379端口,从salve到master流量走向会有以下两步:
1、一个redis slave会连接到redis master service的port上
2、流量会从service节点上的port到targetPort
如果targetPort未指定,默认和port一致

3、启动replicated slave pod
虽然redis master是一个单独的pod,redis slaves是一个replicated pod,在Kubernetes中,一个Replication Controller负责管理一个replicated pod的多个实例,RC会自动拉起down掉的replica(可以通过杀死docker 进程方式简单测试)

[root@centos1 example]# kubectl create -f redis-slave-controller.json
replicationcontrollers/redis-slave
[root@centos1 example]# kubectl get rc
CONTROLLER   CONTAINER(S)  IMAGE(S)          SELECTOR      REPLICAS
redis-master  master     redis            name=redis-master  1
redis-slave  slave     kubernetes/redis-slave:v2  name=redis-slave  2
[root@centos1 example]# kubectl get pods
POD         IP      CONTAINER(S)  IMAGE(S)          HOST          LABELS       STATUS  CREATED   MESSAGE
redis-master-svar7  172.17.0.9                        centos2/192.168.1.112  name=redis-master  Running  41 minutes
                  master     redis                                  Running  41 minutes
redis-slave-31tkb  172.17.0.10                       centos2/192.168.1.112  name=redis-slave  Running  29 seconds
                  slave     kubernetes/redis-slave:v2                        Running  28 seconds
redis-slave-uk8nu  172.17.0.11                       centos2/192.168.1.112  name=redis-slave  Running  29 seconds
                  slave     kubernetes/redis-slave:v2                        Running  28 seconds

可以看到一个master pod和两个slave pod

4、启动slave service
和master一样,我们希望有一个代理服务连接到redis slave,除了服务发现之外,slave service还为web app client提供了透明代理。
这次service 的selector是name=redis-slave,我们可以方便的使用kubectl get services -l "label=value"命令来定位这些服务

[root@centos1 example]# kubectl create -f redis-slave-service.json
services/redis-slave
[root@centos1 example]# kubectl get services
NAME      LABELS                  SELECTOR      IP(S)      PORT(S)
redis-master  name=redis-master             name=redis-master  10.254.154.90  6379/TCP
redis-slave   name=redis-slave             name=redis-slave  10.254.159.145  6379/TCP

5、创建frontend pod
这是一个简单的PHP 服务,用来和master service(写请求)或slave service(读请求)交互

[root@centos1 example]# kubectl create -f frontend-controller.json
replicationcontrollers/frontend
[root@centos1 example]# kubectl get rc
CONTROLLER   CONTAINER(S)  IMAGE(S)                  SELECTOR      REPLICAS
frontend    php-redis   kubernetes/example-guestbook-php-redis:v2  name=frontend    3
redis-master  master     redis                    name=redis-master  1
redis-slave  slave     kubernetes/redis-slave:v2          name=redis-slave  2

运行成功后,查看当前pod运行状态

[root@centos1 example]# kubectl get pods
POD         IP      CONTAINER(S)  IMAGE(S)                  HOST          LABELS       STATUS  CREATED   MESSAGE
frontend-fr5z1    172.17.0.13                               centos2/192.168.1.112  name=frontend    Running  2 minutes
                  php-redis   kubernetes/example-guestbook-php-redis:v2                        Running  2 minutes
frontend-gjx3t    172.17.0.14                               centos2/192.168.1.112  name=frontend    Running  2 minutes
                  php-redis   kubernetes/example-guestbook-php-redis:v2                        Running  2 minutes
frontend-v608r    172.17.0.12                               centos2/192.168.1.112  name=frontend    Running  2 minutes
                  php-redis   kubernetes/example-guestbook-php-redis:v2                        Running  2 minutes
redis-master-svar7  172.17.0.9                                centos2/192.168.1.112  name=redis-master  Running  53 minutes
                  master     redis                                          Running  53 minutes
redis-slave-31tkb  172.17.0.10                               centos2/192.168.1.112  name=redis-slave  Running  12 minutes
                  slave     kubernetes/redis-slave:v2                                Running  12 minutes
redis-slave-uk8nu  172.17.0.11                               centos2/192.168.1.112  name=redis-slave  Running  12 minutes
                  slave     kubernetes/redis-slave:v2                                Running  12 minutes

可以看到一个redis master,两个redis slave和三个frontend pods

6、创建guestbook service
和其他service一样,你可以创建一个service管理frontend pods

[root@centos1 example]# kubectl create -f frontend-service.json
services/frontend
[root@centos1 example]# kubectl get services
NAME      LABELS                  SELECTOR      IP(S)      PORT(S)
frontend    name=frontend               name=frontend    10.254.154.111  80/TCP
redis-master  name=redis-master             name=redis-master  10.254.154.90  6379/TCP
redis-slave   name=redis-slave             name=redis-slave  10.254.159.145  6379/TCP

我们可以通过frontend service(10.254.154.111)访问pods,但是这个IP明显是无法在外部访问的,下一节讲解如何在外部网络访问guestbook

7、外部网络访问guestbook
kubernetes 支持两种访问暴露一个服务到外部IP地址NodePorts 和LoadBalancers,另外可以查看防火墙,找到service对应的端口,如下

[root@centos1 example]# kubectl get pods,services
POD         IP      CONTAINER(S)  IMAGE(S)                  HOST          LABELS       STATUS  CREATED     MESSAGE
frontend-fr5z1    172.17.0.13                               centos2/192.168.1.112  name=frontend    Running  22 minutes
                  php-redis   kubernetes/example-guestbook-php-redis:v2                        Running  22 minutes
frontend-gjx3t    172.17.0.14                               centos2/192.168.1.112  name=frontend    Running  22 minutes
                  php-redis   kubernetes/example-guestbook-php-redis:v2                        Running  22 minutes
frontend-v608r    172.17.0.12                               centos2/192.168.1.112  name=frontend    Running  22 minutes
                  php-redis   kubernetes/example-guestbook-php-redis:v2                        Running  22 minutes
redis-master-svar7  172.17.0.9                                centos2/192.168.1.112  name=redis-master  Running  About an hour
                  master     redis                                          Running  About an hour
redis-slave-31tkb  172.17.0.10                               centos2/192.168.1.112  name=redis-slave  Running  32 minutes
                  slave     kubernetes/redis-slave:v2                                Running  32 minutes
redis-slave-uk8nu  172.17.0.11                               centos2/192.168.1.112  name=redis-slave  Running  32 minutes
                  slave     kubernetes/redis-slave:v2                                Running  32 minutes
NAME      LABELS                  SELECTOR      IP(S)      PORT(S)
frontend    name=frontend               name=frontend    10.254.154.111  80/TCP
kubernetes   component=apiserver,provider=kubernetes  <none>       10.254.0.2    443/TCP
kubernetes-ro  component=apiserver,provider=kubernetes  <none>       10.254.0.1    80/TCP
redis-master  name=redis-master             name=redis-master  10.254.154.90  6379/TCP
redis-slave   name=redis-slave             name=redis-slave  10.254.159.145  6379/TCP
[root@centos1 example]# kubectl get services
NAME      LABELS                  SELECTOR      IP(S)      PORT(S)
frontend    name=frontend               name=frontend    10.254.154.111  80/TCP
kubernetes   component=apiserver,provider=kubernetes  <none>       10.254.0.2    443/TCP
kubernetes-ro  component=apiserver,provider=kubernetes  <none>       10.254.0.1    80/TCP
redis-master  name=redis-master             name=redis-master  10.254.154.90  6379/TCP
redis-slave   name=redis-slave             name=redis-slave  10.254.159.145  6379/TCP

发现redis-master是在10.254.154.90上,登录到centos2上,执行iptables-save,发现其中有这样一条规则

代码如下:

-A KUBE-PORTALS-HOST -d 10.254.154.90/32 -p tcp -m comment --comment "default/redis-master:" -m tcp --dport 6379 -j DNAT --to-destination 192.168.1.112:49038

说明,centos2本机的49038端口映射到master container内的6379了,当然我们就能执行在本机访问redis了

[root@centos2 yum.repos.d]# redis-cli -p 49038
127.0.0.1:49038> set a b
OK
127.0.0.1:49038> get a
"b"

8、使用curl简单测试

提交数据

代码如下:

curl "localhost:8000/index.php?cmd=set&key=messages&value=jay_sais_hi"

查询数据

代码如下:

curl "localhost:8000/index.php?cmd=get&key=messages"

附本案例用到的6个.json文件
1、redis-master-controller.json

{
  "kind":"ReplicationController",
  "apiVersion":"v1beta3",
  "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":"redis",
         "ports":[
           {
            "containerPort":6379
           }
         ]
        }
      ]
     }
   }
  }
}

2、redis-master-service.json

{
  "kind":"Service",
  "apiVersion":"v1beta3",
  "metadata":{
   "name":"redis-master",
   "labels":{
     "name":"redis-master"
   }
  },
  "spec":{
   "ports": [
    {
     "port":6379,
     "targetPort":6379
    }
   ],
   "selector":{
     "name":"redis-master"
   }
  }
}

3、redis-slave-controller.json

{
  "kind":"ReplicationController",
  "apiVersion":"v1beta3",
  "metadata":{
   "name":"redis-slave",
   "labels":{
     "name":"redis-slave"
   }
  },
  "spec":{
   "replicas":2,
   "selector":{
     "name":"redis-slave"
   },
   "template":{
     "metadata":{
      "labels":{
        "name":"redis-slave"
      }
     },
     "spec":{
      "containers":[
        {
         "name":"slave",
         "image":"kubernetes/redis-slave:v2",
         "ports":[
           {
            "containerPort":6379
           }
         ]
        }
      ]
     }
   }
  }
}

4、redis-slave-service.json

{
  "kind":"Service",
  "apiVersion":"v1beta3",
  "metadata":{
   "name":"redis-slave",
   "labels":{
     "name":"redis-slave"
   }
  },
  "spec":{
   "ports": [
    {
     "port":6379
    }
   ],
   "selector":{
     "name":"redis-slave"
   }
  }
}

5、frontend-controller.json

{
  "kind":"ReplicationController",
  "apiVersion":"v1beta3",
  "metadata":{
   "name":"frontend",
   "labels":{
     "name":"frontend"
   }
  },
  "spec":{
   "replicas":3,
   "selector":{
     "name":"frontend"
   },
   "template":{
     "metadata":{
      "labels":{
        "name":"frontend"
      }
     },
     "spec":{
      "containers":[
        {
         "name":"php-redis",
         "image":"kubernetes/example-guestbook-php-redis:v2",
         "ports":[
           {
            "containerPort":80
           }
         ]
        }
      ]
     }
   }
  }
}

6、frontend-service.json

{
  "kind":"Service",
  "apiVersion":"v1beta3",
  "metadata":{
   "name":"frontend",
   "labels":{
     "name":"frontend"
   }
  },
  "spec":{
   "ports": [
    {
     "port":80
    }
   ],
   "selector":{
     "name":"frontend"
   }
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Smarty结合Ajax实现无刷新留言本实例

    看了标题你也许要说,留言本,很基本的东东啊!谁不会啊,还要用Smarty,这不找累吗?别急,我要表达的是一种编程的思想和结构,而不是证明我做的东西多有意义,通过它相信对初学者学习Smarty和ajax有些启发.原本用ajax做的,可惜始终调试不成功,只好用手写JS来弄了,不过不要紧,还是有一定价值的.站点结构大家下了源代码自己看,代码不长,应该不会看烦^_^,听我慢慢道来.     现在都PHP5了OO(面向对象)很流行了都,这里也不错过,首先来看下我们用OO来实现数据库操作和连接:[php]<

  • FLASH与ASP通信入门教程——做真正属于自己的留言本第1/5页

    经常有人问我FLASH留言板的制作方法,无奈这东西一句两句没办法说清楚,于是就萌发了写教程的想法.可后来又一想,授人以鱼,不如授人以渔,还不如集中精力好好讲将FLASH与ASP的通讯原理,原理通了,具体项目就可以自由发挥了. 我这个教程面向初级群体,在开始教程之前,我假设你已经具备FLASH操作基础知识,了解IIS配置以及运行环境.尽管FLASH与ASP通信方式有很多,但这篇教程中我选择使用LoadVars类,一因为LoadVars类容易掌握,易于讲解:二是因为它不牵扯太多其他方面的知识.另外,

  • ThinkPHP之用户注册登录留言完整实例

    本文以实例形式讲述ThinkPHP实现的包括用户的注册.登录以及留言等功能,这里需要大家注意的是,在存在用户模型的情况下实例化一个用户类的时候使用D方法来实现.   UserActiion.class.php页面: <?php class UserAction extends Action{ public function add(){ $user = D("user"); $user->create(); $result = $user->add(); if($re

  • php简单的留言板与回复功能具体实现

    在网上找了这方面的教程 但是基本就是没有人说什么 然后在某一天看见一个PHP程序设计出了一张类似这样的数据库设计图之后就有了很多领悟!下面是数据库的结构图 下面我们就来继续一下介绍 id                        这个算是父Id 可以通过这个id来查询 在这个id下是否有子id 同时也可以记录这个是那条留言的id son_id                    这个是子id 然后通过这个id 可以找到相对应的父id   news_id                  

  • 一个简单的PHP&MYSQL留言板源码第1/2页

    初学PHP,花了几晚上写了个留言板,请高手指正 p.s.我的空间不支持PHP,不能提供演示了T_T 数据库结构:(库名:lyb) 表一: admin 字段: id(int11)   name(varchvr)   password(varchvr) 表二: lo 字段: id(int11)   username(varchvr)  sex(varchvr)  qq(varchvr)  email(varchvr)  info(text)  ip(varchvr)  submit_time(dat

  • 简单的PHP留言本实例代码

    config.php 复制代码 代码如下: <?php $conn = @mysql_connect("localhost","root","") or die("数据库连接出错!"); mysql_select_db("gb",$conn); mysql_query("set names 'GBK'"); ?> add.php 复制代码 代码如下: <?php inc

  • 来自经典的打造简单的PHP&MYSQL留言板第1/4页

    表一: admin 字段: id(int11)   name(varchvr)   password(varchvr) 表二: lo 字段: id(int11)   username(varchvr)  sex(varchvr)  qq(varchvr)  email(varchvr)  info(text)  ip(varchvr)  submit_time(datetime) 1.conn.php(连接数据库文件) 复制代码 代码如下: <?php  mysql_connect("lo

  • HTML5实现留言和回复页面样式

    具体就不做详细讲解了,直接上代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="author" content="http://www.webkfa.com/" /> <title>web开发-webkfa.com</title> <style type="tex

  • php开发留言板的CRUD(增,删,改,查)操作

    项目结构: 添加页面:                                说明:这里只注重操作,对界面的美工没有下工夫,希望大家理解...... 列表页面: 修改页面: 项目中所需的sql: 复制代码 代码如下: create database form; use form; CREATE TABLE `message` ( `id` tinyint(1) NOT NULL auto_increment, `user` varchar(25) NOT NULL, `title` va

  • 超级简单的php+mysql留言本源码

    共3个文件 IncDB.php数据库连接 index.php首页 InsetToDB.php数据库操作 数据库lguestbook里面建表 复制代码 代码如下: CREATE TABLE `intd` ( `id` int(11) NOT NULL auto_increment, `name` varchar(255) character set utf8 collate utf8_bin NOT NULL, `text` text character set utf8 collate utf8

随机推荐