Kubernetes入门实验:service

594 阅读5分钟

k8s service 实验。
注:本文为笔者实验记录,非教程,另会不定时更新。

环境

# kubectl get node
NAME              STATUS     ROLES    AGE   VERSION
edge-node         Ready      <none>   15m   v1.17.0
edge-node2        Ready      <none>   16m   v1.17.0
ubuntu            Ready      master   67d   v1.17.0

service

Service(简称svc)定义了Pod的逻辑集合和访问该集合的策略,是真实服务的抽象。Service提供了一个统一的服务访问入口以及服务代理和发现机制,用户不需要了解后台Pod是如何运行。Service通过Label找到Pod组。

技术总结

编辑yaml文件,将deployment和service写到一起(简单的示例可如此)。
创建服务。
查看pod的IP,获取页面(一般不如此用)。查看servicer的IP,获取页面。
service与pod生命周期无关。即:删除pod,会重新得到IP,可用新IP访问页面。而service的IP未变。

测试yaml文件

# cat <<EOF > nginx-service.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
   app: nginx
spec:
  replicas: 2 # tells deployment to run 2 pods matching the template
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: latelee/lidch
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80

---

apiVersion: v1
kind: Service # 指定为service
metadata:
  labels:
    run: nginx # 匹配nginx
  name: nginx # 这是本service的名称
  namespace: default
spec:
  ports:
  - port: 88 # 对外为88端口
    targetPort: 80
  selector:
    app: nginx
EOF

创建:

kubectl apply -f nginx-service.yaml 

查看:

# kubectl get deployments -o wide
NAME               READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES          SELECTOR
nginx-deployment   2/2     2            2           16s   nginx        latelee/lidch   app=nginx

# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-55677b6b95   2         2         2       30s

# kubectl get pod -l app=nginx
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-55677b6b95-679dc   1/1     Running   0          47s
nginx-deployment-55677b6b95-lrnb4   1/1     Running   0          47s

# 查看服务:
# kubectl get svc | grep nginx
nginx        ClusterIP   10.96.111.49   <none>        88/TCP    7m26s

查看:

# kubectl describe service nginx

主要信息:IP 为服务的IP,Endpoints 为匹配到的后端(即deployment的pod)。

验证:

查看IP:
# kubectl get pod -l app=nginx -o wide | awk '{ print $6 }'
IP
10.244.1.34
10.244.4.30

获取页面:
# curl 10.244.1.34
# curl 10.244.4.30
# curl 10.96.111.49:88

测试: 手动删除2个pod,会自动创建新的pod,其IP变化,但service的IP不变。

更新参数

编辑:

# kubectl edit service nginx

vim模式,将port: 88改为port: 80,保存退出,即时生效,使用curl 10.96.111.49访问页面。

停止:

kubectl apply -f nginx-service.yaml 

endpoints

查看服务内pod的IP,pod重建后,此处会更新。与service同名。

 kubectl get endpoints
输出:
nginx        10.244.1.45:80,10.244.4.39:80   3h50m

记录一个service对应的所有pod的访问地址。前提:service配置selector。通过endpoints功能,保证service能对应到真正的pod。

模式

修改配置,添加type: LoadBalancer

spec:
  ports:
  - port: 88 # 对外为88端口
    targetPort: 80
  selector:
    app: nginx
  type: LoadBalancer

注:type值为ClusterIP NodePort LoadBalancer ExternalName,默认ClusterIP。 更新:

kubectl apply -f nginx-service.yaml 

查看类型:

kubectl get svc
输出:
nginx        LoadBalancer   10.96.106.146   <pending>     88:30212/TCP   3h5m

注:这个功能目前还不知道怎么用,待定。

下面是None的示例:

apiVersion: v1
kind: Service
metadata:
  name: myapp-headless
  namespace: default
spec:
  selector:
    app: myapp
  clusterIP: "None"
  ports:
  - port: 80
    targetPort: 80
# kubectl get svc
NAME             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes       ClusterIP   10.96.0.1    <none>        443/TCP   70d
myapp-headless   ClusterIP   None         <none>        80/TCP    3s

(注:集群IP为None,与配置一致)

新的测试yaml

webgin-service.yaml 文件:

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: webgin-deployment
  labels:
   app: webgin
spec:
  replicas: 3 # tells deployment to run 3 pods matching the template
  selector:
    matchLabels:
      app: webgin
  template:
    metadata:
      labels:
        app: webgin
    spec:
      containers:
      - name: webgin
        image: latelee/webgin
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /etc/localtime
          name: time-zone
      volumes:
      - name: time-zone
        hostPath: 
          path: /etc/localtime

---

apiVersion: v1
kind: Service # 指定为service
metadata:
  labels:
    run: webgin
  name: webgin
  namespace: default
spec:
  ports:
  - port: 88 # 对外为88端口
    targetPort: 80
  selector:
    app: webgin
  type: LoadBalancer

创建及实验:

# kubectl apply -f webgin-service.yaml 

# kubectl get pod
NAME                                 READY   STATUS              RESTARTS   AGE
webgin-deployment-54ff4977c7-92cvk   1/1     Running             0          21m
webgin-deployment-54ff4977c7-blqnj   1/1     Running             0          21m
webgin-deployment-54ff4977c7-dgglx   1/1     Running             0          21m

使用同一命令测试,返回不同的结果。证实web服务运行于不同的后端,但对外接口相同。
理论上看业务的实现,不关注底层。

# curl 10.96.36.4:88
Hello World 
arch: amd64 os: linux hostname: webgin-deployment-54ff4977c7-blqnj
Now: 2020-03-12 00:56:58
# curl 10.96.36.4:88
Hello World 
arch: amd64 os: linux hostname: webgin-deployment-54ff4977c7-dgglx
Now: 2020-03-12 00:57:04
# curl 10.96.36.4:88
Hello World 
arch: amd64 os: linux hostname: webgin-deployment-54ff4977c7-92cvk
Now: 2020-03-12 00:57:09
# curl 10.96.36.4:88
Hello World 
arch: amd64 os: linux hostname: webgin-deployment-54ff4977c7-dgglx
Now: 2020-03-12 00:57:13

指定为nodePort方式webgin-service1.yaml(其它与上述相同):

apiVersion: v1
kind: Service # 指定为service
metadata:
  labels:
    run: webgin
  name: webgin
  namespace: default
spec:
  ports:
  - port: 88 # 对外为88端口
    targetPort: 80
    nodePort: 30800 # 指定节点主机的端口为30800
  selector:
    app: webgin
  type: NodePort

查看服务:

# kubectl get svc
NAME             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
webgin           NodePort    10.96.36.4     <none>        88:30800/TCP   2d22h

使用集群节点的某一IP+端口(包括master和node),均可访问,其结果如上所述。
注:此方法暂未知在实际中作何用处。

记录

有时使用集群IP访问页面较慢,不知何故,或者虚拟机性能问题。