1 - 公开外部 IP 地址以访问集群中应用程序
此页面显示如何创建公开外部 IP 地址的 Kubernetes 服务对象。
Before you begin
- 安装 kubectl.
- 使用 Google Kubernetes Engine 或 Amazon Web Services 等云供应商创建 Kubernetes 集群。 本教程创建了一个外部负载均衡器, 需要云供应商。
- 配置
kubectl与 Kubernetes API 服务器通信。有关说明,请参阅云供应商文档。
Objectives
- 运行 Hello World 应用程序的五个实例。
- 创建一个公开外部 IP 地址的 Service 对象。
- 使用 Service 对象访问正在运行的应用程序。
为一个在五个 pod 中运行的应用程序创建服务
-
在集群中运行 Hello World 应用程序:
apiVersion: apps/v1 kind: Deployment metadata: labels: app.kubernetes.io/name: load-balancer-example name: hello-world spec: replicas: 5 selector: matchLabels: app.kubernetes.io/name: load-balancer-example template: metadata: labels: app.kubernetes.io/name: load-balancer-example spec: containers: - image: gcr.io/google-samples/node-hello:1.0 name: hello-world ports: - containerPort: 8080kubectl apply -f https://k8s.io/examples/service/load-balancer-example.yaml前面的命令创建一个 Deployment 对象和一个关联的 ReplicaSet 对象。 ReplicaSet 有五个 Pods, 每个都运行 Hello World 应用程序。
-
显示有关 Deployment 的信息:
kubectl get deployments hello-world kubectl describe deployments hello-world
-
显示有关 ReplicaSet 对象的信息:
kubectl get replicasets kubectl describe replicasets
-
创建公开 Deployment 的 Service 对象:
kubectl expose deployment hello-world --type=LoadBalancer --name=my-service
-
显示有关 Service 的信息:
kubectl get services my-service输出类似于:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-service LoadBalancer 10.3.245.137 104.198.205.71 8080/TCP 54s提示:
type=LoadBalancer服务由外部云服务提供商提供支持,本例中不包含此部分, 详细信息请参考此页提示:如果外部 IP 地址显示为 <pending>,请等待一分钟再次输入相同的命令。
-
显示有关 Service 的详细信息:
kubectl describe services my-service输出类似于:
Name: my-service Namespace: default Labels: app.kubernetes.io/name=load-balancer-example Annotations: <none> Selector: app.kubernetes.io/name=load-balancer-example Type: LoadBalancer IP: 10.3.245.137 LoadBalancer Ingress: 104.198.205.71 Port: <unset> 8080/TCP NodePort: <unset> 32377/TCP Endpoints: 10.0.0.6:8080,10.0.1.6:8080,10.0.1.7:8080 + 2 more... Session Affinity: None Events: <none>记下服务公开的外部 IP 地址(
LoadBalancer Ingress)。 在本例中,外部 IP 地址是 104.198.205.71。还要注意Port和NodePort的值。 在本例中,Port是 8080,NodePort是32377。
-
在前面的输出中,您可以看到服务有几个端点: 10.0.0.6:8080、10.0.1.6:8080、10.0.1.7:8080 和另外两个, 这些都是正在运行 Hello World 应用程序的 pod 的内部地址。 要验证这些是 pod 地址,请输入以下命令:
kubectl get pods --output=wide输出类似于:
NAME ... IP NODE hello-world-2895499144-1jaz9 ... 10.0.1.6 gke-cluster-1-default-pool-e0b8d269-1afc hello-world-2895499144-2e5uh ... 10.0.1.8 gke-cluster-1-default-pool-e0b8d269-1afc hello-world-2895499144-9m4h1 ... 10.0.0.6 gke-cluster-1-default-pool-e0b8d269-5v7a hello-world-2895499144-o4z13 ... 10.0.1.7 gke-cluster-1-default-pool-e0b8d269-1afc hello-world-2895499144-segjf ... 10.0.2.5 gke-cluster-1-default-pool-e0b8d269-cpuc
-
使用外部 IP 地址(
LoadBalancer Ingress)访问 Hello World 应用程序:curl http://<external-ip>:<port>其中
<external-ip>是您的服务的外部 IP 地址(LoadBalancer Ingress),<port>是您的服务描述中的port的值。 如果您正在使用 minikube,输入minikube service my-service将在浏览器中自动打开 Hello World 应用程序。成功请求的响应是一条问候消息:
Hello Kubernetes!
Cleaning up
要删除服务,请输入以下命令:
kubectl delete services my-service
要删除正在运行 Hello World 应用程序的 Deployment,ReplicaSet 和 Pod,请输入以下命令:
kubectl delete deployment hello-world
What's next
进一步了解将应用程序与服务连接。
2 - 示例:使用 Redis 部署 PHP 留言板应用程序
本教程向您展示如何使用 Kubernetes 和 Docker 构建和部署 一个简单的 (非面向生产的) 多层 web 应用程序。本例由以下组件组成:
- 单实例 Redis 以保存留言板条目
- 多个 web 前端实例
Objectives
- 启动 Redis 领导者(Leader)
- 启动两个 Redis 跟随者(Follower)
- 公开并查看前端服务
- 清理
Before you begin
你必须拥有一个 Kubernetes 的集群,同时你的 Kubernetes 集群必须带有 kubectl 命令行工具。 建议在至少有两个节点的集群上运行本教程,且这些节点不作为控制平面主机。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面任意一个 Kubernetes 工具构建:
Your Kubernetes server must be at or later than version v1.14. To check the version, enterkubectl version.
启动 Redis 数据库
留言板应用程序使用 Redis 存储数据。
创建 Redis Deployment
下面包含的清单文件指定了一个 Deployment 控制器,该控制器运行一个 Redis Pod 副本。
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-leader
labels:
app: redis
role: leader
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
role: leader
tier: backend
spec:
containers:
- name: leader
image: "docker.io/redis:6.0.5"
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 6379-
在下载清单文件的目录中启动终端窗口。
-
从
redis-leader-deployment.yaml文件中应用 Redis Deployment:kubectl apply -f https://k8s.io/examples/application/guestbook/redis-leader-deployment.yaml
-
查询 Pod 列表以验证 Redis Pod 是否正在运行:
kubectl get pods响应应该与此类似:
NAME READY STATUS RESTARTS AGE redis-leader-fb76b4755-xjr2n 1/1 Running 0 13s
-
运行以下命令查看 Redis Deployment 中的日志:
kubectl logs -f deployment/redis-leader
创建 Redis 领导者服务
留言板应用程序需要往 Redis 中写数据。因此,需要创建 Service 来转发 Redis Pod 的流量。Service 定义了访问 Pod 的策略。
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
apiVersion: v1
kind: Service
metadata:
name: redis-leader
labels:
app: redis
role: leader
tier: backend
spec:
ports:
- port: 6379
targetPort: 6379
selector:
app: redis
role: leader
tier: backend-
使用下面的
redis-leader-service.yaml文件创建 Redis的服务:kubectl apply -f https://k8s.io/examples/application/guestbook/redis-leader-service.yaml
-
查询服务列表验证 Redis 服务是否正在运行:
kubectl get service响应应该与此类似:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 1m redis-leader ClusterIP 10.103.78.24 <none> 6379/TCP 16s
redis-leader 的 Service,其中包含一组
与前面定义的标签匹配的标签,因此服务将网络流量路由到 Redis Pod 上。
设置 Redis 跟随者
尽管 Redis 领导者只有一个 Pod,你可以通过添加若干 Redis 跟随者来将其配置为高可用状态, 以满足流量需求。
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-follower
labels:
app: redis
role: follower
tier: backend
spec:
replicas: 2
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
role: follower
tier: backend
spec:
containers:
- name: follower
image: gcr.io/google_samples/gb-redis-follower:v2
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 6379-
应用下面的
redis-follower-deployment.yaml文件创建 Redis Deployment:kubectl apply -f https://k8s.io/examples/application/guestbook/redis-follower-deployment.yaml
-
通过查询 Pods 列表,验证两个 Redis 跟随者副本在运行:
kubectl get pods响应应该类似于这样:
NAME READY STATUS RESTARTS AGE redis-follower-dddfbdcc9-82sfr 1/1 Running 0 37s redis-follower-dddfbdcc9-qrt5k 1/1 Running 0 38s redis-leader-fb76b4755-xjr2n 1/1 Running 0 11m
创建 Redis 跟随者服务
Guestbook 应用需要与 Redis 跟随者通信以读取数据。 为了让 Redis 跟随者可被发现,你必须创建另一个 Service。
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
apiVersion: v1
kind: Service
metadata:
name: redis-follower
labels:
app: redis
role: follower
tier: backend
spec:
ports:
# the port that this service should serve on
- port: 6379
selector:
app: redis
role: follower
tier: backend-
应用如下所示
redis-follower-service.yaml文件中的 Redis Service:kubectl apply -f https://k8s.io/examples/application/guestbook/redis-follower-service.yaml
-
查询 Service 列表,验证 Redis 服务在运行:
kubectl get service响应应该类似于这样:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d19h redis-follower ClusterIP 10.110.162.42 <none> 6379/TCP 9s redis-leader ClusterIP 10.103.78.24 <none> 6379/TCP 6m10s
清单文件创建了一个名为 redis-follower 的 Service,该 Service
具有一些与之前所定义的标签相匹配的标签,因此该 Service 能够将网络流量
路由到 Redis Pod 之上。
设置并公开留言板前端
现在你有了一个为 Guestbook 应用配置的 Redis 存储处于运行状态, 接下来可以启动 Guestbook 的 Web 服务器了。 与 Redis 跟随者类似,前端也是使用 Kubernetes Deployment 来部署的。
Guestbook 应用使用 PHP 前端。该前端被配置成与后端的 Redis 跟随者或者 领导者服务通信,具体选择哪个服务取决于请求是读操作还是写操作。 前端对外暴露一个 JSON 接口,并提供基于 jQuery-Ajax 的用户体验。
创建 Guestbook 前端 Deployment
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 3
selector:
matchLabels:
app: guestbook
tier: frontend
template:
metadata:
labels:
app: guestbook
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v5
env:
- name: GET_HOSTS_FROM
value: "dns"
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 80-
应用来自
frontend-deployment.yaml文件的前端 Deployment:kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml
-
查询 Pod 列表,验证三个前端副本正在运行:
kubectl get pods -l app=guestbook -l tier=frontend响应应该与此类似:
NAME READY STATUS RESTARTS AGE frontend-85595f5bf9-5tqhb 1/1 Running 0 47s frontend-85595f5bf9-qbzwm 1/1 Running 0 47s frontend-85595f5bf9-zchwc 1/1 Running 0 47s
创建前端服务
应用的 Redis 服务只能在 Kubernetes 集群中访问,因为服务的默认类型是
ClusterIP。
ClusterIP 为服务指向的 Pod 集提供一个 IP 地址。这个 IP 地址只能在集群中访问。
如果你希望访客能够访问你的 Guestbook,你必须将前端服务配置为外部可见的,
以便客户端可以从 Kubernetes 集群之外请求服务。
然而即便使用了 ClusterIP,Kubernetes 用户仍可以通过
kubectl port-forward 访问服务。
type: LoadBalancer。
# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
apiVersion: v1
kind: Service
metadata:
name: frontend
labels:
app: guestbook
tier: 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: LoadBalancer
ports:
# the port that this service should serve on
- port: 80
selector:
app: guestbook
tier: frontend-
应用来自
frontend-service.yaml文件中的前端服务:kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-service.yaml
-
查询 Service 列表以验证前端服务正在运行:
kubectl get services响应应该与此类似:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE frontend ClusterIP 10.97.28.230 <none> 80/TCP 19s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d19h redis-follower ClusterIP 10.110.162.42 <none> 6379/TCP 5m48s redis-leader ClusterIP 10.103.78.24 <none> 6379/TCP 11m
通过 kubectl port-forward 查看前端服务
-
运行以下命令将本机的
8080端口转发到服务的80端口。kubectl port-forward svc/frontend 8080:80响应应该与此类似:
Forwarding from 127.0.0.1:8080 -> 80 Forwarding from [::1]:8080 -> 80
- 在浏览器中加载 http://localhost:8080 页面以查看 Guestbook。
通过 LoadBalancer 查看前端服务
如果你部署了 frontend-service.yaml,需要找到用来查看 Guestbook 的
IP 地址。
-
运行以下命令以获取前端服务的 IP 地址。
kubectl get service frontend响应应该与此类似:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE frontend LoadBalancer 10.51.242.136 109.197.92.229 80:32372/TCP 1m
- 复制这里的外部 IP 地址,然后在浏览器中加载页面以查看留言板。
尝试通过输入消息并点击 Submit 来添加一些留言板条目。 你所输入的消息会在前端显示。这一消息表明数据被通过你 之前所创建的 Service 添加到 Redis 存储中。
扩展 Web 前端
你可以根据需要执行伸缩操作,这是因为服务器本身被定义为使用一个 Deployment 控制器的 Service。
-
运行以下命令扩展前端 Pod 的数量:
kubectl scale deployment frontend --replicas=5
-
查询 Pod 列表验证正在运行的前端 Pod 的数量:
kubectl get pods响应应该类似于这样:
NAME READY STATUS RESTARTS AGE frontend-85595f5bf9-5df5m 1/1 Running 0 83s frontend-85595f5bf9-7zmg5 1/1 Running 0 83s frontend-85595f5bf9-cpskg 1/1 Running 0 15m frontend-85595f5bf9-l2l54 1/1 Running 0 14m frontend-85595f5bf9-l9c8z 1/1 Running 0 14m redis-follower-dddfbdcc9-82sfr 1/1 Running 0 97m redis-follower-dddfbdcc9-qrt5k 1/1 Running 0 97m redis-leader-fb76b4755-xjr2n 1/1 Running 0 108m
-
运行以下命令缩小前端 Pod 的数量:
kubectl scale deployment frontend --replicas=2
-
查询 Pod 列表验证正在运行的前端 Pod 的数量:
kubectl get pods响应应该类似于这样:
NAME READY STATUS RESTARTS AGE frontend-85595f5bf9-cpskg 1/1 Running 0 16m frontend-85595f5bf9-l9c8z 1/1 Running 0 15m redis-follower-dddfbdcc9-82sfr 1/1 Running 0 98m redis-follower-dddfbdcc9-qrt5k 1/1 Running 0 98m redis-leader-fb76b4755-xjr2n 1/1 Running 0 109m
Cleaning up
删除 Deployments 和服务还会删除正在运行的 Pod。 使用标签用一个命令删除多个资源。
-
运行以下命令以删除所有 Pod,Deployments 和 Services。
kubectl delete deployment -l app=redis kubectl delete service -l app=redis kubectl delete deployment frontend kubectl delete service frontend响应应该是:
deployment.apps "redis-follower" deleted deployment.apps "redis-leader" deleted deployment.apps "frontend" deleted service "frontend" deleted
-
查询 Pod 列表,确认没有 Pod 在运行:
kubectl get pods响应应该是:
No resources found in default namespace.
What's next
- 完成 Kubernetes 基础 交互式教程
- 使用 Kubernetes 创建一个博客,使用 MySQL 和 Wordpress 的持久卷
- 进一步阅读连接应用程序
- 进一步阅读管理资源