Docker 容器自愈 Kubernetes 适合单实例吗?

Docker container auto healing is Kubernetes suitable for one instance?

我有一个 docker 容器,什么是 运行 pyppeteer。 它有内存泄漏,所以它会在 24 小时后停止。

我需要一些自动修复系统,我认为 Kubernetes 可以做到。没有负载平衡,只有一个实例,一个容器。合适吗?

++++

最后我选择了docker-py,使用containers.run, containers.prune.

管理

它对我有用。

您的用例有多种选择,其中之一是 运行 kubernetes。但是,当 运行 kubernetes 仅用于单个容器时,您应该考虑资源开销和维护负担。

我建议您尝试让 systemd 重新启动您的容器,以防它崩溃或只是简单地使用 docker 本身:使用 --restart=always 参数,docker 守护进程确保容器 运行。注意:即使在重新启动系统后 docker 也会确保容器在这种情况下重新启动。所以 --restart=on-failure 可能是更好的选择。

有关详细信息,请参阅此页面:https://docs.docker.com/config/containers/start-containers-automatically/#use-a-restart-policy

如果您的容器没有状态,并且您知道它每 24 小时 运行 内存不足,我认为 cronjob 是最佳选择。

你可以在 k8s 上做你想做的事,但这太过分了。一个容器的整个 k8s 集群,对我来说听起来不对。

另一件事是,如果您有更多应用程序或容器,因为 k8s 可以 运行 许多服务彼此独立,因此您不会浪费资源。

我没有使用 Puppeteer,但经过短暂的研究发现 this

By default, Docker runs a container with a /dev/shm shared memory space 64MB. This is typically too small for Chrome and will cause Chrome to crash when rendering large pages. To fix, run the container with docker run --shm-size=1gb to increase the size of /dev/shm. Since Chrome 65, this is no longer necessary. Instead, launch the browser with the --disable-dev-shm-usage flag:

const browser = await puppeteer.launch({
  args: ['--disable-dev-shm-usage']
});

This will write shared memory files into /tmp instead of /dev/shm.

希望对您有所帮助。

无需创建完整的 Kubernetes 集群即可使用 Kubernetes 自动修复功能。只需要安装 dockerkubelet 软件包的兼容版本。也可以安装 kubeadm 包。

Kubelet is the part of Kubernetes control-plane that takes care of keeping Pods in healthy condition. It runs as a systemd service, and creates static pods 使用来自 /etc/kubernetes/manifests 的 YAML 清单文件(位置可配置)。

所有其他应用程序故障排除都可以使用常规 docker 命令完成:

docker ps ...
docker inspect
docker logs ...
docker exec ...
docker attach ...
docker cp ...

来自官方文档的这种方法的一个 good example 是 运行 外部 etcd 集群实例。 (注意:Kubelet 配置部分可能无法按预期使用最新的 kubelet 版本。我在下面提供了更多详细信息。)

kubelet 还可以通过应用 pod 规范的 limits 部分来处理 pod 资源的使用。因此,您可以设置内存限制,当容器达到此限制时,kubelet 将重新启动它。

如果 pod 规范中包含 liveness probe 部分,Kubelet 可以对 pod 中的应用程序进行健康检查。如果你可以创建一个命令来更精确地检查你的应用程序条件,kubelet 可以在命令 return 连续多次非零退出代码(可配置)时重启容器。

如果 kubelet 拒绝启动,您可以使用以下命令检查 kubelet 日志:

journalctl -e -u kubelet

Kubelet 拒绝启动的主要原因是:

  • 缺少 kubelet 初始配置。它可以使用 kubeadm 命令生成:kubeadm init phase kubelet-start。 (您可能还需要生成 kubelet 配置中提到的 CA 证书 /etc/kubernetes/pki/ca.crt。可以使用 kubadm 完成:kubeadm init phase certs ca

  • docker 和 kubelet 的不同 cgroups 驱动程序设置。 Kubelet 与 cgroupsfs 和 systemd 驱动程序一起工作良好。 Docker 默认驱动程序是 cgroupfs。 Kubeamd 还使用 cgroupsfs 驱动程序生成 kubelet 配置,因此只需确保它们相同即可。 Docker 可以在服务定义文件中指定 cgroups 驱动程序,例如 /lib/systemd/system/docker.service/usr/lib/systemd/system/docker.service:

    #add cgroups driver option to ExecStart:
    ExecStart=/usr/bin/dockerd \
          --exec-opt native.cgroupdriver=systemd   # or cgroupfs
    

要为最近的 kubelet 版本更改 cgroups 驱动程序,需要为服务指定 kubelet 配置文件,因为现在不推荐使用此类命令行选项:

sed -i 's/ExecStart=\/usr\/bin\/kubelet/ExecStart=\/usr\/bin\/kubelet --config=\/var\/lib\/kubelet\/config.yaml/' /lib/systemd/system/kubelet.service

然后更改 kubelet 配置中的 cgroups 行。几个选项也需要更改。这是我用于相同目的的 kubelet 配置:

address: 127.0.0.1                           # changed, was 0.0.0.0
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
  anonymous:
    enabled: false
  webhook:
    cacheTTL: 2m0s
    enabled: false                           # changed, was true
  x509:
    clientCAFile: /etc/kubernetes/pki/ca.crt  # kubeadm init phase certs ca
authorization:
  mode: AlwaysAllow                          # changed, was Webhook
  webhook:
    cacheAuthorizedTTL: 5m0s
    cacheUnauthorizedTTL: 30s
cgroupDriver: cgroupfs                       # could be changed to systemd or left as is, as docker default driver is cgroupfs
cgroupsPerQOS: true
clusterDNS:
- 10.96.0.10
clusterDomain: cluster.local
configMapAndSecretChangeDetectionStrategy: Watch
containerLogMaxFiles: 5
containerLogMaxSize: 10Mi
contentType: application/vnd.kubernetes.protobuf
cpuCFSQuota: true
cpuCFSQuotaPeriod: 100ms
cpuManagerPolicy: none
cpuManagerReconcilePeriod: 10s
enableControllerAttachDetach: true
enableDebuggingHandlers: true
enforceNodeAllocatable:
- pods
eventBurst: 10
eventRecordQPS: 5
evictionHard:
  imagefs.available: 15%
  memory.available: 100Mi
  nodefs.available: 10%
  nodefs.inodesFree: 5%
evictionPressureTransitionPeriod: 5m0s
failSwapOn: true
fileCheckFrequency: 20s
hairpinMode: promiscuous-bridge
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 20s
imageGCHighThresholdPercent: 85
imageGCLowThresholdPercent: 80
imageMinimumGCAge: 2m0s
iptablesDropBit: 15
iptablesMasqueradeBit: 14
kind: KubeletConfiguration
kubeAPIBurst: 10
kubeAPIQPS: 5
makeIPTablesUtilChains: true
maxOpenFiles: 1000000
maxPods: 110
nodeLeaseDurationSeconds: 40
nodeStatusReportFrequency: 1m0s
nodeStatusUpdateFrequency: 10s
oomScoreAdj: -999
podPidsLimit: -1
port: 10250
registryBurst: 10
registryPullQPS: 5
resolvConf: /etc/resolv.conf
rotateCertificates: true
runtimeRequestTimeout: 2m0s
serializeImagePulls: true
staticPodPath: /etc/kubernetes/manifests
streamingConnectionIdleTimeout: 4h0m0s
syncFrequency: 1m0s
volumeStatsAggPeriod: 1m0s

重新启动 docker/kubelet 服务:

systemctl daemon-reload
systemctl restart docker
systemctl restart kubelet