在 GCP 上使用 Kubernetes 指南
1. 引言
Google Cloud Platform (GCP) 提供了名为 Google Kubernetes Engine (GKE) 的托管式 Kubernetes 服务。GKE 底层使用了一些 GCP 组件,如虚拟专用云 (VPC)、虚拟机实例、持久磁盘 (PD)、防火墙规则和负载均衡器等。
2. 安装 kubectl 命令
若要控制 GKE 上的 Kubernetes 集群,可使用
kubectl
命令,该命令包含在 Cloud SDK 中。若尚未在机器上安装
kubectl
,可通过以下命令进行安装:
$ gcloud components install kubectl
3. 在 GKE 上设置第一个 Kubernetes 集群
使用
gcloud
命令可在 GKE 上设置 Kubernetes 集群,设置时需指定多个参数来确定配置,其中“network”是重要参数之一,需指定要部署的 VPC 和子网。尽管 GKE 支持多区域部署,但至少要为 Kubernetes 主节点指定一个区域。以下是启动 GKE 集群所需的参数:
| 参数 | 描述 | 值 |
| ---- | ---- | ---- |
| –cluster-version | 指定 Kubernetes 版本 | 1.6.7 |
| –machine-type | Kubernetes 节点的虚拟机实例类型 | f1-micro |
| –num-nodes | Kubernetes 节点的初始数量 | 3 |
| –network | 指定 GCP VPC | my-custom-network |
| –subnetwork | 若 VPC 为自定义模式,指定 GCP 子网 | subnet-c |
| –zone | 指定单个区域 | asia-northeast1-a |
| –tags | 分配给 Kubernetes 节点的网络标签 | private |
启动集群的命令如下:
$ gcloud container clusters create my-k8s-cluster --cluster-version 1.6.7 --machine-type f1-micro --num-nodes 3 --network my-custom-network --subnetwork subnet-c --zone asia-northeast1-a --tags private
创建完成后,可使用以下命令检查节点状态:
$ kubectl get nodes
由于指定了
--tags private
选项,Kubernetes 节点虚拟机实例会有“private”网络标签,因此无法从公共互联网进行 SSH 或 HTTP 访问,但可从具有公共网络标签的其他虚拟机实例进行 ping 和 SSH 操作。
当所有节点准备就绪后,可通过以下步骤访问默认安装的 Kubernetes UI:
1. 在机器上运行
kubectl proxy
命令,将绑定到
127.0.0.1:8001
:
$ kubectl proxy
-
使用机器上的 Web 浏览器访问
http://127.0.0.1:8001/ui/。
4. 节点池管理
4.1 调整节点数量
启动 Kubernetes 集群时,可使用
--num-nodes
选项指定节点数量。GKE 将 Kubernetes 节点作为节点池进行管理,这意味着可以管理附加到 Kubernetes 集群的一个或多个节点池。若需要添加或删除节点,可使用以下命令将节点数量从 3 调整为 5:
$ gcloud container clusters resize my-k8s-cluster --size 5 --zone asia-northeast1-a
几分钟后,可使用以下命令查看新增节点:
$ kubectl get nodes
4.2 扩展节点容量
增加节点数量有助于扩展节点容量,但如果单个容器需要的内存超过 0.6GB(
f1-micro
实例类型仅有 0.6GB 内存),则需进行扩展操作,即添加更大规格的虚拟机实例类型。可通过添加新的节点池来实现,例如添加一个包含两个
g1-small
(1.7GB 内存)虚拟机实例类型的新节点池:
$ gcloud container node-pools create large-mem-pool --cluster my-k8s-cluster --machine-type g1-small --num-nodes 2 --tags private --zone asia-northeast1-a
添加完成后,可使用以下命令查看节点:
$ kubectl get nodes
4.3 节点选择器的使用
由于较大的硬件类型,Kubernetes 调度器可能会优先将 Pod 部署到
large-mem-pool
节点池。若想保留
large-mem-pool
节点以满足大型应用(如 Java 应用)对大堆内存的需求,可使用 Kubernetes 标签
beta.kubernetes.io/instance-type
来区分节点实例类型,并使用
nodeSelector
为 Pod 指定所需的节点。例如,以下
nodeSelector
参数将强制
nginx
应用使用
f1-micro
节点:
$ cat nginx-pod-selector.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
nodeSelector:
beta.kubernetes.io/instance-type: f1-micro
部署 Pod 的命令如下:
$ kubectl create -f nginx-pod-selector.yml
查看 Pod 部署情况:
$ kubectl get pods nginx -o wide
4.4 删除节点池
若不再需要某个节点池,可使用以下命令删除
default-pool
(包含 5 个
f1-micro
实例):
$ gcloud container node-pools list --cluster my-k8s-cluster --zone asia-northeast1-a
$ gcloud container node-pools delete default-pool --cluster my-k8s-cluster --zone asia-northeast1-a
几分钟后,可使用以下命令查看节点:
$ kubectl get nodes
5. 多区域集群
5.1 多区域集群的优势
前面的操作均在单个区域(
asia-northeast1-a
)进行,若该区域出现故障,集群将无法正常运行。为避免区域故障,可考虑设置多区域集群。
5.2 创建多区域集群
GKE 支持多区域集群,允许在多个区域启动 Kubernetes 节点,但需在同一区域内。创建新集群时,只需添加
--additional-zones
参数即可。例如,重新创建一个包含
asia-northeast1-a
、
asia-northeast1-b
和
asia-northeast1-c
三个区域的集群:
$ gcloud container clusters delete my-k8s-cluster --zone asia-northeast1-a
$ gcloud container clusters create my-k8s-cluster --cluster-version 1.6.7 --machine-type f1-micro --num-nodes 2 --network my-custom-network --subnetwork subnet-c --zone asia-northeast1-a --tags private --additional-zones asia-northeast1-b,asia-northeast1-c
创建完成后,可使用以下命令查看节点:
$ kubectl get nodes
可使用 Kubernetes 标签
failure-domain.beta.kubernetes.io/zone
区分节点区域,从而指定要部署 Pod 的区域。
6. 集群升级
6.1 查看支持的 Kubernetes 版本
Kubernetes 项目更新频繁,大约每三个月会有一个新版本发布。GKE 会及时添加对新版本的支持,可使用以下命令查看 GKE 支持的 Kubernetes 版本:
$ gcloud container get-server-config
6.2 升级集群
假设之前安装的版本是 1.6.7,现在要更新到 1.7.3。首先需升级主节点:
$ gcloud container clusters upgrade my-k8s-cluster --zone asia-northeast1-a --cluster-version 1.7.3 --master
主节点升级完成后,可使用以下命令验证:
$ gcloud container clusters list --zone asia-northeast1-a
然后升级所有节点:
$ gcloud container clusters upgrade my-k8s-cluster --zone asia-northeast1-a --cluster-version 1.7.3
GKE 会对每个节点进行滚动升级,升级过程如下:
1. 从集群中注销目标节点。
2. 删除旧的虚拟机实例。
3. 配置新的虚拟机实例。
4. 使用 1.7.3 版本设置节点。
5. 注册到主节点。
升级过程中,可通过以下命令查看节点状态:
$ kubectl get nodes
graph LR
A[开始] --> B[升级主节点]
B --> C[验证主节点升级]
C --> D[升级所有节点]
D --> E[查看节点升级状态]
E --> F[结束]
7. Kubernetes 云提供商
GKE 集成了 Kubernetes 云提供商,与 GCP 基础设施深度集成,如通过 VPC 路由实现覆盖网络、通过持久磁盘实现存储类、通过 L4 负载均衡器实现服务等,其中通过 L7 负载均衡器实现的 Ingress 功能尤为出色。
7.1 存储类(StorageClass)
GKE 默认设置了使用持久磁盘的存储类:
$ kubectl get storageclass
$ kubectl describe storageclass standard
创建持久卷声明(Persistent Volume Claim)时,会自动分配 GCP 持久磁盘作为 Kubernetes 持久卷。以下是创建持久卷声明的示例:
$ cat pvc-gke.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-gke-1
spec:
storageClassName: "standard"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
创建持久卷声明的命令如下:
$ kubectl create -f pvc-gke.yml
查看持久卷:
$ kubectl get pv
通过
gcloud
命令查看磁盘:
$ gcloud compute disks list
7.2 L4 负载均衡器
GKE 支持为 Kubernetes 服务使用 L4 负载均衡器,只需将
Service.spec.type
指定为
LoadBalancer
,GKE 会自动设置和配置 L4 负载均衡器。以下是部署
grafana
服务并使用 L4 负载均衡器的示例:
$ cat grafana.yml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: grafana
spec:
replicas: 1
template:
metadata:
labels:
run: grafana
spec:
containers:
- image: grafana/grafana
name: grafana
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: grafana
spec:
ports:
- port: 80
targetPort: 3000
type: LoadBalancer
selector:
run: grafana
部署命令如下:
$ kubectl create -f grafana.yml
查看 L4 负载均衡器的 IP 地址:
$ kubectl get svc grafana
验证是否可通过 GCP L4 负载均衡器访问:
$ curl -I 35.189.128.32
7.3 L7 负载均衡器(Ingress)
GKE 支持 Kubernetes Ingress,可设置 GCP L7 负载均衡器根据 URL 将 HTTP 请求分发到目标服务。需先设置一个或多个 NodePort 服务,然后创建 Ingress 规则指向这些服务,Kubernetes 会自动创建和配置防火墙规则、健康检查、后端服务、转发规则和 URL 映射。
以下是创建
nginx
和
Tomcat
服务并使用 Ingress 的示例:
$ cat nginx-tomcat-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-tomcat-ingress
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: nginx
servicePort: 80
- path: /examples
backend:
serviceName: tomcat
servicePort: 8080
- path: /examples/*
backend:
serviceName: tomcat
servicePort: 8080
创建 Ingress 的命令如下:
$ kubectl create -f nginx-tomcat-ingress.yaml
大约 10 分钟后,可使用以下命令查看 Ingress 状态:
$ kubectl get ing
为 L7 负载均衡器分配静态 IP 地址是最佳实践,可通过以下步骤实现:
1. 分配静态 IP:
$ gcloud compute addresses create my-nginx-tomcat --global
- 查看分配的 IP 地址:
$ gcloud compute addresses list
- 更新 Ingress 设置,添加注解以关联 GCP 静态 IP 地址:
$ cat nginx-tomcat-static-ip-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-tomcat-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: my-nginx-tomcat
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: nginx
servicePort: 80
- path: /examples
backend:
serviceName: tomcat
servicePort: 8080
- path: /examples/*
backend:
serviceName: tomcat
servicePort: 8080
graph LR
A[创建 NodePort 服务] --> B[创建 Ingress 规则]
B --> C[Kubernetes 自动配置组件]
C --> D[查看 Ingress 状态]
D --> E[分配静态 IP 地址]
E --> F[更新 Ingress 设置关联静态 IP]
综上所述,在 GCP 上使用 Kubernetes 可借助 GKE 的强大功能实现高效的容器编排和管理,通过合理设置集群、管理节点池、升级集群以及利用云提供商的特性,可满足不同场景下的应用部署需求。
8. 网络安全与访问控制
8.1 网络标签的影响
在前面设置集群时,我们使用了
--tags private
选项为 Kubernetes 节点虚拟机实例添加了“private”网络标签。这一设置限制了从公共互联网进行 SSH 和 HTTP 访问,但允许从具有公共网络标签的其他虚拟机实例进行 ping 和 SSH 操作。这种访问控制机制有助于增强集群的安全性,防止未经授权的外部访问。
8.2 防火墙规则的自动配置
当使用 GKE 的 L4 和 L7 负载均衡器时,Kubernetes 云提供商会自动创建相应的防火墙规则。例如,在使用 L4 负载均衡器为
grafana
服务时,防火墙规则会自动配置,允许外部流量通过负载均衡器访问服务。这简化了网络安全配置过程,减少了手动配置防火墙规则的工作量。
8.3 自定义访问控制
除了使用网络标签和自动配置的防火墙规则,还可以根据具体需求自定义访问控制策略。例如,可以使用 Kubernetes 的 NetworkPolicy 资源来定义 Pod 之间的网络通信规则。以下是一个简单的 NetworkPolicy 示例,允许
nginx
Pod 接收来自同一命名空间内所有 Pod 的流量:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: nginx-allow-all
spec:
podSelector:
matchLabels:
app: nginx
ingress:
- from:
- podSelector: {}
应用该 NetworkPolicy 的命令如下:
$ kubectl create -f nginx-network-policy.yml
9. 资源管理与优化
9.1 节点资源的合理分配
在管理 Kubernetes 集群时,合理分配节点资源至关重要。通过使用不同规格的节点池(如
f1-micro
和
g1-small
),可以根据应用的资源需求进行灵活配置。例如,对于内存需求较小的应用,可以使用
f1-micro
节点;对于内存需求较大的应用,则可以使用
g1-small
节点。同时,使用
nodeSelector
可以确保应用被调度到合适的节点上,提高资源利用率。
9.2 资源请求与限制
在定义 Pod 时,可以通过
resources
字段设置容器的资源请求和限制。以下是一个
nginx
Pod 的示例,设置了 100m CPU 和 200Mi 内存的请求和限制:
apiVersion: v1
kind: Pod
metadata:
name: nginx-resource
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: "100m"
memory: "200Mi"
limits:
cpu: "100m"
memory: "200Mi"
创建该 Pod 的命令如下:
$ kubectl create -f nginx-resource.yml
9.3 集群资源监控
为了确保集群资源的有效利用,需要对集群资源进行监控。可以使用 Prometheus 和 Grafana 等工具来收集和可视化集群的资源使用情况。以下是一个简单的步骤:
1. 安装 Prometheus 和 Grafana:可以使用 Helm 等工具进行安装。
2. 配置 Prometheus 收集 Kubernetes 指标:通过配置 Prometheus 的
scrape_configs
,可以指定要收集的 Kubernetes 资源指标。
3. 在 Grafana 中创建仪表盘:根据收集的指标,创建可视化的仪表盘,展示集群的 CPU、内存、磁盘等资源使用情况。
10. 故障排除与高可用性
10.1 节点状态检查
在集群运行过程中,可能会遇到节点故障或异常情况。可以使用
kubectl get nodes
命令检查节点状态。如果节点状态显示为
NotReady
或
SchedulingDisabled
,则需要进一步排查问题。常见的原因包括节点资源不足、网络故障、节点组件故障等。
10.2 Pod 故障排查
当 Pod 出现故障时,可以使用
kubectl describe pod <pod-name>
命令查看 Pod 的详细信息,包括事件记录、容器状态等。如果容器崩溃或重启次数过多,可以使用
kubectl logs <pod-name> <container-name>
命令查看容器的日志,找出故障原因。
10.3 多区域集群的高可用性
设置多区域集群可以提高集群的高可用性,避免因单个区域故障导致集群不可用。在创建多区域集群时,GKE 会自动在多个区域部署节点,确保即使某个区域出现问题,集群仍能正常运行。同时,可以使用 Kubernetes 的
failure-domain.beta.kubernetes.io/zone
标签来指定 Pod 部署的区域,进一步提高应用的可用性。
graph LR
A[节点状态检查] --> B{节点是否正常?}
B -- 是 --> C[继续监控]
B -- 否 --> D[排查节点故障]
E[Pod 状态检查] --> F{Pod 是否正常?}
F -- 是 --> C
F -- 否 --> G[排查 Pod 故障]
H[多区域集群] --> I[提高高可用性]
11. 总结与最佳实践
11.1 总结
在 GCP 上使用 Kubernetes 可以借助 GKE 的托管服务实现高效的容器编排和管理。通过设置集群、管理节点池、升级集群、利用云提供商的特性以及进行资源管理和优化,可以满足不同场景下的应用部署需求。同时,合理的网络安全配置和故障排除机制可以确保集群的安全性和高可用性。
11.2 最佳实践
- 集群规划 :在创建集群之前,根据应用的资源需求和可用性要求,合理规划节点池的规格和数量,选择合适的区域和网络配置。
-
资源管理
:使用
nodeSelector和资源请求/限制来确保应用被调度到合适的节点上,并合理利用集群资源。 - 安全配置 :使用网络标签、防火墙规则和 NetworkPolicy 等机制,加强集群的网络安全,防止未经授权的访问。
- 高可用性 :设置多区域集群,利用 Kubernetes 的标签和调度机制,提高应用的可用性。
- 监控与故障排查 :使用 Prometheus 和 Grafana 等工具监控集群资源使用情况,及时发现和解决节点和 Pod 故障。
通过遵循这些最佳实践,可以在 GCP 上构建稳定、高效、安全的 Kubernetes 集群,为应用的部署和运行提供可靠的基础。
| 最佳实践 | 描述 |
|---|---|
| 集群规划 | 根据应用需求合理规划节点池和网络配置 |
| 资源管理 |
使用
nodeSelector
和资源请求/限制
|
| 安全配置 | 利用网络标签、防火墙规则和 NetworkPolicy |
| 高可用性 | 设置多区域集群并合理调度 Pod |
| 监控与故障排查 | 使用监控工具及时发现和解决问题 |
超级会员免费看
1458

被折叠的 条评论
为什么被折叠?



