前面我们讲过了对系统进行运行环境的监控,本文将继续讲述云原生应用架构下的日志收集功能。
说到日志收集模式,又要涉及到之前讲过的伴生(Sidecar)模式,上一次讲过伴生模式的弊端,就是伴生容器是根据主容器数量而增加的,一般一个node上会有数十数百个主容器,这样一来,假设一个node可承载容器的数量是n,若是一个主容器,有k个伴生容器,则这个node可承载主容器的数量就降低到n/(k+1)个了。
是不是不合算?
这时候DaemonSet就出现了。其主要考虑了伴生容器也是基于同一个镜像产生,那是不是可以一个node上只需要一个伴生容器,然后通过代理或其他机制把本应伴生容器做的工作中继给这个DaemonSet呢?
这样,若有m个主服务容器,则只需要m*(k-1)+1个容器了。资源节省了很多,而且管理方便。
再回到我们今天的主题——日志记录上来。因为部署模式有两种,也就出现了两种收集日志的方式。如果空间足够,我们建议采用DaemonSet模式,因为这种模式默认情况下会收集所有容器的日志(不包括DaemonSet);如果是只关注部分容器的日志,则可以采用伴生(Sidecar)模式。
Sidecar模式下的配置
(略……)
DaemonSet模式下的配置
配置命名空间
我们将为日志配置单独的命名空间
# fluentd-ns.yaml
apiVersion: v1
kind: Namespace
metadata:
name: logging
kubectl apply -f fluentd-ns.yaml
配置用户角色
配置专用的一个用户fluentd,然后创建一个角色fluentd,可以对资源pods、namespaces作get、list、watch等操作,并绑定该用户和该角色。
# fluentd-rbac.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: fluentd
namespace: logging
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: fluentd
namespace: logging
rules:
- apiGroups:
- ""
resources:
- pods
- namespaces
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: fluentd
roleRef:
kind: ClusterRole
name: fluentd
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: fluentd
namespace: logging
kubectl apply -f fluentd-rbac.yaml
创建 DaemonSet
注意:
- image一定要选择fluent/fluent-kubernetes-daemonset:v1.3.3-debian-elasticsearch-1.8,版本可以不一样,但必须是debian源的。
- 其中的CPU和内存可以根据实际情况修改
kind: DaemonSet
metadata:
name: fluentd
namespace: logging
labels:
k8s-app: fluentd-logging
version: v1
kubernetes.io/cluster-service: "true"
spec:
template:
metadata:
labels:
k8s-app: fluentd-logging
version: v1
kubernetes.io/cluster-service: "true"
spec:
serviceAccount: fluentd
serviceAccountName: fluentd
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:v1.3.3-debian-elasticsearch-1.8
env:
- name: FLUENT_ELASTICSEARCH_HOST
value: "10.81.247.23"
- name: FLUENT_ELASTICSEARCH_PORT
value: "9200"
- name: FLUENT_ELASTICSEARCH_SCHEME
value: "http"
- name: FLUENT_UID
value: "0"
- name: FLUENTD_SYSTEMD_CONF
value: "disable"
# X-Pack Authentication
# =====================
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
创建DaemonSet
kubectl apply -f fluentd-daemonset.yaml
查看Pod情况
kubectl get pods -n logging
NAME READY STATUS RESTARTS AGE
fluentd-9z7x2 1/1 Running 0 144m
fluentd-h89m2 1/1 Running 0 144m
fluentd-p6xfs 1/1 Running 1 144m
创建 Elasticsearch 和 Kinbana
我们不建议把Elasticsearch和Kinbana放在同一个Kubernetes中,在我们的实践里,我们选择把EK两个部件放在了单独一个Docker Swarm里。所以这里采用stack部署。
创建docker-composer文件
创建stack.yaml文件。本例中没有使用elasticsearch cluster,而是使用了一个node。
version: '3'
services:
elasticsearch:
image: elasticsearch:7.0.1
volumes:
- esdata:/usr/share/elasticsearch/data
environment:
- bootstrap.memory_lock=true
- "ES_JAVA_OPT=-Xms1g -Xmx1g"
- discovery.type=single-node
ports:
- "9300:9300"
- "9200:9200"
kibana:
image: kibana:7.0.1
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- XPACK_SECURITY_ENABLED=true
ports:
- "5601:5601"
volumes:
- $PWD/kibana.yml:/usr/share/kibana/config/kibana.yml
volumes:
esdata:
创建kibana.yaml文件
# Default Kibana configuration for docker target
server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://elasticsearch:9200" ]
xpack.monitoring.ui.container.elasticsearch.enabled: true
以上文件是Kinbana默认配置文件。
启动EK组件
docker stack up elastic -c stack.yaml
注意:Kinbana所在主机的存储空间必须足够才可以,否则将会进入只读状态,导致系统无法正常运作。
进入Kinbana
在Docker Swarm机器上,访问 http://localhost:5601/
进入Kinbana
查看。
由于没有进行任何设置,所以提示用户进行Index Pattern定义。在index pattern中输入logstash*
,然后点击next step。
在Time Filter field name
中选择@timestamp
,然后点击Create index pattern
。
完成后出现上图所示的界面。
返回到首页中,可以看到如上图所示的界面,列出了所有日志。
我们再创建个Filter来显示以前创建的Drupal的容器的日志
在Field中选择 kubernetes.pod_name
Operator: is
Value: drupal
然后保存。
从图中可以看到与之相关的日志,并且关键词以高亮显示。
注意:以上配置是比较简易的配置,在生产中还需要进一步完善。