123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- /*
- Copyright 2016 The Kubernetes Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package dockershim
- import (
- "fmt"
- "math/rand"
- "strconv"
- "strings"
- runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
- "k8s.io/kubernetes/pkg/kubelet/leaky"
- )
- // Container "names" are implementation details that do not concern
- // kubelet/CRI. This CRI shim uses names to fulfill the CRI requirement to
- // make sandbox/container creation idempotent. CRI states that there can
- // only exist one sandbox/container with the given metadata. To enforce this,
- // this shim constructs a name using the fields in the metadata so that
- // docker will reject the creation request if the name already exists.
- //
- // Note that changes to naming will likely break the backward compatibility.
- // Code must be added to ensure the shim knows how to recognize and extract
- // information the older containers.
- //
- // TODO: Add code to handle backward compatibility, i.e., making sure we can
- // recognize older containers and extract information from their names if
- // necessary.
- const (
- // kubePrefix is used to identify the containers/sandboxes on the node managed by kubelet
- kubePrefix = "k8s"
- // sandboxContainerName is a string to include in the docker container so
- // that users can easily identify the sandboxes.
- sandboxContainerName = leaky.PodInfraContainerName
- // Delimiter used to construct docker container names.
- nameDelimiter = "_"
- // DockerImageIDPrefix is the prefix of image id in container status.
- DockerImageIDPrefix = "docker://"
- // DockerPullableImageIDPrefix is the prefix of pullable image id in container status.
- DockerPullableImageIDPrefix = "docker-pullable://"
- )
- func makeSandboxName(s *runtimeapi.PodSandboxConfig) string {
- return strings.Join([]string{
- kubePrefix, // 0
- sandboxContainerName, // 1
- s.Metadata.Name, // 2
- s.Metadata.Namespace, // 3
- s.Metadata.Uid, // 4
- fmt.Sprintf("%d", s.Metadata.Attempt), // 5
- }, nameDelimiter)
- }
- func makeContainerName(s *runtimeapi.PodSandboxConfig, c *runtimeapi.ContainerConfig) string {
- return strings.Join([]string{
- kubePrefix, // 0
- c.Metadata.Name, // 1:
- s.Metadata.Name, // 2: sandbox name
- s.Metadata.Namespace, // 3: sandbox namesapce
- s.Metadata.Uid, // 4 sandbox uid
- fmt.Sprintf("%d", c.Metadata.Attempt), // 5
- }, nameDelimiter)
- }
- // randomizeName randomizes the container name. This should only be used when we hit the
- // docker container name conflict bug.
- func randomizeName(name string) string {
- return strings.Join([]string{
- name,
- fmt.Sprintf("%08x", rand.Uint32()),
- }, nameDelimiter)
- }
- func parseUint32(s string) (uint32, error) {
- n, err := strconv.ParseUint(s, 10, 32)
- if err != nil {
- return 0, err
- }
- return uint32(n), nil
- }
- // TODO: Evaluate whether we should rely on labels completely.
- func parseSandboxName(name string) (*runtimeapi.PodSandboxMetadata, error) {
- // Docker adds a "/" prefix to names. so trim it.
- name = strings.TrimPrefix(name, "/")
- parts := strings.Split(name, nameDelimiter)
- // Tolerate the random suffix.
- // TODO(random-liu): Remove 7 field case when docker 1.11 is deprecated.
- if len(parts) != 6 && len(parts) != 7 {
- return nil, fmt.Errorf("failed to parse the sandbox name: %q", name)
- }
- if parts[0] != kubePrefix {
- return nil, fmt.Errorf("container is not managed by kubernetes: %q", name)
- }
- attempt, err := parseUint32(parts[5])
- if err != nil {
- return nil, fmt.Errorf("failed to parse the sandbox name %q: %v", name, err)
- }
- return &runtimeapi.PodSandboxMetadata{
- Name: parts[2],
- Namespace: parts[3],
- Uid: parts[4],
- Attempt: attempt,
- }, nil
- }
- // TODO: Evaluate whether we should rely on labels completely.
- func parseContainerName(name string) (*runtimeapi.ContainerMetadata, error) {
- // Docker adds a "/" prefix to names. so trim it.
- name = strings.TrimPrefix(name, "/")
- parts := strings.Split(name, nameDelimiter)
- // Tolerate the random suffix.
- // TODO(random-liu): Remove 7 field case when docker 1.11 is deprecated.
- if len(parts) != 6 && len(parts) != 7 {
- return nil, fmt.Errorf("failed to parse the container name: %q", name)
- }
- if parts[0] != kubePrefix {
- return nil, fmt.Errorf("container is not managed by kubernetes: %q", name)
- }
- attempt, err := parseUint32(parts[5])
- if err != nil {
- return nil, fmt.Errorf("failed to parse the container name %q: %v", name, err)
- }
- return &runtimeapi.ContainerMetadata{
- Name: parts[1],
- Attempt: attempt,
- }, nil
- }
|