Kubernetes Service & LB &

作者: Anoyi | 来源:发表于2018-06-03 21:43 被阅读141次

    Service 创建

    1、With Label Selector

    使用标签选择器创建服务,Service 直接关联 Pod,示例:部署 Mysql (细节见文末附录1),再创建服务:

    kind: Service
    apiVersion: v1
    metadata:
      name: mysql-service
    spec:
      selector:             # 与 Pod 创建时的 matchLabels 值相同即可匹配
          environment: dev
          database: mysql
      ports:
      - protocol: TCP       # 协议可选 UDP 和 TCP,默认 TCP
        port: 3306          # 对外暴露的端口号
        targetPort: 3306    # 容器中 Mysql 的端口号,port 与 targetPort 相同时, targetPort 可省略不写
    

    2、Without Label Selector

    Service 通常抽象化访问 Pods,但 Service 也可以抽象化访问其他类型的后端服务。例如:

    • 你希望在生产中访问外部数据库群集(k8s 外),但在测试中你希望使用自己的数据库(k8s 内);
    • 你希望将你的服务指向另一个名称空间或另一个群集中的服务;
    • 你正在将服务迁移到 Kubernetes,而其中一些后端运行在 Kubernetes 之外。

    示例:

    ① 在 minikube 中使用 Docker 启动一个 Mysql 容器(与 Kubernetes 无任何关系)

    docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql-out mysql:5.6
    

    ② 创建不带标签选择器的 Service :

    kind: Service
    apiVersion: v1
    metadata:
      name: mysql-service-outside
    spec:
      ports:
      - port: 3306
        targetPort: 3306
    

    ③ 创建 Endpoints 将 mysql-service-outside 映射到 mysql

    kind: Endpoints
    apiVersion: v1
    metadata:
      name: mysql-service-outside
    subsets:
      - addresses:
          - ip: 192.168.99.100      # IP 地址为 Mysql 所在的服务器的地址
        ports:
          - port: 3307              # 上述创建 mysql 容器所指定的端口号
    

    ④ 测试使用 mysql-service-outside 作为入口访问 Mysql

    kubectl run -it --rm --image=mysql:5.6 mysql-client -- mysql -h mysql-service-outside -p123456
    

    3、ExternalName Service
    ExternalName Service 是没有选择器的特殊服务,它没有定义任何端口或端点。查找主机 mysql-service-domain.default.svc.CLUSTER 时,集群 DNS 服务将返回值为 mysql.anoyi.com 的 CNAME 记录。访问这种服务的方式与其他服务一样,唯一的区别在于重定向发生在 DNS 级别,并且没有代理或转发发生。

    kind: Service
    apiVersion: v1
    metadata:
      name: mysql-service-domain
    spec:
      type: ExternalName
      externalName: mysql.anoyi.com
    

    服务发现

    Kubernetes 支持 2 中发现服务的方式:环境变量 和 DNS。

    1、环境变量

    当 Pod 在节点中运行,kubelet 会为每个 active 状态的服务添加一组环境变量。它支持 Docker links compatible 变量(请参阅 makeLinkVariables )和更简单的 {SVCNAME}_SERVICE_HOST{SVCNAME}_SERVICE_PORT 变量,其中服务名称为大写,破折号转换为下划线。

    示例:服务 redis-master 暴露 TCP 端口 6379 且已分配了clusterIP 地址10.0.0.11 , 会生成以下环境变量:

    REDIS_MASTER_SERVICE_HOST=10.0.0.11
    REDIS_MASTER_SERVICE_PORT=6379
    REDIS_MASTER_PORT=tcp://10.0.0.11:6379
    REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379
    REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
    REDIS_MASTER_PORT_6379_TCP_PORT=6379
    REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11
    

    如何应用这些变量呢?

    示例:创建 Mongo 服务(细节见文末附录 2),创建 Mongo-Express 服务连通 Mongo 服务

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mongo-express
      labels:
        environment: dev
        service: mongo-express
    spec:
      selector:
        matchLabels:
          environment: dev
          web: mongo-express
      strategy:
        type: Recreate
      template:
        metadata:
          labels:
            environment: dev
            web: mongo-express
        spec:
          containers:
          - image: registry.docker-cn.com/library/mongo-express
            name: mongo-express
            ports:
            - containerPort: 8081
              name: mongo-express
            env:
            - name: ME_CONFIG_OPTIONS_EDITORTHEME
              value: ambiance
            - name: ME_CONFIG_MONGODB_SERVER
              value: $(MONGO_SERVICE_SERVICE_HOST) 
    

    如上所示,使用 $(...) 引用环境变量

    2、DNS

    DNS Server 是一个非常推荐的可选的集群插件,它观察 Service 相关 API 动态管理 DNS 记录。如果在整个集群中启用了 DNS,则所有的 Pod 应该能够自动进行服务的名称解析。

    示例,假设在 [Namespace] my-ns 中创建 [Service] my-service ,则会生成一条 DNS 记录 my-service.my-ns,则在 [Namespace] my-ns 中的 Pod 都可以通过 my-service 找到这个服务;如果在集群内的其他 [Namespace] ,则需要通过 my-service.my-ns 来发现这个服务。

    示例:通过 DNS 方式连通 Mongo 和 Mongo-Express,只需修改为如下即可:

            - name: ME_CONFIG_MONGODB_SERVER
              value: mongo-service
    

    发布服务 - Service Types

    Service 支持如下几种类型,默认是 ClusterIP

    • ClusterIP: 暴露服务在一个集群内部的 IP,此类型只支持内部访问服务。
    • NodePort: 暴露服务在集群每个节点的静态端口. 在集群外部通过 <NodeIP>:<NodePort> 即可访问集群内的服务。
    • LoadBalancer: 通过云供应商提供的负载均衡器暴露服务。将自动创建外部负载平衡器路由到的 NodePort 和 ClusterIP 服务。
    • ExternalName: 相当于 DNS 的 CNAME,上述有示例。

    示例:通过 NodePort 暴露 Mongo-Express 服务

    kind: Service
    apiVersion: v1
    metadata:
      name: mongo-express-service
    spec:
      selector:             
        environment: dev
        web: mongo-express
      ports:
      - nodePort: 30005     
        port: 8081
      type: NodePort
    

    多端口 Service

    示例:http 和 https 服务

    kind: Service
    apiVersion: v1
    metadata:
      name: web-service
    spec:
      selector:
        app: webApp
      ports:
      - name: http
        protocol: TCP
        port: 80
        targetPort: 8080
      - name: https
        protocol: TCP
        port: 443
        targetPort: 8443
    

    附录

    1、Mysql Deployment 创建

    # 创建 Secret
    apiVersion: v1
    kind: Secret
    metadata:
      name: mysql-root-password
    type: Opaque
    data:
      password: MTIzNDU2        # '123456' -> base64 -> 'MTIzNDU2'   相关命令: 'echo -n '123456' | base64'
    ---
    # 创建持久化存储卷
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: mysql-pvc
    spec:
      accessModes:
        - ReadWriteOnce        
      resources:
        requests:
          storage: 10Gi 
    ---
    # 创建部署
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mysql
      labels:
        environment: dev
        service: mysql
    spec:
      selector:
        matchLabels:
          environment: dev
          database: mysql
      strategy:
        type: Recreate
      template:
        metadata:
          labels:
            environment: dev
            database: mysql
        spec:
          containers:
          - image: registry.docker-cn.com/library/mysql:5.6
            name: mysql
            env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-root-password
                  key: password
            ports:
            - containerPort: 3306
              name: mysql
            volumeMounts:
            - name: mysql-persistent-storage
              mountPath: /var/lib/mysql
          volumes:
          - name: mysql-persistent-storage
            persistentVolumeClaim:
              claimName: mysql-pvc
    

    2、MongoDB Deployment 创建

    # 创建持久化存储卷
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: mongo-pvc
    spec:
      accessModes:
        - ReadWriteOnce        
      resources:
        requests:
          storage: 10Gi 
    ---
    # 创建部署
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mongo
      labels:
        environment: dev
        service: mongo
    spec:
      selector:
        matchLabels:
          environment: dev
          database: mongo
      strategy:
        type: Recreate
      template:
        metadata:
          labels:
            environment: dev
            database: mongo
        spec:
          containers:
          - image: registry.docker-cn.com/library/mongo
            name: mongo
            ports:
            - containerPort: 27017
              name: mongo
            volumeMounts:
            - name: mongo-persistent-storage
              mountPath: /data/db
          volumes:
          - name: mongo-persistent-storage
            persistentVolumeClaim:
              claimName: mongo-pvc
    ---
    # 创建服务
    kind: Service
    apiVersion: v1
    metadata:
      name: mongo-service
    spec:
      selector:
          environment: dev
          database: mongo
      ports:
      - port: 27017
    

    相关文章

      网友评论

        本文标题:Kubernetes Service & LB &

        本文链接:https://www.haomeiwen.com/subject/ggxjsftx.html