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