k8s资源限制

[toc]

一、网络策略

1.1 部署tomcat和nginx

1.1.1 创建命名空间

  • 创建linux和app命名空间并打label
kubectl create ns linux
kubectl create ns app
kubectl label ns linux nsname=linux
kubectl label ns app nsname=app

1.1.2 tomcat和nginx的yaml

  • tomcat的deployment和service
kind: Deployment
# 这里需要注意自己的k8s版本,通过kubectl explain deployment查看自己的k8s版本支持的版本号
# 这里以kubernetes v1.22.2为例
apiVersion: apps/v1
metadata:
  labels:
    app: app-tomcat-deployment-label
  name: app-tomcat-deployment
  namespace: app
spec:
  replicas: 1
  selector:
    matchLabels:
      app:app-tomcat-selector
  template:
    metadata:
      labels:
        app: app-tomcat-selector
    spec:
      containers:
      - name: app-tomcat-container
        image: tomcat:7.0.109-jdk8-openjdk
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          protocol: TCP
          name: http
          
---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: app-tomcat-service-label
  name: app-tomcat-service
  namespace: app
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
    nodePort: 30015
  selector:
    app: app-tomcat-selector
  • nginx的deployment和service
kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    app: app-nginx-deployment-label
  name: app-nginx-deployment
  namespace: app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-nginx-selector
  template:
    metadata:
      labels:
        app: app-nginx-selector
        project: app
    spec:
      containers:
      - name: app-nginx-container
        image: nginx:1.20.2-alpine
        imagePullPolicy: Always
        ports:
        - containerPort: 80
          protocol: TCP
          name: http
        - containerPort: 443
          protocol: TCP
          name: https

---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: app-nginx-service-label
  name: app-nginx-service
  namespace: app
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30014
  - name: https
    port: 443
    protocol: TCP
    targetPort: 443
    nodePort: 30453
  selector:
    app: app-nginx-selector

linux命名空间下的yaml同样配置,需修改下yaml文件中的命名空间和标签

1.1.3 部署tomcat和nginx

# 部署当前命名空间下的所有yaml文件
kubectl apply -f .

1.1.4 配置动静分离

  • 在tomcat中创建页面
# TOMCAT_CONTAINER需要替换为tomcat真实的容器名
kubectl -n app exec -it TOMCAT_CONTAINER bash 
cd webapps
mkdir app
echo "app app" > app/index.jsp
  • 配置nginx转发
kubectl -n app exec -it NGINX_CONTAINER sh
# nginx是基于alpine系统的,安装vim命令
apk add vim
# 配置匹配目录转发至tomcat规则
vim /etc/nginx/conf.d/default.conf
# 添加如下规则
location /app {
    # TOMCAT_SERVICE需要替换为tomcat真实的service名字
    proxy_pass http://TOMCAT_SERVICE; 
}
# 检查nginx配置文件语法
nginx -t
# 检查正确后,重新加载配置文件,让配置文件生效
nginx -s reload

遇到复制粘贴不了的情况

1645584428139.png

在命令模式下设置即可

1645584683595.png

linux命名空间同样配置,需要修改页面为"linux app"

1.1.5 验证配置

  • nginx页面
1645585087768.png
  • tomcat页面
1645585231992.png
  • 通过nginx端口访问tomcat
1645585279621.png

默认情况下pod跨命名空间也可以访问

1.2 配置网络策略规则

1.2.1 入规则标签限制

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: tomcat-access--networkpolicy
  namespace: app
spec:
  policyTypes:
  - Ingress
  podSelector:
    matchLabels:
      app: app-tomcat-selector # 对匹配到的目的Pod应用以下规则
  ingress: # 入栈规则,如果指定目标端口就是匹配全部端口和协议,协议TCP, UDP, or SCTP
  - from:
    - podSelector:
        matchLabels:
          app: app-nginx-selector # 如果存在多个matchLabel条件,要同时满足条件A、条件B、条件X

添加了网络策略后,默认禁止了跨namespace访问目标pod

没有在配置中允许的pod,同namespace也无法访问

不允许从宿主机访问pod

该策略只允许通namespace含有特定标签的源pod访问目标pod

该策略不影响各namespace的pod与非明确禁止的pod之间的相互访问

  • 可以使用describe查看networkpolicy
kubectl -n app describe networkpolicies.networking.k8s.io tomcat-access--networkpolicy
Name:         tomcat-access--networkpolicy
Namespace:    app
Created on:   2022-02-23 03:18:02 +0000 UTC
Labels:       <none>
Annotations:  <none>
Spec:
  PodSelector:     app=app-tomcat-selector
  Allowing ingress traffic:
    To Port: <any> (traffic allowed to all ports)
    From:
      PodSelector: app=app-nginx-selector
  Not affecting egress traffic
  Policy Types: Ingress
  • 添加规则后从linux命名空间下访问tomcat的地址
1645597541156.png

访问tomcat的pod地址不通,是因为网络规则限制;访问nginx的pod地址可以通过

1.2.2 入规则标签端口限制

  • 在1.2.1的yaml文件后边添加如下内容,位于from下边,跟podSelector同级
ports: #入栈规则,如果指定目标端口就是匹配全部端口和协议,协议TCP, UDP, or SCTP
    - protocol: TCP
      #port: 8080 #允许通过TCP协议访问目标pod的8080端口,但是其它没有允许的端口将全部禁止访问
      port: 80
  • 添加规则后从app命名空间下nginx中访问tomcat的地址,不放开8080端口,同命名空间下,符合podSelector匹配规则也访问不通;放开8080端口,可以访问通
1645598181215.png

1.2.3 入规则多端口限制

  • 1.2.1的yaml文件,用如下内容替换from内容
  - from:
    - podSelector: #匹配源pod,matchLabels: {}为不限制源pod即允许所有pod
        matchLabels: {}
    ports: #入栈规则,如果指定目标端口就是匹配全部端口和协议,协议TCP, UDP, or SCTP
    - protocol: TCP
      port: 8080
    - protocol: TCP
      port: 8081
    - protocol: TCP
      port: 8082
  • 同namespace下的所有pod可以访问目标pod的多个端口
1645599041496.png
1645599069009.png

1.2.4 入规则互访

  • 1.2.1的yaml文件,用如下内容替换Ingress内容
  - Ingress
  podSelector:
    matchLabels: {} 
  ingress:
  - from:
    - podSelector: 
        matchLabels: {}
  • 同namespace下所有pod可以相互访问
1645599069009.png
1645599983023.png

1.2.5 入规则IP限制

  • 1.2.1的yaml文件,用如下内容替换from内容
- from:
    - ipBlock:
        cidr: 10.200.0.0/16 #白名单,允许访问的地址范围,没有允许的将禁止访问目标pod
        except:
        - 10.200.218.0/24 #在以上范围内禁止访问的源IP地址
        - 10.200.230.239/32 #在以上范围内禁止访问的源IP地址
    ports: 
    - protocol: TCP
      port: 8080
    - protocol: TCP
      port: 8081
  • 白名单内地址可以访问通,明确限制的地址访问不通
1645600536617.png
1645600464526.png

这个规则只限制ip地址,不限制命名空间,不通命名空间下的pod,只要ip地址在白名单地址段,也可以访问目标pod

1.2.6 入规则命名空间限制

  • 1.2.1的yaml文件,用如下内容替换Ingress内容
- Ingress
  podSelector: #目标pod
    matchLabels: {} #允许访问app namespace 中的所有pod
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          nsname: linux #只允许指定的namespace访问
    - namespaceSelector:
        matchLabels:
          nsname: app #只允许指定的namespace访问
    ports:
    - protocol: TCP
      port: 8080
    - protocol: TCP
      port: 8081
    - protocol: TCP
      port: 8082
  • 允许多个namespace访问指定namespace中的所有pod和多个端口,没有被允许的namespace中的pod访问不通
1645601040168.png
1645601079875.png

1.2.7 出规则IP端口限制

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: egress-access-networkpolicy
  namespace: app
spec:
  policyTypes:
  - Egress
  podSelector: #目标pod选择器
    matchLabels:  #基于label匹配目标pod
      app: app-tomcat-selector #匹配app namespace中app的值为app-tomcat-selector的pod,然后基于egress中的指定网络策略进行出口方向的网络限制
  egress:
  - to:
    - ipBlock:
        cidr: 10.200.0.0/16 #允许匹配到的pod出口访问的目的CIDR地址范围
    - ipBlock:
        cidr: 172.31.7.106/32 #允许匹配到的pod出口访问的目的主机
    ports:
    - protocol: TCP
      port: 80 #允许匹配到的pod访问目的端口为80的访问
    - protocol: TCP
      port: 53 #允许匹配到的pod访问目的端口为53 即DNS的解析
    - protocol: UDP
      port: 53 #允许匹配到的pod访问目的端口为53 即DNS的解析
  • 目标pod可以访问指定地址段的多个端口,没有放开的端口访问不通
1645602269891.png

1.2.8 出规则标签端口限制

  • 1.2.7的yaml文件,用如下内容替换spec内容
spec:
  policyTypes:
  - Egress
  podSelector:
    matchLabels:
      app: app-nginx-selector
  egress:
  - to:
    - podSelector: 
        matchLabels:
          app: app-tomcat-selector
    ports:
    - protocol: TCP
      port: 8080
    - protocol: TCP
      port: 53
    - protocol: UDP
      port: 53
  • 限制目标pod只能访问匹配标签的pod的多个端口
1645603454703.png

1.2.9 出规则命名空间限制

  • 1.2.7的yaml文件,用如下内容替换egress内容
egress:
  - to:
    - namespaceSelector:
        matchLabels:
          nsname: python #指定允许访问的目的namespace
    - namespaceSelector:
        matchLabels:
          nsname: linux #指定允许访问的目的namespace
    ports:
    - protocol: TCP
      port: 8080
    - protocol: TCP
      port: 53
    - protocol: UDP
      port: 53
  • 指定目标pod可以访问多个命名空间的多个端口,未被允许的端口访问不通
1645604351218.png

calicoctl get networkpolicy -n app

这条命令可以使用calico的命令行工具查看网络规则,使用方法和kubectl一样,可以describe,可以-o yaml

注:网络规则需要网络组件支持,calico支持,flannel不支持

二、Ingress-NGINX

2.1 ExternalName

  • ExternalName的yaml文件
apiVersion: v1
kind: Service
metadata:
  name: my-external-test-name
  namespace: default
spec:
  type: ExternalName  #service类型
  externalName: www.baidu.com   #外部域名
  • 在service的ExternalName类型中绑定baidu的域名,pod内直接访问域名即可
1645666300469.png
  • CLusterIP和Endpoint的yaml文件
apiVersion: v1
kind: Service
metadata:
  name: mysql-production-server-name
  namespace: default
spec:
  ports:
    - port: 6379
---
kind: Endpoints
apiVersion: v1
metadata:
  name: mysql-production-server-name
  namespace: default
subsets:
  - addresses:
      - ip: 192.168.204.182
    ports:
      - port: 6379
  • 修改redis配置文件
1645667181373.png
  • 重启redis服务
systemctl restart redis
  • 进入pod中,安装epel-release,安装redis客户端,通过域名连接redis
1645668178651.png

在centos 7安装redis报错

1645666852755.png

安装epel源

1645666927600.png

再安装

1645666991690.png

2.2 创建ingress-nginx

  • 启动ingress-nginx的pod
1645668585935.png
  • 网页访问测试
1645668637961.png

访问任意一台主机的80端口,会得到这个报错,证明部署成功

2.3 匹配规则

2.3.1 匹配单主机

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-web
  namespace: linux
  annotations:
    kubernetes.io/ingress.class: "nginx" ##指定Ingress Controller的类型
    nginx.ingress.kubernetes.io/use-regex: "true" ##指定后面rules定义的path可以使用正则表达式
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "600" ##连接超时时间,默认为5s
    nginx.ingress.kubernetes.io/proxy-send-timeout: "600" ##后端服务器回转数据超时时间,默认为60s
    nginx.ingress.kubernetes.io/proxy-read-timeout: "600" ##后端服务器响应超时时间,默认为60s
    nginx.ingress.kubernetes.io/proxy-body-size: "50m" ##客户端上传文件,最大大小,默认为20m
    nginx.ingress.kubernetes.io/app-root: /index.html

spec:
  rules:
  - host: www.test.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: linux-tomcat-app1-service
            port:
              number: 80
  • 访问如下
1645670786676.png

需要现在linux命名空间下创建两个tomcat的service和deployment,在tomcat中创建目录和访问页,在主机上的hosts文件添加域名将解析(可以是负载均衡器的地址或者集群任意一个node的地址)

2.3.2 匹配多主机

  • 在2.3.1的yaml中添加如下内容
  - host: mobile.test.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: linux-tomcat-app2-service
            port:
              number: 80
  • 访问如下
1645671237081.png

2.3.3 匹配路径

  • 2.3.1的yaml中,host替换为如下内容
  - host: www.test.com
    http:
      paths:
      - pathType: Prefix
        path: "/app1"
        backend:
          service:
            name: magedu-tomcat-app1-service
            port:
              number: 80

      - pathType: Prefix
        path: "/app2"
        backend:
          service:
            name: magedu-tomcat-app2-service
            port:
              number: 80
  • 访问如下
1645671419515.png
1645671438059.png

2.3.4 匹配单域名

  • 签发域名证书
openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 3560 -nodes -subj '/CN=www.test.com'
openssl req -new -newkey rsa:4096 -keyout server.key -out server.csr -nodes -subj '/CN=www.test.com'
openssl x509 -req -sha256 -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
  • 证书上传至k8s
kubectl -n linux create secret generic tls-secret --from-file=tls.crt=server.crt --from-file=tls.key=server.key
  • 匹配规则yaml文件
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-web
  namespace: linux
  annotations:
    kubernetes.io/ingress.class: "nginx" ##指定Ingress Controller的类型
    nginx.ingress.kubernetes.io/ssl-redirect: 'true' #SSL重定向,即将http请求强制重定向至https,等于nginx中的全站https
spec:
  tls:
  - hosts:
    - www.test.com
    secretName: tls-secret

  rules:
  - host: www.test.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: magedu-tomcat-app1-service
            port:
              number: 80
  • 访问如下
1645673459174.png

2.3.5 匹配多域名

  • 签发多域名证书
openssl req -new -newkey rsa:4096 -keyout mobile.key -out mobile.csr -nodes -subj '/CN=mobile.test.com'
openssl x509 -req -sha256 -days 3650 -in mobile.csr -CA ca.crt -CAkey ca.key -set_serial 01  -out mobile.crt

针对2.3.4中签发的ca证书,签发多个域名

  • 证书上传至k8s
kubectl  create secret generic mobile-tls-secret --from-file=tls.crt=mobile.crt --from-file=tls.key=mobile.key -n linux
  • 2.3.4 的yaml中,spec替换为如下内容
spec:
  tls:
  - hosts:
    - www.test.com
    secretName: tls-secret
  - hosts:
    - mobile.test.com
    secretName: mobile-tls-secret
  rules:
  - host: www.test.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: magedu-tomcat-app1-service
            port:
              number: 80


  - host: mobile.test.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: magedu-tomcat-app2-service
            port:
              number: 80
  • 访问如下
1645673459174.png
1645673765032.png

三、资源限制

3.1 限制资源

  • 限制容器cpu和内存
        resources:
          limits:
            cpu: "1.2"
            memory: "512Mi"
          requests:
            memory: "100Mi"
            cpu: "500m"

requests的值一定要小于等于limits的值,不然创建时会报错;加上limits,容器最大允许使用的资源上限就是limits中设置的值

  • limitRange
apiVersion: v1
kind: LimitRange
metadata:
  name: limitrange-magedu
  namespace: linux
spec:
  limits:
  - type: Container       #限制的资源类型
    max:
      cpu: "2"            #限制单个容器的最大CPU
      memory: "2Gi"       #限制单个容器的最大内存
    min:
      cpu: "500m"         #限制单个容器的最小CPU
      memory: "512Mi"     #限制单个容器的最小内存
    default:
      cpu: "500m"         #默认单个容器的CPU限制
      memory: "512Mi"     #默认单个容器的内存限制
    defaultRequest:
      cpu: "500m"         #默认单个容器的CPU创建请求
      memory: "512Mi"     #默认单个容器的内存创建请求
    maxLimitRequestRatio:
      cpu: 2              #限制CPU limit/request比值最大为2
      memory: 2         #限制内存limit/request比值最大为1.5
  - type: Pod
    max:
      cpu: "4"            #限制单个Pod的最大CPU
      memory: "4Gi"       #限制单个Pod最大内存
  - type: PersistentVolumeClaim
    max:
      storage: 50Gi        #限制PVC最大的requests.storage
    min:
      storage: 30Gi        #限制PVC最小的requests.storage

创建后可以指定命名空间使用describe命令查看;如果设置的资源超过limitrange中规定的值,kubectl创建的时候不会报错,但是pod由于资源超过限制,起不来,不会被看到,但是没有报错信息;需要使用describe命令查看deployment输出yaml或者json格式内容,message有提示信息

  • ResourceQuato
apiVersion: v1
kind: ResourceQuota
metadata:
  name: quota-magedu
  namespace: linux
spec:
  hard:
    requests.cpu: "8" # 最小CPU
    limits.cpu: "8" # 最大CPU
    requests.memory: 4Gi # 最小内存
    limits.memory: 4Gi # 最大内存
    requests.nvidia.com/gpu: 4 # 最小英伟达GPU
    pods: "2" # 最多pod数量
    services: "6" # 最多service数量

ResourceQuato是针对命名空间的资源限制

四、RBAC授权

4.1 创建用户授权

  • 在linux命名空间下创建账户linux
kubectl -n linux create serviceaccount linux

k8s在创建用户的时候,会给用户分配一个token,这个token会一直伴随着用户,除非用户被删除重建,否则token不会变,secret名字可以使用get secret进行查看,describe查看token字符串

  • 创建角色
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: linux
  name: linux-role
rules:
- apiGroups: ["*"]
  resources: ["pods","pods/exec"]
  verbs: ["*"]
- apiGroups: ["extensions", "apps/v1"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

可以使用describe进行查看

  • 创建角色绑定
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: role-bind-magedu
  namespace: magedu
subjects:
- kind: ServiceAccount
  name: magedu
  namespace: magedu
roleRef:
  kind: Role
  name: magedu-role
  apiGroup: rbac.authorization.k8s.io

可以使用describe进行查看

4.2 限制用户授权

  • 创建角色仅有查看权限,替换4.1创建角色中的rules为如下内容
rules:
- apiGroups: ["*"]
  resources: ["pods","pods/exec"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["extensions", "apps/v1"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch"]

使用token登陆dashboard时,没有权限删除

4.3 生成kubeconfig文件

  • 创建csr文件
cat >> linux-csr.json <<EOF
{
  "CN": "China",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF
  • 签发证书
cfssl gencert -ca=/etc/kubernetes/ssl/ca.pem  -ca-key=/etc/kubernetes/ssl/ca-key.pem -config= /etc/kubeasz/clusters/cluster1/ssl/ca-config.json  -profile=kubernetes linux-csr.json | cfssljson -bare  linux
  • 生成普通用户kubeconfig文件
kubectl config set-cluster cluster1 --certificate-authority=/etc/kubernetes/ssl/ca.pem --embed-certs=true --server=https://192.168.204.101:6443 --kubeconfig=magedu.kubeconfig
  • 设置客户端认证参数
kubectl config set-credentials linux \
--client-certificate=linux.pem \
--client-key=linux-key.pem \
--embed-certs=true \
--kubeconfig=linux.kubeconfig
  • 设置上下文参数(多集群使用上下文区分)
kubectl config set-context cluster1 \
--cluster=cluster1 \
--user=linux \
--namespace=linux \
--kubeconfig=linux.kubeconfig

https://kubernetes.io/zh/docs/concepts/configuration/organize-cluster-access-kubeconfig/

  • 设置默认上下文
kubectl config use-context cluster1 --kubeconfig=magedu.kubeconfig
  • 查看token
kubectl -n linux describe secret `kubectl -n linux get secret | grep linux | awk '{print $1}'`
  • 编辑linux.kubeconfig,最后边追加写入token
    token: eyJhbGciOiJSUzI1NiIsImtpZCI6IkxpeWdUSzlaQ1AtMldqNjhwXzdaeVFJWEFHdnhLNEI5bGJ2UTZtaEcyMDQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJtYWdlZHUiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoibWFnZWR1LXRva2VuLWx6Y3g4Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Im1hZ2VkdSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjkwZjZkZTI5LWJlZjMtNGVlOC04MGMxLWI2OWZjZGE2N2IxZSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDptYWdlZHU6bWFnZWR1In0.G2JTuh3B9ncIt8sumk22oD13rUyzvHPtukudvtYZ7W6L_Tn1jRY8YldZKXB9PnejChm2_O3GWh84CCWr2kpad2ELH3nTFMdzFNig-sfoaubt19ZabdLRch1Pd9wu-4YWxPPjUxi3ZQvnxo-TIJ26k_Y5MVQuc81HW2NgvzFGTg4jh6Uusd12uz9HT7Z_JQn7CgSZLg2OrbAuq7OgUVqBqOpoVkN1CXsD6qu_xC7c_dvVsYmU9u-W8VFu4ScKNK1G1P77wsuIiBNN543wJ53dXTePDOrWJbkZvyDBfNFd4PaCCBCl9GVA8GlWVOWiV3A_xFh3D-ZTlFDRLLgJZAI5cQ

五、日志收集

5.1 镜像准备

  • 制作自定义基础系统镜像包centos

添加filebeat到基础镜像包,后续收集日志使用

  • 基于centos制作自定义jdk镜像

添加环境变量,以便能够全局执行java命令

  • 基于jdk制作tomcat镜像

创建日志挂载目录

  • 基于tomcat制作业务镜像

添加filebeat.yml文件,让filebeat读取配置并生效

5.2 搭建中间件

5.2.1 elasticsearch

  • 安装elasticsearch
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.16.0-amd64.deb
dpkg -i elasticsearch-7.16.0-amd64.deb

修改配置文件/etc/elasticsearch/elasticsearch.yml(版本:elasticsearch-7.16.0-amd64.deb)

# ======================== Elasticsearch Configuration =========================
#
# NOTE: Elasticsearch comes with reasonable defaults for most settings.
#       Before you set out to tweak and tune the configuration, make sure you
#       understand what are you trying to accomplish and the consequences.
#
# The primary way of configuring a node is via this file. This template lists
# the most important settings you may want to configure for a production cluster.
#
# Please consult the documentation for further information on configuration options:
# https://www.elastic.co/guide/en/elasticsearch/reference/index.html
#
# ---------------------------------- Cluster -----------------------------------
#
# Use a descriptive name for your cluster:
#
cluster.name: my-es
#
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
#
node.name: node-1
#
# Add custom attributes to the node:
#
#node.attr.rack: r1
#
# ----------------------------------- Paths ------------------------------------
#
# Path to directory where to store the data (separate multiple locations by comma):
#
path.data: /var/lib/elasticsearch
#
# Path to log files:
#
path.logs: /var/log/elasticsearch
#
# ----------------------------------- Memory -----------------------------------
#
# Lock the memory on startup:
#
#bootstrap.memory_lock: true
#
# Make sure that the heap size is set to about half the memory available
# on the system and that the owner of the process is allowed to use this
# limit.
#
# Elasticsearch performs poorly when the system is swapping the memory.
#
# ---------------------------------- Network -----------------------------------
#
# By default Elasticsearch is only accessible on localhost. Set a different
# address here to expose this node on the network:
#
network.host: IP
#
# By default Elasticsearch listens for HTTP traffic on the first free port it
# finds starting at 9200. Set a specific HTTP port here:
#
http.port: 9200
#
# For more information, consult the network module documentation.
#
# --------------------------------- Discovery ----------------------------------
#
# Pass an initial list of hosts to perform discovery when this node is started:
# The default list of hosts is ["127.0.0.1", "[::1]"]
#
discovery.seed_hosts: ["IP"]
#
# Bootstrap the cluster using an initial set of master-eligible nodes:
#
cluster.initial_master_nodes: ["IP"]
#
# For more information, consult the discovery and cluster formation module documentation.
#
# ---------------------------------- Various -----------------------------------
#
# Require explicit names when deleting indices:
#
action.destructive_requires_name: true
#
# ---------------------------------- Security ----------------------------------
#
#                                 *** WARNING ***
#
# Elasticsearch security features are not enabled by default.
# These features are free, but require configuration changes to enable them.
# This means that users don’t have to provide credentials and can get full access
# to the cluster. Network connections are also not encrypted.
#
# To protect your data, we strongly encourage you to enable the Elasticsearch security features.
# Refer to the following documentation for instructions.
#
# https://www.elastic.co/guide/en/elasticsearch/reference/7.16/configuring-stack-security.html
  • 重启elasticsearch
systemctl restart elasticsearch.service

5.2.2 logstash

  • 安装logstach
wget https://artifacts.elastic.co/downloads/logstash/logstash-7.16.0-amd64.deb
dpkg -i logstash-7.16.0-amd64.deb

修改配置文件 /etc/logstash/logstash.yml(版本:logstash-7.16.0-amd64.deb)

这里边只有数据路径和日志路径,可以不用修改

在/etc/logstash/conf.d/目录下编写json配置文件,文件名字可以自定义(kafka-to-es.conf),指定输入的kafka集群和topic,根据类日志型判断输然后出到es集群中

input {
  kafka {
    bootstrap_servers => "KAFKA_IP:9092"
    topics => ["TOPIC"]
    codec => "json"
  }
}

output{
  if [fields][type] == "tomcat-accesslog" {
    elasticsearch {
      hosts => ["ES_IP:9200"]
      index => "accesslog-%{+YYYY.MM.dd}"
    }
  }

  if [fields][type] == "tomcat-catalina" {
    elasticsearch {
      hosts => ["ES_IP:9200"]
      index => "catalinalog-%{+YYYY.MM.dd}"
    }
  }
}
  • 重启logstash
systemctl restart logstash.service

5.2.3 kibana

  • 安装kibana
wget https://artifacts.elastic.co/downloads/kibana/kibana-7.16.0-amd64.deb
dpkg -i kibana-7.16.0-amd64.deb

修改配置文件/etc/kibana/kibana.yml(版本:kibana-7.16.0-amd64.deb)

# Kibana is served by a back end server. This setting specifies the port to use.
server.port: 5601

# Specifies the address to which the Kibana server will bind. IP addresses and host names are both valid values.
# The default is 'localhost', which usually means remote machines will not be able to connect.
# To allow connections from remote users, set this parameter to a non-loopback address.
server.host: "192.168.204.113"

# Enables you to specify a path to mount Kibana at if you are running behind a proxy.
# Use the `server.rewriteBasePath` setting to tell Kibana if it should remove the basePath
# from requests it receives, and to prevent a deprecation warning at startup.
# This setting cannot end in a slash.
#server.basePath: ""

# Specifies whether Kibana should rewrite requests that are prefixed with
# `server.basePath` or require that they are rewritten by your reverse proxy.
# This setting was effectively always `false` before Kibana 6.3 and will
# default to `true` starting in Kibana 7.0.
server.rewriteBasePath: false

# Specifies the public URL at which Kibana is available for end users. If
# `server.basePath` is configured this URL should end with the same basePath.
#server.publicBaseUrl: ""

# The maximum payload size in bytes for incoming server requests.
server.maxPayload: 1048576

# The Kibana server's name.  This is used for display purposes.
server.name: "elasticsearch"

# The URLs of the Elasticsearch instances to use for all your queries.
elasticsearch.hosts: ["http://192.168.204.113:9200"]

# Kibana uses an index in Elasticsearch to store saved searches, visualizations and
# dashboards. Kibana creates a new index if the index doesn't already exist.
kibana.index: ".kibana"

# The default application to load.
kibana.defaultAppId: "home"

# If your Elasticsearch is protected with basic authentication, these settings provide
# the username and password that the Kibana server uses to perform maintenance on the Kibana
# index at startup. Your Kibana users still need to authenticate with Elasticsearch, which
# is proxied through the Kibana server.
#elasticsearch.username: "kibana_system"
#elasticsearch.password: "pass"

# Kibana can also authenticate to Elasticsearch via "service account tokens".
# If may use this token instead of a username/password.
# elasticsearch.serviceAccountToken: "my_token"

# Enables SSL and paths to the PEM-format SSL certificate and SSL key files, respectively.
# These settings enable SSL for outgoing requests from the Kibana server to the browser.
#server.ssl.enabled: false
#server.ssl.certificate: /path/to/your/server.crt
#server.ssl.key: /path/to/your/server.key

# Optional settings that provide the paths to the PEM-format SSL certificate and key files.
# These files are used to verify the identity of Kibana to Elasticsearch and are required when
# xpack.security.http.ssl.client_authentication in Elasticsearch is set to required.
#elasticsearch.ssl.certificate: /path/to/your/client.crt
#elasticsearch.ssl.key: /path/to/your/client.key

# Optional setting that enables you to specify a path to the PEM file for the certificate
# authority for your Elasticsearch instance.
#elasticsearch.ssl.certificateAuthorities: [ "/path/to/your/CA.pem" ]

# To disregard the validity of SSL certificates, change this setting's value to 'none'.
#elasticsearch.ssl.verificationMode: full

# Time in milliseconds to wait for Elasticsearch to respond to pings. Defaults to the value of
# the elasticsearch.requestTimeout setting.
elasticsearch.pingTimeout: 1500

# Time in milliseconds to wait for responses from the back end or Elasticsearch. This value
# must be a positive integer.
elasticsearch.requestTimeout: 30000

# List of Kibana client-side headers to send to Elasticsearch. To send *no* client-side
# headers, set this value to [] (an empty list).
#elasticsearch.requestHeadersWhitelist: [ authorization ]

# Header names and values that are sent to Elasticsearch. Any custom headers cannot be overwritten
# by client-side headers, regardless of the elasticsearch.requestHeadersWhitelist configuration.
#elasticsearch.customHeaders: {}

# Time in milliseconds for Elasticsearch to wait for responses from shards. Set to 0 to disable.
elasticsearch.shardTimeout: 30000

# Logs queries sent to Elasticsearch. Requires logging.verbose set to true.
elasticsearch.logQueries: false

# Specifies the path where Kibana creates the process ID file.
pid.file: /run/kibana/kibana.pid

# Enables you to specify a file where Kibana stores log output.
logging.dest: stdout

# Set the value of this setting to true to suppress all logging output.
logging.silent: false

# Set the value of this setting to true to suppress all logging output other than error messages.
logging.quiet: false

# Set the value of this setting to true to log all events, including system usage information
# and all requests.
logging.verbose: false

# Set the interval in milliseconds to sample system and process performance
# metrics. Minimum is 100ms. Defaults to 5000.
ops.interval: 5000

# Specifies locale to be used for all localizable strings, dates and number formats.
# Supported languages are the following: English - en , by default , Chinese - zh-CN .
i18n.locale: "zh-CN"
  • 重启kibana
systemctl restart kibana.service

5.2.4 zookeeper

  • 安装java
apt install -y openjdk-8-jdk
  • 安装zookeeper
wget https://www.apache.org/dyn/closer.lua/zookeeper/zookeeper-3.5.9/apache-zookeeper-3.5.9-bin.tar.gz
tar xf apache-zookeeper-3.5.9-bin.tar.gz

复制配置文件并重命名为zoo.cfg,修改配置文件

# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
dataDir=/data/zookeeper/zkdata
dataLogDir=/data/zookeeper/zklogs
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
maxClientCnxns=60
#
# Be sure to read the maintenance section of the 
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
server.1=IP:2888:3888
  • 启动zookeeper
./bin/kafka-server-start.sh -daemon ./config/server.properties

5.2.5 kafka

  • 安装kafka
wget https://archive.apache.org/dist/kafka/3.0.0/kafka_2.13-3.0.0.tgz
tar xf kafka_2.13-3.0.0.tgz

修改配置文件

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# see kafka.server.KafkaConfig for additional details and defaults

############################# Server Basics #############################

# The id of the broker. This must be set to a unique integer for each broker.
broker.id=0

############################# Socket Server Settings #############################

# The address the socket server listens on. It will get the value returned from 
# java.net.InetAddress.getCanonicalHostName() if not configured.
#   FORMAT:
#     listeners = listener_name://host_name:port
#   EXAMPLE:
#     listeners = PLAINTEXT://your.host.name:9092
listeners=PLAINTEXT://:9092

# Hostname and port the broker will advertise to producers and consumers. If not set, 
# it uses the value for "listeners" if configured.  Otherwise, it will use the value
# returned from java.net.InetAddress.getCanonicalHostName().
advertised.listeners=PLAINTEXT://192.168.204.111:9092

# Maps listener names to security protocols, the default is for them to be the same. See the config documentation for more details
#listener.security.protocol.map=PLAINTEXT:PLAINTEXT,SSL:SSL,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSL

# The number of threads that the server uses for receiving requests from the network and sending responses to the network
num.network.threads=3

# The number of threads that the server uses for processing requests, which may include disk I/O
num.io.threads=8

# The send buffer (SO_SNDBUF) used by the socket server
socket.send.buffer.bytes=102400

# The receive buffer (SO_RCVBUF) used by the socket server
socket.receive.buffer.bytes=102400

# The maximum size of a request that the socket server will accept (protection against OOM)
socket.request.max.bytes=1073741824


############################# Log Basics #############################

# A comma separated list of directories under which to store log files
log.dirs=/data/kafka/kafka-logs

# The default number of log partitions per topic. More partitions allow greater
# parallelism for consumption, but this will also result in more files across
# the brokers.
num.partitions=1

# The number of threads per data directory to be used for log recovery at startup and flushing at shutdown.
# This value is recommended to be increased for installations with data dirs located in RAID array.
num.recovery.threads.per.data.dir=1

############################# Internal Topic Settings  #############################
# The replication factor for the group metadata internal topics "__consumer_offsets" and "__transaction_state"
# For anything other than development testing, a value greater than 1 is recommended to ensure availability such as 3.
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1

############################# Log Flush Policy #############################

# Messages are immediately written to the filesystem but by default we only fsync() to sync
# the OS cache lazily. The following configurations control the flush of data to disk.
# There are a few important trade-offs here:
#    1. Durability: Unflushed data may be lost if you are not using replication.
#    2. Latency: Very large flush intervals may lead to latency spikes when the flush does occur as there will be a lot of data to flush.
#    3. Throughput: The flush is generally the most expensive operation, and a small flush interval may lead to excessive seeks.
# The settings below allow one to configure the flush policy to flush data after a period of time or
# every N messages (or both). This can be done globally and overridden on a per-topic basis.

# The number of messages to accept before forcing a flush of data to disk
#log.flush.interval.messages=10000

# The maximum amount of time a message can sit in a log before we force a flush
#log.flush.interval.ms=1000

############################# Log Retention Policy #############################

# The following configurations control the disposal of log segments. The policy can
# be set to delete segments after a period of time, or after a given size has accumulated.
# A segment will be deleted whenever *either* of these criteria are met. Deletion always happens
# from the end of the log.

# The minimum age of a log file to be eligible for deletion due to age
log.retention.hours=168

# A size-based retention policy for logs. Segments are pruned from the log unless the remaining
# segments drop below log.retention.bytes. Functions independently of log.retention.hours.
#log.retention.bytes=1073741824

# The maximum size of a log segment file. When this size is reached a new log segment will be created.
log.segment.bytes=1073741824

# The interval at which log segments are checked to see if they can be deleted according
# to the retention policies
log.retention.check.interval.ms=300000

############################# Zookeeper #############################

# Zookeeper connection string (see zookeeper docs for details).
# This is a comma separated host:port pairs, each corresponding to a zk
# server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002".
# You can also append an optional chroot string to the urls to specify the
# root directory for all kafka znodes.
zookeeper.connect=IP:2181

# Timeout in ms for connecting to zookeeper
zookeeper.connection.timeout.ms=18000


############################# Group Coordinator Settings #############################

# The following configuration specifies the time, in milliseconds, that the GroupCoordinator will delay the initial consumer rebalance.
# The rebalance will be further delayed by the value of group.initial.rebalance.delay.ms as new members join the group, up to a maximum of max.poll.interval.ms.
# The default value for this is 3 seconds.
# We override this to 0 here as it makes for a better out-of-the-box experience for development and testing.
# However, in production environments the default value of 3 seconds is more suitable as this will help to avoid unnecessary, and potentially expensive, rebalances during application startup.
group.initial.rebalance.delay.ms=0
  • 启动kafka
./bin/zkServer.sh start

5.2.6 filebeat

  • 安装filebeat
wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.12.1-x86_64.rpm
rpm -ivh filebeat-7.12.1-x86_64.rpm

由于镜像是基于centos系统的,所以下载的镜像是rpm包

修改配置文件/etc/filebeat/filebeat.yml(版本:filebeat-7.12.1-x86_64.rpm)

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /apps/tomcat/logs/catalina.out
  fields:
    type: tomcat-catalina
- type: log
  enabled: true
  paths:
    - /apps/tomcat/logs/localhost_access_log.*.txt
  fields:
    type: tomcat-accesslog
filebeat.config.modules:
  path: ${path.config}/modules.d/*.yml
  reload.enabled: false
setup.template.settings:
  index.number_of_shards: 1
setup.kibana:

# 连接kafka报错时,日志可以打开debug模式,方便定位失败原因
#logging.level

output.kafka:
  hosts: ["192.168.204.111:9092"]
  required_acks: 1
  topic: "magedu-n60-app1"
  compression: gzip
  max_message_bytes: 1000000
  • 启动filebeat
/usr/share/filebeat/bin/filebeat -e -c /etc/filebeat/filebeat.yml -path.home /usr/share/filebeat -path.config /etc/filebeat -path.data /var/lib/filebeat -path.logs /var/log/filebeat

-e选项是将日志标准输出,并且不写日志文件;-c选项是执行配置文件

5.3 查看日志

  • 日志收集逻辑图
1646293470844.png

业务容器中产生业务日志,通过filebeat客户端收集,传输到kafka集群,kafka依赖zookeeper集群,经由logstash进行逻辑判断,对业务类型进行分类,存入elasticsearch集群中,由kibana展示出来

  • kafka查看topic
/opt/kafka_2.12-3.0.0/bin/kafka-topics.sh --list --bootstrap-server localhost:9092 
1646363948681.png
  • kafka消费者指定topic查看日志
/opt/kafka_2.12-3.0.0/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic TOPIC
1646362018263.png

filebeat客户端收集日志到kafka的时候,需要注意kafka的版本,kafka版本太低,会报错

  • 查看es日志
1646361828162.png

谷歌浏览器插件elasticsearch head,如果谷歌浏览器找不到,或者找到插件不可用,可以用谷歌双核浏览器,应用市场中可以搜索到

  • 通过kibana展示日志
1646362242337.png
1646362344096.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容