Guestbook示例:Hello World

  • Guestbook留言板系统将通过Pod、RC、 Service等资源对象搭建完成,成功启动后在网页中显示一条“ Hello World”留言。其系统架构是一个基于PHIP+ Redis的分布式Web应用,前端PHP Web网站通过访问后端的 Redis来完成用户留言的查询和添加等功能。同时 Redis以Master+Slave的模式进行部署,实现数据的读写分离能力。

  • 留言板系统的部署架构如下图所示。Web层是一个基于PHP页面的 Apache服务,启动3个实例组成集群,为客户端(例如浏览器)对网站的访问提供负载均衡。 Redis Master启动个实例用于写操作(添加留言), Redis Slave启动两个实例用于读操作(读取留言)。 Redis Master与 Slave的数据同步由 Redis具备的数据同步机制完成。

在这里插入图片描述

  • 本例用到的3个docker镜像,下载地址:https://hub.docker.com/u/kubeguide/

    • redis-master:用于前端Web应用进行“写”留言操作的 Redis服务,其中已经保存了条内容为“ Hello World!”的留言。
    • guestbook-redis- slave:用于前端Web应用进行“读”留言操作的 Redis服务,并与Redis- Master的数据保持同步。
    • guestbook-php- frontend: PHP Web服务,在网页上展示留言的内容,也提供一个文本输入框供访客添加留言。

1. 创建redis-master RC和Service

  • 首先定义RC来关联Pod,然后定义与之关联的Service。(也可以反过来)

  • 创建一个名为redis-master的RC定义文件redis-master-controller.yaml

    apiVersion: v1
    kind: ReplicationController  #表示这是一个RC
    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: kubeguide/redis-master
         ports:
         - containerPort: 6379
    
    • spec.selector是RC的Pod选择器,即监控和管理拥有这些标签(Label)的Pod实列;确保当前集群上始终有且仅有replicas个Pod实例在运行,这里我们设置replicas表示只运行一个Pod(名为redis-master),当集群中运行的Pod数量小于replicas=1时,RC会根据spec.template段定义的Pod模板来生成一个新的Pod实例,labels属性指定了该Pod的标签。
  • 在Master节点执行创建命令

kubectl apply -f redis-master-controller.yaml 
  • 查看刚刚创建的redis-master
[root@node2 test]# kubectl get rc
NAME           DESIRED   CURRENT   READY   AGE
mysql          1         1         1       6d2h
myweb          1         1         1       6d1h
redis-master   1         1         1       118m
  • 查看Pod列表
[root@node2 test]# kubectl get pods
NAME                 READY   STATUS    RESTARTS   AGE
mysql-sx4r4          1/1     Running   0          6d2h
myweb-hlmxz          1/1     Running   0          6d1h
nginx-rs-v2tgk       1/1     Running   0          5d21h
redis-master-fsdk8   1/1     Running   0          119m
  • redis-master-fsdk8这个实例是K8S根据redis-master这个RC定义自动创建的Pod。RC会给每个Pod实例在用户设置的name后面补充一段UUID,以区分不同的实例。
  • Pod的调度和创建需要一定的时间,比如需要一定的时间来确定调度到哪个节点上以及下载Pod的相关镜像。
  • redis-master Pod已经创建并正常运行了,接下来创建一个与之关联的Service文件redis-master-svc.yaml
apiVersion: v1
kind: Service
metadata:
 name: redis-master
 labels:
  name: redis-master
spec:
 ports:
 - port: 6379
   targetPort: 6379
 selector:
  name: redis-master
  • metadata.name是Service的服务名(ServiceName),spec.selector确定了选择哪些Pod,本例中的定义表明将选择设置过name=redis-master标签的Pod。port属性定义的是Service的虚拟端口号,targetPort属性指定后端Pod内容器应用监听的端口号。
  • 创建service
kubectl apply -f redis-master-svc.yaml 
  • 查看service
[root@node2 test]# kubectl get svc
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes     ClusterIP   10.96.0.1        <none>        443/TCP          9d
mysql          ClusterIP   10.96.114.38     <none>        3306/TCP         6d2h
myweb          NodePort    10.107.166.10    <none>        8080:30001/TCP   6d2h
nginx-svc      NodePort    10.97.62.146     <none>        80:30002/TCP     5d21h
redis-master   ClusterIP   10.106.116.209   <none>        6379/TCP         120m
  • redis-master服务被分配了一个虚拟IP地址10.106.116.209,随后K8S集群中其他新创建的Pod就可以通过这个虚拟IP+端口6379来访问这个服务了。在本例中将要创建的redis-slave和frontend两组Pod都将要通过此方式访问redis-master(服务发现机制)。

2. 创建redis-slave RC和Service

  • 创建一个名为redis-slave-controller.yaml的RC定义文件
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: slave
     image: kubeguide/guestbook-redis-slave
     env:
     - name: GET_HOSTS_FROM
       value: env
     ports:
     - containerPort: 6379
  • 在容器的配置部分设置了一个环境变量GET_HOSTS_FROM=env,意思是从环境变量中获取redis-master服务的IP地址信息。

  • 在创建 redis-slave Pod时,系统将自动在容器内部生成之前已经创建好的 redis-master service相关的环境变量,所以 redis-slave应用程序 redis-server可以直接使用环境变量 REDIS_MASTER_SERVICE_HOST来获取 redis-master服务的IP地址。
    在这里插入图片描述

  • 如果在容器配置部分不设置该env,则将使用 redis-master服务的名称“ redis- master”来访问它,这将使用DNS方式的服务发现,需要预先启动 Kubernetes集群的 skydns服务。

  • 创建RC

[root@node2 test]# kubectl apply -f redis-slave-controller.yaml 
replicationcontroller/redis-slave created
  • 查看RC
[root@node2 test]# kubectl get rc
NAME           DESIRED   CURRENT   READY   AGE
mysql          1         1         1       6d3h
myweb          1         1         1       6d2h
redis-master   1         1         1       158m
redis-slave    2         2         2       119s
  • 查看Pod
[root@node2 test]# kubectl get pods
NAME                 READY   STATUS    RESTARTS   AGE
mysql-sx4r4          1/1     Running   0          6d3h
myweb-hlmxz          1/1     Running   0          6d2h
nginx-rs-v2tgk       1/1     Running   0          5d22h
redis-master-fsdk8   1/1     Running   0          158m
redis-slave-hhwx7    1/1     Running   0          2m31s
redis-slave-qf4rh    1/1     Running   0          2m31s
  • 创建redis-slave服务,与redis-slave相关的一组环境变量也将在后续新建的frontend Pod中由系统自动生成。
  • 创建redis-slave-service.yaml
apiVersion: v1
kind: Service
metadata:
 name: redis-slave
 labels:
  name: redis-slave
spec:
 ports:
 - port: 6379
 selector: 
  name: redis-slave
  • 创建服务
[root@node2 test]# kubectl apply -f redis-slave-service.yaml 
service/redis-slave created
  • 查看服务
[root@node2 test]# kubectl get svc
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes     ClusterIP   10.96.0.1        <none>        443/TCP          9d
mysql          ClusterIP   10.96.114.38     <none>        3306/TCP         6d3h
myweb          NodePort    10.107.166.10    <none>        8080:30001/TCP   6d3h
nginx-svc      NodePort    10.97.62.146     <none>        80:30002/TCP     5d22h
redis-master   ClusterIP   10.106.116.209   <none>        6379/TCP         160m
redis-slave    ClusterIP   10.99.153.217    <none>        6379/TCP         62s

3. 创建frontend RC和Service

  • 创建frontend-controller.yaml
apiVersion: v1
kind: ReplicationController
metadata:
 name: frontend
 labels:
  name: frontend
spec:
 replicas: 3
 selector:
  name: frontend
 template:
  metadata:
   labels:
    name: frontend
  spec: 
   containers:
   - name: frontend
     image: kubeguide/guestbook-php-frontend
     env:
     - name: GET_HOSTS_FROM
       value: env
     ports:
     - containerPort: 80
  • 在容器的配置部分设置了一个环境变量 GET HOSTS FROM=env,意思是从环境变量中获取 redis- master和 redis- slave服务的IP地址信息。
  • 创建RC
[root@node2 test]# kubectl apply -f frontend-controller.yaml 
replicationcontroller/frontend created
  • 查看RC
[root@node2 test]# kubectl get rc
NAME           DESIRED   CURRENT   READY   AGE
frontend       3         3         3       84s
mysql          1         1         1       6d3h
myweb          1         1         1       6d2h
redis-master   1         1         1       176m
redis-slave    2         2         2       20m
  • 查看Pod
[root@node2 test]# kubectl get pods
NAME                 READY   STATUS    RESTARTS   AGE
frontend-5mcwh       1/1     Running   0          2m1s
frontend-8xmsj       1/1     Running   0          2m1s
frontend-njlb2       1/1     Running   0          2m1s
mysql-sx4r4          1/1     Running   0          6d3h
myweb-hlmxz          1/1     Running   0          6d2h
nginx-rs-v2tgk       1/1     Running   0          5d22h
redis-master-fsdk8   1/1     Running   0          177m
redis-slave-hhwx7    1/1     Running   0          21m
redis-slave-qf4rh    1/1     Running   0          21m
  • 创建Service,主要目的是使用Service中的NodePort来给K8S集群中的Service映射一个外网就可以访问的端口。
  • 创建服务定义文件frontend-service.yaml
apiVersion: v1
kind: Service
metadata:
 name: frontend
 labels:
  name: frontend
spec:
 type: NodePort
 ports:
 - port: 80
   nodePort: 30005
 selector:
  name: frontend
  • 关键点是设置type- Nodeport并指定一个 Nodeport的值,表示使用Node上的物理机端口提供对外访问的能力。需要注意的是,spec.pots. Nodeport的端口号范围可以进行限制(通过kube- apiserver的启动参数- service-node-port- range指定),默认为3000032767,如果指定为可用P范围之外的其他端口号,则 Service的创建将会失败。
  • 创建Service
[root@node2 test]# kubectl apply -f frontend-service.yaml 
service/frontend created
  • 查看Service
[root@node2 test]# kubectl get svc
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
frontend       NodePort    10.102.233.226   <none>        80:30005/TCP     89s
kubernetes     ClusterIP   10.96.0.1        <none>        443/TCP          9d
mysql          ClusterIP   10.96.114.38     <none>        3306/TCP         6d3h
myweb          NodePort    10.107.166.10    <none>        8080:30001/TCP   6d3h
nginx-svc      NodePort    10.97.62.146     <none>        80:30002/TCP     5d22h
redis-master   ClusterIP   10.106.116.209   <none>        6379/TCP         3h5m
redis-slave    ClusterIP   10.99.153.217    <none>        6379/TCP         25m
  • 经过上面的三个步骤就搭建好了 Guestbook留言板系统,总共包括3个应用的6个实例,都运行在 Kubernetes集群中。打开浏览器,在地址栏输入http://虚拟机IP:30001/,将看到网页,并且看到网页上有一条留言:“ Hello World!“
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐