四、定制化用法
1、NodeName
默认情况下,Kube-scheduler 将预期的 Pod 资源调度到最佳的 Node 上,但是有些特殊测试场景下,我们需要把不同的应用部署到不同的 Node 上,满足这种绑定很简单,只需要在 Deployment yaml 文件中添加 nodeName 配置即可,然后重新部署 Deployment,Pod 就会分配到指定的 Node 上。
spec:
containers:
- image:
imagePullPolicy: Always
name:
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
nodeName: x.x.x.x
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
2、SecurityContext
在测试过程中,我们会模拟组件与组件之间的网络异常,会使用到 tc 和 iptable 命令,默认情况下,容器没有开放执行网络控制的权限,需要手动添加 securityContext 配置到 deploy yaml 文件中,然后重新部署 Deployment,就可以执行 tc 和 iptable 指令了。
spec:
containers:
- image:
imagePullPolicy: Always
name: tsp-worker
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
3、Volumes
默认情况下容器中的磁盘文件是非持久化的,对于运行在容器中的应用来说面临两个问题,第一:当容器挂掉 kubelet 将重启它时,文件将会丢失;第二:当 Pod 中同时运行多个容器,容器之间需要共享文件时,这两种情况下我们就要用到 Kubernetes 的 Volume。
在 deploy yaml 文件中添加 volumes 配置:
spec:
containers:
- image:
imagePullPolicy: Always
name: etcd
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /default.etcd //容器内的目录
name: etcd-volume
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- hostPath:
path: /data/etcd //挂载到宿主机上的目录
type: Directory
name: etcd-volume
其中 type 有很多种类型,可以根据实际情况选择,配置添加以后,重新部署 Deployment,然后写一条数据到文件里,再删除 Pod,Pod 启动好以后再查询这个数据,如果存在,则说明持久化成功。
4、Ingress
上面说了 Service 的使用,Service 是 Kubernetes 暴露 http 服务的默认方式,其中 NodePort 类型可以将 http 服务暴露在宿主机的端口上,以便外部可以访问,其优点是结构简单,容易理解,其缺点是一个 app 需要占用一个主机端口,端口缺乏管理,L4 转发,无法根据 http header 和 path 进行路由转发。Ingress 是在 Service 之前加了一层,增加了7层识别能力,可以根据 http header,path 进行路由转发。Ingress 的实现由 Ingress Controller 和 Ingress 两部分组成,为了使 Ingress 正常工作,集群中必须运行 Ingress Controller,Ingress Controller 是流量的入口,是一个实体软件,一般是 nginx 和 haproxy,Ingress 则描述具体的路由规则。
一个简单的 ingress.yaml 文件定义如下:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: yz7-ingress
namespace: yz7
spec:
rules:
- host: yz7-test-control.s.yz.com
http:
paths:
- backend:
serviceName: yz7-cluster
servicePort: 8888
path: /
创建 Ingress:
kubectl create -f ingress.yaml
查看 Ingress:
kubectl get ing -n yz7 -o wide
NAME HOSTS ADDRESS PORTS AGE
yz7-ingress x.x.x.x x.x.x.x 80 25d
然后通过 HOSTS 或者 ADDRESS 就可以访问该应用了。Ingress 的功能远不止这些,还可以进行单个 Ingress 的 timeout、登录验证、cros、请求速率 limit、rewrite 规则、ssl 等等设置,如需进一步了解 Ingress,需要查阅资料。
5、DNS
前面我们讲解了 Service 的用法,我们可以通过 Service 生成的 ClusterIP(VIP) 来访问 Pod 提供的服务,但是在实际工作中存在一个问题:VIP 发生变化怎么办?
更理想的方案是:直接使用 Service 的名称,因为 Service 的名称不会变化,我们不需要去关心分配的 ClusterIP 的地址,因为这个地址并不是固定不变的,名字和 ip 之间的转换就是 DNS 系统的功能,因此 kubernetes 提供了 DNS 方法来解决这个问题。
DNS 服务不是独立的系统服务,而是一种 addon ,作为插件来安装的,现在比较推荐的两个插件是Kube-dns 和 CoreDNS,插件的安装方式和配置可以参考其他文档,内容有点多,就不在这儿详解。
通过域名访问应用的方式如下:
普通的 Service,会生成 servicename.namespace.svc.cluster.local 的域名,解析到 Service 对应的 ClusterIP 上,在 Pod 之间的调用可以简写成 servicename.namespace,如果处于同一个命名空间下面,甚至可以只写成 servicename 即可访问;
Headless Service,就是把 clusterIP 设置为 None 的服务,会被解析为指定 Pod 的 IP 列表,通过 podname.servicename.namespace.svc.cluster.local 访问到具体的某一个 Pod。
五、结束语
到目前为止,有赞 PaaS 所有产品的集成测试环境已经从 VM 迁移到了 K8S,留了几台 VM 做备用,不仅提高了集成速度,而且降低了公司成本。但是 K8S 博大精深,还有很多知识点需要去学习,路漫漫其修远兮,吾将上下而求索。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理