أنا قادر على إطلاق الحاويات ورسم خرائط لمنافذها من CLI. ومع ذلك ، يبدو نفس الشيء مستحيلًا من خلال Remote API. في كلتا الحالتين ، أستخدم جهاز الإرساء على نظام التشغيل Mac OS El Capitan.
لقد قمت الآن بتبسيط حالة الاختبار إلى الحد الأدنى المطلق ، والذي يعتمد على صورة ubuntu القياسية مع حزمة واحدة فقط netcat-openbsd ، apt-get مثبتة (وتشغيلها كـ nc
).
قبل كل اختبار ، أجري
eval $(docker-machine env default); docker stop $(docker ps -a -q); docker rm $(docker ps -a -q)
... لإيقاف وإزالة جميع الحاويات السابقة.
يُظهر CLI التالي خدمة قابلة للعنونة بنجاح ...
docker run -it --rm -p 3000:3000 ubuntu-nc /bin/bash -c 'echo "Working" | nc -l 3000'
يمكنني إثبات إمكانية الوصول إلى الخدمة من خلال المنافذ المعينة بشكل صحيح من خارج حاوية عامل الإرساء (على عنوان IP المخصص لجهاز VM بواسطة جهاز الإرساء) عن طريق تشغيل ما يلي ...
$ nc 192.168.99.100 3000
Working
تؤدي محاولة إحضار نفس الخدمة عبر Dockerode على Node إلى إنشاء خدمة غير قابلة للعنونة ، على الرغم من أن Dockerode يمرر على ما يبدو جميع الوسائط إلى Docker ، وأنا على ما يبدو أتوافق مع اصطلاحات https://godoc.org/github. com / docker / engine-api / types / container # Config و https://godoc.org/github.com/docker/engine-api/types/container#HostConfig وبالتالي إثارة هذه المشكلة.
هذا هو الكود الذي أحاول استخدامه ...
var fs = require("fs"),
dockermachine = require("dockermachine"),
dockerode = require("dockerode");
var createOptions = {
Image:"ubuntu-nc",
Tty:true,
ExposedPorts: {
"3000/tcp:": {},
},
Cmd:[
"/bin/bash", "-c", "echo Working | nc -l 3000"
],
HostConfig:{
PortBindings: {
"3000/tcp": [{
"HostIP":"0.0.0.0",
"HostPort": "3000"
}],
},
},
};
dockermachine.inspect("default").then(function(info){
var docker = new dockerode({
host:info.Driver.IPAddress,
port:2376,
ca:fs.readFileSync(info.HostOptions.AuthOptions.CaCertPath),
cert:fs.readFileSync(info.HostOptions.AuthOptions.ClientCertPath),
key:fs.readFileSync(info.HostOptions.AuthOptions.ClientKeyPath),
});
docker.createContainer(createOptions, function(err, result){
var container = docker.getContainer(result.id);
container.attach({stream: true, stdout: true, stderr: true}, function (err, stream) {
stream.pipe(process.stdout);
});
container.start(function(err, data){
if(err) console.log(err);
});
});
});
يعمل إصدار NodeJS بالتأكيد على تشغيل الخدمة في الحاوية
على سبيل المثال يمكنني الوصول إلى الخدمة من داخل الحاوية الخاصة بها ...
$ docker exec -it 3dd7 /bin/bash -c "nc localhost 3000"
Working
ومع ذلك ، يبدو أنه لا يحترم تعيين المنفذ الخارجي الذي تم طلبه ، لذلك إذا أعدت تشغيل اختبار العمل أعلاه من البداية ، فحاول الوصول إلى الخدمة من خارج الحاوية بنفس طريقة "إثبات الخدمة القابلة للعنونة" سابقًا ، يبلغ عن فشل الاتصال.
$ nc -v 192.168.99.100 3000
nc: connectx to 192.168.99.100 port 3000 (tcp) failed: Connection refused
ناتج docker version
:
bash-3.2$ docker version
Client:
Version: 1.10.1
API version: 1.22
Go version: go1.5.3
Git commit: 9e83765
Built: Fri Feb 12 22:11:40 UTC 2016
OS/Arch: darwin/amd64
Server:
Version: 1.11.2
API version: 1.23
Go version: go1.5.4
Git commit: b9f10c9
Built: Wed Jun 1 21:20:08 2016
OS/Arch: linux/amd64
الناتج docker info
:
bash-3.2$ docker info
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 3
Server Version: 1.11.2
Storage Driver: aufs
Root Dir: /mnt/sda1/var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 7
Dirperm1 Supported: true
Logging Driver: json-file
Plugins:
Volume: local
Network: null host bridge
Kernel Version: 4.4.12-boot2docker
Operating System: Boot2Docker 1.11.2 (TCL 7.1); HEAD : a6645c3 - Wed Jun 1 22:59:51 UTC 2016
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 995.9 MiB
Name: default
ID: FWTM:2N6I:VM5L:OL4U:RD3K:HFKH:6VYP:QSV5:VHG5:ZTSW:GFOP:CDNT
Debug mode (server): true
File Descriptors: 14
Goroutines: 35
System Time: 2016-06-10T13:58:19.242425997Z
EventsListeners: 0
Init SHA1:
Init Path:
Docker Root Dir: /mnt/sda1/var/lib/docker
Labels:
provider=virtualbox
حسنًا ، يبدو أنه كان هناك فاصلة منقوطة زائفة مثل ...
ExposedPorts: {
"3000/tcp:": {},
},
... مما تسبب في تجاهل ExposedPorts بصمت.
من المؤسف جدًا عدم وجود أي تقارير واضحة عن الخطأ ، على ما يبدو بفضل سلوك "نموذج المخطط المفتوح" لواجهة برمجة التطبيقات عن بعد.
لا أستطيع أن أرى كيف يمكن أن يكون ابتلاع الأخطاء عندما يكون من الواضح أن الخصائص تهدف إلى التحكم في Docker ميزة.
انتظر ماذا؟ هل كان ذلك؟ ... خطأ مطبعي؟
لقد كنت أقرأ هذا لأن لدي نفس المشكلة - لا يمكنني تشغيل أي تعيين للمنافذ ، ولا يوجد عنوان IP للشبكة.
(لكن ليس لدي خطأ مطبعي)
ألا يوجد شيء آخر يمكن تعلمه هنا؟
لا تهتم ... لقد تعلمت شيئًا ما: بعد إنشاء حاوية ، عليك بعد ذلك "بدء ()" الحاوية قبل أن تحصل على عنوان IP أو تعيينات المنفذ.
التعليق الأكثر فائدة
حسنًا ، يبدو أنه كان هناك فاصلة منقوطة زائفة مثل ...
... مما تسبب في تجاهل ExposedPorts بصمت.
من المؤسف جدًا عدم وجود أي تقارير واضحة عن الخطأ ، على ما يبدو بفضل سلوك "نموذج المخطط المفتوح" لواجهة برمجة التطبيقات عن بعد.
لا أستطيع أن أرى كيف يمكن أن يكون ابتلاع الأخطاء عندما يكون من الواضح أن الخصائص تهدف إلى التحكم في Docker ميزة.