月度归档: 2020年12月

为k8s里运行的容器配置时区

需求背景

我们经常会用一些诸如emqx,nats等第三方中间件,这些中间件往往默认时区就是UTC时区,这其实也没关系,但是打印出来的日志,就会与我们的上海时区差8小时,为了解决这个问题,我的简单解决办法,就是把服务器的时区通过可读的方式挂载进去。

操作步骤

1、把服务器的时区设置成上海时区。ubuntu18系统时区设置方法如下:

timedatectl set-timezone Asia/Shanghai

2、修改emqx的StatefulSet.yaml 。注意挂载服务器的/etc/localtime到容器中,一定要设置readOnly: true,避免被误修改服务器的时区

# Source: emqx/templates/statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app: lzw-emqx
  name: lzw-emqx
spec:
  serviceName: lzw-emqx
  replicas: 1
  updateStrategy:
    type: RollingUpdate
  selector:
    matchLabels:
      app: lzw-emqx
  template:
    metadata:
      labels:
        app: lzw-emqx
    spec:
      containers:
        - image: emqx/emqx:4.2.4-alpine-amd64
          imagePullPolicy: IfNotPresent
          name: lzw-emqx
          envFrom:
            - configMapRef:
                name: lzw-emqx
          volumeMounts:
            - name: lzw-emqx-log
              mountPath: /opt/emqx/log
            - name: sfere-time-zone
              mountPath: /etc/localtime
              readOnly: true
          readinessProbe:
            httpGet:
              path: /status
              port: 8081
            initialDelaySeconds: 15
            periodSeconds: 2
      restartPolicy: Always
      volumes:
        - name: lzw-emqx-log
          emptyDir: {}
        - name: sfere-time-zone
          hostPath:
              path: /etc/localtime

traefik配置用户登录,限制K8S的web服务访问

背景

像Elastic-APM, Traefik-Dashboard等页面,是没有用户登录限制的,如果我们希望给他们加上用户登录限制,我们需要在traeifk里给对应的ingress添加登录用的Middleware,那么该如何添加呢?本文以给K8S部署的traefik dashboard为例进行添加

用户名密码加密

1.假设有如下3个用户名密码
lizhenwei 123
zhenwei.li 456
hello thankyou
2.我们通过htpasswd进行加密

htpasswd -nb lizhenwei 123
lizhenwei:$apr1$0wIJg4EG$RZ7wOIyIdg1R4gj4zAlzq1
htpasswd -nb zhenwei.li 456
zhenwei.li:$apr1$PX8cqECj$5zvC3eB1vhLioyjVjdkkE/
htpasswd -nb hello thankyou
hello:$apr1$4nlPGEqZ$nqz2ojkuxAY4FUEy0Tp3x1

3.将加密的信息放入一个叫policy的文件

vi policy
lizhenwei:$apr1$0wIJg4EG$RZ7wOIyIdg1R4gj4zAlzq1 zhenwei.li:$apr1$PX8cqECj$5zvC3eB1vhLioyjVjdkkE/ hello:$apr1$4nlPGEqZ$nqz2ojkuxAY4FUEy0Tp3x1

4.进行base64加密,获得加密后的字符

cat policy | openssl base64 

bGl6aGVud2VpOiRhcHIxJDB3SUpnNEVHJFJaN3dPSXlJZGcxUjRnajR6QWx6cTEK emhlbndlaS5saTokYXByMSRQWDhjcUVDaiQ1enZDM2VCMXZoTGlveWpWamRra0Uv CmhlbGxvOiRhcHIxJDRubFBHRXFaJG5xejJvamt1eEFZNEZVRXkwVHAzeDEK

创建middleware.yaml

将加密后的字符,复制到data.users下面

# Declaring the user list
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: test-auth
spec:
  basicAuth:
    secret: authsecret
---
# Note: in a kubernetes secret the string (e.g. generated by htpasswd) must be base64-encoded first.
# To create an encoded user:password pair, the following command can be used:
# htpasswd -nb user password | openssl base64
apiVersion: v1
kind: Secret
metadata:
  name: authsecret
  namespace: default
data:
  users: |2
    bGl6aGVud2VpOiRhcHIxJDB3SUpnNEVHJFJaN3dPSXlJZGcxUjRnajR6QWx6cTEK
    emhlbndlaS5saTokYXByMSRQWDhjcUVDaiQ1enZDM2VCMXZoTGlveWpWamRra0Uv
    CmhlbGxvOiRhcHIxJDRubFBHRXFaJG5xejJvamt1eEFZNEZVRXkwVHAzeDEK

创建ingress.yaml

定义访问路径,定义中间件

# dashboard.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: dashboard
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`traefik.test.local`) && (PathPrefix(`/dashboard`) || PathPrefix(`/api`))
      kind: Rule
      services:
        - name: api@internal
          kind: TraefikService
      middlewares:
        - name: test-auth

生效配置

kubectl apply -f middleware.yaml
kubectl apply -f ingress.yaml

检查打开网页时,是否弹出登录对话框

更新密码

如果我们要更新密码,可以重新使用htpasswd生成密码,然后放在policy文件中,使用命令行更新

kubectl create secret generic authsecret --from-file=users=./policy --dry-run=client -o yaml | kubectl apply -f -

 

traefik暴露kubernetes里的http服务和tcp服务

traeifk使用说明

traefik使用helm安装,搭配metalLB使用,由metalLB分配IP地址给traefik的loadbalancer

helm repo add traefik https://helm.traefik.io/traefik
helm upgrade -i traefik traefik/traefik --version 9.11.0 -f traefik/values.yaml

traefik暴露http服务的例子

配置如下http-ingress.yaml文件,暴露一个nginx,浏览器通过nginx.demo.test.local访问

#http-ingress.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: simpleingressroute
  namespace: default
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`nginx.demo.test.local`)
    kind: Rule
    services:
    - name: test-demo-service
      port: 80

解释:

  1. metadata.name不能重复
  2. namespace是暴露的svc对应的namespace
  3. Host(nginx.demo.test.local)表示接受到浏览器访问nginx.aimp.sferetest.local的时候,转到test-demo-service服务的80端口
  4. entryPoints对应的是我们安装traefik时,values.yaml里的ports参数下面的名称,如web的8000是内部端口,80是对外提供访问的端口
#values.yaml
ports:
  # The name of this one can't be changed as it is used for the readiness and
  # liveness probes, but you can adjust its config to your liking
  web:
    port: 8000
    # hostPort: 8000
    expose: true
    exposedPort: 80
    # The port protocol (TCP/UDP)
    protocol: TCP

traefik暴露tcp服务的例子

配置如下tcp-ingress.yaml文件,暴露一个redis,通过loadbalancerIP:6851访问

# tcp-ingress.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
  name: redisingleressroute
  namespace: test
spec:
  entryPoints:
    - redis
  routes:
  - match: HostSNI(`*`)
    kind: Rule
    services:
    - name: redis
      port: 6379

解释:

  1. kind得是IngressRouteTCP
  2. match必须是HostSNI(*)
  3. entryPoints对应的是我们安装traefik时,values.yaml里的ports参数下面的名称,如redis的6379是内部端口,6851是对外提供访问的端口
#values.yaml
  redis:
    port: 6379
    # hostPort: 8000
    expose: true
    exposedPort: 6851
    # The port protocol (TCP/UDP)
    protocol: TCP

苏ICP备18047533号-2