Traefik代理集群外

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。 可以参考官方的例子。

你可以在其他容器中对进程发出信号。例如,发送 SIGHUPnginx 以重启工作进程。 此操作需要 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 上对其关联的DeploymentConfigsDeployments和进行滚动升级。Daemonsets Statefulsets Rollouts

使用 auto 时候他这将自动发现 deploymentconfigs/deployments/daemonsets/statefulset/rolloutsfoo-configmapfoo-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:

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注