二丫讲梵 二丫讲梵
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)

二丫讲梵

行者常至,为者常成
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)
  • Nexus系列文章

  • Jenkins系列文章

  • ELK笔记

  • Kubernetes笔记

    • 手动部署kubernetes-1-8-6集群

    • 其他姿势快速部署

    • 手动搭建k8s-1-10-4高可用集群(推荐版).md

    • 基础学习

      • k8s整体架构的知识整理
      • 配置kubectl命令补全功能
      • k8s基本使用入门-使用Pod
      • k8s基本使用入门-了解ReplicationController
      • k8s基本使用入门-了解ReplicaSet
      • k8s基本使用入门-了解deployments
      • k8s基本使用入门-了解Service
        • 1,引入。
        • 2,缘由。
        • 3,service 概念。
          • 1,ClusterIP 方式。
          • 2,NodePort 方式
          • 3,LoadBalancer 方式
          • 4,ExternalName 方式
        • 5,service 学习示例。
          • 1,cluster IP。
          • 2,NodePort。
    • 从新出发

  • LLM专题

  • 系列专题
  • Kubernetes笔记
  • 基础学习
二丫讲梵
2018-12-07
目录

k8s基本使用入门-了解Service

文章发布较早,内容可能过时,阅读注意甄别。

# 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14

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"
1
2
3
4
5
6
7
8
9
10
11
12
13
14

启动。

kubectl create -f pod_nginx.yml
kubectl create -f pod_busybox.yml
1
2

然后看一下两个 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
1
2
3
4

此时,这两个生成的 ip,在集群当中任一节点里,都是可以畅通访问的。

image

详细的介绍,可以看官方的文档介绍: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
1
2
3
4

# 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: {}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 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
1
2
3
4
5
6
7
8

访问时,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 \"<p>Hello from $(hostname)<p>\" > index.html; python -m SimpleHTTPServer 8080"]
        ports:
        - name: http
          containerPort: 8080
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

创建之前,可以先在 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
1
2
3
4
5
6
7
8
9
10
11

先在分别访问一下这两个 pod:

[root@master deployment]$curl 10.244.1.60:8080
<p>Hello from service-test-7bd7775475-gsmqn<p>
[root@master deployment]$curl 10.244.1.61:8080
<p>Hello from service-test-7bd7775475-mrd8d<p>
1
2
3
4

看到返回了两个不同的结果,之前有对这个名称做过分析,那么现在将请求的返回数据掐在 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      <none>        443/TCP    1d
service-test   ClusterIP   10.100.53.40   <none>        8080/TCP   5s

[root@master deployment]$curl 10.100.53.40:8080
<p>Hello from service-test-7bd7775475-mrd8d<p>
[root@master deployment]$curl 10.100.53.40:8080
<p>Hello from service-test-7bd7775475-gsmqn<p>
[root@master deployment]$curl 10.100.53.40:8080
<p>Hello from service-test-7bd7775475-gsmqn<p>
[root@master deployment]$curl 10.100.53.40:8080
<p>Hello from service-test-7bd7775475-gsmqn<p>
[root@master deployment]$curl 10.100.53.40:8080
<p>Hello from service-test-7bd7775475-mrd8d<p>
[root@master deployment]$curl 10.100.53.40:8080
<p>Hello from service-test-7bd7775475-mrd8d<p>
[root@master deployment]$curl 10.100.53.40:8080
<p>Hello from service-test-7bd7775475-mrd8d<p>
[root@master deployment]$curl 10.100.53.40:8080
<p>Hello from service-test-7bd7775475-gsmqn<p>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

看上去权重貌似是 3。

实验快速更新部署。

现在同时开启两个窗口,一个窗口一直 curl 刚刚的 CLUSTER-IP。

while true; do curl 10.100.53.40:8080 && sleep 1; done

<p>Hello from service-test-7bd7775475-c6cfp<p>
<p>Hello from service-test-7bd7775475-bmlk4<p>
<p>Hello from service-test-7bd7775475-c6cfp<p>
<p>Hello from service-test-7bd7775475-bmlk4<p>
1
2
3
4
5
6

那么现在模拟应用升级,可以通过直接编译 yaml 文件来实现。

[root@master deployment]$kubectl edit deployment service-test
在刚刚的echo处更改一下输出:

添加一个new version然后保存退出:
deployment.extensions "service-test" edited
1
2
3
4
5

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

image

# 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
1
2
3
4
5
6
7
8
9
10
11
12
13

启动这个常规的 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
1
2
3
4
5
6
7
8

现在将其配置为 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       <none>        443/TCP        1d
nginx-pod    NodePort    10.101.193.19   <none>        80:30338/TCP   18s
1
2
3
4
5
6
7

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

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

master:

image

node:

image

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       <none>        443/TCP        1d
nginx-pod    NodePort    10.101.193.19   <none>        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    <none>        443/TCP   1d
1
2
3
4
5
6
7
8
9

然后添加一个文件:

[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
1
2
3
4
5
6
7
8
9
10
11
12
13
14

此文件内容是基于刚刚还存在的 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      <none>        443/TCP           1d
nginx-service   NodePort    10.96.139.29   <none>        30022:30022/TCP   4s
1
2
3
4
5
6

访问之:

image

微信 支付宝
上次更新: 2024/07/04, 22:40:37
k8s基本使用入门-了解deployments
通过kubedog助力应用部署的状态监测与打印

← k8s基本使用入门-了解deployments 通过kubedog助力应用部署的状态监测与打印→

最近更新
01
学习周刊-总第213期-2025年第22周
05-29
02
学习周刊-总第212期-2025年第21周
05-22
03
从赵心童世锦赛夺冠聊聊我的斯诺克情缘
05-16
更多文章>
Theme by Vdoing | Copyright © 2017-2025 | 点击查看十年之约 | 浙ICP备18057030号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式