Подготовка
Далее мы рассмотрим объекты из Kubernetes Service API, которые включают в себя Services, Ingresses и Endpoints.
Как и прежде, скопируйте нашу рабочую схему из предыдущей части урока в новую папку:
cd ~/kubernetes-dashboard-hull && cp -R 05_workloads/ 06_service_api && cd 06_service_api/kubernetes-dashboard-hull
Чтобы удалить HULL hull.objects
из values.full.yaml
и подготовить наш тестовый values.yaml
войдите:
sed '/ objects:/Q' values.full.yaml > values.yaml
и проверьте результат:
cat values.yaml
выглядит как:
metrics-server:
enabled: false
hull:
config:
specific:
protocolHttp: false
rbac:
clusterReadOnlyRole: false
clusterRoleMetrics: true
settings: {}
pinnedCRDs: {}
Проверка наличия существующих объектов Service API
Начните исследование, как вы это делали раньше:
find ../kubernetes-dashboard/templates -type f -iregex '.*(Service|Ingress|Endpoint).*' | sort
возвращается:
../kubernetes-dashboard/templates/ingress.yaml
../kubernetes-dashboard/templates/service.yaml
../kubernetes-dashboard/templates/serviceaccount.yaml
../kubernetes-dashboard/templates/servicemonitor.yaml
Игнорируя ServiceAccount (уже обработанный) и ServiceMonitor (обработанный позже), существует служба и определение Ingress.
Определение служб в HULL
Содержимое шаблона Service в /templates/service.yaml
:
cat ../kubernetes-dashboard/templates/service.yaml
выглядит следующим образом:
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: Service
metadata:
name: {{ template "kubernetes-dashboard.fullname" . }}
labels:
{{ include "kubernetes-dashboard.labels" . | nindent 4 }}
app.kubernetes.io/component: kubernetes-dashboard
{{ .Values.service.clusterServiceLabel.key | nindent 4}}: {{ .Values.service.clusterServiceLabel.enabled | quote }}
{{- if .Values.service.labels }}
{{ toYaml .Values.service.labels | nindent 4 }}
{{- end }}
{{- if .Values.commonLabels }}
{{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }}
{{- end }}
annotations:
{{- if .Values.commonAnnotations }}
{{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
{{- end }}
{{- if .Values.service.annotations }}
{{ toYaml .Values.service.annotations | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.externalPort }}
{{- if .Values.protocolHttp }}
targetPort: http
name: http
{{- else }}
targetPort: https
name: https
{{- end }}
{{- if hasKey .Values.service "nodePort" }}
nodePort: {{ .Values.service.nodePort }}
{{- end }}
{{- if .Values.service.loadBalancerSourceRanges }}
loadBalancerSourceRanges:
{{ toYaml .Values.service.loadBalancerSourceRanges | nindent 4 }}
{{- end }}
selector:
{{ include "kubernetes-dashboard.matchLabels" . | nindent 4 }}
app.kubernetes.io/component: kubernetes-dashboard
{{- if .Values.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.service.loadBalancerIP }}
{{- end }}
Снова есть ссылка на свойство .Values.protocolHttp
, которое теперь существует в разделе hull.config.specific
. Свойства ports
‘ name
и targetPort
устанавливаются в зависимости от protocolHttp
, тогда как externalPort
определяется централизованно. Поэтому имеет смысл централизовать доступ к externalPort
в hull.config.specific
, тем более что к externalPort
также обращаются при определении Ingress (подробнее об этом позже). Для этого выполните следующие действия:
sed '/^ssssspecific/r'<(
echo " externalPort: 443"
) -i -- values.yaml
Кроме port
s есть только selector
, который стоит обсудить, остальная часть шаблона Service представляет собой прямые 1:1 сопоставления. Но также проверьте значения по умолчанию блока службы в kubernetes-dashboard
в values.yaml
:
cat ../kubernetes-dashboard/values.yaml | grep "^service:" -B 1 -A 23
который печатает:
service:
type: ClusterIP
# Dashboard service port
externalPort: 443
## LoadBalancerSourcesRange is a list of allowed CIDR values, which are combined with ServicePort to
## set allowed inbound rules on the security group assigned to the master load balancer
# loadBalancerSourceRanges: []
## A user-specified IP address for load balancer to use as External IP (if supported)
# loadBalancerIP:
## Additional Kubernetes Dashboard Service annotations
annotations: {}
## Here labels can be added to the Kubernetes Dashboard service
labels: {}
## Enable or disable the kubernetes.io/cluster-service label. Should be disabled for GKE clusters >=1.15.
## Otherwise, the addon manager will presume ownership of the service and try to delete it.
clusterServiceLabel:
enabled: true
key: "kubernetes.io/cluster-service"
К объекту Service добавляется метка kubernetes.io/cluster-service
, а в качестве значения выступает enabled
, что представлено в этой части шаблона Service:
{{ .Values.service.clusterServiceLabel.key | nindent 4}}: {{ .Values.service.clusterServiceLabel.enabled | quote }}
Хотя вы можете подражать этой логике и переместить clusterServiceLabel
в раздел hull.config.specific
, это не дает никакого преимущества перед добавлением метки к новому экземпляру службы со значением по умолчанию true
. Конечно, можно добавить комментарий, чтобы объяснить более глубокий смысл этой метки.
Более подробный взгляд на селекторы
служб
Как уже отмечалось ранее, selector
matchLabels
для рабочих нагрузок автоматически строится из следующих меток:
app.kubernetes.io/component: default
app.kubernetes.io/instance: release-name
app.kubernetes.io/name: kubernetes-dashboard
Объекты Службы selector
в HULL следуют тому же принципу построения, поэтому это означает, что любая Служба, чей ключ идентичен экземпляру объекта рабочей нагрузки, selector
будет соответствовать, и Служба будет фронтировать стручки рабочей нагрузки. В нашем примере, если вы определите Deployment, DaemonSet или StatefulSet с ключом dashboard
, любой объект Службы с тем же ключом dashboard
будет соответствовать и будет позиционироваться как объект Службы для стручков на сетевом уровне. Это то, чего вы хотите добиться здесь, – служба для развертывания dashboard
. Попутно заметим, что для Jobs свойство selector
автоматически опускается HULL, поскольку в данном случае обработка selector
Jobs внутренне управляется Kubernetes.
Поэтому если вы опустите спецификацию selector
, у вас автоматически будет создан selector
по умолчанию, но если вы хотите смоделировать свойство selector
самостоятельно, вы можете явно перезаписать его. Примером такого использования является, например, создание дополнительной безголовой службы для StatefulSets или любой другой более тонкий контроль соответствия между службами и бодами. Для этого также существует преобразование HULL, hull.util.transformation.selector
или сокращенно _HT&
, которое будет использовано позже.
А пока вот преобразованный объект Service для dashboard
, использующий уже изученные вами приемы:
echo ' objects:
service:
dashboard:
labels:
## Enable or disable the kubernetes.io/cluster-service label. Should be disabled for GKE clusters >=1.15.
## Otherwise, the addon manager will presume ownership of the service and try to delete it.
"kubernetes.io/cluster-service": "true"
type: ClusterIP
ports:
http:
enabled: _HT?(index . "$").Values.hull.config.specific.protocolHttp
port: _HT*hull.config.specific.externalPort
targetPort: http
https:
enabled: _HT?(not (index . "$").Values.hull.config.specific.protocolHttp)
port: _HT*hull.config.specific.externalPort
targetPort: https' >> values.yaml
Определение ингрессов для входящего трафика
Далее посмотрите на исходное определение ингресса с помощью:
cat ../kubernetes-dashboard/templates/ingress.yaml
возвращение:
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
{{ if .Values.ingress.enabled -}}
{{- $serviceName := include "kubernetes-dashboard.fullname" . -}}
{{- $servicePort := .Values.service.externalPort -}}
{{- $paths := .Values.ingress.paths -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ template "kubernetes-dashboard.fullname" . }}
labels:
{{- include "kubernetes-dashboard.labels" . | nindent 4 }}
{{- range $key, $value := .Values.ingress.labels }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- if .Values.commonLabels }}
{{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }}
{{- end }}
annotations:
{{- if .Values.commonAnnotations }}
{{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
{{- end }}
{{- if not .Values.protocolHttp }}
# Add https backend protocol support for ingress-nginx
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
# Add https backend protocol support for GKE
service.alpha.kubernetes.io/app-protocols: '{"https":"HTTPS"}'
{{- end }}
{{- with .Values.ingress.annotations }}
{{ toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with .Values.ingress.className }}
ingressClassName: {{ . | quote }}
{{- end }}
rules:
{{- if .Values.ingress.hosts }}
{{- range $host := .Values.ingress.hosts }}
- host: {{ $host }}
http:
paths:
{{- if len ($.Values.ingress.customPaths) }}
{{- "n" }}{{ tpl (toYaml $.Values.ingress.customPaths | nindent 10) $ }}
{{- else }}
{{- range $p := $paths }}
- path: {{ $p }}
pathType: ImplementationSpecific
backend:
service:
name: {{ $serviceName }}
port:
number: {{ $servicePort }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- else }}
- http:
paths:
{{- if len ($.Values.ingress.customPaths) }}
{{- "n" }}{{ tpl (toYaml $.Values.ingress.customPaths | nindent 10) $ }}
{{- else }}
{{- range $p := $paths }}
- path: {{ $p }}
pathType: ImplementationSpecific
backend:
service:
name: {{ $serviceName }}
port:
number: {{ $servicePort }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if .Values.ingress.tls }}
tls:
{{ toYaml .Values.ingress.tls | nindent 4 }}
{{- end -}}
{{- end -}}
Вот что говорит values.yaml
об определении ingress
:
cat ../kubernetes-dashboard/values.yaml | grep "^ingress:" -B 1 -A 59
а именно:
ingress:
## If true, Kubernetes Dashboard Ingress will be created.
##
enabled: false
## Kubernetes Dashboard Ingress labels
# labels:
# key: value
## Kubernetes Dashboard Ingress annotations
# annotations:
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: 'true'
## If you plan to use TLS backend with enableInsecureLogin set to false
## (default), you need to uncomment the below.
## If you use ingress-nginx < 0.21.0
# nginx.ingress.kubernetes.io/secure-backends: "true"
## if you use ingress-nginx >= 0.21.0
# nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
## Kubernetes Dashboard Ingress Class
# className: "example-lb"
## Kubernetes Dashboard Ingress paths
## Both `/` and `/*` are required to work on gce ingress.
paths:
- /
# - /*
## Custom Kubernetes Dashboard Ingress paths. Will override default paths.
##
customPaths: []
# - pathType: ImplementationSpecific
# backend:
# service:
# name: ssl-redirect
# port:
# name: use-annotation
# - pathType: ImplementationSpecific
# backend:
# service:
# name: >-
# {{ include "kubernetes-dashboard.fullname" . }}
# port:
# # Don't use string here, use only integer value!
# number: 443
## Kubernetes Dashboard Ingress hostnames
## Must be provided if Ingress is enabled
##
# hosts:
# - kubernetes-dashboard.domain.com
## Kubernetes Dashboard Ingress TLS configuration
## Secrets must be manually created in the namespace
##
# tls:
# - secretName: kubernetes-dashboard-tls
# hosts:
# - kubernetes-dashboard.domain.com
Документация values.yaml
немного запутана, и шаблон довольно сложно расшифровать сразу, поэтому разберите его на части, чтобы понять, что здесь происходит:
- аннотации должны быть добавлены в ingress при условии, что
protocolHttp
не является true. Выдержка из шаблона ingress:
{{- if not .Values.protocolHttp }}
# Add https backend protocol support for ingress-nginx
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
# Add https backend protocol support for GKE
service.alpha.kubernetes.io/app-protocols: '{"https":"HTTPS"}'
{{- end }}
- Раздел
rules
записей в основном повторяется в шаблоне, один раз для всех хостов, если они указаны, или один раз без свойстваhost
, если хосты не указаны. Что касаетсяpaths
для обработки в обоих блоках, шаблон будет записывать все полностью указанныеcustomPaths
, если таковые имеются, или будет перебирать предопределенныеpaths
, еслиcustomPaths
не указаны, гдеpaths
все указывают наdashboard
Service:
rules:
{{- if .Values.ingress.hosts }}
{{- range $host := .Values.ingress.hosts }}
- host: {{ $host }}
http:
paths:
{{- if len ($.Values.ingress.customPaths) }}
{{- "n" }}{{ tpl (toYaml $.Values.ingress.customPaths | nindent 10) $ }}
{{- else }}
{{- range $p := $paths }}
- path: {{ $p }}
pathType: ImplementationSpecific
backend:
service:
name: {{ $serviceName }}
port:
number: {{ $servicePort }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- else }}
- http:
paths:
{{- if len ($.Values.ingress.customPaths) }}
{{- "n" }}{{ tpl (toYaml $.Values.ingress.customPaths | nindent 10) $ }}
{{- else }}
{{- range $p := $paths }}
- path: {{ $p }}
pathType: ImplementationSpecific
backend:
service:
name: {{ $serviceName }}
port:
number: {{ $servicePort }}
{{- end -}}
{{- end -}}
{{- end -}}
Вот простой подход к моделированию этого входа, где добавляется правило по умолчанию, как это было бы в оригинальной конфигурации values.yaml
:
echo ' ingress:
dashboard:
enabled: false
annotations: |-
_HT!{
{{ if not (index . "$").Values.hull.config.specific.protocolHttp }}
"nginx.ingress.kubernetes.io/backend-protocol": "HTTPS",
"service.alpha.kubernetes.io/app-protocols": "{"https":"HTTPS"}"
{{ end }}
}
rules:
default:
http:
paths:
root:
path: /
pathType: ImplementationSpecific
backend:
service:
name: dashboard
port:
number: _HT*hull.config.specific.externalPort' >> values.yaml
Если вам нужно изменить его во время развертывания, вы можете:
- добавить
host
к путиdefault
- изменить
path
для правилаdefault
, например, чтобы оно соответствовало нужному вам маршруту - установить
rule
дляdefault: null
, в котором оно больше не будет отображаться, и создать свое собственноеrule
.
В качестве проверки здравомыслия вы должны включить ингрессию, чтобы увидеть, что она печатается, как ожидалось:
echo 'hull:
objects:
ingress:
dashboard:
enabled: true' > ../configs/enable-ingress.yaml
&& helm template -f ../configs/disable-default-rbac.yaml -f ../configs/enable-ingress.yaml .
и вот оно:
---
# Source: kubernetes-dashboard/templates/hull.yaml
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
app.kubernetes.io/component: dashboard
app.kubernetes.io/instance: release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/part-of: undefined
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
kubernetes.io/cluster-service: "true"
name: release-name-kubernetes-dashboard-dashboard
spec:
ports:
- name: https
port: 443
targetPort: https
selector:
app.kubernetes.io/component: dashboard
app.kubernetes.io/instance: release-name
app.kubernetes.io/name: kubernetes-dashboard
type: ClusterIP
---
# Source: kubernetes-dashboard/templates/hull.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
service.alpha.kubernetes.io/app-protocols: '{"https":"HTTPS"}'
labels:
app.kubernetes.io/component: dashboard
app.kubernetes.io/instance: release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/part-of: undefined
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: release-name-kubernetes-dashboard-dashboard
spec:
rules:
- host:
http:
paths:
- backend:
service:
name: release-name-kubernetes-dashboard-dashboard
port:
number: 443
path: /
pathType: ImplementationSpecific
tls: []
Поскольку опция protocolHttp
оказывает значительное влияние на отображаемый результат, также сделайте быстрый тест, все ли в порядке:
echo 'hull:
config:
specific:
protocolHttp: true
objects:
ingress:
dashboard:
enabled: true' > ../configs/enable-ingress-http.yaml
&& helm template -f ../configs/disable-default-rbac.yaml -f ../configs/enable-ingress-http.yaml .
и вот оно:
---
# Source: kubernetes-dashboard/templates/hull.yaml
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
app.kubernetes.io/component: dashboard
app.kubernetes.io/instance: release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/part-of: undefined
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
kubernetes.io/cluster-service: "true"
name: release-name-kubernetes-dashboard-dashboard
spec:
ports:
- name: http
port: 443
targetPort: http
selector:
app.kubernetes.io/component: dashboard
app.kubernetes.io/instance: release-name
app.kubernetes.io/name: kubernetes-dashboard
type: ClusterIP
---
# Source: kubernetes-dashboard/templates/hull.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations: {}
labels:
app.kubernetes.io/component: dashboard
app.kubernetes.io/instance: release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: kubernetes-dashboard
app.kubernetes.io/part-of: undefined
app.kubernetes.io/version: 2.5.0
helm.sh/chart: kubernetes-dashboard-5.2.0
name: release-name-kubernetes-dashboard-dashboard
spec:
rules:
- host:
http:
paths:
- backend:
service:
name: release-name-kubernetes-dashboard-dashboard
port:
number: 443
path: /
pathType: ImplementationSpecific
tls: []
Еще одно подведение итогов
Итак, чтобы быстро закончить:
-
Вот как сейчас должен выглядеть ваш
values.yaml
:metrics-server: enabled: false hull: config: specific: externalPort: 443 protocolHttp: false rbac: clusterReadOnlyRole: false clusterRoleMetrics: true settings: {} pinnedCRDs: {} objects: service: dashboard: labels: ## Enable or disable the kubernetes.io/cluster-service label. Should be disabled for GKE clusters >=1.15. ## Otherwise, the addon manager will presume ownership of the service and try to delete it. "kubernetes.io/cluster-service": "true" type: ClusterIP ports: http: enabled: _HT?(index . "$").Values.hull.config.specific.protocolHttp port: _HT*hull.config.specific.externalPort targetPort: http https: enabled: _HT?(not (index . "$").Values.hull.config.specific.protocolHttp) port: _HT*hull.config.specific.externalPort targetPort: https ingress: dashboard: enabled: false annotations: |- _HT!{ {{ if not (index . "$").Values.hull.config.specific.protocolHttp }} "nginx.ingress.kubernetes.io/backend-protocol": "HTTPS", "service.alpha.kubernetes.io/app-protocols": "{"https":"HTTPS"}" {{ end }} } rules: default: http: paths: root: path: / pathType: ImplementationSpecific backend: service: name: dashboard port: number: _HT*hull.config.specific.externalPort
-
Запустите резервную копию
values.yaml
:cp values.yaml values.tutorial-part.yaml
-
Добавьте уже созданные объекты:
sed '1,/objects:/d' values.full.yaml > _tmp && cp values.yaml values.full.yaml && cat _tmp >> values.full.yaml && rm _tmp
Спасибо за участие и надеемся увидеть вас в следующей части туториала по расширенной конфигурации объектов!