diff --git a/docs/tasks/debug-application-cluster/fluend-gcp-configmap.yaml b/docs/tasks/debug-application-cluster/fluend-gcp-configmap.yaml
new file mode 100644
index 0000000000..5b281f5b21
--- /dev/null
+++ b/docs/tasks/debug-application-cluster/fluend-gcp-configmap.yaml
@@ -0,0 +1,390 @@
+kind: ConfigMap
+apiVersion: v1
+data:
+ containers.input.conf: |-
+ # This configuration file for Fluentd is used
+ # to watch changes to Docker log files that live in the
+ # directory /var/lib/docker/containers/ and are symbolically
+ # linked to from the /var/log/containers directory using names that capture the
+ # pod name and container name. These logs are then submitted to
+ # Google Cloud Logging which assumes the installation of the cloud-logging plug-in.
+ #
+ # Example
+ # =======
+ # A line in the Docker log file might look like this JSON:
+ #
+ # {"log":"2014/09/25 21:15:03 Got request with path wombat\\n",
+ # "stream":"stderr",
+ # "time":"2014-09-25T21:15:03.499185026Z"}
+ #
+ # The record reformer is used to write the tag to focus on the pod name
+ # and the Kubernetes container name. For example a Docker container's logs
+ # might be in the directory:
+ # /var/lib/docker/containers/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b
+ # and in the file:
+ # 997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b-json.log
+ # where 997599971ee6... is the Docker ID of the running container.
+ # The Kubernetes kubelet makes a symbolic link to this file on the host machine
+ # in the /var/log/containers directory which includes the pod name and the Kubernetes
+ # container name:
+ # synthetic-logger-0.25lps-pod_default-synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log
+ # ->
+ # /var/lib/docker/containers/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b-json.log
+ # The /var/log directory on the host is mapped to the /var/log directory in the container
+ # running this instance of Fluentd and we end up collecting the file:
+ # /var/log/containers/synthetic-logger-0.25lps-pod_default-synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log
+ # This results in the tag:
+ # var.log.containers.synthetic-logger-0.25lps-pod_default-synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log
+ # The record reformer is used is discard the var.log.containers prefix and
+ # the Docker container ID suffix and "kubernetes." is pre-pended giving the tag:
+ # kubernetes.synthetic-logger-0.25lps-pod_default-synth-lgr
+ # Tag is then parsed by google_cloud plugin and translated to the metadata,
+ # visible in the log viewer
+
+ # Example:
+ # {"log":"[info:2016-02-16T16:04:05.930-08:00] Some log text here\n","stream":"stdout","time":"2016-02-17T00:04:05.931087621Z"}
+
+ type tail
+ format json
+ time_key time
+ path /var/log/containers/*.log
+ pos_file /var/log/gcp-containers.log.pos
+ time_format %Y-%m-%dT%H:%M:%S.%N%Z
+ tag reform.*
+ read_from_head true
+
+
+
+ type parser
+ format /^(?\w)(?\d{4} [^\s]*)\s+(?\d+)\s+(?[^ \]]+)\] (?.*)/
+ reserve_data true
+ suppress_parse_error_log true
+ key_name log
+
+
+
+ type record_reformer
+ enable_ruby true
+ tag raw.kubernetes.${tag_suffix[4].split('-')[0..-2].join('-')}
+
+
+ # Detect exceptions in the log output and forward them as one log entry.
+
+ @type copy
+
+
+ @type prometheus
+
+
+ type counter
+ name logging_line_count
+ desc Total number of lines generated by application containers
+
+ tag ${tag}
+
+
+
+
+ @type detect_exceptions
+
+ remove_tag_prefix raw
+ message log
+ stream stream
+ multiline_flush_interval 5
+ max_bytes 500000
+ max_lines 1000
+
+
+ system.input.conf: |-
+ # Example:
+ # 2015-12-21 23:17:22,066 [salt.state ][INFO ] Completed state [net.ipv4.ip_forward] at time 23:17:22.066081
+
+ type tail
+ format /^(?[^ ]* [^ ,]*)[^\[]*\[[^\]]*\]\[(?[^ \]]*) *\] (?.*)$/
+ time_format %Y-%m-%d %H:%M:%S
+ path /var/log/salt/minion
+ pos_file /var/log/gcp-salt.pos
+ tag salt
+
+
+ # Example:
+ # Dec 21 23:17:22 gke-foo-1-1-4b5cbd14-node-4eoj startupscript: Finished running startup script /var/run/google.startup.script
+
+ type tail
+ format syslog
+ path /var/log/startupscript.log
+ pos_file /var/log/gcp-startupscript.log.pos
+ tag startupscript
+
+
+ # Examples:
+ # time="2016-02-04T06:51:03.053580605Z" level=info msg="GET /containers/json"
+ # time="2016-02-04T07:53:57.505612354Z" level=error msg="HTTP Error" err="No such image: -f" statusCode=404
+
+ type tail
+ format /^time="(?[^)]*)" level=(?[^ ]*) msg="(?[^"]*)"( err="(?[^"]*)")?( statusCode=($\d+))?/
+ path /var/log/docker.log
+ pos_file /var/log/gcp-docker.log.pos
+ tag docker
+
+
+ # Example:
+ # 2016/02/04 06:52:38 filePurge: successfully removed file /var/etcd/data/member/wal/00000000000006d0-00000000010a23d1.wal
+
+ type tail
+ # Not parsing this, because it doesn't have anything particularly useful to
+ # parse out of it (like severities).
+ format none
+ path /var/log/etcd.log
+ pos_file /var/log/gcp-etcd.log.pos
+ tag etcd
+
+
+ # Multi-line parsing is required for all the kube logs because very large log
+ # statements, such as those that include entire object bodies, get split into
+ # multiple lines by glog.
+
+ # Example:
+ # I0204 07:32:30.020537 3368 server.go:1048] POST /stats/container/: (13.972191ms) 200 [[Go-http-client/1.1] 10.244.1.3:40537]
+
+ type tail
+ format multiline
+ multiline_flush_interval 5s
+ format_firstline /^\w\d{4}/
+ format1 /^(?\w)(?\d{4} [^\s]*)\s+(?\d+)\s+(?[^ \]]+)\] (?.*)/
+ time_format %m%d %H:%M:%S.%N
+ path /var/log/kubelet.log
+ pos_file /var/log/gcp-kubelet.log.pos
+ tag kubelet
+
+
+ # Example:
+ # I1118 21:26:53.975789 6 proxier.go:1096] Port "nodePort for kube-system/default-http-backend:http" (:31429/tcp) was open before and is still needed
+
+ type tail
+ format multiline
+ multiline_flush_interval 5s
+ format_firstline /^\w\d{4}/
+ format1 /^(?\w)(?\d{4} [^\s]*)\s+(?\d+)\s+(?[^ \]]+)\] (?.*)/
+ time_format %m%d %H:%M:%S.%N
+ path /var/log/kube-proxy.log
+ pos_file /var/log/gcp-kube-proxy.log.pos
+ tag kube-proxy
+
+
+ # Example:
+ # I0204 07:00:19.604280 5 handlers.go:131] GET /api/v1/nodes: (1.624207ms) 200 [[kube-controller-manager/v1.1.3 (linux/amd64) kubernetes/6a81b50] 127.0.0.1:38266]
+
+ type tail
+ format multiline
+ multiline_flush_interval 5s
+ format_firstline /^\w\d{4}/
+ format1 /^(?\w)(?\d{4} [^\s]*)\s+(?\d+)\s+(?[^ \]]+)\] (?.*)/
+ time_format %m%d %H:%M:%S.%N
+ path /var/log/kube-apiserver.log
+ pos_file /var/log/gcp-kube-apiserver.log.pos
+ tag kube-apiserver
+
+
+ # Example:
+ # 2017-02-09T00:15:57.992775796Z AUDIT: id="90c73c7c-97d6-4b65-9461-f94606ff825f" ip="104.132.1.72" method="GET" user="kubecfg" as="" asgroups="" namespace="default" uri="/api/v1/namespaces/default/pods"
+ # 2017-02-09T00:15:57.993528822Z AUDIT: id="90c73c7c-97d6-4b65-9461-f94606ff825f" response="200"
+
+ type tail
+ format multiline
+ multiline_flush_interval 5s
+ format_firstline /^\S+\s+AUDIT:/
+ # Fields must be explicitly captured by name to be parsed into the record.
+ # Fields may not always be present, and order may change, so this just looks
+ # for a list of key="\"quoted\" value" pairs separated by spaces.
+ # Unknown fields are ignored.
+ # Note: We can't separate query/response lines as format1/format2 because
+ # they don't always come one after the other for a given query.
+ # TODO: Maybe add a JSON output mode to audit log so we can get rid of this?
+ format1 /^(?\S+) AUDIT:(?: (?:id="(?(?:[^"\\]|\\.)*)"|ip="(?(?:[^"\\]|\\.)*)"|method="(?(?:[^"\\]|\\.)*)"|user="(?(?:[^"\\]|\\.)*)"|groups="(?(?:[^"\\]|\\.)*)"|as="(?(?:[^"\\]|\\.)*)"|asgroups="(?(?:[^"\\]|\\.)*)"|namespace="(?(?:[^"\\]|\\.)*)"|uri="(?(?:[^"\\]|\\.)*)"|response="(?(?:[^"\\]|\\.)*)"|\w+="(?:[^"\\]|\\.)*"))*/
+ time_format %FT%T.%L%Z
+ path /var/log/kube-apiserver-audit.log
+ pos_file /var/log/gcp-kube-apiserver-audit.log.pos
+ tag kube-apiserver-audit
+
+
+ # Example:
+ # I0204 06:55:31.872680 5 servicecontroller.go:277] LB already exists and doesn't need update for service kube-system/kube-ui
+
+ type tail
+ format multiline
+ multiline_flush_interval 5s
+ format_firstline /^\w\d{4}/
+ format1 /^(?\w)(?\d{4} [^\s]*)\s+(?\d+)\s+(?[^ \]]+)\] (?.*)/
+ time_format %m%d %H:%M:%S.%N
+ path /var/log/kube-controller-manager.log
+ pos_file /var/log/gcp-kube-controller-manager.log.pos
+ tag kube-controller-manager
+
+
+ # Example:
+ # W0204 06:49:18.239674 7 reflector.go:245] pkg/scheduler/factory/factory.go:193: watch of *api.Service ended with: 401: The event in requested index is outdated and cleared (the requested history has been cleared [2578313/2577886]) [2579312]
+
+ type tail
+ format multiline
+ multiline_flush_interval 5s
+ format_firstline /^\w\d{4}/
+ format1 /^(?\w)(?\d{4} [^\s]*)\s+(?\d+)\s+(?[^ \]]+)\] (?.*)/
+ time_format %m%d %H:%M:%S.%N
+ path /var/log/kube-scheduler.log
+ pos_file /var/log/gcp-kube-scheduler.log.pos
+ tag kube-scheduler
+
+
+ # Example:
+ # I1104 10:36:20.242766 5 rescheduler.go:73] Running Rescheduler
+
+ type tail
+ format multiline
+ multiline_flush_interval 5s
+ format_firstline /^\w\d{4}/
+ format1 /^(?\w)(?\d{4} [^\s]*)\s+(?\d+)\s+(?[^ \]]+)\] (?.*)/
+ time_format %m%d %H:%M:%S.%N
+ path /var/log/rescheduler.log
+ pos_file /var/log/gcp-rescheduler.log.pos
+ tag rescheduler
+
+
+ # Example:
+ # I0603 15:31:05.793605 6 cluster_manager.go:230] Reading config from path /etc/gce.conf
+
+ type tail
+ format multiline
+ multiline_flush_interval 5s
+ format_firstline /^\w\d{4}/
+ format1 /^(?\w)(?\d{4} [^\s]*)\s+(?\d+)\s+(?[^ \]]+)\] (?.*)/
+ time_format %m%d %H:%M:%S.%N
+ path /var/log/glbc.log
+ pos_file /var/log/gcp-glbc.log.pos
+ tag glbc
+
+
+ # Example:
+ # I0603 15:31:05.793605 6 cluster_manager.go:230] Reading config from path /etc/gce.conf
+
+ type tail
+ format multiline
+ multiline_flush_interval 5s
+ format_firstline /^\w\d{4}/
+ format1 /^(?\w)(?\d{4} [^\s]*)\s+(?\d+)\s+(?[^ \]]+)\] (?.*)/
+ time_format %m%d %H:%M:%S.%N
+ path /var/log/cluster-autoscaler.log
+ pos_file /var/log/gcp-cluster-autoscaler.log.pos
+ tag cluster-autoscaler
+
+
+ # Logs from systemd-journal for interesting services.
+
+ type systemd
+ filters [{ "_SYSTEMD_UNIT": "docker.service" }]
+ pos_file /var/log/gcp-journald-docker.pos
+ read_from_head true
+ tag docker
+
+
+
+ type systemd
+ filters [{ "_SYSTEMD_UNIT": "kubelet.service" }]
+ pos_file /var/log/gcp-journald-kubelet.pos
+ read_from_head true
+ tag kubelet
+
+ monitoring.conf: |-
+ # Prometheus monitoring
+
+ @type prometheus
+ port 80
+
+
+
+ @type prometheus_monitor
+
+ output.conf: |-
+ # We use 2 output stanzas - one to handle the container logs and one to handle
+ # the node daemon logs, the latter of which explicitly sends its logs to the
+ # compute.googleapis.com service rather than container.googleapis.com to keep
+ # them separate since most users don't care about the node logs.
+
+ @type copy
+
+
+ @type google_cloud
+
+ # Set the buffer type to file to improve the reliability and reduce the memory consumption
+ buffer_type file
+ buffer_path /var/log/fluentd-buffers/kubernetes.containers.buffer
+ # Set queue_full action to block because we want to pause gracefully
+ # in case of the off-the-limits load instead of throwing an exception
+ buffer_queue_full_action block
+ # Set the chunk limit conservatively to avoid exceeding the GCL limit
+ # of 10MiB per write request.
+ buffer_chunk_limit 2M
+ # Cap the combined memory usage of this buffer and the one below to
+ # 2MiB/chunk * (6 + 2) chunks = 16 MiB
+ buffer_queue_limit 6
+ # Never wait more than 5 seconds before flushing logs in the non-error case.
+ flush_interval 5s
+ # Never wait longer than 30 seconds between retries.
+ max_retry_wait 30
+ # Disable the limit on the number of retries (retry forever).
+ disable_retry_limit
+ # Use multiple threads for processing.
+ num_threads 2
+
+
+ @type prometheus
+
+
+ type counter
+ name logging_entry_count
+ desc Total number of log entries generated by either an application container or a system component
+
+ tag ${tag}
+ component container
+
+
+
+
+
+ # Keep a smaller buffer here since these logs are less important than the user's
+ # container logs.
+
+ @type copy
+
+
+ @type google_cloud
+
+ detect_subservice false
+ buffer_type file
+ buffer_path /var/log/fluentd-buffers/kubernetes.system.buffer
+ buffer_queue_full_action block
+ buffer_chunk_limit 2M
+ buffer_queue_limit 2
+ flush_interval 5s
+ max_retry_wait 30
+ disable_retry_limit
+ num_threads 2
+
+
+ @type prometheus
+
+
+ type counter
+ name logging_entry_count
+ desc Total number of log entries generated by either an application container or a system component
+
+ tag ${tag}
+ component system
+
+
+
+
+metadata:
+ name: fluentd-gcp-config
+ labels:
+ addonmanager.kubernetes.io/mode: Reconcile
diff --git a/docs/tasks/debug-application-cluster/fluend-gcp-ds.yaml b/docs/tasks/debug-application-cluster/fluend-gcp-ds.yaml
new file mode 100644
index 0000000000..2b02f6993d
--- /dev/null
+++ b/docs/tasks/debug-application-cluster/fluend-gcp-ds.yaml
@@ -0,0 +1,108 @@
+apiVersion: extensions/v1beta1
+kind: DaemonSet
+metadata:
+ name: fluentd-gcp-v2.0
+ labels:
+ k8s-app: fluentd-gcp
+ kubernetes.io/cluster-service: "true"
+ addonmanager.kubernetes.io/mode: Reconcile
+ version: v2.0
+spec:
+ updateStrategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ labels:
+ k8s-app: fluentd-gcp
+ kubernetes.io/cluster-service: "true"
+ version: v2.0
+ # This annotation ensures that fluentd does not get evicted if the node
+ # supports critical pod annotation based priority scheme.
+ # Note that this does not guarantee admission on the nodes (#40573).
+ annotations:
+ scheduler.alpha.kubernetes.io/critical-pod: ''
+ spec:
+ dnsPolicy: Default
+ containers:
+ - name: fluentd-gcp
+ image: gcr.io/google-containers/fluentd-gcp:2.0.2
+ # If fluentd consumes its own logs, the following situation may happen:
+ # fluentd fails to send a chunk to the server => writes it to the log =>
+ # tries to send this message to the server => fails to send a chunk and so on.
+ # Writing to a file, which is not exported to the back-end prevents it.
+ # It also allows to increase the fluentd verbosity by default.
+ command:
+ - '/bin/sh'
+ - '-c'
+ - '/run.sh $FLUENTD_ARGS 2>&1 >>/var/log/fluentd.log'
+ env:
+ - name: FLUENTD_ARGS
+ value: --no-supervisor
+ resources:
+ limits:
+ memory: 300Mi
+ requests:
+ cpu: 100m
+ memory: 200Mi
+ volumeMounts:
+ - name: varlog
+ mountPath: /var/log
+ - name: varlibdockercontainers
+ mountPath: /var/lib/docker/containers
+ readOnly: true
+ - name: libsystemddir
+ mountPath: /host/lib
+ readOnly: true
+ - name: config-volume
+ mountPath: /etc/fluent/config.d
+ # Liveness probe is aimed to help in situarions where fluentd
+ # silently hangs for no apparent reasons until manual restart.
+ # The idea of this probe is that if fluentd is not queueing or
+ # flushing chunks for 5 minutes, something is not right. If
+ # you want to change the fluentd configuration, reducing amount of
+ # logs fluentd collects, consider changing the threshold or turning
+ # liveness probe off completely.
+ livenessProbe:
+ initialDelaySeconds: 600
+ periodSeconds: 60
+ exec:
+ command:
+ - '/bin/sh'
+ - '-c'
+ - >
+ LIVENESS_THRESHOLD_SECONDS=${LIVENESS_THRESHOLD_SECONDS:-300};
+ STUCK_THRESHOLD_SECONDS=${LIVENESS_THRESHOLD_SECONDS:-900};
+ if [ ! -e /var/log/fluentd-buffers ];
+ then
+ exit 1;
+ fi;
+ LAST_MODIFIED_DATE=`stat /var/log/fluentd-buffers | grep Modify | sed -r "s/Modify: (.*)/\1/"`;
+ LAST_MODIFIED_TIMESTAMP=`date -d "$LAST_MODIFIED_DATE" +%s`;
+ if [ `date +%s` -gt `expr $LAST_MODIFIED_TIMESTAMP + $STUCK_THRESHOLD_SECONDS` ];
+ then
+ rm -rf /var/log/fluentd-buffers;
+ exit 1;
+ fi;
+ if [ `date +%s` -gt `expr $LAST_MODIFIED_TIMESTAMP + $LIVENESS_THRESHOLD_SECONDS` ];
+ then
+ exit 1;
+ fi;
+ nodeSelector:
+ beta.kubernetes.io/fluentd-ds-ready: "true"
+ tolerations:
+ - key: "node.alpha.kubernetes.io/ismaster"
+ effect: "NoSchedule"
+ terminationGracePeriodSeconds: 30
+ volumes:
+ - name: varlog
+ hostPath:
+ path: /var/log
+ - name: varlibdockercontainers
+ hostPath:
+ path: /var/lib/docker/containers
+ - name: libsystemddir
+ hostPath:
+ path: /usr/lib64
+ - name: config-volume
+ configMap:
+ name: fluentd-gcp-config
diff --git a/docs/tasks/debug-application-cluster/logging-stackdriver.md b/docs/tasks/debug-application-cluster/logging-stackdriver.md
index b2946616a4..af2489435e 100644
--- a/docs/tasks/debug-application-cluster/logging-stackdriver.md
+++ b/docs/tasks/debug-application-cluster/logging-stackdriver.md
@@ -5,24 +5,110 @@ assignees:
title: Logging Using Stackdriver
---
-Before reading this page, it's highly recommended to familiarize yourself with the [overview of logging in Kubernetes](/docs/user-guide/logging/overview).
+Before reading this page, it's highly recommended to familiarize yourself
+with the [overview of logging in Kubernetes](/docs/concepts/cluster-administration/logging).
-This article assumes that you have created a Kubernetes cluster with cluster-level logging support for sending logs to Stackdriver Logging. You can do this either by selecting the **Enable Stackdriver Logging** checkbox in the create cluster dialogue in [GKE](https://cloud.google.com/container-engine/), or by setting the `KUBE_LOGGING_DESTINATION` flag to `gcp` when manually starting a cluster using `kube-up.sh`.
+**Note:** By default, Stackdriver logging collects only your container's standard output and
+standard error streams. To collect any logs your application writes to a file (for example),
+see the [sidecar approach](/docs/concepts/cluster-administration/logging/#using-a-sidecar-container-with-the-logging-agent)
+in the Kubernetes logging overview.
-The following guide describes gathering a container's standard output and standard error. To gather logs written by an application to a file, you can use [a sidecar approach](https://github.com/kubernetes/contrib/blob/master/logging/fluentd-sidecar-gcp/README.md).
+## Deploying
-## Overview
+To ingest logs, you must deploy the Stackdriver Logging agent to each node in your cluster.
+The agent is a configured `fluentd` instance, where the configuration is stored in a `ConfigMap`
+and the instances are managed using a Kubernetes `DaemonSet`. The actual deployment of the
+`ConfigMap` and `DaemonSet` for your cluster depends on your individual cluster setup.
-After creation, you can discover logging agent pods in the `kube-system` namespace,
-one per node, by running the following command:
+### Deploying to a new cluster
+
+#### Google Container Engine
+
+Stackdriver is the default logging solution for clusters deployed on Google Container Engine.
+Stackdriver Logging is deployed to a new cluster by default unless you explicitly opt-out.
+
+#### Other platforms
+
+To deploy Stackdriver Logging on a *new* cluster that you're
+creating using `kube-up.sh`, do the following:
+
+1. Set the `KUBE_LOGGING_DESTINATION` environment variable to `gcp`.
+1. **If not running on GCE**, include the `beta.kubernetes.io/fluentd-ds-ready=true`
+in the `KUBE_NODE_LABELS` variable.
+
+Once your cluster has started, each node should be running the Stackdriver Logging agent.
+The `DaemonSet` and `ConfigMap` are configured as addons. If you're not using `kube-up.sh`,
+consider starting a cluster without a pre-configured logging solution and then deploying
+Stackdriver Logging agents to the running cluster.
+
+### Deploying to an existing cluster
+
+1. Apply a label on each node, if not already present.
+
+ The Stackdriver Logging agent deployment uses node labels to determine to which nodes
+ it should be allocated. These labels were introduced to distinguish nodes with the
+ Kubernetes version 1.6 or higher. If the cluster was created with Stackdriver Logging
+ configured and node has version 1.5.X or lower, it will have fluentd as static pod. Node
+ cannot have more than one instance of fluentd, therefore only apply labels to the nodes
+ that don't have fluentd pod allocated already. You can ensure that your node is labelled
+ properly by running `kubectl describe` as follows:
+
+ ```shell
+ kubectl describe node $NODE_NAME
+ ```
+
+ The output should be similar to this:
+
+ ```
+ Name: NODE_NAME
+ Role:
+ Labels: beta.kubernetes.io/fluentd-ds-ready=true
+ ...
+ ```
+
+ Ensure that the output contains the label `beta.kubernetes.io/fluentd-ds-ready=true`. If it
+ is not present, you can add it using the `kubectl label` command as follows:
+
+ ```shell
+ kubectl label node $NODE_NAME beta.kubernetes.io/fluentd-ds-ready=true
+ ```
+
+ **Note:** If a node fails and has to be recreated, you must re-apply the label to
+ the recreated node. To make this easier, you can use Kubelet's command-line parameter
+ for applying node labels in your node startup script.
+
+1. Deploy a `ConfigMap` with the logging agent configuration by running the following command:
+
+ ```shell
+ kubectl create -f https://k8s.io/docs/tasks/debug-application-cluster/fluentd-gcp-configmap.yaml
+ ```
+
+ The command creates the `ConfigMap` in the default namespace. You can download the file
+ manually and change it before creating the `ConfigMap` object.
+
+1. Deploy the logging agent `DaemonSet` by running the following command:
+
+ ```shell
+ kubectl create -f https://k8s.io/docs/tasks/debug-application-cluster/fluentd-gcp-ds.yaml
+ ```
+
+ You can download and edit this file before using it as well.
+
+## Verifying your Logging Agent Deployment
+
+After Stackdriver `DaemonSet` is deployed, you can discover logging agent deployment status
+by running the following command:
```shell
-$ kubectl get pods --namespace=kube-system
-NAME READY STATUS RESTARTS AGE
+kubectl get ds --all-namespaces
+```
+
+If you have 3 nodes in the cluster, the output should looks similar to this:
+
+```
+NAMESPACE NAME DESIRED CURRENT READY NODE-SELECTOR AGE
...
-fluentd-gcp-v1.30-50gnc 1/1 Running 0 5d
-fluentd-gcp-v1.30-v255c 1/1 Running 0 5d
-fluentd-gcp-v1.30-f02l5 1/1 Running 0 5d
+kube-system fluentd-gcp-v2.0 3 3 3 beta.kubernetes.io/fluentd-ds-ready=true 6d
...
```
@@ -36,8 +122,7 @@ that writes out the value of a counter and the date once per
second, and runs indefinitely. Let's create this pod in the default namespace.
```shell
-$ kubectl create -f http://k8s.io/docs/user-guide/logging/examples/counter-pod.yaml
-pod "counter" created
+kubectl create -f http://k8s.io/docs/user-guide/logging/examples/counter-pod.yaml
```
You can observe the running pod: