code: func (ds *dockerService) RemoveImage(_ context.Context, r *runtimeapi.RemoveImageRequest) (*runtimeapi.RemoveImageResponse, error) {
  	image := r.GetImage()
  	// If the image has multiple tags, we need to remove all the tags
  	// TODO: We assume image.Image is image ID here, which is true in the current implementation
  	// of kubelet, but we should still clarify this in CRI.
  	imageInspect, err := ds.client.InspectImageByID(image.Image)
  
  	// dockerclient.InspectImageByID doesn't work with digest and repoTags,
  	// it is safe to continue removing it since there is another check below.
  	if err != nil && !libdocker.IsImageNotFoundError(err) {
  		return nil, err
  	}
  
  	if imageInspect == nil {
  		// image is nil, assuming it doesn't exist.
  		return &runtimeapi.RemoveImageResponse{}, nil
  	}
  
  	// An image can have different numbers of RepoTags and RepoDigests.
  	// Iterating over both of them plus the image ID ensures the image really got removed.
  	// It also prevents images from being deleted, which actually are deletable using this approach.
  	var images []string
  	images = append(images, imageInspect.RepoTags...)
  	images = append(images, imageInspect.RepoDigests...)
  	images = append(images, image.Image)
  
  	for _, image := range images {
  		if _, err := ds.client.RemoveImage(image, dockertypes.ImageRemoveOptions{PruneChildren: true}); err != nil && !libdocker.IsImageNotFoundError(err) {
  			return nil, err
  		}
  	}
  
  	return &runtimeapi.RemoveImageResponse{}, nil
  }
docs: // RemoveImage removes the image.