Create static Pods

    Static Pods are always bound to one Kubelet on a specific node.

    The kubelet automatically tries to create a on the Kubernetes API server for each static Pod. This means that the Pods running on a node are visible on the API server, but cannot be controlled from there. The Pod names will be suffixed with the node hostname with a leading hyphen.

    Note: If you are running clustered Kubernetes and are using static Pods to run a Pod on every node, you should probably be using a DaemonSet instead.

    Note: The of a static Pod cannot refer to other API objects (e.g., , ConfigMap, , etc).

    Note: Static pods do not support ephemeral containers.

    You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. It is recommended to run this tutorial on a cluster with at least two nodes that are not acting as control plane hosts. If you do not already have a cluster, you can create one by using minikube or you can use one of these Kubernetes playgrounds:

    To check the version, enter kubectl version.

    This page assumes you’re using to run Pods, and that your nodes are running the Fedora operating system. Instructions for other distributions or Kubernetes installations may vary.

    You can configure a static Pod with either a or a web hosted configuration file.

    Manifests are standard Pod definitions in JSON or YAML format in a specific directory. Use the staticPodPath: <the directory> field in the kubelet configuration file, which periodically scans the directory and creates/deletes static Pods as YAML/JSON files appear/disappear there. Note that the kubelet will ignore files starting with dots when scanning the specified directory.

    1. Choose a node where you want to run the static Pod. In this example, it’s my-node1.

    2. Choose a directory, say /etc/kubernetes/manifests and place a web server Pod definition there, for example /etc/kubernetes/manifests/static-web.yaml:

      1. # Run this command on the node where kubelet is running
      2. mkdir -p /etc/kubernetes/manifests/
      3. cat <<EOF >/etc/kubernetes/manifests/static-web.yaml
      4. apiVersion: v1
      5. kind: Pod
      6. metadata:
      7. name: static-web
      8. labels:
      9. role: myrole
      10. spec:
      11. containers:
      12. - name: web
      13. image: nginx
      14. ports:
      15. - name: web
      16. containerPort: 80
      17. protocol: TCP
      18. EOF
    3. Restart the kubelet. On Fedora, you would run:

      1. # Run this command on the node where the kubelet is running

    Web-hosted static pod manifest

    Kubelet periodically downloads a file specified by --manifest-url=<URL> argument and interprets it as a JSON/YAML file that contains Pod definitions. Similar to how filesystem-hosted manifests work, the kubelet refetches the manifest on a schedule. If there are changes to the list of static Pods, the kubelet applies them.

    To use this approach:

    1. Create a YAML file and store it on a web server so that you can pass the URL of that file to the kubelet.

      1. apiVersion: v1
      2. kind: Pod
      3. metadata:
      4. name: static-web
      5. labels:
      6. role: myrole
      7. spec:
      8. containers:
      9. - name: web
      10. image: nginx
      11. ports:
      12. - name: web
      13. containerPort: 80
      14. protocol: TCP
    2. Configure the kubelet on your selected node to use this web manifest by running it with --manifest-url=<manifest-url>. On Fedora, edit /etc/kubernetes/kubelet to include this line:

      1. KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --manifest-url=<manifest-url>"
    3. Restart the kubelet. On Fedora, you would run:

      1. # Run this command on the node where the kubelet is running
      2. systemctl restart kubelet

    You can view running containers (including static Pods) by running (on the node):

    The output might be something like:

    1. CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
    2. 129fd7d382018 docker.io/library/nginx@sha256:... 11 minutes ago Running web 0 34533c6729106

    Note: crictl outputs the image URI and SHA-256 checksum. NAME will look more like: docker.io/library/nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31.

    You can see the mirror Pod on the API server:

    1. kubectl get pods
    1. NAME READY STATUS RESTARTS AGE
    2. static-web 1/1 Running 0 2m

    Note: Make sure the kubelet has permission to create the mirror Pod in the API server. If not, the creation request is rejected by the API server.

    Labels from the static Pod are propagated into the mirror Pod. You can use those labels as normal via , etc.

    If you try to use to delete the mirror Pod from the API server, the kubelet doesn’t remove the static Pod:

      1. pod "static-web" deleted

      You can see that the Pod is still running:

      1. kubectl get pods

      Back on your node where the kubelet is running, you can try to stop the container manually. You’ll see that, after a time, the kubelet will notice and will restart the Pod automatically:

      1. # Run these commands on the node where the kubelet is running
      2. crictl stop 129fd7d382018 # replace with the ID of your container
      3. sleep 20
      4. crictl ps
      1. CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
      2. 89db4553e1eeb docker.io/library/nginx@sha256:... 19 seconds ago Running web 1 34533c6729106

      Once you identify the right container, you can get the logs for that container with crictl:

      1. # Run these commands on the node where the container is running
      2. crictl logs <container_id>
      1. 10.240.0.48 - - [16/Nov/2022:12:45:49 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
      2. 10.240.0.48 - - [16/Nov/2022:12:45:50 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
      3. 10.240.0.48 - - [16/Nove/2022:12:45:51 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"

      The running kubelet periodically scans the configured directory (/etc/kubernetes/manifests in our example) for changes and adds/removes Pods as files appear/disappear in this directory.

      1. # This assumes you are using filesystem-hosted static Pod configuration
      2. # Run these commands on the node where the container is running
      3. #
      4. mv /etc/kubernetes/manifests/static-web.yaml /tmp
      5. sleep 20
      6. crictl ps
      7. # You see that no nginx container is running
      8. mv /tmp/static-web.yaml /etc/kubernetes/manifests/
      9. sleep 20
      10. crictl ps
      1. CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID