codecamp

Kubernetes 创建静态Pod

创建静态 Pod

静态 Pod 在指定的节点上由 kubelet 守护进程直接管理,不需要 API 服务器 监管。 与由控制面管理的 Pod(例如,Deployment) 不同;kubelet 监视每个静态 Pod(在它崩溃之后重新启动)。

静态 Pod 永远都会绑定到一个指定节点上的 Kubelet。

kubelet 会尝试通过 Kubernetes API 服务器为每个静态 Pod 自动创建一个 镜像 Pod。 这意味着节点上运行的静态 Pod 对 API 服务来说是可见的,但是不能通过 API 服务器来控制。 Pod 名称将把以连字符开头的节点主机名作为后缀。

Note: 如果你在运行一个 Kubernetes 集群,并且在每个节点上都运行一个静态 Pod, 就可能需要考虑使用 DaemonSet 替代这种方式。

Note: 静态 Pod 的 ​spec ​不能引用其他 API 对象 (如:ServiceAccount、 ConfigMap、 Secret 等)。

在开始之前

你必须拥有一个 Kubernetes 的集群,同时你的 Kubernetes 集群必须带有 kubectl 命令行工具。 建议在至少有两个节点的集群上运行本教程,且这些节点不作为控制平面主机。 如果你还没有集群,你可以通过 Minikube 构建一个你自己的集群,或者你可以使用下面任意一个 Kubernetes 工具构建:

要检查版本,请输入 ​kubectl version​。

本文假定你在使用 Docker 来运行 Pod, 并且你的节点是运行着 Fedora 操作系统。 其它发行版或者 Kubernetes 部署版本上操作方式可能不一样。

创建静态 Pod 

可以通过文件系统上的配置文件 或者 web 网络上的配置文件 来配置静态 Pod。

文件系统上的静态 Pod 声明文件

声明文件是标准的 Pod 定义文件,以 JSON 或者 YAML 格式存储在指定目录。路径设置在 Kubelet 配置文件 的 ​staticPodPath: <目录>​ 字段,kubelet 会定期的扫描这个文件夹下的 YAML/JSON 文件来创建/删除静态 Pod。 注意 kubelet 扫描目录的时候会忽略以点开头的文件。

例如:下面是如何以静态 Pod 的方式启动一个简单 web 服务:

  1. 选择一个要运行静态 Pod 的节点。在这个例子中选择 ​my-node1​。
  2. ssh my-node1
    
  3. 选择一个目录,比如在 ​/etc/kubelet.d​ 目录来保存 web 服务 Pod 的定义文件, ​/etc/kubelet.d/static-web.yaml​:
  4. # 在 kubelet 运行的节点上执行以下命令
    mkdir /etc/kubelet.d/
    cat <<EOF >/etc/kubelet.d/static-web.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: static-web
      labels:
        role: myrole
    spec:
      containers:
        - name: web
          image: nginx
          ports:
            - name: web
              containerPort: 80
              protocol: TCP
    EOF
  5. 配置这个节点上的 kubelet,使用这个参数执行 ​--pod-manifest-path=/etc/kubelet.d/​。 在 Fedora 上编辑 ​/etc/kubernetes/kubelet​ 以包含下行:
  6. KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --pod-manifest-path=/etc/kubelet.d/"
    

    或者在 Kubelet 配置文件 中添加 ​staticPodPath: <目录>​字段。

  7. 重启 kubelet。Fedora 上使用下面的命令:
  8. # 在 kubelet 运行的节点上执行以下命令
    systemctl restart kubelet

Web 网上的静态 Pod 声明文件

Kubelet 根据 ​--manifest-url=<URL>​ 参数的配置定期的下载指定文件,并且转换成 JSON/YAML 格式的 Pod 定义文件。 与文件系统上的清单文件使用方式类似,kubelet 调度获取清单文件。 如果静态 Pod 的清单文件有改变,kubelet 会应用这些改变。

按照下面的方式来:

  1. 创建一个 YAML 文件,并保存在 web 服务上,为 kubelet 生成一个 URL。
  2. apiVersion: v1
    kind: Pod
    metadata:
      name: static-web
      labels:
        role: myrole
    spec:
      containers:
        - name: web
          image: nginx
          ports:
            - name: web
              containerPort: 80
              protocol: TCP
  3. 通过在选择的节点上使用 ​--manifest-url=<manifest-url>​ 配置运行 kubelet。 在 Fedora 添加下面这行到 ​/etc/kubernetes/kubelet​ :
  4. KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --manifest-url=<manifest-url>"
    
  5. 重启 kubelet。在 Fedora 上运行如下命令:
  6. # 在 kubelet 运行的节点上执行以下命令
    systemctl restart kubelet

观察静态 pod 的行为 

当 kubelet 启动时,会自动启动所有定义的静态 Pod。 当定义了一个静态 Pod 并重新启动 kubelet 时,新的静态 Pod 就应该已经在运行了。

可以在节点上运行下面的命令来查看正在运行的容器(包括静态 Pod):

# 在 kubelet 运行的节点上执行以下命令
crictl ps

输出可能会像这样:

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

Note: ​crictl ​会输出镜像 URI 和 SHA-256 校验和。 ​NAME ​看起来像: ​docker.io/library/nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31​。

可以在 API 服务上看到镜像 Pod:

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

Note: 要确保 kubelet 在 API 服务上有创建镜像 Pod 的权限。如果没有,创建请求会被 API 服务拒绝。

静态 Pod 上的标签 被传到镜像 Pod。 你可以通过 选择算符 使用这些标签。

如果你用 ​kubectl ​从 API 服务上删除镜像 Pod,kubelet 不会 移除静态 Pod:

kubectl delete pod static-web
pod "static-web" deleted

可以看到 Pod 还在运行:

kubectl get pods
NAME         READY   STATUS    RESTARTS   AGE
static-web   1/1     Running   0          4s

回到 kubelet 运行的节点上,你可以手动停止容器。 可以看到过了一段时间后 kubelet 会发现容器停止了并且会自动重启 Pod:

# 在 kubelet 运行的节点上执行以下命令
# 把 ID 换为你的容器的 ID
crictl stop 129fd7d382018
sleep 20
crictl ps
CONTAINER       IMAGE                                 CREATED           STATE      NAME    ATTEMPT    POD ID
89db4553e1eeb   docker.io/library/nginx@sha256:...    19 seconds ago    Running    web     1          34533c6729106

动态增加和删除静态 pod 

运行中的 kubelet 会定期扫描配置的目录(比如例子中的 ​/etc/kubelet.d​ 目录)中的变化, 并且根据文件中出现/消失的 Pod 来添加/删除 Pod。

# 前提是你在用主机文件系统上的静态 Pod 配置文件
# 在 kubelet 运行的节点上执行以下命令
mv /etc/kubelet.d/static-web.yaml /tmp
sleep 20
crictl ps
# 可以看到没有 nginx 容器在运行
mv /tmp/static-web.yaml  /etc/kubelet.d/
sleep 20
crictl ps
CONTAINER       IMAGE                                 CREATED           STATE      NAME    ATTEMPT    POD ID
f427638871c35   docker.io/library/nginx@sha256:...    19 seconds ago    Running    web     1          34533c6729106


Kubernetes 在Pod中的容器之间共享进程命名空间
Kubernetes 将Docker Compose文件转换为Kubernetes资源
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

Kubernetes 管理集群

Kubernetes Service

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }