описание проблемы
- Междоменная проблема внешнего интерфейса: когда страница загружает или асинхронно запрашивает ресурсы из источника, отличного от исходной страницы, политика браузера с тем же источником перехватит запрос. Более простой способ — добавить службу nginx на серверную часть. и добавьте данные, связанные с CORS, в данные ответа.
- Проблема с сертификатом: когда https-страница загружает http-ресурсы или ресурсы без действительного сертификата, на странице будет отображаться «небезопасный» логотип, поэтому вам необходимо подать заявку на сертификат для доменного имени, которое запрашивает ресурс, вы можете использоватьLet's EncryptПодайте заявку на получение сертификата бесплатно. Для ситуации, когда внутреннее доменное имя компании и другие внешние сети недоступны, вы можете только самостоятельно приобрести сертификат и настроить его в nginx.
Ниже с K8s отрабатываются как NGINX Service, так и Nginx Ingress.
решение
Вариант 1. Используйте сервис nginx.
Два набора сервисов развертываются отдельно, один — это сервис и развертывание веб-приложения, а другой — nginx.Пользователь напрямую обращается к сервису nginx, а затем nginx перенаправляет его в сервис, где находится веб-приложение. процесс очень похож на традиционный метод развертывания nginx.Точно так же просто измените адрес proxy_pass на доменное имя, которое может быть разрешено внутренним dns k8s:my-svc.my-namespace.svc.cluster-domain.example
, структура аналогична следующей:
Это решение требует развертывания отдельного nginx и монтирования локального файла в модуль, который необходимо настроить в соответствии с хостом, и не может полностью обеспечить развертывание одним щелчком мыши.
Каталог файлов программы выглядит следующим образом:
app
├── nginx
│ ├── deploy.yaml
│ └── svc.yaml
├── app.conf # nginx 配置文件
└── app.yaml
NGINX, связанная с конфигурацией
- Обслуживание и развертывание Nginx
# app/nginx/deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
volumeMounts:
- mountPath: /etc/nginx/conf.d/default.conf # nginx 配置文件在 pod 中的路径
name: nginx-volume
ports:
- containerPort: 80
volumes:
- name: nginx-volume
hostPath:
path: /path/to/app/app.conf # nginx 配置文件在本地的路径,将挂载到上面 volumeMounts 配置的路径,并覆盖 pod 中的 /etc/nginx/conf.d/default.conf
# app/nginx/svc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
run: nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: nginx
- конфигурация nginx
# app/app.conf
server {
server_name _ ;
listen 80;
location / {
# 允许 CORS 所需要的 header,如果浏览器中仍然出现 Access-Control-Allow-Headers 相关的报错则需要另外添加和修改 Access-Control-Allow-Headers 这一项
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
proxy_pass http://app.default.svc.cluster.local:8018; # 这里根据 k8s 集群内部的 dns 规则填写 web app 的地址,host 遵循 my-svc.my-namespace.svc.cluster-domain.example 的规则
}
}
конфигурация, связанная с веб-приложением
# app/app.yaml
apiVersion: v1
kind: Service
metadata:
name: app
spec:
selector:
app: app
ports:
- protocol: "TCP"
port: 8018
targetPort: 8018
# type: LoadBalancer 内网下无法使用 LoadBalancer 分配 External IP,会导致 service 的 External IP 一直是 <Pending>。因此不可使用 LoadBalancer 模式,可以使用默认的 NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
selector:
matchLabels:
app: app
replicas: 2
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: app:prod
ports:
- containerPort: 8018
Конфигурация HTTPS-сертификата
Если сервер имеет внешний сетевой IP-адрес, вы можете использовать Let's Encrypt для подачи заявки на бесплатный сертификат.Общий процесс заключается в использовании его на сервере.certbotПодать заявку на сертификат.crt
и.key
файл, а затем используйте тома k8s для монтирования сертификата в соответствующее место в контейнере nginx.
# app/nginx/deploy.yaml
...
spec:
containers:
- name: nginx
image: nginx:1.7.9
volumeMounts:
- mountPath: /etc/nginx/conf.d/default.conf # nginx 配置文件在 pod 中的路径
name: nginx-volume
- mountPath: /etc/ssl/YOUR_SSL.crt # crt 文件在 pod 中的路径
name: ssl-crt
- mountPath: /etc/ssl/YOUR_DOMAIN_NAME.key # 域名的 key 文件在 pod 中的路径
name: domain-key
ports:
- containerPort: 80
volumes:
- name: nginx-volume
hostPath:
path: /path/to/app/app.conf # nginx 配置文件在本地的路径,将挂载到上面 volumeMounts 配置的路径,并覆盖 pod 中的 /etc/nginx/conf.d/default.conf
- name: ssl-srt
hostPath:
path: /path/to/YOUR_SSL.crt # crt 文件在本地的路径
- name: domain-key
hostPath:
path: /path/to/YOUR_DOMAIN_NAME.key # 域名的 key 文件在本地的路径
Соответствующая конфигурация nginx выглядит следующим образом:
server {
listen 443;
ssl on;
ssl_certificate /etc/ssl/YOUR_SSL.crt;
ssl_certificate_key /etc/ssl/YOUR_DOMAIN_NAME.key;
server_name YOUR.DOMAIN;
location / {
proxy_pass http://app.default.svc.cluster.local:8018;
}
}
При использовании этого метода также необходимо настроить на сервере программу, связанную с автоматическим обновлением сертификата, что также можно сделать с помощьюcertbotУстановить.
Если это самостоятельный сертификат, вы также можете смонтировать и настроить его вышеописанным способом..crt
и.key
документ
Вариант 2
С Ingress внешние запросы сначала обращаются к Ingress, а затем распределяют запросы по разным сервисам, поэтому нет необходимости создавать еще одно развертывание nginx.Структура следующая:
Каталог файлов программы выглядит следующим образом:
app
├── cloud-generic.yaml
├── mandatory.yaml
├── ingress.yaml
├── deploy.yaml
└── svc.yaml
Настройка входа-nginx
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud-generic.yaml
ingress-nginx, определенный выше в облаке, используетtype: LoadBalancer
, если это интранет-среда и нельзя назначить внешний IP-адрес, его необходимо изменить наtype: NodePort
$ kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE nginx-ingress-controller-7dcc95dfbf-zxmc4 1/1 Running 0 11h
$ kubectl exec -it nginx-ingress-controller-7dcc95dfbf-zxmc4 bash -n ingress-nginx
www-data@nginx-ingress-controller-7dcc95dfbf-zxmc4:/etc/nginx$ cat nginx.conf
这里将输出 nginx 默认配置
Настройте попадание ниже и установите перекрестный доменную конфигурацию Nginx в проникновении
# app/ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/proxy-connect-timeout: '30'
nginx.ingress.kubernetes.io/proxy-send-timeout: '500'
nginx.ingress.kubernetes.io/proxy-read-timeout: '500'
nginx.ingress.kubernetes.io/send-timeout: "500"
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-methods: "*"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /app
backend:
serviceName: app
servicePort: 8018
После подготовки ingress.yaml снова проверьте конфигурацию nginx в модуле nginx-ingress следующим образом:
# nginx.conf
## start server _
server {
server_name _ ;
listen 80 default_server reuseport backlog=511 ;
listen 443 default_server reuseport backlog=511 ssl http2 ;
...
location /app{
set $namespace "default";
set $ingress_name "app-ingress";
set $service_name "";
set $service_port "";
set $location_path "/app";
...
more_set_headers 'Access-Control-Allow-Origin: *';
more_set_headers 'Access-Control-Allow-Credentials: true';
more_set_headers 'Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH, OPTIONS';
more_set_headers 'Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
}
...
}
## end server _
Вы можете видеть, что были добавлены заголовки, связанные с CORS./app
, если вам нужно добавить другие местоположения, вы можете добавить их в ingress.yamlspec/rules/paths
Средняя конфигурация
Deploy.yaml и svc.yaml веб-приложения такие же, как и в предыдущем методе.
Конфигурация HTTPS-сертификата
Настройка сертификатов HTTPS для входа в основном требует использованияcert managerЭта инструментальная комната, собственный инструмент управления сертификатами K8S, поддерживает бесплатные сертификаты, такие как Let's Encrypt, также поддерживает собственный сертификат и обеспечивает функцию автоматического обновления сертификатов.Подробные методы использования приведены в официальном документе или см.How to Set Up an Nginx Ingress with Cert-Manager on DigitalOcean Kubernetes
Ссылаться на
- Политика одинакового происхождения в браузере и как ее избежать
- Nginx Ingress Controller can't find nodes on Google Kubernetes Engine
- Service - Kubernetes Guide with Examples
- How to Set Up an Nginx Ingress with Cert-Manager on DigitalOcean Kubernetes
- Kubernetes Ingress with Nginx Example
- Kubernetes Ingress simply visually explained