Starting to Learn Kubernetes a Step Behind - 08. discovery&LB Part 1 -
Story
- Starting to Learn Kubernetes a Step Behind - 01. Environment Selection -
- Starting to Learn Kubernetes a Step Behind - 02. Docker For Mac -
- Starting to Learn Kubernetes a Step Behind - 03. Raspberry Pi -
- Starting to Learn Kubernetes a Step Behind - 04. kubectl -
- Starting to Learn Kubernetes a Step Behind - 05. workloads Part 1 -
- Starting to Learn Kubernetes a Step Behind - 06. workloads Part 2 -
- Starting to Learn Kubernetes a Step Behind - 07. workloads Part 3 -
- Starting to Learn Kubernetes a Step Behind - 08. discovery&LB Part 1 -
- Starting to Learn Kubernetes a Step Behind - 09. discovery&LB Part 2 -
- Starting to Learn Kubernetes a Step Behind - 10. config&storage Part 1 -
- Starting to Learn Kubernetes a Step Behind - 11. config&storage Part 2 -
- Starting to Learn Kubernetes a Step Behind - 12. Resource Limitations -
- Starting to Learn Kubernetes a Step Behind - 13. Health Checks and Container Lifecycle -
- Starting to Learn Kubernetes a Step Behind - 14. Scheduling -
- Starting to Learn Kubernetes a Step Behind - 15. Security -
- Starting to Learn Kubernetes a Step Behind - 16. Components -
Last time
In Starting to learn Kubernetes a step behind - 07. workloads Part 3 -, we finally finished the workloads. This time, I'm thinking of advancing discovery&LB.
discovery&LB
In Kubernetes, there are types of resources as follows. This time, we will learn about discovery&LB.
Resource Classification | Content |
---|---|
Workloads Resources | Resources related to the execution of containers |
Discovery&LB Resources | Resources that provide endpoints to expose containers externally |
Config&Storage Resources | Resources related to configuration, secret information, persistent volumes, etc. |
Cluster Resources | Resources related to security and quotas |
Metadata Resources | Resources for operating resources |
※ Kubernetes Workloads Resources (Part 1)
There are 8 types of discovery&LB.
- Service
- ClusterIP
- ExternalIP
- NodePort
- LoadBalancer
- Headless (None)
- ExternalName
- None-Selector
- Ingress
We will learn about the overview of Service.
Kubernetes and Network
In Kubernetes, an IP address is assigned to each Pod. Therefore, when communicating between different Pods, you need the IP address of the Pod. On the other hand, you can communicate with localhost within the same Pod.
To explain, let's prepare.
# sample-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.12
ports:
- containerPort: 80
- name: redis-container
image: redis:3.2
pi@raspi001:~/tmp $ k apply -f sample-deployment.yaml
pi@raspi001:~/tmp $ k get pods -l app=sample-app -o custom-columns="NAME:{metadata.name}, IP:{status.podIP},NODE:{spec.nodeName}"
NAME IP NODE
sample-deployment-9dc487867-h7lww 10.244.1.72 raspi002
sample-deployment-9dc487867-n8x5w 10.244.2.66 raspi003
sample-deployment-9dc487867-nxbxc 10.244.2.67 raspi003
In such a situation, we will focus on sample-deployment-9dc487867-n8x5w:redis
.
※ nginx is open on port 80.
Preparation
pi@raspi001:~/tmp $ k exec -it sample-deployment-9dc487867-n8x5w -c redis-container /bin/bash
root@sample-deployment-9dc487867-n8x5w:/data# apt-get update && apt-get install curl -y
root@sample-deployment-9dc487867-n8x5w:/data# exit
Install curl because it is not installed.
Communication to the container in the same Node, same Pod
pi@raspi001:~/tmp $ k exec -it sample-deployment-9dc487867-n8x5w -c redis-container /bin/bash
root@sample-deployment-9dc487867-n8x5w:/data# curl localhost:80
<!DOCTYPE html>
...
OK
Communication to the container in the same Node, different Pod
pi@raspi001:~/tmp $ k exec -it sample-deployment-9dc487867-n8x5w -c redis-container /bin/bash
root@sample-deployment-9dc487867-n8x5w:/data# curl 10.244.2.66:80
<!DOCTYPE html>
...
root@sample-deployment-9dc487867-n8x5w:/data# curl 10.244.2.67:80
<!DOCTYPE html>
...
OK
Communication to the container in a different Node, different Pod
pi@raspi001:~/tmp $ k exec -it sample-deployment-9dc487867-n8x5w -c redis-container /bin/bash
root@sample-deployment-9dc487867-n8x5w:/data# curl 10.244.1.72:80
<!DOCTYPE html>
...
OK
Communication from MasterNode to each Pod
pi@raspi001:~/tmp $ curl 10.244.1.72:80
<!DOCTYPE html>
...
pi@raspi001:~/tmp $ curl 10.244.2.66:80
<!DOCTYPE html>
...
pi@raspi001:~/tmp $ curl 10.244.2.67:80
<!DOCTYPE html>
...
OK
As you can see from here, the network is built by Kubernetes, which includes communication within the Pod, between Pods, and even between Nodes.
Service
Service has two major functions:
- Load balancing of traffic to pods
- Service discovery and intra-cluster DNS
Load balancing of traffic to pods
In the previous example, it is possible to communicate between Pods. However, every time you recreate a pod, the IP address changes, so it's a bit of a hassle to create your own. That's where Service comes in. Service automatically load balances for multiple existing Pods, and also provides external IP addresses (ExternalIP) and internal IP addresses (ClusterIP).
Let's try it out.
# sample-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
name: sample-clusterip
spec:
type: ClusterIP
ports:
- name: "http-port"
protocol: "TCP"
port: 8080
targetPort: 80
selector:
app: sample-app
This will load balance for Pods that match app=sample-app
. It listens on port 8080 from the outside and communicates with the container on port 80.
Since spec.type is ClusterIP, an internal IP address is provided.
pi@raspi001:~/tmp $ k apply -f sample-clusterip.yaml
pi@raspi001:~/tmp $ k get service sample-clusterip
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
sample-clusterip ClusterIP 10.111.197.69 <none> 8080/TCP 30s
pi@raspi001:~/tmp $ k describe service sample-clusterip
Name: sample-clusterip
...
Selector: app=sample-app
Type: ClusterIP
IP: 10.111.197.69
Port: http-port 8080/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.72:80,10.244.2.66:80,10.244.2.67:80
...
An IP address of 10.111.197.69 has been assigned for internal use. Also, the target Pod for load balancing is the IP address of the Pod mentioned earlier.
As you can see from :80
in Endpints, you can also create a service(clusterIP) for each port. (service's spec.ports is an array specification)
Let's see if we can access it. Let's change the content of index.html for each pod.
pi@raspi001:~/tmp $ for PODNAME in `k get pods -l app=sample-app -o jsonpath='{.items[*].metadata.name}'`; do
> k exec -it ${PODNAME} -- cp /etc/hostname /usr/share/nginx/html/index.html;
> done
pi@raspi001:~/tmp $ curl 10.111.197.69:8080
sample-deployment-9dc487867-nxbxc
pi@raspi001:~/tmp $ curl 10.111.197.69:8080
sample-deployment-9dc487867-n8x5w
pi@raspi001:~/tmp $ curl 10.111.197.69:8080
sample-deployment-9dc487867-h7lww
Indeed, you can access the pod with a reasonable randomness due to load balancing. Of course, you cannot access it from the outside.
Move to iMac
~ $ curl 10.111.197.69:8080
# No response
Service discovery and intra-cluster DNS
Service discovery refers to the "solution to a problem". The problem in Kubernetes is that it is difficult to identify services because services are continuously being generated dynamically. That service discovery is in Service. The following methods are available:
- Service discovery using environment variables
- IP address, port, and protocol are set in the Pod.
- Service discovery using DNS A records
- Access by domain name is possible due to the intra-cluster DNS in Kubernetes. (Follow the domain name naming rules)
- Service discovery using DNS SRV records
- Reverse lookup from IP address to domain name is also possible.
Unless explicitly set by dnsPolicy, records are added to the intra-cluster DNS when a Pod is created. If the intra-cluster DNS cannot resolve the name, it will query the external DNS.
Cleaning up
pi@raspi001:~/tmp $ k delete -f sample-deployment.yaml -f sample-clusterip.yaml
Finally
This time, we learned about the overview of Service. In the world of Kubernetes, the network is automatically built, so there was nothing in particular to be aware of. As we understand more, we want to know how the network is built and how the intra-cluster DNS works. Next time is here.
※ Drawing and outputting deepens understanding, so it is recommended.
Share
Related tags
- Cloud Native Days Tokyo 2019 - Participation Report for July 22-23, 2019
- Starting to Learn Kubernetes a Step Behind - 16. Components -
- Starting to Learn Kubernetes a Step Behind - 15. Security -
- Starting to Learn Kubernetes a Step Behind - 14. Scheduling -
- Osaka, Umeda - Participation Report for Kubernetes Meetup Tokyo 19 Osaka Satellite - May 31, 2019
- Starting to Learn Kubernetes a Step Behind - 13. Health Checks and Container Lifecycle -
- Starting to Learn Kubernetes a Step Behind - 12. Resource Limits -
- Starting to Learn Kubernetes a Step Behind - 11. config&storage Part 2 -
- Starting to Learn Kubernetes a Step Behind - 10. config&storage Part 1 -
- Osaka BMXUG Study Meeting -Kubernates Experience & Watson Discovery Introduction- Participation Report on March 27, 2019
- Starting to Learn Kubernetes a Step Behind - 09. discovery&LB Part 2 -
- Starting to Learn Kubernetes a Step Behind - 07. Workloads Part 3 -
- Starting to Learn Kubernetes a Step Behind - 06. Workloads Part 2 -
- Starting to Learn Kubernetes a Step Behind - 05. workloads Part 1 -
- Starting to Learn Kubernetes a Step Behind - 04. kubectl -
- Starting to Learn Kubernetes a Step Behind - 03. Raspberry Pi -
- Starting to Learn Kubernetes a Step Behind - 02. Docker For Mac -
- Starting to Learn Kubernetes a Step Behind - 01. Choosing the Environment -