containers / skopeo

Work with remote images registries - retrieving information, images, signing content
Apache License 2.0
8.23k stars 780 forks source link

EOF issue when `skopeo copy` a large image layer from local to remote registry #1627

Closed yuyanj143 closed 1 year ago

yuyanj143 commented 2 years ago

Hi all, I'm trying to copy a fairly large image (10GB) from my local OCI-layout directory to my private docker registry hosted on s3 using: skopeo --debug --insecure-policy copy --dest-creds=user.momo:pwd oci:/home/momo/oci:new docker://my-private-registry

but this is consistently failing with EOF errors:

DEBU[0000] Returning credentials from DockerAuthConfig  
DEBU[0000] Using registries.d directory /etc/containers/registries.d for sigstore configuration 
DEBU[0000]  Using "default-docker" configuration        
DEBU[0000]   Using file:///var/lib/containers/sigstore  
DEBU[0000] Looking for TLS certificates and private keys in /etc/docker/certs.d/my.private.repo 
DEBU[0000] Loading registries configuration "/etc/containers/registries.conf" 
DEBU[0000] Loading registries configuration "/etc/containers/registries.conf.d/000-shortnames.conf" 
DEBU[0000] Using blob info cache at /home/momo/.local/share/containers/cache/blob-info-cache-v1.boltdb 
DEBU[0000] IsRunningImageAllowed for image oci:/home/momo/oci 
DEBU[0000]  Using default policy section                
DEBU[0000]  Requirement 0: allowed                      
DEBU[0000] Overall: allowed                             
Getting image source signatures
DEBU[0000] Manifest has MIME type application/vnd.oci.image.manifest.v1+json, ordered candidate list [application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.v2+json, application/vnd.docker.distribution.manifest.v1+prettyjws, application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.docker.distribution.manifest.v1+json] 
DEBU[0000] ... will first try using the original manifest unmodified 
DEBU[0000] Checking /v2/u/momo/test_images/jupyter_singleuser/blobs/sha256:3a82b9fe4e3b349a0fd5d2a44fc7fcabc9abebff7a3b55f1a3341dd931817f72 
DEBU[0000] GET https://my.private.repo/v2/   
DEBU[0000] Ping https://my.private.repo/v2/ status 401 
DEBU[0000] GET https://my.private.repo.auth/auth/token?account=user.momo&scope=repository%3Au%2Fmomo%2Ftest_images%2Fjupyter_singleuser%3Apull%2Cpush&service=my.private.repo 
DEBU[0001] Increasing token expiration to: 60 seconds   
DEBU[0001] HEAD https://my.private.repo/v2/u/momo/test_images/jupyter_singleuser/blobs/sha256:3a82b9fe4e3b349a0fd5d2a44fc7fcabc9abebff7a3b55f1a3341dd931817f72 
DEBU[0001] ... not present                              
DEBU[0001] Trying to reuse cached location sha256:3a82b9fe4e3b349a0fd5d2a44fc7fcabc9abebff7a3b55f1a3341dd931817f72 in my.private.repo/u/momo/test_images/basic_python3_server 
DEBU[0001] Checking /v2/u/momo/test_images/basic_python3_server/blobs/sha256:3a82b9fe4e3b349a0fd5d2a44fc7fcabc9abebff7a3b55f1a3341dd931817f72 
DEBU[0001] GET https://my.private.repo.auth/auth/token?account=user.momo&scope=repository%3Au%2Fmomo%2Ftest_images%2Fjupyter_singleuser%3Apull%2Cpush&scope=repository%3Au%2Fmomo%2Ftest_images%2Fbasic_python3_server%3Apull&service=my.private.repo 
DEBU[0001] Increasing token expiration to: 60 seconds   
DEBU[0001] HEAD https://my.private.repo/v2/u/momo/test_images/basic_python3_server/blobs/sha256:3a82b9fe4e3b349a0fd5d2a44fc7fcabc9abebff7a3b55f1a3341dd931817f72 
DEBU[0001] ... already exists                           
DEBU[0001] Trying to mount /v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/?from=u%2Fmomo%2Ftest_images%2Fbasic_python3_server&mount=sha256%3A3a82b9fe4e3b349a0fd5d2a44fc7fcabc9abebff7a3b55f1a3341dd931817f72 
DEBU[0001] POST https://my.private.repo/v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/?from=u%2Fmomo%2Ftest_images%2Fbasic_python3_server&mount=sha256%3A3a82b9fe4e3b349a0fd5d2a44fc7fcabc9abebff7a3b55f1a3341dd931817f72 
DEBU[0001] ... mount OK                                 
DEBU[0001] Skipping blob sha256:3a82b9fe4e3b349a0fd5d2a44fc7fcabc9abebff7a3b55f1a3341dd931817f72 (already present): 
Copying blob 3a82b9fe4e3b skipped: already exists  
DEBU[0001] Checking /v2/u/momo/test_images/jupyter_singleuser/blobs/sha256:5dfaa45a485490902af457e19868bb4da1a414e72f9a6faf618aa850e3396da6 
Copying blob 3a82b9fe4e3b skipped: already exists  
DEBU[0001] ... not present                              
DEBU[0001] Trying to reuse cached location sha256:5dfaa45a485490902af457e19868bb4da1a414e72f9a6faf618aa850e3396da6 in my.private.repo/u/momo/test_images/basic_python3_server 
DEBU[0001] Checking /v2/u/momo/test_images/basic_python3_server/blobs/sha256:5dfaa45a485490902af457e19868bb4da1a414e72f9a6faf618aa850e3396da6 
DEBU[0001] HEAD https://my.private.repo/v2/u/momo/test_images/basic_python3_server/blobs/sha256:5dfaa45a485490902af457e19868bb4da1a414e72f9a6faf618aa850e3396da6 
DEBU[0001] ... already exists                           
DEBU[0001] Trying to mount /v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/?from=u%2Fmomo%2Ftest_images%2Fbasic_python3_server&mount=sha256%3A5dfaa45a485490902af457e19868bb4da1a414e72f9a6faf618aa850e3396da6 
DEBU[0001] POST https://my.private.repo/v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/?from=u%2Fmomo%2Ftest_images%2Fbasic_python3_server&mount=sha256%3A5dfaa45a485490902af457e19
Copying blob 3a82b9fe4e3b skipped: already exists  
DEBU[0001] ... mount OK                                 
Copying blob 3a82b9fe4e3b skipped: already exists  
Copying blob 5dfaa45a4854 skipped: already exists  
Copying blob 3a82b9fe4e3b skipped: already exists  
Copying blob 5dfaa45a4854 skipped: already exists  
DEBU[0002] ... not present                              
DEBU[0002] Trying to reuse cached location sha256:a757b484827e618c5263d0b8dca00a3aa4e241c7796eaf6cc3ffe039f1eee373 in my.private.repo/u/momo/test_images/basic_python3_server 
DEBU[0002] Checking /v2/u/momo/test_images/basic_python3_server/blobs/sha256:a757b484827e618c5263d0b8dca00a3aa4e241c7796eaf6cc3ffe039f1eee373 
DEBU[0002] HEAD https://my.private.repo/v2/u/momo/test_images/basic_python3_server/blobs/sha256:a757b484827e618c5263d0b8dca00a3aa4e241c7796eaf6cc3ffe039f1eee373 
DEBU[0002] ... already exists                           
DEBU[0002] Trying to mount /v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/?from=u%2Fmomo%2Ftest_images%2Fbasic_python3_server&mount=sha256%3Aa757b484827e618c5263d0b8dca00a3aa4e241c7796eaf6cc3ffe039f1eee373 
Copying blob 3a82b9fe4e3b skipped: already exists  
Copying blob 3a82b9fe4e3b skipped: already exists  
Copying blob 3a82b9fe4e3b skipped: already exists  
Copying blob 5dfaa45a4854 skipped: already exists  
Copying blob 3a82b9fe4e3b skipped: already exists  
Copying blob 3a82b9fe4e3b skipped: already exists  
Copying blob 5dfaa45a4854 skipped: already exists  
Copying blob a757b484827e skipped: already exists  
Copying blob 832fc2dcccb6 [--------------------------------------] 0.0b / 9.7GiB
DEBU[0002] Detected compression format gzip             
DEBU[0002] Using original blob without modification     
DEBU[0002] Checking /v2/u/momo/test_images/jupyter_singleuser/blobs/sha256:832fc2dcccb6e28b98a3f7b1c00ccc9373b4d86e206abec717e26cf8b4638481 
Copying blob 3a82b9fe4e3b skipped: already exists  
Copying blob 5dfaa45a4854 skipped: already exists  
Copying blob a757b484827e skipped: already exists  
Copying blob 3a82b9fe4e3b skipped: already exists  
Copying blob 5dfaa45a4854 skipped: already exists  
Copying blob a757b484827e skipped: already exists  
Copying blob 832fc2dcccb6 done  
DEBU[0183] Error uploading layer chunked Patch "https://my.private.repo/v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/fa28d48c-5e6c-4330-be99-b4ad27590aa3?_state=0g11C5PhHo2x2LFADqPxtbczIadNGLRobMpF_rvryuR7Ik5hbWUiOiJ1L3l1eWFuai90ZXN0X2ltYWdlcy9qdXB5dGVyX3NpbmdsZXVzZXIiLCJVVUlEIjoiZmEyOGQ0OGMtNWU2Yy00MzMwLWJlOTktYjRhZDI3NTkwYWEzIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDIyLTA0LTI1VDIzOjQzOjEwLjE4NjE5NTcyMloifQ%3D%3D": EOF 
FATA[0183] Error writing blob: Patch "https://my.private.repo/v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/fa28d48c-5e6c-4330-be99-b4ad27590aa3?_state=0g11C5PhHo2x2LFADqPxtbczIadNGLRobMpF_rvryuR7Ik5hbWUiOiJ1L3l1eWFuai90ZXN0X2ltYWdlcy9qdXB5dGVyX3NpbmdsZXVzZXIiLCJVVUlEIjoiZmEyOGQ0OGMtNWU2Yy00MzMwLWJlOTktYjRhZDI3NTkwYWEzIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDIyLTA0LTI1VDIzOjQzOjEwLjE4NjE5NTcyMloifQ%3D%3D": EOF

Additional info: skopeo version: 1.3.0 docker-registry version: 2.7.1 cat /etc/*release

44
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.4 LTS"
NAME="Ubuntu"
VERSION="20.04.4 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.4 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

registry config:

version: 0.1

log:
  ...
auth:
  ...

storage:
  s3:
    # accesskey and secretkey are set via environment variables.
    region: us-west-2
    bucket: my-private-repo
  cache:
    blobdescriptor: inmemory
  delete:
    enabled: false
  redirect:
    disable: true

http:
  addr: :8443
  host: ...
  draintimeout: 10s
  tls:
    ...
  debug:
    addr: localhost:8444
    prometheus:
      enabled: true
      path: /metrics
  headers:
    X-Content-Type-Options: [nosniff]

health:
  storagedriver:
    enabled: true
    interval: 30s
    threshold: 3

I've tried the following and they work:

I suspect this is somewhat similar to issue 1083 but mine doesn't involve a slow/fast pipe as I'm copying from the local directory. I'm looking for some tips how to debug and if there's any workaround (I'm open to patch skopeo) for pushing large images with skopeo. Thanks!

mtrmac commented 2 years ago

Thanks for your report.

Yes, this does look somewhat similar to https://github.com/containers/image/issues/1083 , and the cause is unknown. With EOF (and not unexpected EOF) it seems like a code bug somewhere, whether or not there is some underlying infrastructure issue ultimately causing the transfer to fail.

If you can reproduce this on-demand, that’s valuable.

yuyanj143 commented 2 years ago

Thanks @mtrmac for your reply! It does seem like the EOF is coming from client.Do in makeRequestToResolvedURLOnce

DEBU[0001] ####################### in makeRequestToResolvedURLOnce Making PATCH request to https://my.private.repo/v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/fe635bff-d3ca-49b4-893d-76fd48e5f460?_state=M2CY5Cx9zZdurLSYr8JNKu-otW3qyhTKg9OjxUJ8gJ97Ik5hbWUiOiJ1L3l1eWFuai90ZXN0X2ltYWdlcy9qdXB5dGVyX3NpbmdsZXVzZXIiLCJVVUlEIjoiZmU2MzViZmYtZDNjYS00OWI0LTg5M2QtNzZmZDQ4ZTVmNDYwIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDIyLTA0LTI3VDIwOjE4OjM2LjQzNDQxMjc4M1oifQ%3D%3D 
DEBU[0001] ####################### in makeRequestToResolvedURLOnce before client.Do - method PATCH, stream &uploadreader.UploadReader{mutex:sync.Mutex{state:0, sema:0x0}, reader:(*io.teeReader)(0xc0002f0f40), terminationError:error(nil)} @ 2022-04-27 20:18:36.508113597 +0000 UTC m=+1.050623237 
DEBU[0001] ################################################################################################################### 
Copying blob 3a82b9fe4e3b skipped: already exists  
Copying blob 5dfaa45a4854 skipped: already exists  
Copying blob a757b484827e skipped: already exists  
Copying blob 832fc2dcccb6 done  
ERRO[0130] ####################### in makeRequestToResolvedURLOnce RETURN 3: err from client.Do - method PATCH, res (*http.Response)(nil), err &url.Error{Op:"Patch", URL:"https://my.private.repo/v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/fe635bff-d3ca-49b4-893d-76fd48e5f460?_state=M2CY5Cx9zZdurLSYr8JNKu-otW3qyhTKg9OjxUJ8gJ97Ik5hbWUiOiJ1L3l1eWFuai90ZXN0X2ltYWdlcy9qdXB5dGVyX3NpbmdsZXVzZXIiLCJVVUlEIjoiZmU2MzViZmYtZDNjYS00OWI0LTg5M2QtNzZmZDQ4ZTVmNDYwIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDIyLTA0LTI3VDIwOjE4OjM2LjQzNDQxMjc4M1oifQ%3D%3D", Err:(*errors.errorString)(0xc000070060)}, stream &uploadreader.UploadReader{mutex:sync.Mutex{state:0, sema:0x0}, reader:(*io.teeReader)(0xc0002f0f40), terminationError:error(nil)} @ 2022-04-27 20:20:45.910428175 +0000 UTC m=+130.452937839 
INFO[0130] ####################### in makeRequestToResolvedURL RETURN 1: res (*http.Response)(nil), err &url.Error{Op:"Patch", URL:"https://my.private.repo/v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/fe635bff-d3ca-49b4-893d-76fd48e5f460?_state=M2CY5Cx9zZdurLSYr8JNKu-otW3qyhTKg9OjxUJ8gJ97Ik5hbWUiOiJ1L3l1eWFuai90ZXN0X2ltYWdlcy9qdXB5dGVyX3NpbmdsZXVzZXIiLCJVVUlEIjoiZmU2MzViZmYtZDNjYS00OWI0LTg5M2QtNzZmZDQ4ZTVmNDYwIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDIyLTA0LTI3VDIwOjE4OjM2LjQzNDQxMjc4M1oifQ%3D%3D", Err:(*errors.errorString)(0xc000070060)}, stream &uploadreader.UploadReader{mutex:sync.Mutex{state:0, sema:0x0}, reader:(*io.teeReader)(0xc0002f0f40), terminationError:error(nil)}, attempts 1 
ERRO[0130] ####################### in docker_iamge_dest.go:PutBlob err from makeRequestToResolvedURL PATCH &url.Error{Op:"Patch", URL:"https://my.private.repo/v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/fe635bff-d3ca-49b4-893d-76fd48e5f460?_state=M2CY5Cx9zZdurLSYr8JNKu-otW3qyhTKg9OjxUJ8gJ97Ik5hbWUiOiJ1L3l1eWFuai90ZXN0X2ltYWdlcy9qdXB5dGVyX3NpbmdsZXVzZXIiLCJVVUlEIjoiZmU2MzViZmYtZDNjYS00OWI0LTg5M2QtNzZmZDQ4ZTVmNDYwIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDIyLTA0LTI3VDIwOjE4OjM2LjQzNDQxMjc4M1oifQ%3D%3D", Err:(*errors.errorString)(0xc000070060)} 
DEBU[0130] ####################### in copy.go:copyBlobFromStream RETURN err from PutBlob @ 2022-04-27 20:20:45.910538118 +0000 UTC m=+130.453047828 
ERRO[0130] ####################### in copy.go:copyLayer err from copyLayerFromStream Error writing blob: Patch "https://my.private.repo/v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/fe635bff-d3ca-49b4-893d-76fd48e5f460?_state=M2CY5Cx9zZdurLSYr8JNKu-otW3qyhTKg9OjxUJ8gJ97Ik5hbWUiOiJ1L3l1eWFuai90ZXN0X2ltYWdlcy9qdXB5dGVyX3NpbmdsZXVzZXIiLCJVVUlEIjoiZmU2MzViZmYtZDNjYS00OWI0LTg5M2QtNzZmZDQ4ZTVmNDYwIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDIyLTA0LTI3VDIwOjE4OjM2LjQzNDQxMjc4M1oifQ%3D%3D": EOF 
FATA[0130] Error writing blob: Patch "https://my.private.repo/v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/fe635bff-d3ca-49b4-893d-76fd48e5f460?_state=M2CY5Cx9zZdurLSYr8JNKu-otW3qyhTKg9OjxUJ8gJ97Ik5hbWUiOiJ1L3l1eWFuai90ZXN0X2ltYWdlcy9qdXB5dGVyX3NpbmdsZXVzZXIiLCJVVUlEIjoiZmU2MzViZmYtZDNjYS00OWI0LTg5M2QtNzZmZDQ4ZTVmNDYwIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDIyLTA0LTI3VDIwOjE4OjM2LjQzNDQxMjc4M1oifQ%3D%3D": EOF 

Interestingly, the docker registry logs show that the HTTP PATCH request for the blob was successful but with http.response.written=0:

time="2022-04-27T20:18:36.606746326Z" level=info msg="authorized request" go.version=go1.14.6 http.request.contenttype="application/octet-stream" http.request.host=my.private.repo http.request.id=db66ee85-d9b2-4cca-a5a6-89193d8fddbd http.request.method=PATCH http.request.remoteaddr="10.245.156.71:35770" http.request.uri="/v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/fe635bff-d3ca-49b4-893d-76fd48e5f460?_state=M2CY5Cx9zZdurLSYr8JNKu-otW3qyhTKg9OjxUJ8gJ97Ik5hbWUiOiJ1L3l1eWFuai90ZXN0X2ltYWdlcy9qdXB5dGVyX3NpbmdsZXVzZXIiLCJVVUlEIjoiZmU2MzViZmYtZDNjYS00OWI0LTg5M2QtNzZmZDQ4ZTVmNDYwIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDIyLTA0LTI3VDIwOjE4OjM2LjQzNDQxMjc4M1oifQ%3D%3D" http.request.useragent="Go-http-client/1.1" vars.name="u/momo/test_images/jupyter_singleuser" vars.uuid=fe635bff-d3ca-49b4-893d-76fd48e5f460 
time="2022-04-27T20:23:50.117097012Z" level=info msg="response completed" go.version=go1.14.6 http.request.contenttype="application/octet-stream" http.request.host=my.private.repo http.request.id=db66ee85-d9b2-4cca-a5a6-89193d8fddbd http.request.method=PATCH http.request.remoteaddr="10.245.156.71:35770" http.request.uri="/v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/fe635bff-d3ca-49b4-893d-76fd48e5f460?_state=M2CY5Cx9zZdurLSYr8JNKu-otW3qyhTKg9OjxUJ8gJ97Ik5hbWUiOiJ1L3l1eWFuai90ZXN0X2ltYWdlcy9qdXB5dGVyX3NpbmdsZXVzZXIiLCJVVUlEIjoiZmU2MzViZmYtZDNjYS00OWI0LTg5M2QtNzZmZDQ4ZTVmNDYwIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDIyLTA0LTI3VDIwOjE4OjM2LjQzNDQxMjc4M1oifQ%3D%3D" http.request.useragent="Go-http-client/1.1" http.response.duration=5m13.511523807s http.response.status=202 http.response.written=0 
10.245.156.71 - - [27/Apr/2022:20:18:36 +0000] "PATCH /v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/fe635bff-d3ca-49b4-893d-76fd48e5f460?_state=M2CY5Cx9zZdurLSYr8JNKu-otW3qyhTKg9OjxUJ8gJ97Ik5hbWUiOiJ1L3l1eWFuai90ZXN0X2ltYWdlcy9qdXB5dGVyX3NpbmdsZXVzZXIiLCJVVUlEIjoiZmU2MzViZmYtZDNjYS00OWI0LTg5M2QtNzZmZDQ4ZTVmNDYwIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDIyLTA0LTI3VDIwOjE4OjM2LjQzNDQxMjc4M1oifQ%3D%3D HTTP/1.1" 202 0 "" "Go-http-client/1.1"

I also tried to capture the packets, seeing the following logs:

...
20:19:45.412555 IP (tos 0x0, ttl 64, id 2022, offset 0, flags [DF], proto TCP (6), length 1400)
    client > server: Flags [.], cksum 0x843e (incorrect -> 0x7d93), seq 1819353947:1819355295, ack 3513, win 502, options [nop,nop,TS val 117955162 ecr 2225082029], length 1348
20:19:45.412555 IP (tos 0x0, ttl 64, id 2023, offset 0, flags [DF], proto TCP (6), length 1400)
    client > server: Flags [.], cksum 0x843e (incorrect -> 0x958b), seq 1819355295:1819356643, ack 3513, win 502, options [nop,nop,TS val 117955162 ecr 2225082029], length 1348
20:19:45.419938 IP (tos 0x0, ttl 255, id 53898, offset 0, flags [DF], proto TCP (6), length 52)
    server > client: Flags [.], cksum 0x8d2d (correct), seq 3513, ack 1820283697, win 13788, options [nop,nop,TS val 2225082037 ecr 117955169], length 0
20:19:45.419956 IP (tos 0x0, ttl 255, id 53899, offset 0, flags [DF], proto TCP (6), length 52)
    server > client: Flags [.], cksum 0x50b1 (correct), seq 3513, ack 1820299181, win 13788, options [nop,nop,TS val 2225082037 ecr 117955169], length 0

20:20:00.656080 IP (tos 0x0, ttl 64, id 2772, offset 0, flags [DF], proto TCP (6), length 52)
    client > server: Flags [.], cksum 0x7efa (incorrect -> 0x4914), seq 1820299180, ack 3513, win 502, options [nop,nop,TS val 117970405 ecr 2225082037], length 0
20:20:00.656708 IP (tos 0x0, ttl 255, id 53900, offset 0, flags [DF], proto TCP (6), length 52)
    server > client: Flags [.], cksum 0x152d (correct), seq 3513, ack 1820299181, win 13788, options [nop,nop,TS val 2225097273 ecr 117955169], length 0
20:20:15.760077 IP (tos 0x0, ttl 64, id 2773, offset 0, flags [DF], proto TCP (6), length 52)
    client > server: Flags [.], cksum 0x7efa (incorrect -> 0xd28f), seq 1820299180, ack 3513, win 502, options [nop,nop,TS val 117985509 ecr 2225097273], length 0
20:20:15.760706 IP (tos 0x0, ttl 255, id 53901, offset 0, flags [DF], proto TCP (6), length 52)
    server > client: Flags [.], cksum 0xda2c (correct), seq 3513, ack 1820299181, win 13788, options [nop,nop,TS val 2225112377 ecr 117955169], length 0

20:20:30.864078 IP (tos 0x0, ttl 64, id 2774, offset 0, flags [DF], proto TCP (6), length 52)
    client > server: Flags [.], cksum 0x7efa (incorrect -> 0x5c8f), seq 1820299180, ack 3513, win 502, options [nop,nop,TS val 118000613 ecr 2225112377], length 0
20:20:30.864705 IP (tos 0x0, ttl 255, id 53902, offset 0, flags [DF], proto TCP (6), length 52)
    server > client: Flags [.], cksum 0x9f2c (correct), seq 3513, ack 1820299181, win 13788, options [nop,nop,TS val 2225127481 ecr 117955169], length 0
20:20:45.910257 IP (tos 0x0, ttl 255, id 53903, offset 0, flags [DF], proto TCP (6), length 52)
    server > client: Flags [F.], cksum 0x6465 (correct), seq 3513, ack 1820299181, win 13788, options [nop,nop,TS val 2225142527 ecr 117955169], length 0
20:20:45.910355 IP (tos 0x0, ttl 64, id 2775, offset 0, flags [DF], proto TCP (6), length 76)
    client > server: Flags [P.], cksum 0x7f12 (incorrect -> 0x0e25), seq 1820299181:1820299205, ack 3514, win 502, options [nop,nop,TS val 118015660 ecr 2225142527], length 24
20:20:45.910376 IP (tos 0x0, ttl 64, id 2776, offset 0, flags [DF], proto TCP (6), length 52)
    client > server: Flags [F.], cksum 0x7efa (incorrect -> 0xabe6), seq 1820299205, ack 3514, win 502, options [nop,nop,TS val 118015660 ecr 2225142527], length 0
20:20:45.910977 IP (tos 0x0, ttl 255, id 0, offset 0, flags [DF], proto TCP (6), length 40)
    server > client: Flags [R], cksum 0xa8c7 (correct), seq 3427670409, win 0, length 0
20:20:45.911007 IP (tos 0x0, ttl 255, id 0, offset 0, flags [DF], proto TCP (6), length 40)
    server > client: Flags [R], cksum 0xa8c7 (correct), seq 3427670409, win 0, length 0

The timeline looks like this:

20:18:36.508113597 client sends PATCH request
20:18:36.606746326 server receives request
20:19:45.419956    note in my terminal, it says Copying blob 832fc2dcccb6 done, but nothing happens it just hangs there
20:20:45.910257    server sends FIN,ACK
20:20:45.910376    client sends FIN,ACK
20:20:45.910428175 skopeo returns EOF error
20:20:45.911007    connection closed
20:23:50.117097012 server logs response completed

I'm not sure if these logs are helpful or how to read these as this is way out of my comfort zone :c, does it mean that the registry server decides to terminate the connection for whatever reason (perhaps due to a timeout/deadline setting somewhere?) and that caused EOF?

mtrmac commented 2 years ago

Thanks @mtrmac for your reply! It does seem like the EOF is coming from client.Do in makeRequestToResolvedURLOnce

INFO[0130] ####################### in makeRequestToResolvedURL RETURN 1: res (*http.Response)(nil), err &url.Error{Op:"Patch", URL:"https://my.private.repo/v2/u/momo/test_images/jupyter_singleuser/blobs/uploads/fe635bff-d3ca-49b4-893d-76fd48e5f460?_state=…", Err:(*errors.errorString)(0xc000070060)}, stream &uploadreader.UploadReader{mutex:sync.Mutex{state:0, sema:0x0}, reader:(*io.teeReader)(0xc0002f0f40), terminationError:error(nil)}, attempts 1 

OK, that seems to be consistent with the hypotheses so far.

ERRO[0130] ####################### in docker_iamge_dest.go:PutBlob err from makeRequestToResolvedURL Interestingly, the docker registry logs show that the HTTP PATCH request for the blob was successful but with http.response.written=0:

That is fine; the registry only needs to confirm that the upload succeeded, it is not expected to return any data. (https://github.com/distribution/distribution/blob/edf5aa3c399f3c7e9b7250676050e4691846bbaa/registry/handlers/blobupload.go#L352 ).


So if the server has successfully processed the upload (implying it was correctly and completely sent), there is really no data to read…

One avenue would be to just continue this kind of tracing inside the standard library (though, fair warning, the HTTP stack is fairly complex).

github-actions[bot] commented 2 years ago

A friendly reminder that this issue had no activity for 30 days.

mtrmac commented 2 years ago

For the record, one possible path where the net/http stack can return io.EOF and not an “unexpected EOF” is if the server reads the request, and cleanly closes the connection without producing any response header. Reported as https://github.com/golang/go/issues/53472 .

github-actions[bot] commented 2 years ago

A friendly reminder that this issue had no activity for 30 days.

mtrmac commented 1 year ago

@hanakawamomo is this still outstanding? At least https://github.com/tetrateio/tetrate-service-bridge-sandbox/pull/146 suggests that Skopeo is now being used.

mtrmac commented 1 year ago

Closing, assuming that this got resolved. Please reopen if that’s not the case.