diff --git a/playbooks/setup_metrics_server.yml b/playbooks/setup_metrics_server.yml new file mode 100644 index 0000000..9934c5c --- /dev/null +++ b/playbooks/setup_metrics_server.yml @@ -0,0 +1,6 @@ +--- +- name: Deploy Kubernetes Metrics Server + hosts: manager_nodes + become: false + roles: + - metrics_server diff --git a/roles/metrics_server/defaults/main.yml b/roles/metrics_server/defaults/main.yml new file mode 100644 index 0000000..5fdcb6a --- /dev/null +++ b/roles/metrics_server/defaults/main.yml @@ -0,0 +1,15 @@ +--- +metrics_server_namespace: kube-system +metrics_server_kubeconfig: "/home/{{ ansible_user }}/.kube/config" +metrics_server_chart_version: "3.12.0" +metrics_server_use_helm: true + +metrics_server_args: + - --kubelet-insecure-tls + - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname + - --metric-resolution=15s + +metrics_server_resources_requests_memory: "200Mi" +metrics_server_resources_requests_cpu: "100m" +metrics_server_resources_limits_memory: "500Mi" +metrics_server_resources_limits_cpu: "500m" diff --git a/roles/metrics_server/files/metrics-server-manifest.yml b/roles/metrics_server/files/metrics-server-manifest.yml new file mode 100644 index 0000000..cc50a93 --- /dev/null +++ b/roles/metrics_server/files/metrics-server-manifest.yml @@ -0,0 +1,199 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + k8s-app: metrics-server + name: metrics-server + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + k8s-app: metrics-server + name: system:aggregated-metrics-reader +rules: +- apiGroups: + - metrics.k8s.io + resources: + - pods + - nodes + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + k8s-app: metrics-server + name: system:metrics-server +rules: +- apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - pods + - nodes + - nodes/stats + - namespaces + - configmaps + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + k8s-app: metrics-server + name: metrics-server-auth-reader + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + k8s-app: metrics-server + name: metrics-server:system:auth-delegator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + k8s-app: metrics-server + name: system:metrics-server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:metrics-server +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + k8s-app: metrics-server + name: extension-apiserver-authentication-reader + namespace: kube-system +rules: +- apiGroups: + - "" + resources: + - configmaps + name: extension-apiserver-authentication + verbs: + - get +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + k8s-app: metrics-server + name: metrics-server + namespace: kube-system +spec: + selector: + matchLabels: + k8s-app: metrics-server + strategy: + rollingUpdate: + maxUnavailable: 0 + template: + metadata: + labels: + k8s-app: metrics-server + spec: + containers: + - args: + - --kubelet-insecure-tls + - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname + - --metric-resolution=15s + image: registry.k8s.io/metrics-server/metrics-server:v0.7.2 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /livez + port: https + scheme: HTTPS + periodSeconds: 10 + name: metrics-server + ports: + - containerPort: 4443 + name: https + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /readyz + port: https + scheme: HTTPS + periodSeconds: 10 + resources: + requests: + cpu: 100m + memory: 200Mi + limits: + cpu: 500m + memory: 500Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /tmp + name: tmp-dir + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + serviceAccountName: metrics-server + volumes: + - emptyDir: {} + name: tmp-dir +--- +apiVersion: apiregistration.k8s.io/v1 +kind: APIService +metadata: + labels: + k8s-app: metrics-server + name: v1beta1.metrics.k8s.io +spec: + group: metrics.k8s.io + groupPriorityMinimum: 100 + insecureSkipTLSVerify: true + service: + name: metrics-server + namespace: kube-system + version: v1beta1 + versionPriority: 100 diff --git a/roles/metrics_server/meta/main.yml b/roles/metrics_server/meta/main.yml new file mode 100644 index 0000000..23d65c7 --- /dev/null +++ b/roles/metrics_server/meta/main.yml @@ -0,0 +1,2 @@ +--- +dependencies: [] diff --git a/roles/metrics_server/tasks/helm.yml b/roles/metrics_server/tasks/helm.yml new file mode 100644 index 0000000..769a88d --- /dev/null +++ b/roles/metrics_server/tasks/helm.yml @@ -0,0 +1,30 @@ +--- +- name: Helm | Add metrics-server repository + ansible.builtin.command: helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/ + register: _helm_repo_add + changed_when: "'already exists' not in _helm_repo_add.stdout" + failed_when: _helm_repo_add.rc != 0 and 'already exists' not in _helm_repo_add.stdout + +- name: Helm | Update repositories + ansible.builtin.command: helm repo update + changed_when: false + +- name: Helm | Install or upgrade metrics-server + ansible.builtin.command: > + helm upgrade --install metrics-server metrics-server/metrics-server + --namespace {{ metrics_server_namespace }} + --create-namespace + --version {{ metrics_server_chart_version }} + --set args[0]=--kubelet-insecure-tls + --set args[1]=--metric-resolution=15s + --set resources.requests.cpu={{ metrics_server_resources_requests_cpu }} + --set resources.requests.memory={{ metrics_server_resources_requests_memory }} + --set resources.limits.cpu={{ metrics_server_resources_limits_cpu }} + --set resources.limits.memory={{ metrics_server_resources_limits_memory }} + --timeout 10m0s + --wait + environment: + KUBECONFIG: "{{ metrics_server_kubeconfig }}" + PATH: "/usr/local/bin:/usr/bin:/bin" + register: _helm_install + changed_when: "'STATUS: deployed' in _helm_install.stdout or 'has been upgraded' in _helm_install.stdout" diff --git a/roles/metrics_server/tasks/main.yml b/roles/metrics_server/tasks/main.yml new file mode 100644 index 0000000..9abf928 --- /dev/null +++ b/roles/metrics_server/tasks/main.yml @@ -0,0 +1,8 @@ +--- +- name: Helm | Deploy metrics-server + ansible.builtin.include_tasks: helm.yml + when: metrics_server_use_helm | bool + +- name: Manifest | Deploy metrics-server + ansible.builtin.include_tasks: manifest.yml + when: not metrics_server_use_helm | bool diff --git a/roles/metrics_server/tasks/manifest.yml b/roles/metrics_server/tasks/manifest.yml new file mode 100644 index 0000000..c728688 --- /dev/null +++ b/roles/metrics_server/tasks/manifest.yml @@ -0,0 +1,9 @@ +--- +- name: Manifest | Apply metrics-server + ansible.builtin.command: kubectl apply -f {{ role_path }}/files/metrics-server-manifest.yml + environment: + KUBECONFIG: "{{ metrics_server_kubeconfig }}" + PATH: "/usr/local/bin:/usr/bin:/bin" + register: _manifest_apply + changed_when: "'created' in _manifest_apply.stdout or 'configured' in _manifest_apply.stdout" + failed_when: _manifest_apply.rc != 0 and 'already exists' not in _manifest_apply.stderr diff --git a/roles/metrics_server/templates/metrics-server-manifest.yml.j2 b/roles/metrics_server/templates/metrics-server-manifest.yml.j2 new file mode 100644 index 0000000..cc50a93 --- /dev/null +++ b/roles/metrics_server/templates/metrics-server-manifest.yml.j2 @@ -0,0 +1,199 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + k8s-app: metrics-server + name: metrics-server + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + k8s-app: metrics-server + name: system:aggregated-metrics-reader +rules: +- apiGroups: + - metrics.k8s.io + resources: + - pods + - nodes + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + k8s-app: metrics-server + name: system:metrics-server +rules: +- apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - pods + - nodes + - nodes/stats + - namespaces + - configmaps + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + k8s-app: metrics-server + name: metrics-server-auth-reader + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + k8s-app: metrics-server + name: metrics-server:system:auth-delegator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + k8s-app: metrics-server + name: system:metrics-server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:metrics-server +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + k8s-app: metrics-server + name: extension-apiserver-authentication-reader + namespace: kube-system +rules: +- apiGroups: + - "" + resources: + - configmaps + name: extension-apiserver-authentication + verbs: + - get +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + k8s-app: metrics-server + name: metrics-server + namespace: kube-system +spec: + selector: + matchLabels: + k8s-app: metrics-server + strategy: + rollingUpdate: + maxUnavailable: 0 + template: + metadata: + labels: + k8s-app: metrics-server + spec: + containers: + - args: + - --kubelet-insecure-tls + - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname + - --metric-resolution=15s + image: registry.k8s.io/metrics-server/metrics-server:v0.7.2 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /livez + port: https + scheme: HTTPS + periodSeconds: 10 + name: metrics-server + ports: + - containerPort: 4443 + name: https + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /readyz + port: https + scheme: HTTPS + periodSeconds: 10 + resources: + requests: + cpu: 100m + memory: 200Mi + limits: + cpu: 500m + memory: 500Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /tmp + name: tmp-dir + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + serviceAccountName: metrics-server + volumes: + - emptyDir: {} + name: tmp-dir +--- +apiVersion: apiregistration.k8s.io/v1 +kind: APIService +metadata: + labels: + k8s-app: metrics-server + name: v1beta1.metrics.k8s.io +spec: + group: metrics.k8s.io + groupPriorityMinimum: 100 + insecureSkipTLSVerify: true + service: + name: metrics-server + namespace: kube-system + version: v1beta1 + versionPriority: 100 diff --git a/roles/metrics_server/templates/metrics-server-values.yml.j2 b/roles/metrics_server/templates/metrics-server-values.yml.j2 new file mode 100644 index 0000000..9d9ac8c --- /dev/null +++ b/roles/metrics_server/templates/metrics-server-values.yml.j2 @@ -0,0 +1,12 @@ +args: +{% for arg in metrics_server_args %} + - {{ arg }} +{% endfor %} + +resources: + requests: + memory: {{ metrics_server_resources_requests_memory }} + cpu: {{ metrics_server_resources_requests_cpu }} + limits: + memory: {{ metrics_server_resources_limits_memory }} + cpu: {{ metrics_server_resources_limits_cpu }}