kubernetes - 在 Kubernetes 上从 http 端口(80)重定向到 https 端口(443)
问题描述
我是新手,
如何在 Kubernetes 的同一域(服务)上从 http 端口(80)重定向到 https 端口(443)。
我尝试将 nginx 放在同一个 pod(容器)上并从 http 重定向到 https,但它没有用。
我在同一个吊舱上试过这种方式
//nginx
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
Kubernetes 示例部署文件。
//Jupyterhub is running on port 8000.
spec:
ports:
- port: 443
name: https
protocol: TCP
targetPort: 8000
- port: 80
name: http
protocol: TCP
targetPort: 433
Kubernetes中有默认方式吗?
任何帮助深表感谢。
解决方案
任何帮助深表感谢。
免责声明:到目前为止,这不是一个生产设置,主要旨在阐明整体的点点滴滴,以帮助您确定方向。此外,这将是一堵文字墙。
目标:在 kubernetes 集群中通过 https 运行 JupyterHub。
初步考虑:同时运行 nginx 和 JupyterHub 并不真正符合 k8s 哲学。仅当容器自然地缩放在一起时,容器才会一起放置在同一个 pod 中。事实并非如此。因此建议单独运行它们...
在 k8s 集群中为 JupyterHub 创建最小示例。
第 1 步:为此示例创建命名空间
这是相当简单的,只是在这里作为额外的保障,不要混淆。
清单文件:ns-example.yaml
apiVersion: v1
kind: Namespace
metadata:
name: ns-example
简单地说:kubectl create -f ns-example.yaml
命名空间就在那里。从现在开始,可以通过这种方式轻松创建/删除资源。
第 2 步:创建基本的 JupyterHub 设置
为了实现这个jupyterhub/jupyterhub
公开的官方 docker 图像被使用。无需自定义或其他任何东西,只需启动简单的多用户 JupyterHub 并做出响应,以便我们可以将其封装在服务包装器中。
我们从服务开始,没什么花哨的,只是一个方便的名称和暴露给本地集群的 8000 端口。官方文档建议在 sts/deploy/pod 资源之前创建服务,因此我们符合这一点。
清单文件:svc-jupyterhub.yaml
apiVersion: v1
kind: Service
metadata:
namespace: ns-example
name: svc-jupyterhub
labels:
name: jupyterhub
spec:
selector:
name: jupyterhub
ports:
- protocol: TCP
port: 8000
targetPort: 8000
现在对于上述服务将公开的 JupyterHub 的实际部署。同样,没什么特别的,这只是模仿官方 JupyterHub 存储库docker run -p 8000:8000 -d --name jupyterhub jupyterhub/jupyterhub jupyterhub
中提到的默认值。这没有任何定制,只是作为一个基本示例......
清单文件:dep-jupyterhub.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
namespace: ns-example
name: dep-jupyterhub
labels:
name: jupyterhub
spec:
replicas: 1
template:
metadata:
labels:
name: jupyterhub
spec:
containers:
- name: jupyterhub
image: jupyterhub/jupyterhub
command: ['jupyterhub']
ports:
- containerPort: 8000
注意:对于我的本地测试运行,从网上拉取初始图像需要相当长的时间,但是 ymmv...
创建此资源后,JupterHub 应该已启动并运行,但仅在本地 k8s 集群中可见。
第三步:创建nginx服务器
现在我们缺少 nginx 来公开和终止 JupyterHub 周围的 TLS。给猫剥皮的方法还有很多,但由于您只分享了 nginx 的部分设置,这里有一些粗略的部分可以帮助您入门。
要创建一些最小的 nginx 并模仿 TLS,我们需要一些配置文件。
我们从nginx.conf
保存 nginx 配置的文件开始。这是 ConfigMap 的自然候选者。另外,请注意,这绝不是完美的或完整的或生产就绪的设置 - 它只是一些快速启动 nginx 的方法,例如运行。有重复,这可以而且应该优化,端口 80 的重定向无法正常工作,因为它会将您触发到不存在的域,给定服务器的域是虚构的,通配符证书是自签名的,yada,yada,yada.. . 但它说明了这个想法:nginx 正在终止 TLS 并将流量发送到 JupyterHub 周围的上游服务。
清单文件:cm-nginx.yaml
kind: ConfigMap
apiVersion: v1
metadata:
namespace: ns-example
name: cm-nginx
data:
nginx.conf: |
# Exmaple nginx configuration file
#
# Commented out parts are left for pointers
upstream jupyterhub {
server svc-jupyterhub:8000 fail_timeout=0;
}
# jupyterhub.my-domain.com https request sent to upstream jupyterhub proxy
server {
listen 443 ssl;
server_name jupyterhub.my-domain.com;
ssl_certificate /etc/nginx/ssl/wildcard.my-domain.com.crt;
ssl_certificate_key /etc/nginx/ssl/wildcard.my-domain.com.key;
location / {
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect http:// https://;
proxy_pass http://jupyterhub;
# Required for new HTTP-based CLI
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_buffering off; # Required for HTTP-based CLI to work over SSL
}
}
# redicrection from http to https for jupyterhub.my-domain.com
# this obviously doesn't work since my-domain.com is not pointing to our server
server {
listen 80;
server_name jyputerhub.my-domain.com;
# root /nowhere;
# rewrite ^ https://jupyterhub.my-domain.com$request_uri permanent;
location / {
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect http:// https://;
proxy_pass http://jupyterhub;
# Required for new HTTP-based CLI
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_buffering off; # Required for HTTP-based CLI to work over SSL
}
}
# if none of named servers is matched on http...
# this obviously doesn't work since my-domain.com is not pointing to our server
server {
listen 80 default_server;
# root /nowhere;
# rewrite ^ https://jupyterhub.my-domain.com permanent;
location / {
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect http:// https://;
proxy_pass http://jupyterhub;
# Required for new HTTP-based CLI
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_buffering off; # Required for HTTP-based CLI to work over SSL
}
}
# if none of named server is matched on https...
# this obviously doesn't work since my-domain.com is not pointing to our server
server {
listen 443 default_server;
ssl_certificate /etc/nginx/ssl/wildcard.my-domain.com.crt;
ssl_certificate_key /etc/nginx/ssl/wildcard.my-domain.com.key;
# root /nowhere;
# rewrite ^ https://juputerhub.my-domain.com permanent;
location / {
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect http:// https://;
proxy_pass http://jupyterhub;
# Required for new HTTP-based CLI
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_buffering off; # Required for HTTP-based CLI to work over SSL
}
}
现在我们需要这些证书来运行......
当然,证书(尤其是私钥)是 Secret k8s 资源的完美候选者,但这是不存在的示例域的自签名证书(仅为本文动态生成)......接下来,我想说明ConfigMap 在这里和最后也有两个文件,但也许是最重要的 - 例如,我懒得再输入两个命令来获取 base64 中的所有内容。所以在这里它再次作为 ConfigMap ......(是的,它应该是 Secret,是的,REAL 证书/密钥不应该是公开的,但是 pssst,不要告诉任何人)......
清单文件:cm-wildcard-certificate-my-domain-com.yaml
kind: ConfigMap
apiVersion: v1
metadata:
namespace: ns-example
name: cm-wildcard-certificate-my-domain-com
data:
wildcard.my-domain.com.key: |
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCtU3Yk+tKSnPFC
l+0Iutma0xI79MiWEf8Z2vacyfgMUNvthqFxTfTIeeySzzFh1KVx8pYJbfL1Gkxx
iDfYZbKwQxhlV363bx8J+j2YnIIQ4uZGQ0MlxMlb65e0JfLayLOIffo7vSPqqBDa
6MY4qjqVuiJ7zW9/X9h+38Y76fHyEzde03cHihKnkW0smNKZcwYBLz5oa1D39zv5
WTqQrq+2GXEGfHvArDc06azbAm3o55iRmFPhIWEJcX6oCs0nd5jLIpycy43ayIKv
HvjEmChDnsrQDkMImFk0nDsMn0Leu0DAsyPopm3TIGqoPwZY4Sk+zn7ttjU/6VUI
pndJDVd5AgMBAAECggEAH6mTd4XqWaYZ3JRsVJ/tiH7uYc2Bpwh6lXqOem3axkUv
J+DkNRKMmOLM+LSozLpPztUF24seSvAW7tZ3fSx2zAQ1vK2TFGdUQDpabjqI+BS7
BDLdXVTpg8Ux3VLhXl4zjceVorwWh5NUIOlM7KUMNrXd/se0iowzvFmcmO1PqWzU
O6KI5EKz6LTUpEU/7RSl+wt/Ix4yTRYblkHlzWL1GXmQ50HYFZtC3iFEk4H4yDiQ
Z4VI+gGSpQGKDBQdR9OIXc3seVPOPnSd5NjDXQU8IR36VWHE8xG6k9/+TeU8r9ue
zNecjieWbFny4UE+uELXdeaRcmH+M8MTrKDApDj+QQKBgQDZ0WdOZ1O8QqILMwuR
Up2+oT88A6JZjfUICpDlsXgCaitT4YyBXkBwQyyQiTVspo6+ENHSBS584JdmjRpe
rqXazlwimY0vdINcm4O1279gmHOGaKffLzik1AKNSQEm52rNhle8xoXWD/cmLjvc
NYgzpPPFIWwXG0dniCCnbfR8tQKBgQDLtXpuckotb8guCGThFn6nb01Hcsit9OfC
QG9KXd8fpRV+YKqKF2wx1KeVgMoXMbmT78LRl0wArCQZsh16cqS/abH8S5k2v9jx
L5q+YYVcXC1U7Oolekoddob8af0qp4FnVDjRU9GiMtv2UQoX4yoX4kHkdWZqqFNr
q12VlksuNQKBgQCC6odq6lO7zVjT3mRPfhZto0D8czq7FMV3hdI9HAODgAh2rBPl
FZ8pWlaIsM85dIpK1pUl5BNi3yJgcuKskdAByRI7gYsIQMFLgfUR8vf9uOOGn5R2
Yk1rVDoMbRqSJXld+ib1wWRjmsjzW8qCunIYiEYz77il0rGCGqF1wHK4GQKBgQCN
RCTLQua9667efWO31GmwozbsPWV9fUDbLOQApmh9AXaOVWruqJ+XTumIe++pdgpD
1Rk9T7adIMNILoTSzX4CX8HWPHbbyN8hIuok7GwXSLUHF+SoaM3M8M1bbgTq9459
oaJlR8MwwCRaBIkDV71xIq6fR+rmPCTdndEgU0F/oQKBgQCWC1K5FySXxaxzomsZ
eM3Ey6cQ36QnidjuHAEiEcaJ+E/YmG/s9MPbLCRI8tn6KGvOW3zKzrHXOsoeXsMU
SCmRUpB0J5PqVbbTdj12kggX3x6I7TIkXucopCA3Nparhlnqx7amski2EB/EVE0C
YWkjEAMUCquUmJeEg2dELIiGOw==
-----END PRIVATE KEY-----
wildcard.my-domain.com.crt: |
-----BEGIN CERTIFICATE-----
MIIDNjCCAh4CCQCUtoVaGZH/NDANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJV
UzELMAkGA1UECAwCTlkxCzAJBgNVBAcMAk5ZMQwwCgYDVQQKDANOL0ExDDAKBgNV
BAsMA04vQTEYMBYGA1UEAwwPKi5teS1kb21haW4uY29tMB4XDTE4MDgyODA5Mzkz
N1oXDTIyMDUyNDA5MzkzN1owXTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMQsw
CQYDVQQHDAJOWTEMMAoGA1UECgwDTi9BMQwwCgYDVQQLDANOL0ExGDAWBgNVBAMM
DyoubXktZG9tYWluLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AK1TdiT60pKc8UKX7Qi62ZrTEjv0yJYR/xna9pzJ+AxQ2+2GoXFN9Mh57JLPMWHU
pXHylglt8vUaTHGIN9hlsrBDGGVXfrdvHwn6PZicghDi5kZDQyXEyVvrl7Ql8trI
s4h9+ju9I+qoENroxjiqOpW6InvNb39f2H7fxjvp8fITN17TdweKEqeRbSyY0plz
BgEvPmhrUPf3O/lZOpCur7YZcQZ8e8CsNzTprNsCbejnmJGYU+EhYQlxfqgKzSd3
mMsinJzLjdrIgq8e+MSYKEOeytAOQwiYWTScOwyfQt67QMCzI+imbdMgaqg/Bljh
KT7Ofu22NT/pVQimd0kNV3kCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAI+G44qo6
BPTC+bLm+2SAlr6oEC09JZ8Q/0m8Se1MLJnzhIXrWJZIdvEB1TtXPYDChz8TPKTd
QQCh7xNPZahMkVQWwbsknNCPdaLp0SAHMNs3nfTQjZ3cE/RRITqFkT0LGSjXkhtj
dTZdzKvcP8YEYnDhNn3ZBK04djEsAoIyordRATFQh1B7/0I3BsUAwItDEwH+Mv5G
rvSYkoi+yw7/koijxJHDbH0+WXYdcsmbWrMEh6H92Z64TMOFS+N6ZQRsNvzfiSwZ
KM2yEtU9c74CPKS+UleQLjDufk8epmNHx6+80aHj7R9z3mbw4dL7yKwlbGws2GAW
TE+Fk0HB+9W7fw==
-----END CERTIFICATE-----
现在我们需要围绕 nginx 的服务。
给猫剥皮的方法还有很多,但为了简单起见,这里再次采用最简单的方法 - NodePort 方法。您可以使用 ingress,您可以使用 externalIP 或其他什么,但这是示例,所以它是 NodePort。
清单文件:svc-nginx.yaml
apiVersion: v1
kind: Service
metadata:
namespace: ns-example
name: svc-nginx
labels:
name: nginx
spec:
type:
NodePort
selector:
name: nginx
ports:
- protocol: TCP
name: http-port
port: 80
targetPort: 80
- protocol: TCP
name: ssl-port
port: 443
targetPort: 443
最后,在创建完所有内容之后,我们可以启动我们的 nginx 部署。同样,将所有 ConfigMaps 与官方 nginx 映像粘合在一起并没有什么特别的(是的,使用“最新”或省略 docker 映像的标签是个坏主意,就像这里所做的那样,但是,这又是一个示例,请记住不要在生产部署中被它咬住......)
清单文件:dep-nginx.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
namespace: ns-example
name: dep-nginx
labels:
name: nginx
annotations:
ingress.kubernetes.io/secure-backends: "true"
kubernetes.io/tls-acme: "true"
spec:
replicas: 1
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /etc/nginx/conf.d
name: nginx-conf
- mountPath: /etc/nginx/ssl
name: wildcard-certificate
volumes:
- name: nginx-conf
configMap:
name: cm-nginx
items:
- key: nginx.conf
path: nginx.conf
- name: wildcard-certificate
configMap:
name: cm-wildcard-certificate-my-domain-com
最后注意事项:
- 如前所述,这些并不意味着在生产中使用,从资源处理到版本控制的许多微小细节都会让你望而却步。这只是一个例子。
- 证书是自签名的,如果您导航到 nginx,浏览器会抱怨这一点。
- 一切都是从 DockerCE Edge 版本 18.06.0-ce-mac69 (26398) 和 1.9.3 k8s 上的测试设置粘贴的,因此应该或多或少没有错误。
- 键入
kubectl get cm,deploy,svc,pod -n ns-example -o wide
应该显示所有信息(对于 svc-nginx 的目标浏览器端口将特别感兴趣)。 - 最后,由于所有内容都包含在 yaml 清单文件中,因此清理只是有序删除资源的问题(注意最后删除命名空间)。
推荐阅读
- facebook-pixel - Facebook Pixel 未在所有页面上触发
- firebase - 在 Flutter 中保存网络图像以离线加载它们
- android - 从url打开pdf文件时在flutter中添加进度条
- python - 如何禁用按钮直到完成一个功能并使用 python 和 html.Button 再次启用
- wso2 - 如何在 WSO2 AM docker 中使用相同的超级管理员
- wpf - 获取标题名称
- css - CSS 无限水平动画“闪烁”(在移动设备上)
- angular - 获取被删除元素的名称和ID
- mocking - 是否有任何可用于非角度应用程序的 Protractor HTTP Mock 库?
- java - 如何保留或保存选定的值?