mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 05:57:25 +00:00
Merge pull request #5713 from AAzza/kubelet_build_parse_dockername
Refactor build/parse DockerName from Kubelet. #3511
This commit is contained in:
commit
adac4328e8
@ -213,13 +213,14 @@ func (self *realContainerGC) evictableContainers() (containersByEvictUnit, []con
|
|||||||
createTime: data.Created,
|
createTime: data.Created,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, uid, name, _, err := dockertools.ParseDockerName(container.Names[0])
|
containerName, _, err := dockertools.ParseDockerName(container.Names[0])
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
unidentifiedContainers = append(unidentifiedContainers, containerInfo)
|
unidentifiedContainers = append(unidentifiedContainers, containerInfo)
|
||||||
} else {
|
} else {
|
||||||
key := evictUnit{
|
key := evictUnit{
|
||||||
uid: uid,
|
uid: containerName.PodUID,
|
||||||
name: name,
|
name: containerName.ContainerName,
|
||||||
}
|
}
|
||||||
evictUnits[key] = append(evictUnits[key], containerInfo)
|
evictUnits[key] = append(evictUnits[key], containerInfo)
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,12 @@ type DockerInterface interface {
|
|||||||
// DockerID is an ID of docker container. It is a type to make it clear when we're working with docker container Ids
|
// DockerID is an ID of docker container. It is a type to make it clear when we're working with docker container Ids
|
||||||
type DockerID string
|
type DockerID string
|
||||||
|
|
||||||
|
type KubeletContainerName struct {
|
||||||
|
PodFullName string
|
||||||
|
PodUID types.UID
|
||||||
|
ContainerName string
|
||||||
|
}
|
||||||
|
|
||||||
// DockerPuller is an abstract interface for testability. It abstracts image pull operations.
|
// DockerPuller is an abstract interface for testability. It abstracts image pull operations.
|
||||||
type DockerPuller interface {
|
type DockerPuller interface {
|
||||||
Pull(image string) error
|
Pull(image string) error
|
||||||
@ -396,13 +402,13 @@ func (c DockerContainers) FindPodContainer(podFullName string, uid types.UID, co
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// TODO(proppy): build the docker container name and do a map lookup instead?
|
// TODO(proppy): build the docker container name and do a map lookup instead?
|
||||||
dockerManifestID, dockerUUID, dockerContainerName, hash, err := ParseDockerName(dockerContainer.Names[0])
|
dockerName, hash, err := ParseDockerName(dockerContainer.Names[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if dockerManifestID == podFullName &&
|
if dockerName.PodFullName == podFullName &&
|
||||||
(uid == "" || dockerUUID == uid) &&
|
(uid == "" || dockerName.PodUID == uid) &&
|
||||||
dockerContainerName == containerName {
|
dockerName.ContainerName == containerName {
|
||||||
return dockerContainer, true, hash
|
return dockerContainer, true, hash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -421,12 +427,12 @@ func (c DockerContainers) FindContainersByPod(podUID types.UID, podFullName stri
|
|||||||
if len(dockerContainer.Names) == 0 {
|
if len(dockerContainer.Names) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
dockerPodName, uuid, _, _, err := ParseDockerName(dockerContainer.Names[0])
|
dockerName, _, err := ParseDockerName(dockerContainer.Names[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if podUID == uuid ||
|
if podUID == dockerName.PodUID ||
|
||||||
(podUID == "" && podFullName == dockerPodName) {
|
(podUID == "" && podFullName == dockerName.PodFullName) {
|
||||||
containers[DockerID(dockerContainer.ID)] = dockerContainer
|
containers[DockerID(dockerContainer.ID)] = dockerContainer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -471,17 +477,17 @@ func GetRecentDockerContainersWithNameAndUUID(client DockerInterface, podFullNam
|
|||||||
if len(dockerContainer.Names) == 0 {
|
if len(dockerContainer.Names) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
dockerPodName, dockerUUID, dockerContainerName, _, err := ParseDockerName(dockerContainer.Names[0])
|
dockerName, _, err := ParseDockerName(dockerContainer.Names[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if dockerPodName != podFullName {
|
if dockerName.PodFullName != podFullName {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if uid != "" && dockerUUID != uid {
|
if uid != "" && dockerName.PodUID != uid {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if dockerContainerName != containerName {
|
if dockerName.ContainerName != containerName {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
inspectResult, _ := client.InspectContainer(dockerContainer.ID)
|
inspectResult, _ := client.InspectContainer(dockerContainer.ID)
|
||||||
@ -628,16 +634,17 @@ func GetDockerPodStatus(client DockerInterface, manifest api.PodSpec, podFullNam
|
|||||||
if len(value.Names) == 0 {
|
if len(value.Names) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
dockerManifestID, dockerUUID, dockerContainerName, _, err := ParseDockerName(value.Names[0])
|
dockerName, _, err := ParseDockerName(value.Names[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if dockerManifestID != podFullName {
|
if dockerName.PodFullName != podFullName {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if uid != "" && dockerUUID != uid {
|
if uid != "" && dockerName.PodUID != uid {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
dockerContainerName := dockerName.ContainerName
|
||||||
c, found := expectedContainers[dockerContainerName]
|
c, found := expectedContainers[dockerContainerName]
|
||||||
terminationMessagePath := ""
|
terminationMessagePath := ""
|
||||||
if !found {
|
if !found {
|
||||||
@ -713,26 +720,26 @@ func HashContainer(container *api.Container) uint64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Creates a name which can be reversed to identify both full pod name and container name.
|
// Creates a name which can be reversed to identify both full pod name and container name.
|
||||||
func BuildDockerName(podUID types.UID, podFullName string, container *api.Container) string {
|
func BuildDockerName(dockerName KubeletContainerName, container *api.Container) string {
|
||||||
containerName := container.Name + "." + strconv.FormatUint(HashContainer(container), 16)
|
containerName := dockerName.ContainerName + "." + strconv.FormatUint(HashContainer(container), 16)
|
||||||
return fmt.Sprintf("%s_%s_%s_%s_%08x",
|
return fmt.Sprintf("%s_%s_%s_%s_%08x",
|
||||||
containerNamePrefix,
|
containerNamePrefix,
|
||||||
containerName,
|
containerName,
|
||||||
podFullName,
|
dockerName.PodFullName,
|
||||||
podUID,
|
dockerName.PodUID,
|
||||||
rand.Uint32())
|
rand.Uint32())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unpacks a container name, returning the pod full name and container name we would have used to
|
// Unpacks a container name, returning the pod full name and container name we would have used to
|
||||||
// construct the docker name. If we are unable to parse the name, an error is returned.
|
// construct the docker name. If we are unable to parse the name, an error is returned.
|
||||||
func ParseDockerName(name string) (podFullName string, podUID types.UID, containerName string, hash uint64, err error) {
|
func ParseDockerName(name string) (dockerName *KubeletContainerName, hash uint64, err error) {
|
||||||
// For some reason docker appears to be appending '/' to names.
|
// For some reason docker appears to be appending '/' to names.
|
||||||
// If it's there, strip it.
|
// If it's there, strip it.
|
||||||
name = strings.TrimPrefix(name, "/")
|
name = strings.TrimPrefix(name, "/")
|
||||||
parts := strings.Split(name, "_")
|
parts := strings.Split(name, "_")
|
||||||
if len(parts) == 0 || parts[0] != containerNamePrefix {
|
if len(parts) == 0 || parts[0] != containerNamePrefix {
|
||||||
err = fmt.Errorf("failed to parse Docker container name %q into parts", name)
|
err = fmt.Errorf("failed to parse Docker container name %q into parts", name)
|
||||||
return
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
if len(parts) < 6 {
|
if len(parts) < 6 {
|
||||||
// We have at least 5 fields. We may have more in the future.
|
// We have at least 5 fields. We may have more in the future.
|
||||||
@ -740,12 +747,11 @@ func ParseDockerName(name string) (podFullName string, podUID types.UID, contain
|
|||||||
// manage.
|
// manage.
|
||||||
glog.Warningf("found a container with the %q prefix, but too few fields (%d): %q", containerNamePrefix, len(parts), name)
|
glog.Warningf("found a container with the %q prefix, but too few fields (%d): %q", containerNamePrefix, len(parts), name)
|
||||||
err = fmt.Errorf("Docker container name %q has less parts than expected %v", name, parts)
|
err = fmt.Errorf("Docker container name %q has less parts than expected %v", name, parts)
|
||||||
return
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Container name.
|
|
||||||
nameParts := strings.Split(parts[1], ".")
|
nameParts := strings.Split(parts[1], ".")
|
||||||
containerName = nameParts[0]
|
containerName := nameParts[0]
|
||||||
if len(nameParts) > 1 {
|
if len(nameParts) > 1 {
|
||||||
hash, err = strconv.ParseUint(nameParts[1], 16, 32)
|
hash, err = strconv.ParseUint(nameParts[1], 16, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -753,12 +759,10 @@ func ParseDockerName(name string) (podFullName string, podUID types.UID, contain
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pod fullname.
|
podFullName := parts[2] + "_" + parts[3]
|
||||||
podFullName = parts[2] + "_" + parts[3]
|
podUID := types.UID(parts[4])
|
||||||
|
|
||||||
// Pod UID.
|
return &KubeletContainerName{podFullName, podUID, containerName}, hash, nil
|
||||||
podUID = types.UID(parts[4])
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetRunningContainers(client DockerInterface, ids []string) ([]*docker.Container, error) {
|
func GetRunningContainers(client DockerInterface, ids []string) ([]*docker.Container, error) {
|
||||||
|
@ -92,13 +92,13 @@ func verifyPackUnpack(t *testing.T, podNamespace, podUID, podName, containerName
|
|||||||
util.DeepHashObject(hasher, *container)
|
util.DeepHashObject(hasher, *container)
|
||||||
computedHash := uint64(hasher.Sum32())
|
computedHash := uint64(hasher.Sum32())
|
||||||
podFullName := fmt.Sprintf("%s_%s", podName, podNamespace)
|
podFullName := fmt.Sprintf("%s_%s", podName, podNamespace)
|
||||||
name := BuildDockerName(types.UID(podUID), podFullName, container)
|
name := BuildDockerName(KubeletContainerName{podFullName, types.UID(podUID), container.Name}, container)
|
||||||
returnedPodFullName, returnedUID, returnedContainerName, hash, err := ParseDockerName(name)
|
returned, hash, err := ParseDockerName(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to parse Docker container name %q: %v", name, err)
|
t.Errorf("Failed to parse Docker container name %q: %v", name, err)
|
||||||
}
|
}
|
||||||
if podFullName != returnedPodFullName || podUID != string(returnedUID) || containerName != returnedContainerName || computedHash != hash {
|
if podFullName != returned.PodFullName || podUID != string(returned.PodUID) || containerName != returned.ContainerName || computedHash != hash {
|
||||||
t.Errorf("For (%s, %s, %s, %d), unpacked (%s, %s, %s, %d)", podFullName, podUID, containerName, computedHash, returnedPodFullName, returnedUID, returnedContainerName, hash)
|
t.Errorf("For (%s, %s, %s, %d), unpacked (%s, %s, %s, %d)", podFullName, podUID, containerName, computedHash, returned.PodFullName, returned.PodUID, returned.ContainerName, hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,12 +117,12 @@ func TestContainerManifestNaming(t *testing.T) {
|
|||||||
name := fmt.Sprintf("k8s_%s_%s_%s_%s_42", container.Name, podName, podNamespace, podUID)
|
name := fmt.Sprintf("k8s_%s_%s_%s_%s_42", container.Name, podName, podNamespace, podUID)
|
||||||
podFullName := fmt.Sprintf("%s_%s", podName, podNamespace)
|
podFullName := fmt.Sprintf("%s_%s", podName, podNamespace)
|
||||||
|
|
||||||
returnedPodFullName, returnedPodUID, returnedContainerName, hash, err := ParseDockerName(name)
|
returned, hash, err := ParseDockerName(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to parse Docker container name %q: %v", name, err)
|
t.Errorf("Failed to parse Docker container name %q: %v", name, err)
|
||||||
}
|
}
|
||||||
if returnedPodFullName != podFullName || string(returnedPodUID) != podUID || returnedContainerName != container.Name || hash != 0 {
|
if returned.PodFullName != podFullName || string(returned.PodUID) != podUID || returned.ContainerName != container.Name || hash != 0 {
|
||||||
t.Errorf("unexpected parse: %s %s %s %d", returnedPodFullName, returnedPodUID, returnedContainerName, hash)
|
t.Errorf("unexpected parse: %s %s %s %d", returned.PodFullName, returned.PodUID, returned.ContainerName, hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -737,7 +737,7 @@ func (kl *Kubelet) runContainer(pod *api.Pod, container *api.Container, podVolum
|
|||||||
exposedPorts, portBindings := makePortsAndBindings(container)
|
exposedPorts, portBindings := makePortsAndBindings(container)
|
||||||
|
|
||||||
opts := docker.CreateContainerOptions{
|
opts := docker.CreateContainerOptions{
|
||||||
Name: dockertools.BuildDockerName(pod.UID, GetPodFullName(pod), container),
|
Name: dockertools.BuildDockerName(dockertools.KubeletContainerName{GetPodFullName(pod), pod.UID, container.Name}, container),
|
||||||
Config: &docker.Config{
|
Config: &docker.Config{
|
||||||
Cmd: container.Command,
|
Cmd: container.Command,
|
||||||
Env: envVariables,
|
Env: envVariables,
|
||||||
@ -1411,12 +1411,6 @@ func (kl *Kubelet) syncPod(pod *api.Pod, hasMirrorPod bool, containersInPod dock
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type podContainer struct {
|
|
||||||
podFullName string
|
|
||||||
uid types.UID
|
|
||||||
containerName string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stores all volumes defined by the set of pods into a map.
|
// Stores all volumes defined by the set of pods into a map.
|
||||||
// Keys for each entry are in the format (POD_ID)/(VOLUME_NAME)
|
// Keys for each entry are in the format (POD_ID)/(VOLUME_NAME)
|
||||||
func getDesiredVolumes(pods []api.Pod) map[string]api.Volume {
|
func getDesiredVolumes(pods []api.Pod) map[string]api.Volume {
|
||||||
@ -1461,11 +1455,11 @@ func (kl *Kubelet) cleanupOrphanedVolumes(pods []api.Pod, running []*docker.Cont
|
|||||||
if len(running[ix].Name) == 0 {
|
if len(running[ix].Name) == 0 {
|
||||||
glog.V(2).Infof("Found running container ix=%d with info: %+v", ix, running[ix])
|
glog.V(2).Infof("Found running container ix=%d with info: %+v", ix, running[ix])
|
||||||
}
|
}
|
||||||
_, uid, _, _, err := dockertools.ParseDockerName(running[ix].Name)
|
containerName, _, err := dockertools.ParseDockerName(running[ix].Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
runningSet.Insert(string(uid))
|
runningSet.Insert(string(containerName.PodUID))
|
||||||
}
|
}
|
||||||
for name, vol := range currentVolumes {
|
for name, vol := range currentVolumes {
|
||||||
if _, ok := desiredVolumes[name]; !ok {
|
if _, ok := desiredVolumes[name]; !ok {
|
||||||
@ -1513,7 +1507,7 @@ func (kl *Kubelet) SyncPods(allPods []api.Pod, podSyncTypes map[types.UID]metric
|
|||||||
|
|
||||||
glog.V(4).Infof("Desired: %#v", pods)
|
glog.V(4).Infof("Desired: %#v", pods)
|
||||||
var err error
|
var err error
|
||||||
desiredContainers := make(map[podContainer]empty)
|
desiredContainers := make(map[dockertools.KubeletContainerName]empty)
|
||||||
desiredPods := make(map[types.UID]empty)
|
desiredPods := make(map[types.UID]empty)
|
||||||
|
|
||||||
dockerContainers, err := kl.dockerCache.RunningContainers()
|
dockerContainers, err := kl.dockerCache.RunningContainers()
|
||||||
@ -1530,9 +1524,9 @@ func (kl *Kubelet) SyncPods(allPods []api.Pod, podSyncTypes map[types.UID]metric
|
|||||||
desiredPods[uid] = empty{}
|
desiredPods[uid] = empty{}
|
||||||
|
|
||||||
// Add all containers (including net) to the map.
|
// Add all containers (including net) to the map.
|
||||||
desiredContainers[podContainer{podFullName, uid, dockertools.PodInfraContainerName}] = empty{}
|
desiredContainers[dockertools.KubeletContainerName{podFullName, uid, dockertools.PodInfraContainerName}] = empty{}
|
||||||
for _, cont := range pod.Spec.Containers {
|
for _, cont := range pod.Spec.Containers {
|
||||||
desiredContainers[podContainer{podFullName, uid, cont.Name}] = empty{}
|
desiredContainers[dockertools.KubeletContainerName{podFullName, uid, cont.Name}] = empty{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the sync in an async manifest worker.
|
// Run the sync in an async manifest worker.
|
||||||
@ -1559,28 +1553,27 @@ func (kl *Kubelet) SyncPods(allPods []api.Pod, podSyncTypes map[types.UID]metric
|
|||||||
killed := []string{}
|
killed := []string{}
|
||||||
for ix := range dockerContainers {
|
for ix := range dockerContainers {
|
||||||
// Don't kill containers that are in the desired pods.
|
// Don't kill containers that are in the desired pods.
|
||||||
podFullName, uid, containerName, _, err := dockertools.ParseDockerName(dockerContainers[ix].Names[0])
|
dockerName, _, err := dockertools.ParseDockerName(dockerContainers[ix].Names[0])
|
||||||
_, found := desiredPods[uid]
|
_, found := desiredPods[dockerName.PodUID]
|
||||||
if err == nil && found {
|
if err == nil && found {
|
||||||
// syncPod() will handle this one.
|
// syncPod() will handle this one.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
pc := podContainer{podFullName, uid, containerName}
|
_, ok := desiredContainers[*dockerName]
|
||||||
_, ok := desiredContainers[pc]
|
|
||||||
if err != nil || !ok {
|
if err != nil || !ok {
|
||||||
// call the networking plugin for teardown
|
// call the networking plugin for teardown
|
||||||
if containerName == dockertools.PodInfraContainerName {
|
if dockerName.ContainerName == dockertools.PodInfraContainerName {
|
||||||
name, namespace, _ := ParsePodFullName(podFullName)
|
name, namespace, _ := ParsePodFullName(dockerName.PodFullName)
|
||||||
err := kl.networkPlugin.TearDownPod(namespace, name, dockertools.DockerID(dockerContainers[ix].ID))
|
err := kl.networkPlugin.TearDownPod(namespace, name, dockertools.DockerID(dockerContainers[ix].ID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Network plugin pre-delete method returned an error: %v", err)
|
glog.Errorf("Network plugin pre-delete method returned an error: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glog.V(1).Infof("Killing unwanted container %+v", pc)
|
glog.V(1).Infof("Killing unwanted container %+v", *dockerName)
|
||||||
err = kl.killContainer(dockerContainers[ix])
|
err = kl.killContainer(dockerContainers[ix])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Error killing container %+v: %v", pc, err)
|
glog.Errorf("Error killing container %+v: %v", *dockerName, err)
|
||||||
} else {
|
} else {
|
||||||
killed = append(killed, dockerContainers[ix].ID)
|
killed = append(killed, dockerContainers[ix].ID)
|
||||||
}
|
}
|
||||||
|
@ -148,11 +148,11 @@ func (self *podAndContainerCollector) Collect(ch chan<- prometheus.Metric) {
|
|||||||
// Get a set of running pods.
|
// Get a set of running pods.
|
||||||
runningPods := make(map[types.UID]struct{})
|
runningPods := make(map[types.UID]struct{})
|
||||||
for _, cont := range runningContainers {
|
for _, cont := range runningContainers {
|
||||||
_, uid, _, _, err := dockertools.ParseDockerName(cont.Names[0])
|
containerName, _, err := dockertools.ParseDockerName(cont.Names[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
runningPods[uid] = struct{}{}
|
runningPods[containerName.PodUID] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
Loading…
Reference in New Issue
Block a user