前
K8S 集群希望再暴露其他的服务,但是不想再做一层Ingerss。
所以就这里记录一个偷懒的方法,直接使用 Traefik吧流量打到nginx 的Svc上来进行二次的转发。从而可以直接把入口流量打到集群之外的实例上去。
当然感觉整体的思路不大对,这样做破坏了集群的整体性。但是如服务还是处于混合的状态。也不失为一种办法。
正文
TLDR
因为是用的 K8s来进行部署的, 这里直接把yaml贴出来。用来一键部署就可以了。
yaml 包含 Deployment/configmap/service资源
但是这里的问题是 Config 改变了Nginx本身不会自行进行reload。所以后面的文章来也试图进优化
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ext
namespace: traefik
spec:
selector:
matchLabels:
app: nginx-ext
template:
metadata:
labels:
app: nginx-ext
spec:
containers:
- name: nginx-ext
image: nginx
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
volumeMounts:
- mountPath: /etc/nginx/
name: ge-config
volumes:
- name: ge-config
configMap:
name: nginx-config
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
namespace: traefik
data:
nginx.conf: >
worker_processes 2;
error_log /dev/stdout info;
worker_rlimit_nofile 8192;
events {
worker_connections 4096;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /dev/stdout main;
sendfile on;
tcp_nopush on;
server_names_hash_bucket_size 128;
server {
listen 80 default;
access_log /dev/stdout;
return 200 'This is text!';
}
server {
listen 80;
server_name domain2.com www.domain2.com;
access_log /dev/stdout main;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
}
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
namespace: traefik
spec:
selector:
app: nginx-ext
ports:
- port: 80
targetPort: 80
更近一步
Sidecar
前面提到的问题:如果实现configmap 监控从而实现自动reload。如果在容器内可以直接nginx -s reload
了。但是在Pod中,我们需要进行一个监控。
所以这里就要用到 Sidecar了,启用一个sidecar 来对内容进行监控,如果发生改变。那么就对nginx 进行reload操作。
这里需要注意的是POD中如果需要共享进程命名空间,这里需要启用 shareProcessNamespace。 可以参考官方的例子。
你可以在其他容器中对进程发出信号。例如,发送
SIGHUP
到nginx
以重启工作进程。 此操作需要SYS_PTRACE
权能。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
shareProcessNamespace: true
containers:
- name: nginx
image: nginx
- name: shell
image: busybox:1.28
securityContext:
capabilities:
add:
- SYS_PTRACE
stdin: true
tty: true
那么打通了进程命名的路子,这里就开始着手监控以及重启命令的代码。这里就可以用到 inotify来操作。实例代码如下
# 监视的文件或目录
filename=$1
# 监视发现有增、删、改时执行的脚本
script=$2
inotifywait -mrq --format '%w %f %e' --event create,delete,modify $filename | while read event
do
case $event in MODIFY|CREATE|DELETE) bash $script ;;
esac
done
Plugin-Reloader
这里还有更简单通用的方法 Reloader,ConfigMap Reloader
可以观察和中的变化,Secret
并在 Pod 上对其关联的DeploymentConfigs
、Deployments
和进行滚动升级。Daemonsets
Statefulsets
Rollouts
。
使用 auto 时候他这将自动发现 deploymentconfigs/deployments/daemonsets/statefulset/rollouts
foo-configmap
或foo-secret
正在通过环境变量或从卷挂载使用。foo-configmap
并且当或foo-secret
更新时,它会在相关的 Pod 上进行滚动升级
kind: Deployment
metadata:
annotations:
reloader.stakater.com/auto: "true"
spec:
template:
metadata:
监控特定的config文件时:
kind: Deployment
metadata:
annotations:
configmap.reloader.stakater.com/reload: "=foo-configmap"
# configmap.reloader.stakater.com/reload: "foo-configmap,bar-configmap,baz-configmap"
# secret.reloader.stakater.com/reload: "foo-secret,bar-secret,baz-secret"
spec:
template:
metadata: