如何用 K8s 创建一个 guestbook 留言簿应用 ?

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
任务调度 XXL-JOB 版免费试用,400 元额度,开发版规格
简介: 本文介绍一个简单的K8s上手应用,希望通过这个简单的实践让大家对K8s的核心概念有更深入的理解。这个案例要在 Kubernetes 集群上部署一个名叫 guestbook 的 CURD 应用。guestbook 是 Kubernetes 社区的一个经典的应用示例,它有一个 Web 界面来让用户进行 CURD 操作,然后向一个 Redis 主节点写入数据,从多个 Redics 从节点读去数据。

原文作者:木环
原文链接
更多云原生技术资讯可关注阿里巴巴云原生技术圈

课后实践:Kubernetes 核心概念

1. 目标概述

本文介绍一个简单的K8s上手应用,希望通过这个简单的实践让大家对K8s的核心概念有更深入的理解。

  1. 巩固 Kubernetes 的基本概念
  2. 学会使用 Kubernetes 部署一个标准的“多层(multi-tier)”应用
  3. 了解 Kubernetes 里如何通过 Pod,Deployment,Service 等 API 原语描述“应用”

2. 实验概览

完成此实验后,可以掌握的能力有:
本实验主要在 Kubernetes 集群上部署一个名叫 guestbook 留言簿的 CURD (增查改删)应用。guestbook 是 Kubernetes 社区的一个经典的应用示例,它有一个 Web 界面来让用户进行 CURD 操作,然后向一个 Redis 主节点写入数据,从多个 Redics 从节点读去数据。
实验分以下几个步骤:

  1. 创建 Redis 主节点
  2. 创建 Redis 从节点集群
  3. 创建 guestbook 应用
  4. 将 guestbook 应用通过 Service 暴露出来并进行访问
  5. 水平扩展 guestbook 应用

3. 所需资源:

一个完备的 Kubernetes 集群。您可以选择阿里云容器服务Kubernetes(ACK)进行上手操作。
可以用 Minikube 快速启动一个单节点集群(国内建议使用Minikube 中国版),也可以用云上的 Kubernetes 集群。本次实验演示将使用阿里云容器服务提供的 Kubernetes 集群,版本为 1.12。
你可以使用使用 kubectl version 查看你的集群版本同实验版本一致。

4. 实验详情

4.1 创建 Redis 主节点

在这里,我们使用一个叫做 Deployment 的 API 对象,来描述单实例的Redis 主节点。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-master
  labels:
    app: redis
spec:
  selector:
    matchLabels:
      app: redis
      role: master
      tier: backend
  replicas: 1
  template:
    metadata:
      labels:
        app: redis
        role: master
        tier: backend
    spec:
      containers:
      - name: master
        image: registry.cn-hangzhou.aliyuncs.com/kubeapps/redis
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 6379

我们需要把这个上述内容保存为本地 YAML文件,名叫:redis-master-deployment.yaml。这个文件主要定义了两个东西:第一,Pod 里的容器的镜像是 redis;第二,这个 Deployment 的实例数(replicas)是 1,即指启动一个 Pod。
然后,我们使用 Kubernetes 的客户端,执行如下操作:

$  kubectl apply -f  redis-master-deployment.yaml
 deployment.apps/redis-master created

这一步完成后,Kubernetes 就会按照这个 YAML 文件里的描述为你创建对应的 Pod。这种使用方式就是声明式 API 的典型特征。
接下来,我们可以查看到这个 Pod:

$ kubectl get pods
NAME                            READY   STATUS    RESTARTS   AGE
redis-master-68979f4ddd-pg9cv   1/1     Running   0          49s

可以看到,Pod 已经进入了 Running 状态,表示一切正常。这时,我们就可以查看这个 Pod 里的 Redis 的日志:

$ kubectl logs -f redis-master-68979f4ddd-pg9cv
1:C 26 Apr 2019 18:49:29.303 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 26 Apr 2019 18:49:29.303 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 26 Apr 2019 18:49:29.303 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
1:M 26 Apr 2019 18:49:29.304 * Running mode=standalone, port=6379.
1:M 26 Apr 2019 18:49:29.304 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:M 26 Apr 2019 18:49:29.304 # Server initialized
1:M 26 Apr 2019 18:49:29.304 * Ready to accept connections

4.2 为 Redis 主节点创建 Service

Kubernetes 里要访问 Pod 最好通过 Service 的方式,这样客户端就不需要记录 Pod 的 IP 地址了。我们的 guestbook 网站需要访问 Redis 主节点的 Pod,所以也要通过 Service 来做。这个 Service API 对象的定义如下所示:

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

这个 Service 名叫 redis-master,它声明用自己的 6379 端口代理 Pod 的 6379端口。
我们还是把上述内容保存成文件然后让 Kubernetes 为我们创建它:

$  kubectl apply -f redis-master-service.yaml
service/redis-master created

然后我们可以查看一下这个 Service:

$ kubectl get service
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
kubernetes     ClusterIP   10.96.0.1        <none>        443/TCP    181d
redis-master   ClusterIP   10.107.220.208   <none>        6379/TCP   9s

这时候,你就可以通过 10.107.220.208:6379 访问到这个 Redis 主节点。

4.3 创建 Redis 从节点集群

我们这个示例中,有多个 Redis 从节点来共同响应读请求。同样的,我们还是通过 Deployment 来描述"一个服务由多个相同的 Pod 实例副本组成"这种语义。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-slave
  labels:
    app: redis
spec:
  selector:
    matchLabels:
      app: redis
      role: slave
      tier: backend
  replicas: 2
  template:
    metadata:
      labels:
        app: redis
        role: slave
        tier: backend
    spec:
      containers:
      - name: slave
        image: registry.cn-hangzhou.aliyuncs.com/kubeapps/gb-redisslave:v1
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:
        - name: GET_HOSTS_FROM
          value: env
        ports:
        - containerPort: 6379

在这个 Deployment 中,我们指定了 replicas: 2,即这个 Deployment 会启动两个相同 Pod(Redis 从节点)。
此外,gb-redisslave:v1 这个镜像,会自动读取 REDIS_MASTER_SERVICE_HOST 这个环境变量的值,也就是 Redis 主节点的 Service 地址,然后用它来组建集群。这个环境变量是Kubernetes 自动根据 redis-master 这个 Service 名字,自动注入到集群的每一个 Pod 当中的。
然后,我们创建 Redis 从节点:

$ kubectl apply -f redis-slave-deployment.yaml
deployment.apps/redis-slave created

这时候,我们就可以查看这些从节点的状态:

$ kubectl get pods
NAME                            READY   STATUS              RESTARTS   AGE
redis-master-68979f4ddd-pg9cv   1/1     Running             0          17m
redis-slave-78b464f5cd-2kn7w    0/1     ContainerCreating   0          37s
redis-slave-78b464f5cd-582bk    0/1     ContainerCreating   0          37s

4.4 为 Redis 从节点创建 Service

类似的,为了让 guestbook 应用访问上述 Redis 从节点,我们还需要为它们创建一个 Service。在Kubernetes 里,Service 可以通过 selector 选择代理多个 Pod,并且负责负载均衡。这个Service 内容如下所示:

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

创建和查看 Service( 注意:这里 6379 端口使用了简化写法,就不需要写明 targetPort了):

$ kubectl apply -f redis-slave-svc.yaml
service/redis-slave created
$ kubectl get services
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
kubernetes     ClusterIP   10.96.0.1        <none>        443/TCP    181d
redis-master   ClusterIP   10.107.220.208   <none>        6379/TCP   16m
redis-slave    ClusterIP   10.101.244.239   <none>        6379/TCP   57s

这样,你就可以通过 10.10.101.244:6379 访问到任何一个 Redis 从节点了。

4.5 创建 guestbook 应用

guestbook 应用本身,依然通过一个 Deployment 来描述,如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
  labels:
    app: guestbook
spec:
  selector:
    matchLabels:
      app: guestbook
      tier: frontend
  replicas: 3
  template:
    metadata:
      labels:
        app: guestbook
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: registry.cn-hangzhou.aliyuncs.com/kubeapps/gb-frontend:v4
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:
        - name: GET_HOSTS_FROM
          value: env
        ports:
        - containerPort: 80

这个 YAML 定义了一个 3 副本的 Deployment,即 guestbook 应用会启动 3 个 Pod。
我们还是通过同样的步骤创建这个 Deployment:

$ kubectl apply -f frontend.yaml
deployment.apps/frontend created

查看 Pod 的状态:

$ kubectl get pods -l app=guestbook -l tier=frontend
NAME                       READY   STATUS    RESTARTS   AGE
frontend-78d6c59f4-2x24x   1/1     Running   0          3m4s
frontend-78d6c59f4-7mz87   1/1     Running   0          3m4s
frontend-78d6c59f4-sw7f2   1/1     Running   0          3m4s

4.6 为 guestbook 应用创建 Service

为了能够让用户访问到 guestbook,我们也需要为 guestbook 来创建一个 Service,从而把这个应用以服务的形式暴露出来给用户使用。
而为了能够让 Kubernetes 集群以外的用户,这个 Service 就必须是一个外部可访问的 Service。这个在 Kubernetes 里有几种做法。在云上最常见的,是 LoadBalancer 模式。

apiVersion: v1
kind: Service
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  # 自建集群只能使用 NodePort 模式
  # type: NodePort 
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: guestbook
    tier: frontend

由于我的集群由阿里云容器服务提供,所以像上面这样直接用 LoadBalancer 模式即可。

$ kubectl apply -f frontend-service.yaml
$ kubectl get service frontend
NAME       TYPE        CLUSTER-IP      EXTERNAL-IP        PORT(S)        AGE
frontend   ClusterIP   172.19.10.209   101.37.192.20     80:32372/TCP   1m

现在,你只要用浏览器打开 EXTERNAL-IP 对应的地址: http://101.37.192.20:31323 ,就可以访问到这个部署好的 guestbook 应用了。
而如果你是自建集群,那就只能用 NodePort 模式来实验(上面 YAML 的注释已经给出了使用方法)。需要注意的是 NodePort 由于安全性问题,不建议在生产环境中使用。

4.7 水平扩展 guestbook 应用

要通过 Kubernetes 来水平扩展你的应用以响应更多的请求非常简单,只需要如下一条命令:

$ kubectl scale deployment frontend --replicas=5
deployment.extensions/frontend scaled

你就会立刻看到你的 guestbook 应用的实例从 3 个变成了 5 个:

$ kubectl get pods -l app=guestbook -l tier=frontend
NAME                       READY   STATUS    RESTARTS   AGE
frontend-78d6c59f4-2x24x   1/1     Running   0          14m
frontend-78d6c59f4-7mz87   1/1     Running   0          14m
frontend-78d6c59f4-chxwd   1/1     Running   0          19s
frontend-78d6c59f4-jrvfx   1/1     Running   0          19s
frontend-78d6c59f4-sw7f2   1/1     Running   0          14m

阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术圈。”

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
1月前
|
缓存 Kubernetes Docker
GitLab Runner 全面解析:Kubernetes 环境下的应用
GitLab Runner 是 GitLab CI/CD 的核心组件,负责执行由 `.gitlab-ci.yml` 定义的任务。它支持多种执行方式(如 Shell、Docker、Kubernetes),可在不同环境中运行作业。本文详细介绍了 GitLab Runner 的基本概念、功能特点及使用方法,重点探讨了流水线缓存(以 Python 项目为例)和构建镜像的应用,特别是在 Kubernetes 环境中的配置与优化。通过合理配置缓存和镜像构建,能够显著提升 CI/CD 流水线的效率和可靠性,助力开发团队实现持续集成与交付的目标。
|
1天前
|
Kubernetes 持续交付 开发工具
阿里云协同万兴科技落地ACK One GitOps方案,全球多机房应用自动化发布,效率提升50%
阿里云协同万兴科技落地ACK One GitOps方案,全球多机房应用自动化发布,效率提升50%
|
29天前
|
存储 监控 对象存储
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
针对本地存储和 PVC 这两种容器存储使用方式,我们对 ACK 的容器存储监控功能进行了全新升级。此次更新完善了对集群中不同存储类型的监控能力,不仅对之前已有的监控大盘进行了优化,还针对不同的云存储类型,上线了全新的监控大盘,确保用户能够更好地理解和管理容器业务应用的存储资源。
117 21
|
1月前
|
存储 监控 对象存储
ACK容器监控存储全面更新:让您的应用运行更稳定、更透明
介绍升级之后的ACK容器监控体系,包括各大盘界面展示和概要介绍。
|
2月前
|
人工智能 Kubernetes 安全
赋能加速AI应用交付,F5 BIG-IP Next for Kubernetes方案解读
赋能加速AI应用交付,F5 BIG-IP Next for Kubernetes方案解读
82 13
|
2月前
|
存储 Kubernetes 关系型数据库
阿里云ACK备份中心,K8s集群业务应用数据的一站式灾备方案
本文源自2024云栖大会苏雅诗的演讲,探讨了K8s集群业务为何需要灾备及其重要性。文中强调了集群与业务高可用配置对稳定性的重要性,并指出人为误操作等风险,建议实施周期性和特定情况下的灾备措施。针对容器化业务,提出了灾备的新特性与需求,包括工作负载为核心、云资源信息的备份,以及有状态应用的数据保护。介绍了ACK推出的备份中心解决方案,支持命名空间、标签、资源类型等维度的备份,并具备存储卷数据保护功能,能够满足GitOps流程企业的特定需求。此外,还详细描述了备份中心的使用流程、控制台展示、灾备难点及解决方案等内容,展示了备份中心如何有效应对K8s集群资源和存储卷数据的灾备挑战。
|
3月前
|
Kubernetes 监控 安全
容器化技术:Docker与Kubernetes的实战应用
容器化技术:Docker与Kubernetes的实战应用
|
1月前
|
缓存 容灾 网络协议
ACK One多集群网关:实现高效容灾方案
ACK One多集群网关可以帮助您快速构建同城跨AZ多活容灾系统、混合云同城跨AZ多活容灾系统,以及异地容灾系统。
|
2月前
|
Kubernetes Ubuntu 网络安全
ubuntu使用kubeadm搭建k8s集群
通过以上步骤,您可以在 Ubuntu 系统上使用 kubeadm 成功搭建一个 Kubernetes 集群。本文详细介绍了从环境准备、安装 Kubernetes 组件、初始化集群到管理和使用集群的完整过程,希望对您有所帮助。在实际应用中,您可以根据具体需求调整配置,进一步优化集群性能和安全性。
148 12
|
2月前
|
Prometheus Kubernetes 监控
OpenAI故障复盘 - 阿里云容器服务与可观测产品如何保障大规模K8s集群稳定性
聚焦近日OpenAI的大规模K8s集群故障,介绍阿里云容器服务与可观测团队在大规模K8s场景下我们的建设与沉淀。以及分享对类似故障问题的应对方案:包括在K8s和Prometheus的高可用架构设计方面、事前事后的稳定性保障体系方面。

相关产品

  • 容器服务Kubernetes版