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: EndpointsapiVersion: v1metadata: name: mysql-service-outsidesubsets: - 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: ServiceapiVersion: v1metadata: name: mysql-service-domainspec: 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.11REDIS_MASTER_SERVICE_PORT=6379REDIS_MASTER_PORT=tcp://10.0.0.11:6379REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379REDIS_MASTER_PORT_6379_TCP_PROTO=tcp REDIS_MASTER_PORT_6379_TCP_PORT=6379REDIS_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 创建
# 创建 SecretapiVersion: v1 kind: Secret metadata: name: mysql-root-passwordtype: 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
作者:Anoyi
链接:https://www.jianshu.com/p/ca6b902b7a21