# 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上部署了一个多层应用。
- 前言
- 安装minikube
- 启动一个单节点的Kubernetes集群
- 启动一个多节点的集群使用kubeadm
- 使用kubectl部署容器
- 使用YAML部署容器
- 在K8s上部署Guestbook(留言簿)示例
- K8s网络介绍
- 创建Ingress路由
- Liveness(存活探针)、Readiness(就绪探针)和健康检查
- 使用CRI-O和kubeadm开始
- 在K8s上运行一个有状态服务
- 管理K8s中的秘钥和密码
- 使用Kompose部署Docker Compose文件
- 在Kubernates上从源代码部署一个服务
- 使用Heptio Velero备份和恢复
- Helm包管理器
- 基本的K8s的可观察性(监控)
- 使用EFK记录日志
- 在K8s上安装Weave Scope