EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
7 D# D) Y* y/ Z. ^, \& q7 `: J* B: t 前 言' q9 Q3 t1 w% q+ k. t7 E
本案例适用开发环境:
2 d5 e/ S/ \) n5 d Windows开发环境:Windows 7 64bit、Windows 10 64bit0 n. {# t- P \" ` A
Linux开发环境:Ubuntu 18.04.4 64bit
; r' ?5 P- d! _( F4 \. d$ g 虚拟机:VMware15.1.0
& _; b C- `. W) H0 b Docker是一个开源的应用容器引擎,让开发者可打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows机器上,亦可实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。使用Docker,可像管理应用程序一样管理基础结构。通过利用Docker的快速发布、测试和部署代码的方法,可显著减少产品开发时间。
6 l! a; q8 j/ N, R3 g5 D 图1
9 v+ H' R' x" i- s( M) D 1 Docker架构 Docker使用客户端——服务器(C/S)体系结构。Docker客户端与Docker守护进程进行通信,后者执行构建、运行和分发Docker容器的繁重工作。Docker客户端和守护进程可在同一个系统上运行,亦可将Docker客户端连接至远程Docker守护进程。Docker客户端和守护进程使用REST API、UNIX套接字或网络接口进行通信。. Y7 d8 K, m- [4 v, u
安装方法
+ S! U: n' c |+ ^ (1) 安装依赖包# g- f( o8 C1 j J" K4 U! k
打开Ubuntu,确保Ubuntu可正常访问互联网,执行如下命令进行安装Docker依赖包。7 ]$ c$ e# ~3 U- I4 r" T
Host# sudo apt-get update, D& J8 q+ h# K3 k( R
. ?' |# @, `" n" D& J5 @4 ^
! z1 C/ [3 X& a: [2 T! E, _% k* ^ ![]()
- Y( R2 r3 F) B2 y% N图 2
' U5 A: T# G% l- m. t" n Host# sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release# }3 i6 S$ u0 _( g T
) S6 |& N6 C% l$ ~% n: o. t
) ?" ?5 d+ S' Y; d$ Q; L1 u4 s
![]()
/ C l. J4 _/ Y8 z9 P6 |- x图 3 $ X! [ R4 K9 ^
(2) 添加Docker官方GPG密钥; C. s# P1 F8 q) p T; w
Host# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --deARMor -o /usr/share/keyrings/docker-archive-keyring.gpg
! E+ _' B7 S3 ]* ]& j% B
E6 ]8 k: x' i( N) X, r% f& i
2 g$ g8 V+ E* s, |- | ) u3 R, _1 H+ [* S) T: i
图 4
) g0 y1 k2 _" i& C2 Z" E2 E& s' L* e (3) 设置Docker Stable存储库% \& B: ^" a# X
Host# echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null4 ~0 I+ K R% b
- o" p1 t0 Z0 R* W& |
, e: ^5 z$ P! W3 v& ~9 ~' H
- X0 y( D4 ?4 k" r
图 5 a& r* {8 a& S1 J6 `" ^/ t
(4) 安装Docker
$ f h2 F3 ~: A3 P8 \! J. V4 p Host# sudo apt-get update, f* H, K( Z$ Z$ l0 L
Host# sudo apt-get install docker-ce
' _) c4 {9 L+ `7 y% u5 q
+ ?, }+ b( u- x& ]
( O& l5 Y0 h" i' ]8 Z+ s* E* t9 R: E " p" t! t: t' b# c* j" d/ E5 h
图 6 ( O4 `0 a* D8 W- ^/ X& _! H$ z
![]()
+ ~& z5 c) r' F! W- \图 7 6 u/ v3 B% M) q" Y4 B8 M
(5) 验证Docker
7 V. Q* U6 G2 t* F2 v' { 执行如下命令,通过运行Docker自带的hello-world镜像来验证是否已安装成功。程序运行后,输出如下内容则表示Docker安装成功。5 `2 Y( B' Y& C( k
Host# sudo docker run hello-world& R* v! ]$ I: k% w+ B4 R
3 q7 [1 Q5 h+ D9 v/ h; `6 f3 B1 e- U" P) O! A }; z0 }
![]()
$ W$ q- t3 \6 l图 8
- j# F; }6 S2 ]! r3 i: o2 b 2搭建本地镜像仓库
! |8 N4 t5 @! j' ~$ | Docker用Registry来保存用户构建的镜像。Registry分为公共和私有两种。Docker公司运营的公共Registry叫做Docker Hub,用户可在Docker Hub注册账号,分享并保存自己的镜像。Docker公司的公共镜像仓库提供了庞大的镜像集合供用户使用。一个Docker Registry中可包含多个仓库,每个仓库可包含多个标签(Tag),每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签对应该软件的各个版本。用户可通过“[<仓库名>:<标签>]”的格式来指定具体是某个软件某个版本的镜像。如未给出标签,将以[latest]作为默认标签。4 k+ C( g9 M! o( H; z& i+ H
本次使用的镜像是registry:2,请执行如下命令自动下载并启动。+ K! X2 G; R3 ]2 E5 J7 ?( z! h
Host# mkdir -p /home/tronlong/docker/myregistry
4 K3 E, P2 e* w' P Host# sudo docker run -d -p 5000:5000 -v /home/tronlong/docker/myregistry:/var/lib/registry registry:2
' J! [9 B1 v* U6 B4 _1 {. t 参数说明:! I; A: C. T r( L* `) I1 {
-d:后台启动容器。& S- J2 c0 }! k3 a. K- |
-p:将容器的5000端口映射至Ubuntu的5000端口(5000是registry服务端口)。5 d n' Z3 w+ H' [+ m, s, B! y
-v:将容器"/var/lib/registry"目录映射至Ubuntu的"/home/tronlong/docker/myregistry",用于存放镜像数据。
# A' M+ ]( s0 H k& d2 ?0 H4 ?* F7 s) r9 v) e* \
. {2 v% ^7 u& y; @$ ]
![]()
* b( e$ u# T, p+ {图 9 @9 O' P" [4 |& p
请执行如下命令,查看容器是否已启动,出现如下内容说明容器已正常启动。4 V" n/ N- u1 r5 J
Host# sudo docker ps/ Q9 Q6 s9 c4 E7 B) ^
" O, ^6 q0 @) z; p; A, U$ N1 b
* c' A: u1 e: w1 q; g $ C1 L9 C( u* [: U" x% G7 A _
图 10
9 ^5 ^3 A( z9 G4 g/ N2 e$ m& |% k 请通过浏览器访问"http://192.168.0.40:5000/v2/_catalog",如返回如下内容则说明registry已经成功启动,192.168.0.40为Ubuntu的IP。$ _% V; F. u9 x/ Z9 _- w7 H' E
# [" d. j( a( z9 q# G) T4 D8 V7 W- v" Z( C, y$ m" I4 Y
! s6 G7 k) d( _7 ?# g
图11 4 t& Q I5 C( v! _0 Q. N
由于刚建立运行,故里面无任何镜像内容。至此,Docker环境安装完成。
1 a. v. N0 W7 Y& u6 }: L4 }
% \$ m5 Q0 q$ s; N2 V; B8 F$ ^8 d2 C; Y D
3 构建镜像 请在Ubuntu上新建工作目录"/home/tronlong/docker/dockeRFile/",并将产品资料“4-软件资料\Linux\Filesystem\docker\”目录下的文件系统压缩包和产品资料“4-软件资料\Demo\base-demos\led_flash\bin\”目录下的可执行文件拷贝至Ubuntu共享目录下,再执行如下命令拷贝至Docker工作目录。3 n& c* Q, k2 B1 a. u
Host# mkdir /home/tronlong/docker/dockerfile
5 S4 m* z3 G7 G' I Host# cp /mnt/hgfs/SharedFolders/led_flash /home/tronlong/docker/dockerfile/
3 e( I1 m: ]5 @7 r Host# cp /mnt/hgfs/SharedFolders/rootfs-v1.2-gcbfe5f3.tar.gz /home/tronlong/docker/dockerfile/
' X5 B- B. t6 X, } k4 `# h& S( W
" n4 u$ r1 N% P" ]2 A% i$ e: E; h7 Y" M
![]()
" ~$ p! Q2 [+ V# ^4 _9 ^图 12 * J6 ]. z3 j- U* n2 U9 k
在"/home/tronlong/docker/dockerfile/"目录下,创建Dockerfile文件,并编写如下内容。, B3 r) A5 W7 g# u) J
Host# cd /home/tronlong/docker/dockerfile
3 m1 O |$ _ x# P% p Host# gedit Dockerfile, w! N; b: e& L- ^
4 @5 I8 G8 V4 n) s1 Y' C) O5 p0 ]3 h
![]()
( [! |/ L3 V: h图 13
" m, E$ E& ~7 h# I5 Z1 C ![]()
" S. S5 @# i4 G: C x6 F图 14 8 S/ R( d! X+ N9 {. ?5 R$ A7 N
Dockerfile文件内容如下:
1 Q8 Y' E% r. ]9 g' \# M, k FROM scratch #基于空的基础镜像构建新的镜像, Q! v% u$ s& o% }( l1 N" P/ }
# Set work directory
) C% m. n* O5 ~5 c" Z) U9 | WORKDIR /root #为CMD、COPY和AND设置工作目录
' n$ x- V! H# L* U6 k# @+ A; G # Decompress the file system
! q) F! Z0 h6 f: C ADD rootfs-v1.2-gcbfe5f3.tar.gz / #解压文件系统
' K% N2 o: |9 H+ M # Copy file to image
4 H7 P" Z1 n7 b* G. Z, V COPY led_flash . #拷贝可执行文件至镜像的"/home/root/"目录下# x I3 P: o- h/ f, l
# Shell command executed when the container is started
0 z; s7 Z3 I1 f: C7 g # CMD ["executable","param1","param2"]
9 A. s* }& x9 |6 d; P2 g CMD ["./led_flash", "-n 2"] #容器启动时执行的shell命令,此处为执行LED闪烁程序的命令" }- n9 g$ y* P7 K. q' ^
在Dockerfile文件所在的目录下执行如下命令,进行构建镜像。
' B/ e& w8 \4 b, g0 ~) z$ [( [ Host# sudo docker build -t 192.168.0.40:5000/led_flash:v1.0 . //注意命令最后含有"."# d6 `1 W! b8 i7 o' B8 U
Host# sudo docker images //查看已构建的镜像. m* K% `: p' I
参数说明:
( ^, `4 |5 m( g: z( v$ Q V 192.168.0.40:Ubuntu的IP地址; @$ @" @# h/ |5 ^$ t; k
-t:指定镜像的名字及标签(name:tag)。
- e4 u- a, d) _! M/ w( {2 v6 W5 {. ?. p; y1 m" H' d6 \0 Z
7 a) n! [4 R2 W0 M% `
9 g1 E! X* |. o7 @
图 15
# X. k) m3 w, g& _/ n/ { 请执行如下命令,将镜像推送至本地仓库Registry。
9 K7 P$ a* p N9 t E, E Host# sudo docker push 192.168.0.40:5000/led_flash:v1.0$ B' M4 e/ Q, G5 J5 i8 t
/ C8 X! S$ ^" R0 ~3 h; f1 y
! B0 \0 j" L- H+ e3 o9 ^ . \5 ?8 _0 X- J3 {
图 16 0 w+ y! Q6 L$ k7 y
Docker版本从1.3.X之后,与Docker Registry交互默认使用https,然而前面搭建的私有仓库仅提供http服务,因此当与私有仓库交互时将出现上面的错误提示。可通过修改"/etc/docker/daemon.json"文件来解决该问题,请执行如下命令,192.168.0.40为Ubuntu的IP。5 J$ \9 f- [' p1 o) F
Host# sudovi /etc/docker/daemon.json
& w7 A. J# \- F4 ^3 Y( t8 D
" A8 v! w" [9 H2 y; }- I& _( t
3 l c% Z% m* o, R: _7 H8 w. D$ t ![]()
% [# ^( U0 S$ b" M0 a6 y1 x图 17 , y3 ?- h9 ^9 ~8 ?, ^$ f
请在daemon.json中添加如下配置内容: Y* B# ?1 S" T
{ "insecure-registries": ["192.168.0.40:5000"]}:8 F7 R2 q( d% ]1 p& f1 T. u* S9 N
执行如下命令,重新启动Docker、Registry容器(通过指定ID),并重新推送镜像至本地Registry。
R- W! o6 D' F# ^) M+ M* T5 ?) U Host# sudo /etc/init.d/docker restart
, R; o$ _, n- q& I7 t5 X Host# sudo docker ps -a5 `; d3 M8 B6 n& n% F
Host# sudo docker start b898d3391bb9 //以查询得到的CONTAINER ID为准8 }0 a( \/ i, B! O; S
Host# sudo docker push 192.168.0.40:5000/led_flash:v1.00 v9 n, z9 J) t$ A; p" I
6 {+ X+ w! t: D3 |2 T4 B! U
9 d: c c) G2 e6 `* u8 L % ~# U9 {" D6 @4 f, e( g+ e
图 18
" t* r/ u9 Q. E) C 通过浏览器访问"http://192.168.0.40:5000/v2/_catalog",即可看到当前仓库里已有的镜像。8 @' ?( q# b) s3 L3 @# I a
4 j* L! H6 b5 ]: @& H' U% T
4 `6 s8 |5 W6 {, o; r; t$ l
![]()
3 [9 `* S2 y9 \! x+ k图 19 ( d, [1 F7 K9 ?7 ^ m( [
4 下载镜像并运行容器 (1) 请使用网线将评估板RGMII ETH网口连接至路由器,并确保和Ubuntu处于同一网络下,评估板上电启动,执行如下命令启动dockerd守护进程。执行命令后,将会打印警告信息,不影响功能正常使用,请忽略。
. W. T8 W, k& n4 z& ? Target# dockerd --storage-driver=vfs &
# `& \ P0 u( s' j& M7 L8 y/ Y7 A# K9 E
. @0 s& E2 M' `0 W( @0 t
% ~1 q7 `) }6 B4 v* A
图 20
1 q7 F9 G, P( M& ^7 \5 E (2) 执行如下命令下载镜像并列举出下载后的镜像。下载镜像过程中将会打印警告和错误信息,不影响功能正常使用,请忽略。: U4 h/ b/ H- k4 L1 x! b
Target# docker pull 192.168.0.40:5000/led_flash:v1.0 //下载镜像
( p4 J( m8 K* D6 M Target# docker images //列举已下载的镜像' A7 ?' C5 W6 [& z [% G' x4 v
+ n5 K( l. d+ ]5 R. q
$ g1 r) {- h) Q3 t' G ![]()
3 d, G! g* }" k& \2 |; M: H' ]7 m图 21
! c) R1 K: J9 {& }( e3 \ 若出现如下错误,请执行如下命令,通过修改"/etc/docker/daemon.json"文件来解决此问题,修改保存后,重新启动dockerd守护进程。
4 x" D3 I, B' d& ^9 ]7 i1 d
: a6 v m5 w& V n( [
0 {5 |, t' T' O6 u8 Y* h) D O; x ![]()
. x& a" `4 O6 w! y图 22 - j' m8 `; `9 u% V, M6 N2 f
Target# vi /etc/docker/daemon.json- |$ g# [ @+ J# R5 B' R6 N5 H
6 H/ q7 P6 C* g9 _' _( p! u W. D% k$ H+ G
![]()
3 t: }% @3 `" ]: _# r& M图 23 % ?# k. G0 y* z) B+ h$ ~7 U9 v( K2 [% a
请在daemon.json中添加如下配置内容:. W4 [! c; d( k* F. C% E
{ "insecure-registries": ["192.168.0.40:5000"]}
: H" p( c& s5 C, J8 d5 i" {5 g Target# killall -9 dockerd //终止进程- z p% G& N. m
Target# dockerd --storage-driver=vfs & //重启dockerd守护进程
, ?4 s0 M" ]4 q V- l6 z# D7 b
( I: r. g3 A7 ^7 _$ q
& I+ ?: Z$ Z0 ^, ?0 | ![]()
( A* M2 p) R; E) N" W图 24
) l4 Q* h+ d, u (3) 创建并启动容器。由于Docker使用VFS存储驱动程序,当创建容器时,需要先创建容器层,该容器层需要对上一层进行“深拷贝”,因此完成创建并启动容器整个过程需要耗时约1min,请耐心等待。
% N' O. Q C2 u, d; D Target# docker run -d --name led_flash -v /sys/:/sys 97c8b410ef97! Q. {4 Z0 ~+ O& e. `; Z6 \6 z
参数说明:4 C4 b8 L( d* X
-d:后台运行容器;; G' n$ x% D: t m+ x# L: c* J
--name:为容器指定一个名称;4 F8 Q: V) r! j. C. Z- S- q. L
-v:映射卷(将主机的目录"/sys"映射至容器的"/sys");
% x$ `- G& d' b5 `2 g6 V) p& ] 97c8b410ef97:镜像ID,以docker images命令列举的"IMAGE ID"为准。7 g2 z# Z+ R- f# U( ]8 H
9 Q% W: [2 k% x/ T' Y: _3 m
2 l/ R7 ]6 a7 R8 Z
! D1 I* H/ q7 o# I, V9 g
图 25
& B& n! j! }6 k# w. h/ V4 p 容器启动完成后,评估底板的2个用户LED灯同时闪烁。* H. S: j& G) p! Q. L
(4) 容器的基本操作6 E# |7 K0 A. P0 V- X/ b$ }% j% J! T, H
执行如下命令,查看正在运行的容器并进入容器。
5 v% a0 t) N( c/ w' J5 b' X1 L Target# docker ps -a, u v- Y. y! f1 j/ ~% u4 }
Target# docker exec -it d5e56fbbd1a8 /bin/bash
7 \: s C5 b5 ^5 v; E5 X 参数说明:
: a- ^$ J4 L/ h5 _! b2 p -i:以交互模式运行容器,通常与-t同时使用;3 V1 c: N" u6 O2 j8 L$ y/ i3 A
-t:为容器重新分配一个伪输入终端,通常与-i同时使用;8 f! M; p+ x1 ?. j7 H1 I& ~
d5e56fbbd1a8:容器ID,以实际"CONTAINER ID"为准;! ^6 a1 A6 \4 y7 {" {5 A: w( S7 U
/bin/bash:在容器内执行"/bin/bash"命令。
7 A7 I) S0 M8 g5 D8 {% I! @- c' F# M$ Y
( R' v. i+ Z, M; y
![]()
/ D1 f8 k8 M7 {6 m$ T0 e图 26
0 R( {; j, L$ z 执行如下命令,退出容器。
/ O! S) w0 t& g Bash# exit/ L4 I4 L, K. S0 f0 E
( [9 x Y' e3 K# a7 ] x6 h
8 ?& C- l: S' H0 j( E ' H# m. o0 Q- a6 ~, [6 ?+ s' P
图 27
4 |3 ~- f$ u8 _; k% B 执行如下命令,停止容器。此时,评估底板的2个用户LED灯不再闪烁。! ^9 S9 U5 `% U$ d
Target# docker stop d5e56fbbd1a83 p* M. J/ ~2 I7 Y8 ?5 W
f2 D& a; \1 U# `* M; Y8 K
8 A# k+ F5 _) D n8 j" I. a 1 g% n7 N4 d, s5 G* j
图 28
5 G4 \# \' Y2 m# B% Z. x8 j 执行如下命令,启动容器。此时,评估底板的2个用户LED灯同时闪烁。, \* z8 q9 V0 S9 r" u8 c
Target# docker start d5e56fbbd1a8! I: Q* ~, e/ }; M2 k8 j' V
8 [$ k1 W9 G- U
3 q# S# z+ g d5 N2 _- P ![]()
; k% S- D4 Y" q1 f图 29
/ ^5 ^0 Z; s7 k) r, { 备注:若运行Docker时,出现"x509: certificate has expired or is not yet valid"类似警告信息(如下图),请执行date命令同步系统时间即可。该警告信息是由于评估板系统时间与实际时间不同步导致。
% J1 P( q3 _9 n+ {
) U$ l( T+ W7 z" ^
2 h& Z, D4 m- A; N' A$ {$ { ![]()
( O2 f' v( o. l& V图 30
( i$ d" u ~$ _) y 如果你还想了解更多嵌入式应用的相关知识,欢迎关注Tronlong创龙科技~
1 R: \5 ], {4 n+ o7 ]% M8 O8 [( j& y
+ u0 _- M$ l+ K; Q9 s |