|
| 1 | +--- |
| 2 | +reviewers: |
| 3 | +- jsafrane |
| 4 | +title: Create static Pods |
| 5 | +weight: 170 |
| 6 | +content_type: task |
| 7 | +--- |
| 8 | + |
| 9 | +<!-- overview --> |
| 10 | + |
| 11 | + |
| 12 | +*Static Pods* are managed directly by the kubelet daemon on a specific node, |
| 13 | +without the {{< glossary_tooltip text="API server" term_id="kube-apiserver" >}} |
| 14 | +observing them. |
| 15 | +Unlike Pods that are managed by the control plane (for example, a |
| 16 | +{{< glossary_tooltip text="Deployment" term_id="deployment" >}}); |
| 17 | +instead, the kubelet watches each static Pod (and restarts it if it fails). |
| 18 | + |
| 19 | +Static Pods are always bound to one {{< glossary_tooltip term_id="kubelet" >}} on a specific node. |
| 20 | + |
| 21 | +The kubelet automatically tries to create a {{< glossary_tooltip text="mirror Pod" term_id="mirror-pod" >}} |
| 22 | +on the Kubernetes API server for each static Pod. |
| 23 | +This means that the Pods running on a node are visible on the API server, |
| 24 | +but cannot be controlled from there. |
| 25 | + |
| 26 | +{{< note >}} |
| 27 | +If you are running clustered Kubernetes and are using static |
| 28 | +Pods to run a Pod on every node, you should probably be using a |
| 29 | +{{< glossary_tooltip text="DaemonSet" term_id="daemonset" >}} |
| 30 | +instead. |
| 31 | +{{< /note >}} |
| 32 | + |
| 33 | + |
| 34 | + |
| 35 | +## {{% heading "prerequisites" %}} |
| 36 | + |
| 37 | + |
| 38 | +{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} |
| 39 | + |
| 40 | +This page assumes you're using {{< glossary_tooltip term_id="docker" >}} to run Pods, |
| 41 | +and that your nodes are running the Fedora operating system. |
| 42 | +Instructions for other distributions or Kubernetes installations may vary. |
| 43 | + |
| 44 | + |
| 45 | + |
| 46 | + |
| 47 | + |
| 48 | +<!-- steps --> |
| 49 | + |
| 50 | +## Create a static pod {#static-pod-creation} |
| 51 | + |
| 52 | +You can configure a static Pod with either a [file system hosted configuration file](/docs/tasks/configure-pod-container/static-pod/#configuration-files) or a [web hosted configuration file](/docs/tasks/configure-pod-container/static-pod/#pods-created-via-http). |
| 53 | + |
| 54 | +### Filesystem-hosted static Pod manifest {#configuration-files} |
| 55 | + |
| 56 | +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](/docs/tasks/administer-cluster/kubelet-config-file), which periodically scans the directory and creates/deletes static Pods as YAML/JSON files appear/disappear there. |
| 57 | +Note that the kubelet will ignore files starting with dots when scanning the specified directory. |
| 58 | + |
| 59 | +For example, this is how to start a simple web server as a static Pod: |
| 60 | + |
| 61 | +1. Choose a node where you want to run the static Pod. In this example, it's `my-node1`. |
| 62 | + |
| 63 | + ```shell |
| 64 | + ssh my-node1 |
| 65 | + ``` |
| 66 | + |
| 67 | +2. Choose a directory, say `/etc/kubelet.d` and place a web server Pod definition there, for example `/etc/kubelet.d/static-web.yaml`: |
| 68 | + |
| 69 | + ```shell |
| 70 | + # Run this command on the node where kubelet is running |
| 71 | + mkdir /etc/kubelet.d/ |
| 72 | + cat <<EOF >/etc/kubelet.d/static-web.yaml |
| 73 | + apiVersion: v1 |
| 74 | + kind: Pod |
| 75 | + metadata: |
| 76 | + name: static-web |
| 77 | + labels: |
| 78 | + role: myrole |
| 79 | + spec: |
| 80 | + containers: |
| 81 | + - name: web |
| 82 | + image: nginx |
| 83 | + ports: |
| 84 | + - name: web |
| 85 | + containerPort: 80 |
| 86 | + protocol: TCP |
| 87 | + EOF |
| 88 | + ``` |
| 89 | +
|
| 90 | +3. Configure your kubelet on the node to use this directory by running it with `--pod-manifest-path=/etc/kubelet.d/` argument. On Fedora edit `/etc/kubernetes/kubelet` to include this line: |
| 91 | +
|
| 92 | + ``` |
| 93 | + KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --pod-manifest-path=/etc/kubelet.d/" |
| 94 | + ``` |
| 95 | + or add the `staticPodPath: <the directory>` field in the [kubelet configuration file](/docs/tasks/administer-cluster/kubelet-config-file). |
| 96 | +
|
| 97 | +4. Restart the kubelet. On Fedora, you would run: |
| 98 | +
|
| 99 | + ```shell |
| 100 | + # Run this command on the node where the kubelet is running |
| 101 | + systemctl restart kubelet |
| 102 | + ``` |
| 103 | +
|
| 104 | +### Web-hosted static pod manifest {#pods-created-via-http} |
| 105 | +
|
| 106 | +Kubelet periodically downloads a file specified by `--manifest-url=<URL>` argument |
| 107 | +and interprets it as a JSON/YAML file that contains Pod definitions. |
| 108 | +Similar to how [filesystem-hosted manifests](#configuration-files) work, the kubelet |
| 109 | +refetches the manifest on a schedule. If there are changes to the list of static |
| 110 | +Pods, the kubelet applies them. |
| 111 | +
|
| 112 | +To use this approach: |
| 113 | +
|
| 114 | +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. |
| 115 | +
|
| 116 | + ```yaml |
| 117 | + apiVersion: v1 |
| 118 | + kind: Pod |
| 119 | + metadata: |
| 120 | + name: static-web |
| 121 | + labels: |
| 122 | + role: myrole |
| 123 | + spec: |
| 124 | + containers: |
| 125 | + - name: web |
| 126 | + image: nginx |
| 127 | + ports: |
| 128 | + - name: web |
| 129 | + containerPort: 80 |
| 130 | + protocol: TCP |
| 131 | + ``` |
| 132 | +
|
| 133 | +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: |
| 134 | +
|
| 135 | + ``` |
| 136 | + KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --manifest-url=<manifest-url>" |
| 137 | + ``` |
| 138 | +
|
| 139 | +3. Restart the kubelet. On Fedora, you would run: |
| 140 | +
|
| 141 | + ```shell |
| 142 | + # Run this command on the node where the kubelet is running |
| 143 | + systemctl restart kubelet |
| 144 | + ``` |
| 145 | +
|
| 146 | +## Observe static pod behavior {#behavior-of-static-pods} |
| 147 | +
|
| 148 | +When the kubelet starts, it automatically starts all defined static Pods. As you have |
| 149 | +defined a static Pod and restarted the kubelet, the new static Pod should |
| 150 | +already be running. |
| 151 | +
|
| 152 | +You can view running containers (including static Pods) by running (on the node): |
| 153 | +```shell |
| 154 | +# Run this command on the node where the kubelet is running |
| 155 | +docker ps |
| 156 | +``` |
| 157 | +
|
| 158 | +The output might be something like: |
| 159 | +
|
| 160 | +``` |
| 161 | +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
| 162 | +f6d05272b57e nginx:latest "nginx" 8 minutes ago Up 8 minutes k8s_web.6f802af4_static-web-fk-node1_default_67e24ed9466ba55986d120c867395f3c_378e5f3c |
| 163 | +``` |
| 164 | +
|
| 165 | +You can see the mirror Pod on the API server: |
| 166 | +
|
| 167 | +```shell |
| 168 | +kubectl get pods |
| 169 | +``` |
| 170 | +``` |
| 171 | +NAME READY STATUS RESTARTS AGE |
| 172 | +static-web-my-node1 1/1 Running 0 2m |
| 173 | +``` |
| 174 | +
|
| 175 | +{{< note >}} |
| 176 | +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. See |
| 177 | +[PodSecurityPolicy](/docs/concepts/policy/pod-security-policy/). |
| 178 | +{{< /note >}} |
| 179 | +
|
| 180 | +
|
| 181 | +{{< glossary_tooltip term_id="label" text="Labels" >}} from the static Pod are |
| 182 | +propagated into the mirror Pod. You can use those labels as normal via |
| 183 | +{{< glossary_tooltip term_id="selector" text="selectors" >}}, etc. |
| 184 | +
|
| 185 | +If you try to use `kubectl` to delete the mirror Pod from the API server, |
| 186 | +the kubelet _doesn't_ remove the static Pod: |
| 187 | +
|
| 188 | +```shell |
| 189 | +kubectl delete pod static-web-my-node1 |
| 190 | +``` |
| 191 | +``` |
| 192 | +pod "static-web-my-node1" deleted |
| 193 | +``` |
| 194 | +You can see that the Pod is still running: |
| 195 | +```shell |
| 196 | +kubectl get pods |
| 197 | +``` |
| 198 | +``` |
| 199 | +NAME READY STATUS RESTARTS AGE |
| 200 | +static-web-my-node1 1/1 Running 0 12s |
| 201 | +``` |
| 202 | +
|
| 203 | +Back on your node where the kubelet is running, you can try to stop the Docker |
| 204 | +container manually. |
| 205 | +You'll see that, after a time, the kubelet will notice and will restart the Pod |
| 206 | +automatically: |
| 207 | +
|
| 208 | +```shell |
| 209 | +# Run these commands on the node where the kubelet is running |
| 210 | +docker stop f6d05272b57e # replace with the ID of your container |
| 211 | +sleep 20 |
| 212 | +docker ps |
| 213 | +``` |
| 214 | +``` |
| 215 | +CONTAINER ID IMAGE COMMAND CREATED ... |
| 216 | +5b920cbaf8b1 nginx:latest "nginx -g 'daemon of 2 seconds ago ... |
| 217 | +``` |
| 218 | +
|
| 219 | +## Dynamic addition and removal of static pods |
| 220 | +
|
| 221 | +The running kubelet periodically scans the configured directory (`/etc/kubelet.d` in our example) for changes and adds/removes Pods as files appear/disappear in this directory. |
| 222 | +
|
| 223 | +```shell |
| 224 | +# This assumes you are using filesystem-hosted static Pod configuration |
| 225 | +# Run these commands on the node where the kubelet is running |
| 226 | +# |
| 227 | +mv /etc/kubelet.d/static-web.yaml /tmp |
| 228 | +sleep 20 |
| 229 | +docker ps |
| 230 | +# You see that no nginx container is running |
| 231 | +mv /tmp/static-web.yaml /etc/kubelet.d/ |
| 232 | +sleep 20 |
| 233 | +docker ps |
| 234 | +``` |
| 235 | +``` |
| 236 | +CONTAINER ID IMAGE COMMAND CREATED ... |
| 237 | +e7a62e3427f1 nginx:latest "nginx -g 'daemon of 27 seconds ago |
| 238 | +``` |
| 239 | +
|
| 240 | +
|
0 commit comments