静态POD
静态pod的原理
静态 Pod 直接由特定节点上的kubelet进程来管理,不通过 master 节点上的apiserver。无法与我们常用的控制器Deployment或者DaemonSet进行关联,它由kubelet进程自己来监控,当pod崩溃时重启该pod,kubelete也无法对他们进行健康检查。静态 pod 始终绑定在某一个kubelet,并且始终运行在同一个节点上。 kubelet会自动为每一个静态 pod 在 Kubernetes 的 apiserver 上创建一个镜像 Pod(Mirror Pod),因此我们可以在 apiserver 中查询到该 pod,但是不能通过 apiserver 进行控制(例如不能删除)。
实现效果
-
如果把pod的yaml描述文件放到这个目录中,等kubelet扫描到文件,会自动在本机–>文件所在node的kubelet创建出来 pod
-
如果把 pod的yaml文件更改了,kubelet也会识别到,会自动更新pod
-
如果把 pod的yaml文件删除了kubelet会自动删除掉pod
-
因为静态pod 不能被 api-server 直接管理,所以它的更新删除操作不能由 kubectl 来执行,'只能直接修改或删除文本文件
-
备注:但是在etcd数据库会进行记录
创建静态 Pod 有两种方式:
配置文件
首先需要设置kubelet 的启动参数"--config",指定kubelet需要监控的配置文件所在的目录,kubelet会定期扫描该目录,并根据该目录下的.yaml或.json文件进行创建操作。
假设配置目录为/etc/kubernetes/conf/,配置启动参数为--config=/etc/kubernetes/conf/然后重启kubelet服务。
等待一会,查看本机中已经启动的容器,可以看到容器已经被kubelet创建出来了。
由于静态pod无法通过api server直接管理,所以在master上删除这个pod时,会使其变成pending状态,且不会被删除。
删除该pod的操作只能是到其所在node上将其定义文件.yaml从/etc/kubernetes/conf/目录下删除
HTTP
通过设置kubelet的启动参数“--manifest-url”,kubelet将会定期从该URL地址下载pod的定义文件,并以.yaml或.json文件的格式进行解析,然后创建pod。其实现方式与配置文件方式是一致的。
配置文件方式
配置文件方式就是把JSON或者YAML格式的pod定义文件存放到指定目录,例如通过kubeadm安装的主要进程都是以配置文件的方式添加到静态pod
[root@k8s-master ~]# ll /etc/kubernetes/manifests
总用量 16
-rw------- 1 root root 1893 2月 22 15:47 etcd.yaml
-rw------- 1 root root 2741 2月 22 15:47 kube-apiserver.yaml
-rw------- 1 root root 2594 2月 22 15:47 kube-controller-manager.yaml
-rw------- 1 root root 1149 2月 22 15:47 kube-scheduler.yaml
#此文件中的yaml文件都是静态pod
通过kubeadm的方式来安装的集群环境,对应的kubelet已经配置了我们的静态 Pod 文件的路径,那就是
/etc/kubernetes/manifests
比如我们在 node01 这个节点上用静态 pod 的方式来启动一个 nginx 的服务。我们登录到node01节点上面,可以通过下面命令找到kubelet对应的启动配置文件路径
node01
[root@k8s-node01 ~]# systemctl status kubelet.service -l
[root@k8s-node01 ~]# systemctl show --property=Environment kubelet | cat
#查看kubelet的环境配置 下方为输出信息
Environment=KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf\x20--kubeconfig=/etc/kubernetes/kubelet.conf KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml
其中,/var/lib/kubelet/config.yaml中我们可以看到相关的环境变量配置
[root@k8s-node01 ~]# cat /var/lib/kubelet/config.yaml | grep static
#此目录就是静态pod的存放目录
staticPodPath: /etc/kubernetes/manifests
创建一个yaml文件进行测试
[root@k8s-node01 ~]# cd /etc/kubernetes/manifests
[root@k8s-node01 manifests]# ls
[root@k8s-node01 manifests]# vim static-web.yaml
apiVersion: v1
kind: Pod
metadata:
name: static-web
labels:
app: static
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
node-01下载镜像
[root@k8s-node01 manifests]# docker pull nginx
前往master查看是否生效
[root@k8s-master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
static-web-k8s-node01 1/1 Running 0 3m21s 10.244.1.2 k8s-node01 <none> <none>
#可以查看到此时已经生效在node-01上创建成功
生成的静态pod,Kubectl删除后还会重新构建,如果更改了yaml文件,也会更新pod,如果想删除此pod,把对应的yaml移出静态pod目录即可,或者删除该yaml文件
示例:删除静态pod
[root@k8s-node01 manifests]# ls
static-web.yaml
[root@k8s-node01 manifests]# mv static-web.yaml /tmp/ #移动出此目录即可删除
#前往master节点进行验证
[root@k8s-master ~]# kubectl get pods -o wide
No resources found in default namespace. #默认命名空间没有任何pod
#此时已经成功移出静态pod
通过 HTTP 创建静态 Pods
Kubelet 根据 --manifest-url=<URL>
参数的配置定期的下载指定文件,并且转换成 JSON/YAML 格式的 Pod 定义文件。 与文件系统上的清单文件使用方式类似,kubelet 调度获取清单文件。 如果静态 Pod 的清单文件有改变,kubelet 会应用这些改变。
按照下面的方式来:
-
创建一个 YAML 文件,并保存在 web 服务上,为 kubelet 生成一个 URL。
apiVersion: v1 kind: Pod metadata: name: static-web labels: role: myrole spec: containers: - name: web image: nginx ports: - name: web containerPort: 80 protocol: TCP
-
通过在选择的节点上使用
--manifest-url=<manifest-url>
配置运行 kubelet。 在 Fedora 添加下面这行到/etc/kubernetes/kubelet
:KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --manifest-url=<manifest-url>"
-
重启 kubelet。在 Fedora 上运行如下命令:
# 在 kubelet 运行的节点上执行以下命令 systemctl restart kubelet
观察静态 pod 的行为
当 kubelet 启动时,会自动启动所有定义的静态 Pod。 当定义了一个静态 Pod 并重新启动 kubelet 时,新的静态 Pod 就应该已经在运行了。
可以在节点上运行下面的命令来查看正在运行的容器(包括静态 Pod):
# 在 kubelet 运行的节点上执行以下命令
docker ps
输出可能会像这样:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f6d05272b57e nginx:latest "nginx" 8 minutes ago Up 8 minutes k8s_web.6f802af4_static-web-fk-node1_default_67e24ed9466ba55986d120c867395f3c_378e5f3c
可以在 API 服务上看到镜像 Pod:
kubectl get pods
NAME READY STATUS RESTARTS AGE
static-web-my-node1 1/1 Running 0 2m
说明: 要确保 kubelet 在 API 服务上有创建镜像 Pod 的权限。如果没有,创建请求会被 API 服务拒绝。 可以看Pod安全策略。
静态 Pod 上的标签 被传到镜像 Pod。 你可以通过 选择算符 使用这些标签。
如果你用 kubectl
从 API 服务上删除镜像 Pod,kubelet 不会 移除静态 Pod:
kubectl delete pod static-web-my-node1
pod "static-web-my-node1" deleted
可以看到 Pod 还在运行:
kubectl get pods
NAME READY STATUS RESTARTS AGE
static-web-my-node1 1/1 Running 0 12s
回到 kubelet 运行的节点上,可以手工停止 Docker 容器。 可以看到过了一段时间后 kubelet 会发现容器停止了并且会自动重启 Pod:
# 在 kubelet 运行的节点上执行以下命令
# 把 ID 换为你的容器的 ID
docker stop f6d05272b57e
sleep 20
docker ps
CONTAINER ID IMAGE COMMAND CREATED ...
5b920cbaf8b1 nginx:latest "nginx -g 'daemon of 2 seconds ago ...
动态增加和删除静态 pod
运行中的 kubelet 会定期扫描配置的目录(比如例子中的 /etc/kubelet.d
目录)中的变化, 并且根据文件中出现/消失的 Pod 来添加/删除 Pod。
# 前提是你在用主机文件系统上的静态 Pod 配置文件
# 在 kubelet 运行的节点上执行以下命令
mv /etc/kubelet.d/static-web.yaml /tmp
sleep 20
docker ps
# 可以看到没有 nginx 容器在运行
mv /tmp/static-web.yaml /etc/kubelet.d/
sleep 20
docker ps