在生产环境中,如果没有配置合适的告警,可能会发现某个 Pod 有 restartCount,但是由于已经重启了超过一小时,没有相关的 Events,导致无法看到响应的 Pod 重启原因。想要捕获每一次 Pod 退出异常,K8s 为我们提供了 Pod.spec.container[0].terminationMessagePath field ,来记录 Pod 异常退出时的信息。
for idx := range opts.Mounts { v := opts.Mounts[idx] selinuxRelabel := v.SELinuxRelabel && selinux.SELinuxEnabled() mount := &runtimeapi.Mount{ HostPath: v.HostPath, ContainerPath: v.ContainerPath, Readonly: v.ReadOnly, SelinuxRelabel: selinuxRelabel, Propagation: v.Propagation, }
volumeMounts = append(volumeMounts, mount) }
// The reason we create and mount the log file in here (not in kubelet) is because // the file's location depends on the ID of the container, and we need to create and // mount the file before actually starting the container. // we can only mount individual files (e.g.: /etc/hosts, termination-log files) on Windows only if we're using Containerd. supportsSingleFileMapping := m.SupportsSingleFileMapping() if opts.PodContainerDir != "" && len(container.TerminationMessagePath) != 0 && supportsSingleFileMapping { // Because the PodContainerDir contains pod uid and container name which is unique enough, // here we just add a random id to make the path unique for different instances // of the same container. cid := makeUID() containerLogPath := filepath.Join(opts.PodContainerDir, cid) fs, err := m.osInterface.Create(containerLogPath) if err != nil { utilruntime.HandleError(fmt.Errorf("error on creating termination-log file %q: %v", containerLogPath, err)) } else { fs.Close()
// Chmod is needed because ioutil.WriteFile() ends up calling // open(2) to create the file, so the final mode used is "mode & // ~umask". But we want to make sure the specified mode is used // in the file no matter what the umask is. if err := m.osInterface.Chmod(containerLogPath, 0666); err != nil { utilruntime.HandleError(fmt.Errorf("unable to set termination-log file permissions %q: %v", containerLogPath, err)) }
// Volume Mounts fail on Windows if it is not of the form C:/ containerLogPath = volumeutil.MakeAbsolutePath(goruntime.GOOS, containerLogPath) terminationMessagePath := volumeutil.MakeAbsolutePath(goruntime.GOOS, container.TerminationMessagePath) selinuxRelabel := selinux.SELinuxEnabled() volumeMounts = append(volumeMounts, &runtimeapi.Mount{ HostPath: containerLogPath, ContainerPath: terminationMessagePath, SelinuxRelabel: selinuxRelabel, }) } }