博客 > 术业专攻> 云计算> kubernetes> k8s基本使用入门-了解Service 2019年08月29日 11:24:42
现在准备了两个pod的yaml文件。
pod_nginx.yml
[root@master services]$cat pod_nginx.yml apiVersion: v1 kind: Pod metadata: name: nginx-pod labels: app: nginx spec: containers: - name: nginx-container image: nginx ports: - name: nginx-port containerPort: 80
pod_busybox.yml
[root@master services]$cat pod_busybox.yml apiVersion: v1 kind: Pod metadata: name: busybox-pod labels: app: busybox spec: containers: - name: busybox-container image: busybox command: - sleep - "360000"
启动。
kubectl create -f pod_nginx.yml kubectl create -f pod_busybox.yml
然后看一下两个pod的ip:
[root@master services]$kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE busybox-pod 1/1 Running 0 15m 10.244.1.58 node nginx-pod 1/1 Running 0 15m 10.244.1.59 node
此时,这两个生成的ip,在集群当中任一节点里,都是可以畅通访问的。
详细的介绍,可以看官方的文档介绍:https://kubernetes.io/docs/concepts/cluster-administration/networking/
现在可以思考一个问题:为什么不直接通过pod来作为k8s的管理单位进行管理呢?
之于如上所提问题,那么就引入了service这个概念。
k8s分配给Service一个固定IP,这是一个虚拟IP(也称为ClusterIP),并不是一个真实存在的IP,而是由k8s虚拟出来的。虚拟IP的范围通过k8s API Server的启动参数 –service-cluster-ip-range=19.254.0.0/16配置;
虚拟IP属于k8s内部的虚拟网络,外部是寻址不到的。在k8s系统中,实际上是由k8s Proxy组件负责实现虚拟IP路由和转发的,所以k8s Node中都必须运行了k8s Proxy,从而在容器覆盖网络之上又实现了k8s层级的虚拟转发网络。
服务代理:
在逻辑层面上,Service被认为是真实应用的抽象,每一个Service关联着一系列的Pod。在物理层面上,Service有事真实应用的代理服务器,对外表现为一个单一访问入口,通过k8s Proxy转发请求到Service关联的Pod。
Service同样是根据Label Selector来刷选Pod进行关联的,实际上k8s在Service和Pod之间通过Endpoint衔接,Endpoints同Service关联的Pod;相对应,可以认为是Service的服务代理后端,k8s会根据Service关联到Pod的PodIP信息组合成一个Endpoints。
4,service几种类型。
kubernetes 默认就是这种方式,是集群内部访问的方式,外部的话,是无法访问的。
spec: clusterIP: 10.0.0.1 ports: - name: http
NodePort方式主要通过节点IP加端口的形式暴露端口,是最常见也常用的方式,比较推荐。
apiVersion: v1 kind: Service metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"creationTimestamp":"2017-05-24T06:38:16Z","labels":{"kubernetes.io/name":"heapster","plugin":"heapster"},"name":"heapster","namespace":"kube-system","resourceVersion":"173906247","selfLink":"/api/v1/namespaces/kube-system/services/heapster","uid":"91470fbb-404b-11e7-ba41-5254eec04736"},"spec":{"clusterIP":"10.3.129.117","externalTrafficPolicy":"Cluster","ports":[{"nodePort":30003,"port":80,"protocol":"TCP","targetPort":8082}],"selector":{"k8s-app":"heapster"},"sessionAffinity":"None","type":"NodePort"},"status":{"loadBalancer":{}}} creationTimestamp: 2018-07-25T03:22:01Z labels: kubernetes.io/name: heapster plugin: heapster name: heapster namespace: kube-system resourceVersion: "789489505" selfLink: /api/v1/namespaces/kube-system/services/heapster uid: e56886a2-8fb9-11e8-acd2-5254171bf8db spec: clusterIP: 10.3.129.117 externalTrafficPolicy: Cluster ports: - nodePort: 30003 port: 80 protocol: TCP targetPort: 8082 selector: k8s-app: heapster sessionAffinity: None type: NodePort status: loadBalancer: {}
这种方式主要是利用其他第三方的LB暴露服务的,谷歌或者亚马逊的LB等等
kind: Service apiVersion: v1 metadata: name: my-service spec: selector: app: MyApp ports: - protocol: TCP port: 80 targetPort: 9376 clusterIP: 10.0.171.239 loadBalancerIP: 78.11.24.19 type: LoadBalancer status: loadBalancer: ingress: - ip: 146.148.47.155
这种方式主要是通过CNAME实现的,在kubernetes 1.7.x以及以上才支持这种方式,例如
kind: Service apiVersion: v1 metadata: name: my-service namespace: prod spec: type: ExternalName externalName: my.database.example.com
访问时,kube-dns服务直接解析到指定的Cnamemy.database.example.com这个域名上。
首先准备一个deployment的yaml文件:
[root@master deployment]$cat deployment_python_http.yaml apiVersion: extensions/v1bete1 kind: Deployment metadata: name: service-test spec: replicas: 2 selector: matchLabels: app: service_test_pod template: metadata: labels: app: service_test_pod spec: containers: - name: simple-http image: python:2.7 imagePullPolicy: IfNotPresent command: ["/bin/bash"] args: ["-c","echo \"Hello from $(hostname)
\" > index.html; python -m SimpleHTTPServer 8080"] ports: - name: http containerPort: 8080
创建之前,可以先在node节点将镜像pull下来,以免等会儿创建的时候比较慢。
[root@master deployment]$kubectl create -f deployment_python_http.yaml deployment.extensions "service-test" created [root@master deployment]$kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE service-test 2 2 2 2 16s [root@master deployment]$kubectl get pod NAME READY STATUS RESTARTS AGE busybox-pod 1/1 Running 0 2h nginx-pod 1/1 Running 0 2h service-test-7bd7775475-gsmqn 1/1 Running 0 47s service-test-7bd7775475-mrd8d 1/1 Running 0 47s
先在分别访问一下这两个pod:
[root@master deployment]$curl 10.244.1.60:8080Hello from service-test-7bd7775475-gsmqn
[root@master deployment]$curl 10.244.1.61:8080
Hello from service-test-7bd7775475-mrd8d
看到返回了两个不同的结果,之前有对这个名称做过分析,那么现在将请求的返回数据掐在service阶段,从而让访问统一,让返回值负载均衡。
[root@master deployment]$kubectl expose deployment service-test service "service-test" exposed [root@master deployment]$kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1443/TCP 1d service-test ClusterIP 10.100.53.40 8080/TCP 5s [root@master deployment]$curl 10.100.53.40:8080 Hello from service-test-7bd7775475-mrd8d
[root@master deployment]$curl 10.100.53.40:8080
Hello from service-test-7bd7775475-gsmqn
[root@master deployment]$curl 10.100.53.40:8080
Hello from service-test-7bd7775475-gsmqn
[root@master deployment]$curl 10.100.53.40:8080
Hello from service-test-7bd7775475-gsmqn
[root@master deployment]$curl 10.100.53.40:8080
Hello from service-test-7bd7775475-mrd8d
[root@master deployment]$curl 10.100.53.40:8080
Hello from service-test-7bd7775475-mrd8d
[root@master deployment]$curl 10.100.53.40:8080
Hello from service-test-7bd7775475-mrd8d
[root@master deployment]$curl 10.100.53.40:8080
Hello from service-test-7bd7775475-gsmqn
看上去权重貌似是3。
实验快速更新部署。
现在同时开启两个窗口,一个窗口一直curl刚刚的CLUSTER-IP。
while true; do curl 10.100.53.40:8080 && sleep 1; doneHello from service-test-7bd7775475-c6cfp
Hello from service-test-7bd7775475-bmlk4
Hello from service-test-7bd7775475-c6cfp
Hello from service-test-7bd7775475-bmlk4
那么现在模拟应用升级,可以通过直接编译yaml文件来实现。
[root@master deployment]$kubectl edit deployment service-test 在刚刚的echo处更改一下输出: 添加一个new version然后保存退出: deployment.extensions "service-test" edited
不用动,可以看到下边的输出已经自动的变化了,基本上零停顿。
了解之前,先将之前所有的环境都清理一波,还原成一个干净的环境。
准备有nginx的一个yaml文件:
apiVersion: v1 kind: Pod metadata: name: nginx-pod labels: app: nginx spec: containers: - name: nginx-container image: nginx ports: - name: nginx-port containerPort: 80
启动这个常规的pod:
[root@master services]$kubectl create -f pod_nginx.yml pod "nginx-pod" created [root@master services]$kubectl get pod NAME READY STATUS RESTARTS AGE nginx-pod 0/1 ContainerCreating 0 5s [root@master services]$kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE nginx-pod 1/1 Running 0 48m 10.244.1.72 node
现在将其配置为NodePort的形式,使用如下指令:
[root@master services]$kubectl expose pod nginx-pod --type=NodePort service "nginx-pod" exposed [root@master services]$kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1443/TCP 1d nginx-pod NodePort 10.101.193.19 80:30338/TCP 18s
这个时候可以看到类型变成NodePort了,而且后边也详细标出了端口的映射关系,是将pod的80端口映射到node的30338上。
那么现在就可以通过这种方式就可以访问了:
master:
node:
现在介绍另外一种情况,介绍之前,先将刚刚的service删除。
[root@master services]$kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1443/TCP 1d nginx-pod NodePort 10.101.193.19 80:30338/TCP 8m [root@master services]$kubectl delete svc nginx-pod service "nginx-pod" deleted [root@master services]$kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 443/TCP 1d
然后添加一个文件:
[root@master services]$more service_nginx.yml apiVersion: v1 kind: Service metadata: name: nginx-service spec: ports: - port: 30022 nodePort: 30022 targetPort: nginx-port protocol: TCP selector: app: nginx type: NodePort
此文件内容是基于刚刚还存在的pod而成立的,selector,就是检索刚刚创建的nginx的pod,然后直接将端口类型设置为NodePort,端口为30022。
然后创建之:
[root@master services]$kubectl create -f service_nginx.yml service "nginx-service" created [root@master services]$kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1443/TCP 1d nginx-service NodePort 10.96.139.29 30022:30022/TCP 4s
访问之:
© 2018 www.qingketang.net 鄂ICP备18027844号-1
武汉快勤科技有限公司 13554402156 武汉市东湖新技术开发区关山二路特一号国际企业中心6幢4层7号
扫码关注,全站教程免费播放
订单金额:
支付金额:
支付方式: