播放记录

k8s基本使用入门-了解Service

博客术业专攻云计算kubernetesk8s基本使用入门-了解Service 2019年08月29日 11:24:42

1,引入。

现在准备了两个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/

2,缘由。

现在可以思考一个问题:为什么不直接通过pod来作为k8s的管理单位进行管理呢?

  • 当我们使用ReplicaSet或者ReplicationController做水平扩展scale的时候,Pod会在这个过程中被terminated,随着这个更替,Pod的ip等的也都在变幻。
  • 当我们使用Deployment的时候,我们去更新Docker Image Version,旧的Pods会被terminated,然后新的Pods创建,这个过程中,同样会发生Pod的ip改变等问题。从而难于对其进行访问。

3,service概念。

之于如上所提问题,那么就引入了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几种类型。

1,ClusterIP 方式。

kubernetes 默认就是这种方式,是集群内部访问的方式,外部的话,是无法访问的。

spec:
  clusterIP: 10.0.0.1
  ports:
  - name: http

2,NodePort 方式

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: {}

3,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

4,ExternalName 方式

这种方式主要是通过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这个域名上。

5,service学习示例。

1,cluster IP。

首先准备一个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:8080

Hello 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.1              443/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; done

Hello 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

不用动,可以看到下边的输出已经自动的变化了,基本上零停顿。

2,NodePort。

了解之前,先将之前所有的环境都清理一波,还原成一个干净的环境。

  • 1,通过指令创建NodePort。
  • 准备有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.1               443/TCP        1d
    nginx-pod    NodePort    10.101.193.19           80:30338/TCP   18s
    

    这个时候可以看到类型变成NodePort了,而且后边也详细标出了端口的映射关系,是将pod的80端口映射到node的30338上。

    那么现在就可以通过这种方式就可以访问了:

    master:

    node:

  • 2,通过yaml形式创建NodePort。
  • 现在介绍另外一种情况,介绍之前,先将刚刚的service删除。

    [root@master services]$kubectl get svc
    NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
    kubernetes   ClusterIP   10.96.0.1               443/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.1              443/TCP           1d
    nginx-service   NodePort    10.96.139.29           30022:30022/TCP   4s
    

    访问之:


    转载:http://www.eryajf.net/2127.html

    © 2018 www.qingketang.net 鄂ICP备18027844号-1

    武汉快勤科技有限公司 13554402156 武汉市东湖新技术开发区关山二路特一号国际企业中心6幢4层7号

    微信登录

    扫码关注,全站教程免费播放

    发表评论 X

    登录成功
    开通VIP

    订单金额:

    支付金额:

    支付方式: