适合 Kubernetes 初学者的一些实战练习(二)

简介: 适合 Kubernetes 初学者的一些实战练习(二)

本系列的第一篇文章,我们学习了每一个 Kubernetes 从业者的实际工作中几乎都会使用的步骤:创建 Deployment 和 Service,同时通过实际例子讲解了 Pod 和 Service 绑定的实现方式,介绍了使用 Kubernetes Job 计算圆周率这种费时的操作。


本文作为 Kubernetes 学习系列的第二篇文章,我们继续学习 XX.

练习1 - 使用脚本在 Linux 服务器上自动安装 Kubernetes 的包管理器 Helm

Helm 之于 Kubernetes 好比 yum 之于 Red Hat Enterprise Linux,或者 apt-get 之于 Ubuntu.


Helm 是由 helm CLI 和 Tiller 组成,是典型的 Client/Server 应用。helm 运行于客户端,提供命令行界面;Tiller 应用运行于 Kubernetes 内部。

本练习使用一种全自动的做法,使用安装脚本自动安装。

(1) 自动下载安装脚本

curl https://raw.githubusercontent.com/helm/helm/master/scripts/get > get_helm.sh

打开脚本,可以看到 helm 安装的环境变量 HELM_INSTALL_DIR/usr/local/bin:

(2) chmod 700 get_helm.sh

./get_helm.sh:

(3) 执行 helm init, 看到 Happy Helming 消息,说明安装成功。

练习2 - 一个简单的例子理解 Kubernetes 的三种 IP 地址类型

很多 Kubernetes 的初学者对 Kubernetes 里面三种不同的 IP 地址和工作机制理解得不是很清楚。

本练习我们通过一个最简单的例子来学习。

用如下命令行创建一个基于 nginx 的 deployment:

kubectl run nginx --image=nginx:maxline

用 kubectl get deploy 查看成功生成的名为 nginx 的 deployment:

此时这个 deployment 里的 nginx pod 还无法对外界提供服务。

我们创建一个 service 让外界能够消费。使用命令行创建这样的一个 service:

kubectl expose deployment nginx --type=LoadBalancer --port=80 --target-port=80

type 的类型选择为 LoadBalancer, --port 指定的是 80 端口,意思是这个 service 对外界暴露出来的服务端口是 80,–target-port=80,这个端口是 pod 内部的 nginx docker 容器提供服务的工作端口,默认为 80。这里实际上建立了向外界开发的 80 端口同 nginx 容器内部端口的一个映射关系。

执行完毕后,我们调用下面的命令行,看到了创建的 service 的 Cluster IP 和 External IP.

其中 external IP 很好理解,这个 service 通过 external IP 加上我们前面介绍的被映射到 80 端口向外界提供服务:

浏览器里输入External IP http://35.241.173.27:80, 能成功访问 nginx 服务器的 index.html:

而我们通过 Service 的 Cluster IP 是无法访问这个 Service 提供的功能的。


我们知道 Kubernetes 里的所有 pod 都可以彼此通信,而不需要通过网络地址转换(Network Address Translation-NAT),所有的节点也可以与所有的 pod 通信。而 Service 的 Cluster IP,是一个内部的 IP 地址,专门用于同 Cluste r内部的节点或者 pod 通信。同外界通信,还是通过 External IP 进行。


接下来再试试 NodePort.

kubectl expose deployment nginx --type=NodePort --port=80 --target-port=80

注意看下图的 PORT 栏下面显示的类型为 NodePort 的端口:31375


这个端口号是 Kubernetes expose 命令自动生成的,范围在 30000 到 32767 之间。如果需要修改,可以编辑 api server 的配置文件:/etc/kubernetes/apiserver:

有了这个端口号,我们随便使用一个 node 的 IP 地址,后面拼接上 :31375 即是外部可以消费的完整地址。

使用命令行 kubectl get nodes -o wide, 在结果里选择任意节点的 External-IP,后面加上:31375:

测试:

http://146.148.23.183:31375/

测试通过。

接下来继续学习 Pod 的端口转发功能。


值得一提的是,有时我们出于测试的目的,需要一种简单的办法查看一个 pod 是否能正常提供服务。如果每次通过 kubectl 的方式创建 service 就太麻烦了。


本练习介绍一种简单的办法:pod的端口转发功能(port forward)。

比如我们想测试下图get pods返回的第一个pod的功能,名称为nginx-6f754dd4b9-74jdn:

执行命令行 kubectl port-forward pod/nginx-6f754dd4b9-74jdn 8080:80

看到提示信息 Forwarding from 127.0.0.1:8080 -> 80, 意思是把当前主机的 8080 端口映射到nginx pod 的 80 工作端口:

最后,就能够通过 localhost:8080 直接访问 nginx pod 提供的服务了:

练习3 - 使用 describe 命令进行 Kubernetes pod 错误排查

我有一个 pod 名叫 another,用 kubectl create 创建后发现过了 29 分钟,状态还是处于 ContainerCreating 阶段。

使用 kubectl describe 命令检查:

从错误消息发现是因为这个 pod attach volume 失败:

FailedAttachVolume 2m1s (x22 over 31m) attachdetach-controller AttachVolume.Attach failed for volume “pvc-c4d41f5c-e7ed-11e8-8726-fe6d42bf075f” : googleapi: Error 400: RESOURCE_IN_USE_BY_ANOTHER_RESOURCE - The disk resource ‘projects/sap-pi-coo-acdc-dev/zones/europe-west1-b/disks/shoot–k8s-train–shac-pvc-c4d41f5c-e7ed-11e8-8726-fe6d42bf075f’ is already being used by ‘projects/sap-pi-coo-acdc-dev/zones/europe-west1-b/instances/shoot–k8s-train–shacw46-worker-prvfv-z1-7844dc6744-ghd5m’

Warning FailedMount 31s (x14 over 29m) kubelet, shoot–k8s-train–shacw46-worker-prvfv-z1-7844dc6744-hhrmd Unable to mount volumes for pod “another_part-0110(13f15fa4-e819-11e8-8726-fe6d42bf075f)”: timeout expired waiting for volumes to attach or mount for pod “part-0110”/“another”. list of unmounted volumes=[content-storage]. list of unattached volumes=[content-storage default-token-6z5sk]

根据上面的错误消息顺藤摸瓜,查看这个 pod 的 yaml 文件,果然发现有一个 persistent volume 的 claim:

用命令 kubectl get pv, 发现当前所有的 persistent volume 都被占用了(BOUND状态):

解决方案有很多种,出于测试目的,我只是简单地将另一个同样声明了 nginx-pvc 作为PersistentVolumeClaim 的 pod 删除,然后这个名为 another 的 pod 状态就很快变成 Running 了:

describe 命令生成的日志里也能清楚的观察到这个成功 mount volume 的事件:

Normal SuccessfulAttachVolume 84s attachdetach-controller AttachVolume.Attach succeeded for volume “pvc-c4d41f5c-e7ed-11e8-8726-fe6d42bf075f

总结

继本系列第一部分 介绍了 Kubernetes 创建 Pod 和 Service 的基础操作,以及 Pod 和 Service 绑定的实现原理后,本文作为该系列的第二部分,分享了 Kubernetes 包管理器 Helm 的安装方式,以及 Kubernetes 三种 IP 类型,最后介绍了如何使用 describe 命令分析一个 Pod 不能启动的实际问题。


相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
4月前
|
Kubernetes 监控 调度
Kubernetes Pod调度:从基础到高级实战技巧
Kubernetes Pod调度:从基础到高级实战技巧
198 0
|
5月前
|
Kubernetes Perl 容器
k8s学习-ReplicationController 、ReplicaSet(工作原理、模板、实战)
k8s学习-ReplicationController 、ReplicaSet(工作原理、模板、实战)
39 0
|
5月前
|
Kubernetes Cloud Native 应用服务中间件
云原生|kubernetes 你真的学废了吗---实战k8s 一(jsonpath实战)
云原生|kubernetes 你真的学废了吗---实战k8s 一(jsonpath实战)
67 0
|
4月前
|
存储 Kubernetes 监控
Kubernetes快速进阶与实战:构建可靠的容器化应用平台
Kubernetes快速进阶与实战:构建可靠的容器化应用平台
99 0
|
4月前
|
存储 Kubernetes 安全
Kubernetes Pod配置:从基础到高级实战技巧
Kubernetes Pod配置:从基础到高级实战技巧
154 0
|
5月前
|
Kubernetes Cloud Native 应用服务中间件
云原生|kubernetes 你真的学废了吗---实战k8s 二(命令行创建各类资源)
云原生|kubernetes 你真的学废了吗---实战k8s 二(命令行创建各类资源)
79 1
|
5月前
|
存储 关系型数据库 MySQL
猿创征文|云原生|kubernetes实务---部署MySQL--实战(一)
猿创征文|云原生|kubernetes实务---部署MySQL--实战(一)
53 0
|
5月前
|
Kubernetes Cloud Native 应用服务中间件
【云原生】kubernetes学习之资源(对象)控制器概述---概念和实战(五)
【云原生】kubernetes学习之资源(对象)控制器概述---概念和实战(五)
22 0
|
5月前
|
存储 Kubernetes 安全
k8s学习-持久化存储(Volumes、hostPath、emptyDir、PV、PVC)详解与实战
k8s学习-持久化存储(Volumes、hostPath、emptyDir、PV、PVC)详解与实战
71 0
|
5月前
|
JSON Kubernetes 数据格式
k8s学习-kubectl命令常用选项详解与实战
k8s学习-kubectl命令常用选项详解与实战
61 0

推荐镜像

更多