{"id":403124,"date":"2024-06-29T16:55:44","date_gmt":"2024-06-29T16:55:44","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=403124"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=403124","title":{"rendered":"<span>Monitoring and Logging external services in Kubernetes<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/lc\/ag\/uf\/lcagufb_76iokvvi5hbzdgmgfqy.png\" alt=\"image\" data-src=\"https:\/\/habrastorage.org\/webt\/lc\/ag\/uf\/lcagufb_76iokvvi5hbzdgmgfqy.png\"\/><\/p>\n<p>  Greetings to all!<\/p>\n<p>  As a matter of fact I haven&#8217;t found so far any generalized guide on logging and monitoring of metrics from external systems to <a href=\"https:\/\/kubernetes.io\" rel=\"nofollow\">Kubernetes<\/a> on the web. Here I want to share with you my own version. First of all it is supposed that you have already got working <a href=\"https:\/\/prometheus.io\/\" rel=\"nofollow\">Prometheus<\/a> and other services.<\/p>\n<p>  As an example I use third-party data for stateful service RDBMS <a href=\"https:\/\/www.postgresql.org\" rel=\"nofollow\">PostgreSQL<\/a> in a <a href=\"https:\/\/www.docker.com\" rel=\"nofollow\">Docker<\/a> container. In our company we also use the <a href=\"https:\/\/helm.sh\" rel=\"nofollow\">Helm<\/a> package manager, and you&#8217;ll find how it works below. You can see same examples in this article below. You can see same examples in this article below. For a complete solution we create a nested chart. <br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h4>Logging<\/h4>\n<p>  Many companies use ELK stack for centralized logging (<a href=\"https:\/\/www.elastic.co\/\" rel=\"nofollow\">Elasticsearch<\/a> + <a href=\"https:\/\/www.elastic.co\/products\/logstash\" rel=\"nofollow\">Logstash<\/a> + <a href=\"https:\/\/www.elastic.co\/products\/kibana\" rel=\"nofollow\">kibana<\/a>). In our case we don&#8217;t need to index the content and I apply lightweight <a href=\"https:\/\/grafana.com\/oss\/loki\/\" rel=\"nofollow\">Loki<\/a>. It is available and can be installed as a Helm package. We added it as subchart having changed values for ingress &amp; pv.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">values.yaml<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"xml\">ingress:   enabled: true   annotations:      kubernetes.io\/ingress.class: nginx   hosts:     - host: kube-loki.example.domain       paths:          - \/   tls: []  ....  persistence:   type: pvc   enabled: true   accessModes:     - ReadWriteOnce   size: 100Gi   finalizers:     - kubernetes.io\/pvc-protection   existingClaim: \"pv-loki\" <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  We use <a href=\"https:\/\/github.com\/grafana\/loki\/tree\/master\/cmd\/docker-driver\" rel=\"nofollow\">Loki Docker Logging Driver<\/a> for log sending to instance <a href=\"https:\/\/grafana.com\/oss\/loki\/\" rel=\"nofollow\">Loki<\/a>.<br \/>  You have to set it up as a <a href=\"https:\/\/www.docker.com\" rel=\"nofollow\">Docker<\/a> plugin on all hosts from which you want to get logs. There are several ways to use plugin. My choice is to put it in the yaml file of <a href=\"https:\/\/docs.docker.com\/compose\/\" rel=\"nofollow\">Docker Compose<\/a> which is a part of <a href=\"https:\/\/www.ansible.com\/\" rel=\"nofollow\">Ansible<\/a> playbook.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">postgres.yaml<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"xml\">    - name: Run containers       docker_compose:         project_name: main-postgres         definition:           version: '3.7'           services:             p:               image: \"{{ postgres_version }}\"               container_name: postgresql               restart: always               volumes:                 - \"{{ postgres_dir }}\/data:\/var\/lib\/postgresql\/data\"                 - \"{{ postgres_dir }}\/postgres_init_scripts:\/docker-entrypoint-initdb.d\"               environment:                 POSTGRES_PASSWORD: {{ postgres_pass }}                 POSTGRES_USER: {{ postgres_user }}               ports:                 - \"{{ postgres_ip }}:{{ postgres_port }}:5432\"               logging:                 driver: \"loki\"                 options:                   loki-url: \"{{ loki_url }}\"                   loki-batch-size: \"{{ loki_batch_size }}\"                   loki-retries: \"{{ loki_retries }}\" ... <\/code><\/pre>\n<p>  where is loki_url: <a href=\"http:\/\/kube-loki.example.domain\/loki\/api\/v1\/push\" rel=\"nofollow\">kube-loki.example.domain\/loki\/api\/v1\/push<\/a>   <\/div>\n<\/p><\/div>\n<p>  <\/p>\n<h4>Metrics<\/h4>\n<p>  PostgreSQL metrics are collected to <a href=\"https:\/\/prometheus.io\/\" rel=\"nofollow\">Prometheus<\/a> with a <a href=\"https:\/\/github.com\/wrouesnel\/postgres_exporter\" rel=\"nofollow\">postgres_exporter<\/a>. See extension of <a href=\"https:\/\/www.ansible.com\/\" rel=\"nofollow\">Ansible<\/a> playbook file below.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">postgres.yaml<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"xml\">...             pexp:               image: \"wrouesnel\/postgres_exporter\"               container_name: pexporter               restart: unless-stopped               environment:                 DATA_SOURCE_NAME: \"postgresql:\/\/{{ postgres_user }}:{{ postgres_pass }}@p:5432\/postgres?sslmode=disable\"               ports:                 - \"{{ postgres_ip }}:{{ postgres_exporter_port }}:9187\"               logging:                 driver: \"json-file\"                 options:                   max-size: \"5m\" ... <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  For better clarity the names of external stateful services are presented with Endpoints.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">postgres-service.yaml<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"xml\">apiVersion: v1 kind: Endpoints metadata:   name: postgres-exporter subsets:   - addresses:       - ip: {{ .Values.service.postgres.ip }}     ports:       - port: {{ .Values.service.postgres.port }}         protocol: TCP --- apiVersion: v1 kind: Service metadata:   name: postgres-exporter   labels:     chart:  \"{{ .Chart.Name }}-{{ .Chart.Version | replace \"+\" \"_\" }}\" spec:   ports:     - protocol: TCP       port: {{ .Values.service.postgres.port }}       targetPort: {{ .Values.service.postgres.port }} <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  Prometheus settings for getting data from postgres_exporter are tuned by means of value editing in the subchart.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">values.yaml<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"xml\">scrape_configs: ...   - job_name: postgres-exporter     static_configs:       - targets:           - postgres-exporter.applicationnamespace.svc.cluster.local:9187         labels:           alias: postgres ... <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  For visualisation of data install a proper dashboard for <a href=\"https:\/\/grafana.com\" rel=\"nofollow\">Grafana<\/a> and add datasource. That can be done with values of Grafana subchart. See how it looks below.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">How it looks<\/b>                         <\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/fg\/sd\/j4\/fgsdj4wp_ivdihvncu5tbxzyytu.png\" data-src=\"https:\/\/habrastorage.org\/webt\/fg\/sd\/j4\/fgsdj4wp_ivdihvncu5tbxzyytu.png\"\/>  <\/div>\n<\/p><\/div>\n<p>  I hope my first brief article in English will help you to understand basic ideas of this solution and save your time when adjusting monitoring and logging procedures of external services in Loki\/Prometheus in Kubernetes.<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/506278\/\"> https:\/\/habr.com\/ru\/articles\/506278\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/lc\/ag\/uf\/lcagufb_76iokvvi5hbzdgmgfqy.png\" alt=\"image\" data-src=\"https:\/\/habrastorage.org\/webt\/lc\/ag\/uf\/lcagufb_76iokvvi5hbzdgmgfqy.png\"\/><\/p>\n<p>  Greetings to all!<\/p>\n<p>  As a matter of fact I haven&#8217;t found so far any generalized guide on logging and monitoring of metrics from external systems to <a href=\"https:\/\/kubernetes.io\" rel=\"nofollow\">Kubernetes<\/a> on the web. Here I want to share with you my own version. First of all it is supposed that you have already got working <a href=\"https:\/\/prometheus.io\/\" rel=\"nofollow\">Prometheus<\/a> and other services.<\/p>\n<p>  As an example I use third-party data for stateful service RDBMS <a href=\"https:\/\/www.postgresql.org\" rel=\"nofollow\">PostgreSQL<\/a> in a <a href=\"https:\/\/www.docker.com\" rel=\"nofollow\">Docker<\/a> container. In our company we also use the <a href=\"https:\/\/helm.sh\" rel=\"nofollow\">Helm<\/a> package manager, and you&#8217;ll find how it works below. You can see same examples in this article below. You can see same examples in this article below. For a complete solution we create a nested chart.   <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-403124","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/403124","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=403124"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/403124\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=403124"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=403124"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=403124"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}