Skip to content
This repository was archived by the owner on Sep 30, 2020. It is now read-only.

Commit c67b469

Browse files
jollinsheadmumoshu
authored andcommitted
Send Journald logs to AWS CloudWatch (#707)
A service has been introduced which runs a dockerised image of journald-cloudwatch-logs. This service forwards journald logs to AWS CloudWatch to a LogGroup with the name of .ClusterName and is run on all nodes (Etcds, Controllers and Workers). journald-cloudwatch-logs is a goLang project https://github.com/saymedia/journald-cloudwatch-logs. This feature is disabled by default and configurable in cluster.yaml: ``` cloudWatchLogging: enabled: false retentionInDays: 7 journaldCloudWatchLogsImage: jollinshead/journald-cloudwatch-logs:0.1 ```
1 parent 8bc860d commit c67b469

File tree

13 files changed

+237
-13
lines changed

13 files changed

+237
-13
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Journald logging to AWS CloudWatch
2+
3+
A service has been introduced which runs a dockerised image of *journald-cloudwatch-logs*. This service forwards journald logs to AWS CloudWatch to a LogGroup with the name of .ClusterName and is run on all nodes (Etcds, Controllers and Workers).
4+
5+
*journald-cloudwatch-logs* is a goLang project https://github.com/saymedia/journald-cloudwatch-logs.
6+
7+
The default docker image *[jollinshead/journald-cloudwatch-logs](https://hub.docker.com/r/jollinshead/journald-cloudwatch-logs/)* is a wrapper around the go binary of *journald-cloudwatch-logs*.
8+
9+
This feature is disabled by default and configurable in cluster.yaml:
10+
11+
```
12+
cloudWatchLogging:
13+
enabled: false
14+
imageWithTag: jollinshead/journald-cloudwatch-logs:0.1
15+
retentionInDays: 7
16+
```

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Check out our getting started tutorial on launching your first Kubernetes cluste
4747
* [Backup and restore for etcd](/Documentation/kubernetes-on-aws-backup-and-restore-for-etcd.md)
4848
* [Backup Kubernetes resources](/Documentation/kubernetes-on-aws-backup.md)
4949
* [Restore Kubernetes resources](/contrib/cluster-backup/README.md)
50+
* [Journald logging to AWS CloudWatch](/Documentation/kubernetes-on-aws-journald-cloudwatch-logs.md)
5051

5152
## Examples
5253

core/controlplane/config/config.go

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -103,16 +103,20 @@ func NewDefaultCluster() *Cluster {
103103

104104
return &Cluster{
105105
DeploymentSettings: DeploymentSettings{
106-
ClusterName: "kubernetes",
107-
VPCCIDR: "10.0.0.0/16",
108-
ReleaseChannel: "stable",
109-
K8sVer: k8sVer,
110-
ContainerRuntime: "docker",
111-
Subnets: []model.Subnet{},
112-
EIPAllocationIDs: []string{},
113-
MapPublicIPs: true,
114-
Experimental: experimental,
115-
ManageCertificates: true,
106+
ClusterName: "kubernetes",
107+
VPCCIDR: "10.0.0.0/16",
108+
ReleaseChannel: "stable",
109+
K8sVer: k8sVer,
110+
ContainerRuntime: "docker",
111+
Subnets: []model.Subnet{},
112+
EIPAllocationIDs: []string{},
113+
MapPublicIPs: true,
114+
Experimental: experimental,
115+
ManageCertificates: true,
116+
CloudWatchLogging: CloudWatchLogging{
117+
Enabled: false,
118+
RetentionInDays: 7,
119+
},
116120
HyperkubeImage: model.Image{Repo: "quay.io/coreos/hyperkube", Tag: k8sVer, RktPullDocker: false},
117121
AWSCliImage: model.Image{Repo: "quay.io/coreos/awscli", Tag: "master", RktPullDocker: false},
118122
CalicoNodeImage: model.Image{Repo: "quay.io/calico/node", Tag: "v1.2.1", RktPullDocker: false},
@@ -132,6 +136,7 @@ func NewDefaultCluster() *Cluster {
132136
PauseImage: model.Image{Repo: "gcr.io/google_containers/pause-amd64", Tag: "3.0", RktPullDocker: false},
133137
FlannelImage: model.Image{Repo: "quay.io/coreos/flannel", Tag: "v0.7.1", RktPullDocker: false},
134138
DexImage: model.Image{Repo: "quay.io/coreos/dex", Tag: "v2.4.1", RktPullDocker: false},
139+
JournaldCloudWatchLogsImage: model.Image{Repo: "jollinshead/journald-cloudwatch-logs", Tag: "0.1", RktPullDocker: true},
135140
},
136141
KubeClusterSettings: KubeClusterSettings{
137142
DNSServiceIP: "10.3.0.10",
@@ -485,6 +490,7 @@ type DeploymentSettings struct {
485490
Experimental Experimental `yaml:"experimental"`
486491
ManageCertificates bool `yaml:"manageCertificates,omitempty"`
487492
WaitSignal WaitSignal `yaml:"waitSignal"`
493+
CloudWatchLogging `yaml:"cloudWatchLogging,omitempty"`
488494

489495
// Images repository
490496
HyperkubeImage model.Image `yaml:"hyperkubeImage,omitempty"`
@@ -506,6 +512,7 @@ type DeploymentSettings struct {
506512
PauseImage model.Image `yaml:"pauseImage,omitempty"`
507513
FlannelImage model.Image `yaml:"flannelImage,omitempty"`
508514
DexImage model.Image `yaml:"dexImage,omitempty"`
515+
JournaldCloudWatchLogsImage model.Image `yaml:"journaldCloudWatchLogsImage,omitempty"`
509516
}
510517

511518
// Part of configuration which is specific to worker nodes
@@ -742,6 +749,11 @@ type KubeResourcesAutosave struct {
742749
S3Path string
743750
}
744751

752+
type CloudWatchLogging struct {
753+
Enabled bool `yaml:"enabled"`
754+
RetentionInDays int `yaml:"retentionInDays"`
755+
}
756+
745757
type LoadBalancer struct {
746758
Enabled bool `yaml:"enabled"`
747759
Names []string `yaml:"names"`

core/controlplane/config/templates/cloud-config-controller

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,34 @@ coreos:
4141
{{ $l }}
4242
{{- end }}
4343
{{- end}}
44+
{{if .CloudWatchLogging.Enabled}}
45+
- name: journald-cloudwatch-logs.service
46+
command: start
47+
content: |
48+
[Unit]
49+
Description=Docker run journald-cloudwatch-logs to send journald logs to CloudWatch
50+
Requires=network-online.target
51+
After=network-online.target
52+
53+
[Service]
54+
ExecStartPre=-/usr/bin/mkdir -p /var/journald-cloudwatch-logs
55+
ExecStart=/usr/bin/rkt run \
56+
--insecure-options=image \
57+
--volume resolv,kind=host,source=/etc/resolv.conf,readOnly=true \
58+
--mount volume=resolv,target=/etc/resolv.conf \
59+
--volume journald-cloudwatch-logs,kind=host,source=/var/journald-cloudwatch-logs \
60+
--mount volume=journald-cloudwatch-logs,target=/var/journald-cloudwatch-logs \
61+
--volume journal,kind=host,source=/var/log/journal,readOnly=true \
62+
--mount volume=journal,target=/var/log/journal \
63+
--volume machine-id,kind=host,source=/etc/machine-id,readOnly=true \
64+
--mount volume=machine-id,target=/etc/machine-id \
65+
{{ .JournaldCloudWatchLogsImage.RktRepo }} -- {{.ClusterName}}
66+
Restart=always
67+
RestartSec=60s
68+
69+
[Install]
70+
WantedBy=multi-user.target
71+
{{end}}
4472
- name: cfn-etcd-environment.service
4573
enable: true
4674
command: start
@@ -2309,4 +2337,4 @@ write_files:
23092337
{{ end -}}
23102338
{{ end }}
23112339

2312-
{{ end }}
2340+
{{ end }}

core/controlplane/config/templates/cloud-config-etcd

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,34 @@ coreos:
7373

7474
[Install]
7575
RequiredBy=format-etcd2-volume.service
76+
{{if .CloudWatchLogging.Enabled}}
77+
- name: journald-cloudwatch-logs.service
78+
command: start
79+
content: |
80+
[Unit]
81+
Description=Docker run journald-cloudwatch-logs to send journald logs to CloudWatch
82+
Requires=network-online.target
83+
After=network-online.target
7684

85+
[Service]
86+
ExecStartPre=-/usr/bin/mkdir -p /var/journald-cloudwatch-logs
87+
ExecStart=/usr/bin/rkt run \
88+
--insecure-options=image \
89+
--volume resolv,kind=host,source=/etc/resolv.conf,readOnly=true \
90+
--mount volume=resolv,target=/etc/resolv.conf \
91+
--volume journald-cloudwatch-logs,kind=host,source=/var/journald-cloudwatch-logs \
92+
--mount volume=journald-cloudwatch-logs,target=/var/journald-cloudwatch-logs \
93+
--volume journal,kind=host,source=/var/log/journal,readOnly=true \
94+
--mount volume=journal,target=/var/log/journal \
95+
--volume machine-id,kind=host,source=/etc/machine-id,readOnly=true \
96+
--mount volume=machine-id,target=/etc/machine-id \
97+
{{ .JournaldCloudWatchLogsImage.RktRepo }} -- {{.ClusterName}}
98+
Restart=always
99+
RestartSec=60s
100+
101+
[Install]
102+
WantedBy=multi-user.target
103+
{{end}}
77104
{{if .Etcd.DisasterRecovery.SupportsEtcdVersion .Etcd.Version -}}
78105
- name: etcdadm-reconfigure.service
79106
enable: true

core/controlplane/config/templates/cloud-config-worker

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,34 @@ coreos:
8080
[Mount]
8181
What={{$volumeMountSpec.Device}}
8282
Where={{$volumeMountSpec.Path}}
83+
{{end}}
84+
{{if .CloudWatchLogging.Enabled}}
85+
- name: journald-cloudwatch-logs.service
86+
command: start
87+
content: |
88+
[Unit]
89+
Description=Docker run journald-cloudwatch-logs to send journald logs to CloudWatch
90+
Requires=network-online.target
91+
After=network-online.target
92+
93+
[Service]
94+
ExecStartPre=-/usr/bin/mkdir -p /var/journald-cloudwatch-logs
95+
ExecStart=/usr/bin/rkt run \
96+
--insecure-options=image \
97+
--volume resolv,kind=host,source=/etc/resolv.conf,readOnly=true \
98+
--mount volume=resolv,target=/etc/resolv.conf \
99+
--volume journald-cloudwatch-logs,kind=host,source=/var/journald-cloudwatch-logs \
100+
--mount volume=journald-cloudwatch-logs,target=/var/journald-cloudwatch-logs \
101+
--volume journal,kind=host,source=/var/log/journal,readOnly=true \
102+
--mount volume=journal,target=/var/log/journal \
103+
--volume machine-id,kind=host,source=/etc/machine-id,readOnly=true \
104+
--mount volume=machine-id,target=/etc/machine-id \
105+
{{ .JournaldCloudWatchLogsImage.RktRepo }} -- {{.ClusterName}}
106+
Restart=always
107+
RestartSec=60s
108+
109+
[Install]
110+
WantedBy=multi-user.target
83111
{{end}}
84112
- name: cfn-etcd-environment.service
85113
enable: true

core/controlplane/config/templates/cluster.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,12 @@ worker:
10771077
# tag: v0.7.1
10781078
# rktPullDocker: false
10791079

1080+
# JournaldCloudWatchLogsImage image repository to use. This sends journald logs to CloudWatch.
1081+
#journaldCloudWatchLogsImage:
1082+
# repo: "jollinshead/journald-cloudwatch-logs"
1083+
# tag: "0.1"
1084+
# rktPullDocker: true
1085+
10801086
# Use Calico for network policy.
10811087
# useCalico: false
10821088

@@ -1124,6 +1130,12 @@ worker:
11241130
#kubeResourcesAutosave:
11251131
# enabled: false
11261132

1133+
# When enabled, all nodes will forward journald logs to AWS CloudWatch.
1134+
# It is disabled by default.
1135+
#cloudWatchLogging:
1136+
# enabled: false
1137+
# retentionInDays: 7
1138+
11271139
# Addon features
11281140
addons:
11291141
# Will provision controller nodes with IAM permissions to run cluster-autoscaler and

core/controlplane/config/templates/stack-template.json

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010
"Type": "String",
1111
"Description": "Role to be used by ASG LifecycleHook to publish notification"
1212
}
13+
{{if .CloudWatchLogging.Enabled}}
14+
,
15+
"CloudWatchLogGroupARN": {
16+
"Type": "String",
17+
"Description": "CloudWatch LogGroup to send journald logs to"
18+
}
19+
{{end}}
1320
},
1421
"Resources": {
1522
"{{.Controller.LogicalName}}": {
@@ -183,6 +190,19 @@
183190
"Effect": "Allow",
184191
"Resource": "*"
185192
},
193+
{{if .CloudWatchLogging.Enabled}}
194+
{
195+
"Effect": "Allow",
196+
"Action": [
197+
"logs:CreateLogStream",
198+
"logs:PutLogEvents",
199+
"logs:DescribeLogStreams"
200+
],
201+
"Resource": [
202+
{ "Ref": "CloudWatchLogGroupARN" },
203+
{ "Fn::Join" : [ "", [{ "Ref": "CloudWatchLogGroupARN" }, ":log-stream:*"]] }
204+
]
205+
},{{ end }}
186206
{{ if .UserDataController.Parts.s3 }}
187207
{
188208
"Effect": "Allow",
@@ -192,6 +212,19 @@
192212
"Resource": "arn:{{.Region.Partition}}:s3:::{{ .UserDataController.Parts.s3.Asset.S3Prefix }}*"
193213
},
194214
{{ end }}
215+
{{if .CloudWatchLogging.Enabled}}
216+
{
217+
"Effect": "Allow",
218+
"Action": [
219+
"logs:CreateLogStream",
220+
"logs:PutLogEvents",
221+
"logs:DescribeLogStreams"
222+
],
223+
"Resource": [
224+
{ "Ref": "CloudWatchLogGroupARN" },
225+
{ "Fn::Join" : [ "", [{ "Ref": "CloudWatchLogGroupARN" }, ":log-stream:*"]] }
226+
]
227+
},{{ end }}
195228
{{if .WaitSignal.Enabled}}
196229
{
197230
"Action": "cloudformation:SignalResource",
@@ -301,7 +334,7 @@
301334
{{if .Controller.IAMConfig.Role.Name }}
302335
"RoleName": {"Fn::Join": ["",[{"Ref": "AWS::Region"},"-","{{.Controller.IAMConfig.Role.Name}}"]]},
303336
{{end}}
304-
"ManagedPolicyArns": [
337+
"ManagedPolicyArns": [
305338
{{range $policyIndex, $policyArn := .Controller.IAMConfig.Role.ManagedPolicies }}
306339
"{{$policyArn.Arn}}",
307340
{{end}}
@@ -420,6 +453,19 @@
420453
],
421454
"Resource": "arn:{{.Region.Partition}}:s3:::{{$.EtcdSnapshotsS3Bucket}}"
422455
},
456+
{{if .CloudWatchLogging.Enabled}}
457+
{
458+
"Effect": "Allow",
459+
"Action": [
460+
"logs:CreateLogStream",
461+
"logs:PutLogEvents",
462+
"logs:DescribeLogStreams"
463+
],
464+
"Resource": [
465+
{ "Ref": "CloudWatchLogGroupARN" },
466+
{ "Fn::Join" : [ "", [{ "Ref": "CloudWatchLogGroupARN" }, ":log-stream:*"]] }
467+
]
468+
},{{ end }}
423469
{
424470
"Effect": "Allow",
425471
"Action": [
@@ -981,7 +1027,7 @@
9811027
{{/* 443 ingress from controller to controller is required by:
9821028
- API server endpoint with HA controllers
9831029
- calico-policy-controller when calico is enabled
984-
See https://github.com/kubernetes-incubator/kube-aws/issues/494#issuecomment-291687137
1030+
See https://github.com/kubernetes-incubator/kube-aws/issues/494#issuecomment-291687137
9851031
and https://github.com/kubernetes-incubator/kube-aws/issues/512 */}}
9861032
"SecurityGroupControllerIngressFromControllerToController": {
9871033
"Properties": {

core/nodepool/config/templates/stack-template.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,20 @@
314314
"Resource": "arn:{{.Region.Partition}}:s3:::{{ $.UserDataWorker.Parts.s3.Asset.S3Prefix }}*"
315315
},
316316
{{- end }}
317+
{{if .CloudWatchLogging.Enabled}}
318+
{
319+
"Effect": "Allow",
320+
"Action": [
321+
"logs:CreateLogStream",
322+
"logs:PutLogEvents",
323+
"logs:DescribeLogStreams"
324+
],
325+
"Resource": [
326+
{ "Ref": "CloudWatchLogGroupARN" },
327+
{ "Fn::Join" : [ "", [{ "Ref": "CloudWatchLogGroupARN" }, ":log-stream:*"]] }
328+
]
329+
},
330+
{{ end }}
317331
{{ if .KubeResourcesAutosave.Enabled }}
318332
{
319333
"Effect": "Allow",
@@ -481,6 +495,13 @@
481495
"Type": "String",
482496
"Description": "Role to be used by ASG LifecycleHook to publish notification"
483497
}
498+
{{if .CloudWatchLogging.Enabled}}
499+
,
500+
"CloudWatchLogGroupARN": {
501+
"Type": "String",
502+
"Description": "CloudWatch LogGroup to send journald logs to"
503+
}
504+
{{ end }}
484505
},
485506
"Resources": {
486507
{{if .SpotFleet.Enabled}}

core/root/config/templates/stack-template.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,24 @@
3535
},
3636
"Type": "AWS::IAM::Role"
3737
},
38+
{{if .CloudWatchLogging.Enabled}}
39+
"CloudWatchLogGroup": {
40+
"Type" : "AWS::Logs::LogGroup",
41+
"Properties" : {
42+
"LogGroupName" : "{{.ClusterName}}",
43+
"RetentionInDays" : {{.CloudWatchLogging.RetentionInDays}}
44+
}
45+
},{{ end }}
3846
"{{.ControlPlane.Name}}": {
3947
"Type" : "AWS::CloudFormation::Stack",
4048
"Properties" : {
4149
"Parameters": {
4250
"NotificationTargetARN": { "Fn::GetAtt": [ "ASGNotificationTarget", "Arn" ] },
4351
"NotificationRoleARN": { "Fn::GetAtt": [ "ASGNotificationRole", "Arn" ] }
52+
{{if .CloudWatchLogging.Enabled}}
53+
,
54+
"CloudWatchLogGroupARN": { "Fn::GetAtt": [ "CloudWatchLogGroup", "Arn" ] }
55+
{{ end }}
4456
},
4557
"Tags" : [
4658
{
@@ -62,6 +74,10 @@
6274
"ControlPlaneStackName": {"Fn::GetAtt" : [ "{{$.ControlPlane.Name}}" , "Outputs.StackName" ]},
6375
"NotificationTargetARN": { "Fn::GetAtt": [ "ASGNotificationTarget", "Arn" ] },
6476
"NotificationRoleARN": { "Fn::GetAtt": [ "ASGNotificationRole", "Arn" ] }
77+
{{if .CloudWatchLogging.Enabled}}
78+
,
79+
"CloudWatchLogGroupARN": { "Fn::GetAtt": [ "CloudWatchLogGroup", "Arn" ] }
80+
{{ end }}
6581
},
6682
"Tags" : [
6783
{

0 commit comments

Comments
 (0)