k8s nginx междоменная конфигурация и конфигурация https

Kubernetes

описание проблемы

  1. Междоменная проблема внешнего интерфейса: когда страница загружает или асинхронно запрашивает ресурсы из источника, отличного от исходной страницы, политика браузера с тем же источником перехватит запрос. Более простой способ — добавить службу nginx на серверную часть. и добавьте данные, связанные с CORS, в данные ответа.
  2. Проблема с сертификатом: когда 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, связанная с конфигурацией

  1. Обслуживание и развертывание 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
  1. конфигурация 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

Ссылаться на