Service
Данная сущность кластера k8s обеспечивает доступ к ресурсу в поде извне кластера. Также её можно использовать для доступа к ресурсам пода внутри кластера.
Так для чего же нужна такая сущность как Service, если у пода есть свой адрес и к нему можно обращаться напрямую? Дело в том, что под это сущность не постоянная. Сейчас под есть, а завтра его нет. Завтра вместо этого пода будет другой под с другим адресом. А может не завтра, а через час. И постоянно отслеживать какой адрес сейчас у пода будет неудобно. А если подов не один, а десять? То это рехнуться можно. Вот здесь и появляется сущность Service, которая берёт на себя функцию отслеживания адресов у подов и предоставляет единый интерфейс для доступа к ним.
1. NodePort. Позволяет обращаться к поду извне кластера k8s с использованием адреса ноды и откытого на ней порта из специального диапазона.
2. ClusterIP. Работает только внутри кластера потому что поддерживает только внутренний ip адрес. Используется по дефолту, если не указан другой тип.
3. LoadBalancer. Данное решение отлично работает в облаке. Форвардит запросы извне на группу бэкендов.
1. port. Это порт, который открыт у самого сервиса. Является обязательным параметром.
2. targetPort. Это порт который открыт в контейнере. Если не указан, то используется тот же порт что и в port.
3. nodePort. Используется для доступа к сервису извне. Если не указать, то берётся случайный порт из диапазона 30000-32767
1. Сервис ищет по лейблам поды, а не деплойменты.
2. Когда поды c определённым лейблом обновляются/добавляются сервис автоматически включает их в правила маршрутизации.
3. Работает на уровне L3.
4. Сервис - это эфемерный объект, представляющий собой набор правил, обеспечивающих взаимодействие подов друг с другом.
5. У сервиса есть тип, селектор по которому ищутся подходящие поды и набор портов к которым открывается доступ.
Для примера работы разных сервисов создадим Deployment с nginx.
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: default
name: cam-nginx
labels:
app: nginx-prod
environment: prod
annotations:
author: cameda
spec:
replicas: 2
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
resources:
requests:
cpu: 300m
memory: 300Mi
limits:
cpu: 400m
memory: 400Mi
restartPolicy: Always
EOFПредоставим доступ к поду с помощью Service NodePort:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
namespace: default
name: nginx-service
labels:
environment: prod
annotations:
author: cameda
spec:
type: NodePort
selector:
app: nginx
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 80
EOFkubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-service NodePort 10.12.198.238 <none> 8080:32038/TCP 10s
Доступ к поду будет осуществляться с помощью адреса ноды, введённого в браузере и номера nodeport (здесь это 32038). Адрес ноды на которой вертится под можно посмотреть в её дескрайбе.
kubectl describe po cam-nginx-74fdbbbc8d-lrhlq kubectl describe no cl1n0nosftbqt0s7gocp-ufeg
Этими командами мы смотрим на какой ноде запущен под и какой у ноды внешний адрес. Далее уже с помощью curl проверяем доступность сайта.
curl http://51.250.46.40:32038/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>kubectl delete svc nginx-service -n preprod
Откроем доступ по нескольким портам.
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
namespace: default
name: nginx-service
labels:
environment: prod
annotations:
author: cameda
spec:
type: NodePort
selector:
app: nginx
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 80
- name: https
protocol: TCP
port: 443
targetPort: 8070
EOFПредоставим доступ к поду с помощью Service ClusterIP:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: default
labels:
environment: prod
annotations:
author: cameda
spec:
type: ClusterIP
selector:
app: nginx
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
nodePort: 31282
EOFПолезные ссылки.
Вот здесь создавал namespace: https://teletype.in/@cameda2/6tbWe-V5XxZ