{"id":1094,"date":"2023-10-06T01:46:00","date_gmt":"2023-10-06T01:46:00","guid":{"rendered":"https:\/\/blog.ngocha.biz\/?p=1094"},"modified":"2023-10-06T01:46:00","modified_gmt":"2023-10-06T01:46:00","slug":"kubernetes-cluster-configurations","status":"publish","type":"post","link":"https:\/\/blog.ngocha.biz\/?p=1094","title":{"rendered":"Essential Guide to Kubernetes Configuration: Key Cluster Settings"},"content":{"rendered":"<p>In this blog, we will look at the important Kubernetes configurations every <a href=\"https:\/\/devopscube.com\/become-devops-engineer\/\">devops engineer<\/a> or Kubernetes administrator should know.<\/p>\n<p>Toward the end of the guide, I added the configurations involved in a real-world Kubernetes cluster setup.<\/p>\n<blockquote><p><strong>Note<\/strong>: All the config locations refered in this guide are based on the default Kubernetes installation using <a href=\"https:\/\/devopscube.com\/setup-kubernetes-cluster-kubeadm\/\">kubeadm<\/a>.<\/p><\/blockquote>\n<h2 id=\"kubernetes-cluster-configurations\">Kubernetes Cluster Configurations<\/h2>\n<p>Whether you are preparing for <a href=\"https:\/\/devopscube.com\/best-kubernetes-certifications\/\">Kubernetes certifications<\/a> or plan to work on kubernetes projects, it is very important to know about the key configuration of the Kubernetes cluster.<\/p>\n<p>Also, when it comes to <a href=\"https:\/\/devopscube.com\/cka-exam-study-guide\/\">CKA certification<\/a>, you will get scenarios to rectify issues in the cluster. So understanding the cluster configurations will make it easier for you to troubleshoot and find issues in the cluster the right way.<\/p>\n<p>Let&#8217;s start with the configurations related to control plane components.<\/p>\n<h3 id=\"static-pod-manifests\">Static Pod Manifests<\/h3>\n<p>As we discussed in the <a href=\"https:\/\/devopscube.com\/kubernetes-architecture-explained\/\">Kubernetes architecture<\/a>, all the control plane components are started by the kubelet from the static pod manifests present in the <code>\/etc\/kubernetes\/manifests<\/code> directory. Kubelet manages the <a href=\"https:\/\/devopscube.com\/kubernetes-pod-lifecycle\/\">lifecycle of all the pods<\/a> created from the static pods manifests.<\/p>\n<p>The following components are deployed from the static pod manifests.<\/p>\n<ol>\n<li>etcd<\/li>\n<li>API server<\/li>\n<li>Kube controller manager<\/li>\n<li>Kube scheduler.<\/li>\n<\/ol>\n<pre><code>manifests\n  \u251c\u2500\u2500 etcd.yaml\n  \u251c\u2500\u2500 kube-apiserver.yaml\n  \u251c\u2500\u2500 kube-controller-manager.yaml\n  \u2514\u2500\u2500 kube-scheduler.yaml<\/code><\/pre>\n<p>You can get all the configuration locations of these components from these pod manifests.<\/p>\n<h3 id=\"api-server-configurations\">API Server Configurations<\/h3>\n<p>If you look at the <strong><code>kube-apiserver.yaml<\/code><\/strong>, under the <a href=\"https:\/\/devopscube.com\/what-is-a-container-and-how-does-it-work\/\">container<\/a> spec you can see all the parameters that point to TLS certs and other required parameters for the API server to work and communicate with other cluster components.<\/p>\n<pre><code>apiVersion: v1\nkind: Pod\nmetadata:\n  annotations:\n    kubeadm.kubernetes.io\/kube-apiserver.advertise-address.endpoint: 172.31.42.106:6443\n  creationTimestamp: null\n  labels:\n    component: kube-apiserver\n    tier: control-plane\n  name: kube-apiserver\n  namespace: kube-system\nspec:\n  containers:\n  - command:\n    - kube-apiserver\n    - --advertise-address=172.31.42.106\n    - --allow-privileged=true\n    - --authorization-mode=Node,RBAC\n    - --client-ca-file=\/etc\/kubernetes\/pki\/ca.crt\n    - --enable-admission-plugins=NodeRestriction\n    - --enable-bootstrap-token-auth=true\n    - --etcd-cafile=\/etc\/kubernetes\/pki\/etcd\/ca.crt\n    - --etcd-certfile=\/etc\/kubernetes\/pki\/apiserver-etcd-client.crt\n    - --etcd-keyfile=\/etc\/kubernetes\/pki\/apiserver-etcd-client.key\n    - --etcd-servers=https:\/\/127.0.0.1:2379\n    - --kubelet-client-certificate=\/etc\/kubernetes\/pki\/apiserver-kubelet-client.crt\n    - --kubelet-client-key=\/etc\/kubernetes\/pki\/apiserver-kubelet-client.key\n    - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname\n    - --proxy-client-cert-file=\/etc\/kubernetes\/pki\/front-proxy-client.crt\n    - --proxy-client-key-file=\/etc\/kubernetes\/pki\/front-proxy-client.key\n    - --requestheader-allowed-names=front-proxy-client\n    - --requestheader-client-ca-file=\/etc\/kubernetes\/pki\/front-proxy-ca.crt\n    - --requestheader-extra-headers-prefix=X-Remote-Extra-\n    - --requestheader-group-headers=X-Remote-Group\n    - --requestheader-username-headers=X-Remote-User\n    - --secure-port=6443\n    - --service-account-issuer=https:\/\/kubernetes.default.svc.cluster.local\n    - --service-account-key-file=\/etc\/kubernetes\/pki\/sa.pub\n    - --service-account-signing-key-file=\/etc\/kubernetes\/pki\/sa.key\n    - --service-cluster-ip-range=10.96.0.0\/12\n    - --tls-cert-file=\/etc\/kubernetes\/pki\/apiserver.crt\n    - --tls-private-key-file=\/etc\/kubernetes\/pki\/apiserver.key\n    image: registry.k8s.io\/kube-apiserver:v1.26.3<\/code><\/pre>\n<p>So if you want to troubleshoot or verify the cluster components configurations, first you should look at the static pod manifest configurations.<\/p>\n<h3 id=\"etcd-configurations\">ETCD Configurations<\/h3>\n<p>If you want to interact with the etcd component, you can use the details from the static pod YAML.<\/p>\n<p>For example, if you want to <a href=\"https:\/\/devopscube.com\/backup-etcd-restore-kubernetes\/\">backup etcd<\/a> you need to know the etcd service endpoint and related certificates to authenticate against etcd and create a backup.<\/p>\n<p>If you open the <strong><code>etcd.yaml<\/code><\/strong> manifest you can view all the etcd-related configurations as shown below.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-11-26.png\" class=\"kg-image\" alt loading=\"lazy\"><\/figure>\n<h3 id=\"tls-certificates\">TLS Certificates<\/h3>\n<p>In Kubernetes, all the components talk to each other over mTLS. Under the PKI folder, you will find all the TLS certificates and keys. Kubernetes control plane components use these certificates to authenticate and communicate with each other.<\/p>\n<p>Also, there is an etcd subdirectory that contains the etcd-specific certificates and private keys. These are used to secure communication between etcd nodes and between the API server and etcd nodes.<\/p>\n<p>The following image shows the file structure of the PKI folder.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-8-32.png\" class=\"kg-image\" alt=\"kubernetes TLS certificates\" loading=\"lazy\"><\/figure>\n<p>The static pod manifests refer to the required TLS certificates and keys from this folder.<\/p>\n<p>When you work on a self-hosted cluster using tools like kubeadm, these certificates are automatically generated by the tool. In managed kubernetes clusters, the cloud provider takes care of all the TLS requirements as it is their responsibility to manage control plane components.<\/p>\n<p>However, if you are setting up a self-hosted cluster for production use, these certificates have to be requested from the organization&#8217;s network or security team. They will generate these certificates signed by the organization&#8217;s internal Certificate authority and provide them to you.<\/p>\n<h3 id=\"kubeconfig-files\">Kubeconfig Files<\/h3>\n<p>Any components that need to authenticate to the API server need the <a href=\"https:\/\/devopscube.com\/kubernetes-kubeconfig-file\/\" rel=\"noreferrer noopener\">kubeconfig file<\/a>.<\/p>\n<p>All the cluster Kubeconfig files are present in the <code><strong>\/etc\/kubernetes<\/strong><\/code> folder (.conf files). You will find the following files.<\/p>\n<ol>\n<li>admin.conf<\/li>\n<li>controller-manager.conf<\/li>\n<li>kubelet.conf<\/li>\n<li>scheduler.conf<\/li>\n<\/ol>\n<p>It contains the API server endpoint, cluster CA certificate, cluster client certificate, and other information.<\/p>\n<p>The <strong><code>admin.conf,<\/code><\/strong> file, which is the admin kubeconfig file used by end users to access the API server to manage the clusters. You can use this file to connect the cluster from a remote workstation.<\/p>\n<p>The Kubeconfig for the Controller manager, scheduler, and Kubelet is used for API server authentication and authorization.<\/p>\n<p>For example, if you check the Controller Manager static pod manifest file, you can see the <strong><code>controller-manager.conf<\/code><\/strong> added as the authentication and authorization parameter.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-10-33.png\" class=\"kg-image\" alt loading=\"lazy\"><\/figure>\n<h2 id=\"kubelet-configurations\">Kubelet Configurations<\/h2>\n<p>Kubelet service runs as a systems service on all the cluster nodes.<\/p>\n<p>You can view the kubelet systemd service under<strong><code> \/etc\/systemd\/system\/kubelet.service.d<\/code><\/strong><\/p>\n<p>Here are the system file contents.<\/p>\n<pre><code>[Service]\nEnvironment=\"KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=\/etc\/kubernetes\/bootstrap-kubelet.conf --kubeconfig=\/etc\/kubernetes\/kubelet.conf\"\nEnvironment=\"KUBELET_CONFIG_ARGS=--config=\/var\/lib\/kubelet\/config.yaml\"\nEnvironmentFile=-\/var\/lib\/kubelet\/kubeadm-flags.env\nEnvironmentFile=-\/etc\/default\/kubelet\nExecStart=\nExecStart=\/usr\/bin\/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS<\/code><\/pre>\n<p>I have highlighted two important kubelet configurations in bold.<\/p>\n<ol>\n<li>kubelet kubeconfig file: <strong>\/etc\/kubernetes\/kubelet.conf<\/strong><\/li>\n<li>kubelet config file: <strong>\/var\/lib\/kubelet\/config.yaml<\/strong><\/li>\n<li>EnvironmentFile=-<strong>\/var\/lib\/kubelet\/kubeadm-flags.env<\/strong><\/li>\n<\/ol>\n<p>The kubeconfig file will be used for API server authentication and authorization.<\/p>\n<p>The <strong>\/var\/lib\/kubelet\/config.yaml<\/strong> contains all the kubelet-related configurations. The static pod manifest location is added as part of the <strong>staticPodPath<\/strong> parameter.<\/p>\n<pre><code>staticPodPath: \/etc\/kubernetes\/manifests<\/code><\/pre>\n<p><strong>\/var\/lib\/kubelet\/kubeadm-flags.env<\/strong> file contains the container runtime environment Linux socket and the infra container (pause container) image.<\/p>\n<p>For example, here is the kubelet config that is using the CRI-O container runtime, as indicated by the Unix socket and the pause container image.<\/p>\n<pre><code>KUBELET_KUBEADM_ARGS=\"--container-runtime-endpoint=unix:\/\/\/var\/run\/crio\/crio.sock --pod-infra-container-image=registry.k8s.io\/pa<\/code><\/pre>\n<p>A pause container is a minimal container that is the first to be started within a Kubernetes Pod. Then the role of the pause container is to hold the networking namespace and other shared resources for all the other containers in the same Pod.<\/p>\n<p>If you look at the kubelet configuration in the managed k8s cluster, it looks a little different than the kubeadm setup.<\/p>\n<p>For example, here is a kubelet service file for an <a href=\"https:\/\/devopscube.com\/create-aws-eks-cluster-eksctl\/\">AWS EKS cluster<\/a>.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/carbon-9-1.png\" class=\"kg-image\" alt=\"EKS kubelet config.\" loading=\"lazy\"><\/figure>\n<p>Here you can see the container runtime is containerd and its Unix socket flag is directly added to the service file<\/p>\n<p>The kubelet kubeconfig file is in a different directory as compared to kubeadm configurations.<\/p>\n<h2 id=\"coredns-configurations\">CoreDNS Configurations<\/h2>\n<p><a href=\"https:\/\/coredns.io\/?ref=devopscube.com\" rel=\"noreferrer noopener\">CoreDNS<\/a> addon components deal with the cluster DNS configurations.<\/p>\n<p>All the CoreDNS configurations are part of a configmap named CoreDNS in the kubesystem namespace.<\/p>\n<p>If you list the <strong><code>Configmaps<\/code><\/strong> in the kube-system namespace, you can see the CoreDNS configmap.<\/p>\n<pre><code>kubectl get configmap --namespace=kube-system<\/code><\/pre>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-12-23.png\" class=\"kg-image\" alt loading=\"lazy\"><\/figure>\n<p>use the following command to view the <strong>CoreDNS<\/strong> configmap contents.<\/p>\n<pre><code>kubectl edit configmap coredns --namespace=kube-system<\/code><\/pre>\n<p>You will see the following contents.<\/p>\n<pre><code>apiVersion: v1\ndata:\n  Corefile: |\n    .:53 {\n        errors\n        health {\n           lameduck 5s\n        }\n        ready\n        kubernetes cluster.local in-addr.arpa ip6.arpa {\n           pods insecure\n           fallthrough in-addr.arpa ip6.arpa\n           ttl 30\n        }\n        prometheus :9153\n        forward . \/etc\/resolv.conf {\n           max_concurrent 1000\n        }\n        cache 30\n        loop\n        reload\n        loadbalance\n    }<\/code><\/pre>\n<p>When it comes to DNS connectivity, applications may need to connect to:<\/p>\n<ol>\n<li>Internal services using Kubernetes service endpoints.<\/li>\n<li>Publicly available services using public DNS endpoints.<\/li>\n<li>In hybrid cloud environments, services are hosted in on-premise environments using private DNS endpoints.<\/li>\n<\/ol>\n<p>If you have a use case where you need to have custom DNS servers, for example, the applications in the cluster need to connect to private DNS endpoints in the on-premise data center, you can add the custom DNS server to the core DNS configmap configurations.<\/p>\n<p>For example, let&#8217;s say the custom DNS server IP is <strong>10.45.45.34<\/strong> and your DNS suffix is <strong>dns-onprem.com<\/strong>, we have to add a block as shown below. So that all the DNS requests related to that domain endpoint will be forwarded to <strong>10.45.45.34<\/strong> DNS server.<\/p>\n<pre><code>dns-onprem.com:53 {\n    errors\n    cache 30\n    forward . 10.45.45.34\n}<\/code><\/pre>\n<p>Here is the full configmap configuration with the custom block highlighted in bold.<\/p>\n<pre><code>apiVersion: v1\ndata:\n  Corefile: |\n    .:53 {\n        errors\n        health {\n           lameduck 5s\n        }\n        ready\n        kubernetes cluster.local in-addr.arpa ip6.arpa {\n           pods insecure\n           fallthrough in-addr.arpa ip6.arpa\n           ttl 30\n        }\n        prometheus :9153\n        forward . \/etc\/resolv.conf {\n           max_concurrent 1000\n        }\n        cache 30\n        loop\n        reload\n        loadbalance\n    }\n    dns-onprem.com:53 {\n    errors\n    cache 30\n    forward . 10.45.45.34\n    }<\/code><\/pre>\n<h2 id=\"audit-logging-configuration\">Audit Logging Configuration<\/h2>\n<p>When it comes to production clusters, audit logging is a must-have feature.<\/p>\n<p>Audit logging is enabled in the <strong><code>kube-api-server.yaml<\/code><\/strong> static pod manifest.<\/p>\n<p>The command argument should have the following two parameters. The file path is arbitrary and it depends on the cluster administrator.<\/p>\n<pre><code> --audit-policy-file=\/etc\/kubernetes\/audit\/audit-policy.yaml\n --audit-log-path=\/var\/log\/kubernetes\/audit.log<\/code><\/pre>\n<p><code>audit-policy.yaml <\/code>contains all the audit policies and <code>audit.log<\/code> file contains the audit logs generated by Kubernetes.<\/p>\n<h2 id=\"kubernetes-configurations-video\">Kubernetes Configurations Video<\/h2>\n<p>I have made a video explaining the Kubernetes configuration. You can watch the video on Youtube. Here is the embedded video.<\/p>\n<figure class=\"kg-card kg-embed-card\"><iframe loading=\"lazy\" width=\"160\" height=\"90\" src=\"https:\/\/www.youtube.com\/embed\/AM5x51UiZMA?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen=\"\"><\/iframe><\/figure>\n<h2 id=\"kubernetes-configurations-involved-in-production-setup\">Kubernetes Configurations Involved in Production Setup<\/h2>\n<p>It is very important to know about kubernetes cluster configuration when working on real-time projects.<\/p>\n<p>When it comes to self-hosted Kubernetes clusters, which primarily happen in on-premise environments, you need to know each and every configuration of the cluster control plane and the worker nodes.<\/p>\n<p>Although there are automation tools available to set up the whole cluster, you need to work on the following.<\/p>\n<ol>\n<li>Requesting cluster certificates from the organization&#8217;s network or security teams.<\/li>\n<li>Ensure cluster control plane components use the correct TLS certificates.<\/li>\n<li>Cluster DNS configurations are configured with the custom DNS servers.<\/li>\n<\/ol>\n<p>When it comes to managed kubernetes clusters, \u00a0you will not have access to the control plane components.<\/p>\n<p>However, having good knowledge of the cluster configuration would help during implementation and discussions with the cloud support teams to fix cluster-related issues.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>In this guide, we have looked at the important Kubernetes cluster configurations that would help you in Kubernetes cluster administration activities.<\/p>\n<p>Also, you can check out the detailed blog on <a href=\"https:\/\/devopscube.com\/production-ready-kubernetes-cluster\/\">Production Kubernetes cluster activities<\/a>.<\/p>\n<p>If you want to level up your kubernetes skills, check out my 40+ comprehensive <a href=\"https:\/\/devopscube.com\/kubernetes-tutorials-beginners\/\">kubernetes tutorials<\/a>.<\/p>\n<hr>\n<p><strong>Ngu\u1ed3n:<\/strong> <a href=\"https:\/\/devopscube.com\/kubernetes-cluster-configurations\/\" target=\"_blank\" rel=\"noopener noreferrer\">Essential Guide to Kubernetes Configuration: Key Cluster Settings \u2014 DevOpsCube<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/devopscube.com\/kubernetes-cluster-configurations\/<\/p>\n","protected":false},"author":1,"featured_media":1095,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1094","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"_links":{"self":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/1094","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1094"}],"version-history":[{"count":0,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/1094\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/media\/1095"}],"wp:attachment":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1094"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1094"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1094"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}