设置一个用于测试服务
用于测试的服务是一个回显的小程序,get方法返回hello信息,post方法计算数组的和。
router := gin.Default()
router.GET("/test", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "Hello, this is your test service!"})
})
router.POST("/test", func(ctx *gin.Context) {
var payload PayLoad
if err := ctx.ShouldBindJSON(&payload); err != nil {
ctx.JSON(400, gin.H{"error": err.Error() + "payload like {datas:[1,2,3]}"})
return
}
sum := 0
for _, v := range payload.Datas {
sum += v
}
ctx.JSON(200, gin.H{"sum": sum})
})
router.Run(addr)
将服务部署到pod中,如下yaml。其中指定端口名称为test-svc-port(超过15个字符会报错),因为根据Service | Kubernetes的描述如果在pod中定义了端口的名称,那么后面可以在Service的targetPort中直接引用,可以避免端口变更时Service的改动。
apiVersion: apps/v1
kind: Deployment
metadata:
name: testservice
spec:
selector:
matchLabels:
app: testservice
replicas: 1
template:
metadata:
labels:
app: testservice
spec:
containers:
- name: testservice
image: myrepo/testservice
command: ["/app/test-service"]
ports:
- containerPort: 8080
name: test-svc-port
关于deployment对象中的spec/template/spec/containers/ports
ports是一个数组,列出了容器暴露的端口。在这里填写暴露端口只是给系统提供更详细的容器网络信息,不填写端口并不会影响容器暴露端口。
创建Service
在Service对象中用selector来指定将请求路由到testservice的pod上,在ports中描述Service上的端口和pod端口的对应信息,如果不指定targetPort,其值默认为port的值。最终完成Service对象如下。
apiVersion: v1
kind: Service
metadata:
name: testservice
spec:
selector:
app: testservice
ports:
- port: 8080
targetPort: test-svc-port
从内部访问Service
创建Service后检查Service状态:
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 18d
testservice ClusterIP 10.100.52.191 <none> 8080/TCP 35m
创建一个pod,在pod中访问已经创建好的Service。
$ kubectl run curl-test --rm -it --image=curlimages/curl:latest -- /bin/sh
If you don't see a command prompt, try pressing enter.
~ $ nslookup testservice
Server: 10.96.0.10
Address: 10.96.0.10:53
Name: testservice.default.svc.cluster.local
Address: 10.100.52.191
~ $ curl http://testservice:8080/test
{"message":"Hello, this is your test service!"}
~ $
~ $ curl http://testservice:8080/test -d '{"datas":[1,2,3,4,5]}'
{"sum":15}