Kubernetes Service & LB & Networking :Services

Keywords: MySQL DNS Database Docker

Service Creation

1,With Label Selector

Create a service using label selector. Service directly associates Pod. Example: Deploy Mysql (see Appendix 1 at the end of this article for details) and then create a service:

kind: Service
apiVersion: v1
metadata:
  name: mysql-service
spec:
  selector:             # Match with the same matchLabels value as when Pod was created
      environment: dev
      database: mysql
  ports:
  - protocol: TCP       # UDP and TCP are optional protocols, default TCP
    port: 3306          # Exposed port number
    targetPort: 3306    # When the port number of Mysql in the container is the same as that of targetPort, targetPort can be omitted from writing.

2,Without Label Selector

Service usually abstracts access to Pods, but Service can also abstract access to other types of back-end services. For example:

  • You want to access external database clusters in production (outside k8s), but in testing you want to use your own database (within k8s);
  • You want to point your services to another namespace or another cluster of services.
  • You are migrating services to Kubernetes, and some of the back-ends are running outside of Kubernetes.

Example:

(1) Start a Mysql container with Docker in minikube (nothing to do with Kubernetes)

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

(2) Create a Service without Label Selector:

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

Create Endpoints to map mysql-service-outside to MySQL

kind: Endpoints
apiVersion: v1
metadata:
  name: mysql-service-outside
subsets:
  - addresses:
      - ip: 192.168.99.100      # IP address is the address of Mysql's server
    ports:
      - port: 3307              # The port number specified above for creating mysql container

(4) The test uses mysql-service-outside as the entry to access Mysql

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

3,ExternalName Service
External Name Service is a special service without selectors. It does not define any ports or endpoints. When looking for host mysql-service-domain.default.svc.CLUSTER, the cluster DNS service returns a CNAME record with a value of mysql.anoyi.com. The only difference between access to this service and other services is that redirection occurs at the DNS level and no proxy or forwarding occurs.

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

Service discovery

Kubernetes supports two ways to discover services: environment variables and DNS.

1. Environmental variables

When Pod runs in a node, kubelet adds a set of environment variables for each active state service. It supports Docker links compatible Variables (see makeLinkVariables ) and simpler {SVCNAME}_SERVICE_HOST and {SVCNAME}_SERVICE_PORT variables, where the service name is capitalized and the dash is converted to underscore.

Example: Service redis-master exposes TCP port 6379 and has assigned cluster IP address 10.0.0.11, which generates the following environment variables:

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

How do you apply these variables?

Example: Create a Mongo service (see Appendix 2 at the end of this article for details), and create a Mongo-Express service to connect to a Mongo service

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) 

As shown above, use $(...) to refer to environment variables

2,DNS

DNS Server is a highly recommended cluster plug-in that observes Service-related API s to dynamically manage DNS records. If DNS is enabled throughout the cluster, all Pod s should be able to automatically resolve the name of the Service.

For example, assuming [Service] my-service is created in [Namespace] my-ns, a DNS record my-service.my-ns is generated, then Pod in [Namespace] my-ns can find the service through my-service; if other [Namespace] in the cluster, the service needs to be discovered through my-service.my-ns.

Example: Connecting Mongo and Mono-Express via DNS only needs to be modified as follows:

        - name: ME_CONFIG_MONGODB_SERVER
          value: mongo-service

Publishing Services - Service Types

Service supports the following types by default: ClusterIP:

  • Cluster IP: Exposing the IP of a service within a cluster, which only supports internal access services.
  • NodePort: Expose the static ports of services at each node of the cluster. Access to services within the cluster can be achieved through <NodeIP>: <NodePort> outside the cluster.
  • LoadBalancer: Exposure services through load balancers provided by cloud providers. NodePort and Cluster IP services routed to external load balancers will be automatically created.
  • External Name: CNAME equivalent to DNS, as shown above.

Example: Exposing Mongo-Express services through NodePort

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

Multiport Service

Example: http and https services

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

appendix

1. Mysql Deployment Creation

# Create Secret
apiVersion: v1
kind: Secret
metadata:
  name: mysql-root-password
type: Opaque
data:
  password: MTIzNDU2        # '123456'-> base64->'MTIzNDU2'command:'echo-n'123456' | base64'
---
# Create persistent storage volumes
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce        
  resources:
    requests:
      storage: 10Gi 
---
# Create deployment
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 Creation

# Create persistent storage volumes
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongo-pvc
spec:
  accessModes:
    - ReadWriteOnce        
  resources:
    requests:
      storage: 10Gi 
---
# Create deployment
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
---
# Create service
kind: Service
apiVersion: v1
metadata:
  name: mongo-service
spec:
  selector:
      environment: dev
      database: mongo
  ports:
  - port: 27017

Posted by trace on Wed, 12 Dec 2018 01:30:06 -0800