# 1、启动Kubernates 开始我们需要一个运行的K8s集群。详细的已经在启动K8s集群的章节解释过了。 ## Task 启动一个单节点的集群使用帮助脚本。帮助脚本将会启动API server,Master,一个代理和DNS发现。Web App使用DNS发现找到Redis从节点来存储数据。 ``` launch.sh ``` launch.sh文件: ``` #!/bin/bash echo Waiting for Kubernetes to start... while [ ! -f /root/.kube/config ] do sleep 1 done echo Kubernetes started if [ -f /root/.kube/start ]; then /root/.kube/start fi ``` ## 健康检查 检查所有组件是否启动使用下面的健康检查: ``` kubectl cluster-info kubectl get nodes ``` 如果节点返回NotReady,然后需要继续等待。重试之前多等一会。 # 2、Redis 主节点控制器 启动应用的第一步是启动Redis主节点。一个K8s服部署只要有两个部署,一个RC(复制控制器)和一个Service。 复制控制器定义了有多少个实例应该被运行,要使用的Docker镜像,标识服务的名称。其他选项用于配置和发现。使用上面的编辑器查看YAML定义。 如果Redis出故障了,复制控制器将重启它在另一个活动的节点上。 redis-master.service.yaml ``` 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: redis:3.0.7-alpine ports: - containerPort: 6379 ``` ## 创建复制控制器(RC) 在这个例子上,YAML文件定义了一个名叫redis-master的redis服务器,它使用官方的redis运行在6379端口。kubectl create命令使用YAML定义并指示主节点启动控制器。 ``` kubectl create -f redis-master-controller.yaml ``` ## 运行了什么? 上面的命令运行了复制控制器,查看: ``` kubectl get rc ``` 所有的容器描述为Pod。pod是组成特定应用程序的容器的集合,例如Redis。你可以查看这个使用: ``` kubectl get pods ``` # 3、Redis 主节点 Service 第二部分就是Service,一个K8s服务就是一个命名的负载均衡器,它代理流量到一个或更多容器。即使容器是在不同的节点上,这个代理仍是有用的。 Service代理在集群内进行通信,很少向外部接口公开端口。 当你启动一个service,看起来你不能使用curl或者netcat连接它,除非你作为K8s的一部分启动它。推荐的方法是用一个负载均衡器服务去处理外部通信。 redis-master-service.yaml文件: ```yaml apiVersion: v1 kind: Service metadata: name: redis-master labels: name: redis-master spec: ports: # the port that this service should serve on - port: 6379 targetPort: 6379 selector: name: redis-master ``` ## 创建Service 这个YAML文件定义了复制控制器的名字redis-master,和应该被代理的端口。 ``` kubectl create -f redis-master-service.yaml ``` 列出和描述 Service ``` kubectl get services ``` ``` kubectl describe service redis-master ``` # 4、复制从节点pods 在这个例子中,我们将会运行redis从节点,它从主节点复制数据。更多Redis复制的详细信息查阅[http://redis.io/topics/replication](http://redis.io/topics/replication)。 想先前描述的那样,控制器定义服务如何运行。在这个例子中,我们需要决定服务如何发现其他pods。这个YAML将GET\_HOSTS\_FROM属性表示为DNS。您可以将其更改为使用yaml中的环境变量,但这会引入创建顺序依赖关系,因为需要运行服务才能定义环境变量。 redis-slave-controller.yaml文件 ``` 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: gcr.io/google_samples/gb-redisslave:v1 env: - name: GET_HOSTS_FROM value: dns # If your cluster config does not include a dns service, then to # instead access an environment variable to find the master # service's host, comment out the 'value: dns' line above, and # uncomment the line below. # value: env ports: - containerPort: 6379 ``` ## 启动Redis从节点控制器 在这种情况下,我们将会使用镜像kubernates/redis-slave:v2启动两个pod实例。它将通过DNS连接到redis-master。 ``` kubcetl create -f redis-slave-controller.yaml ``` 列出复制控制器 ``` kubectl get rc ``` # 5、Redis 从节点 Service 与前面一样,我们需要使我们的从节点能够被传入的请求访问。这是通过启动一个知道如何与redis-slave通信的服务来实现的。 因为我们有两个复制的pod,service将会在这两个pod之间提供负载均衡。 启动Redis从节点Service ``` kubectl create -f redis-slave-service.yaml ``` ``` kubectl get services ``` # 6、前端复制pod 数据服务启动后,现在我们可以部署web应用。部署web应用的方式和我们之前部署pod是一样的。 ## 启动前台 YAML定义了一个叫做frontend的service。它使用镜像 gcr.io/googlesamples/gb-frontend:v3 。这个复制控制器将会确保总有3个pod存在。 fronted-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: php-redis image: gcr.io/google_samples/gb-frontend:v3 env: - name: GET_HOSTS_FROM value: dns # If your cluster config does not include a dns service, then to # instead access environment variables to find service host # info, comment out the 'value: dns' line above, and uncomment the # line below. # value: env ports: - containerPort: 80 ``` ``` kubectl create -f fronted-controller.yaml ``` 列出控制器和pods ``` kubectl get rc ``` ``` kubectl get pods ``` ## PHP 代码 这个PHP代码使用HTTP和JSON与Redis通信。写操作请求redis-master,读操作请求redis-slave节点。 # 7、Guestbook 前端 Service 访问前端,我们需要启动一个service,配置代理。 ## 启动代理 YAML文件定义了一个NodePort的service。NodePort可以设置一个在整个集群都众所周知的端口。这类似于在Docker中的 -p 80:80。 在这里,我们定义我们的web app运行在80端口,但是我们在30080端口暴露服务。 fronted-service.yaml文件: ``` apiVersion: v1 kind: Service metadata: name: frontend labels: name: frontend spec: # if your cluster supports it, uncomment the following to automatically create # an external load-balanced IP for the frontend service. # type: LoadBalancer type: NodePort ports: # the port that this service should serve on - port: 80 nodePort: 30080 selector: name: frontend ``` ``` kubectl create -f fronted-service.yaml ``` ``` kubectl get services ``` 我们将会在将来的章节讨论NortPort。 # 8、访问Guestbook 前端 当所有的控制器和servies定义好,K8s将会把他们作为pod启动。一个pod可以根据正在发生的动作有不同的状态。例如,如果Docker镜像正在下载,pod将会是pending状态,因此它不能启动。一旦准备好,它的状态将会转变为运行中。 ## 查看Pod状态 你可以查看相应的状态,使用下面的命令: ``` kubectl get pods ``` ## 查看 NortPort 如果你没有分配一个都知道的NortPort,K8s会随机分配一个可用的端口。你可以使用kubectl找到这个已分配的NortPort。 ``` kubcetl describe service frontend | grep NodePort ``` ## 查看UI 一旦pod是运行状态,你可以通过端口30080查看UI。访问: [https://2886795308-30080-cykoria08.environments.katacoda.com](https://2886795308-30080-cykoria08.environments.katacoda.com/) 在背后,PHP服务通过DNS发现了Redis实例。现在你在K8s上部署了一个多层应用。