docker学习

环境:ubuntu 16.04

网上docker文章都写的太复杂了,实际自己安装一次是入门最快的方法。

关键词简单理解


为了便于理解可以简单的把docker当成虚拟机(当然实际上这两个有很大区别):
系统Image镜像:相当于虚拟机的ISO文件。
容器Container:相当于虚拟机实例。

安装docker


安装:

sudo apt-get update
sudo curl -fsSL https://get.docker.com/ | sh

查看docker是否成功及版本:

docker -v

docker安装redis及启动等


先查找一下Docker上的redis镜像:

sudo docker search  redis

可以看到有很多镜像,并且还有star评分。

拉取镜像:

sudo docker pull redis

查看本地镜像仓库:

sudo docker images

创建本地redis目录和下载配置文件redis.conf:

mkdir docker
cd docker
mkdir redis
cd redis
mkdir data
mkdir conf
cd conf
wget http://download.redis.io/redis-stable/redis.conf
cd ..

创建redis容器:

sudo docker run --name redis1  -d -p 6379:6379 -v $PWD/conf/redis.conf:/etc/redis.conf -v $PWD/data:/data redis redis-server /etc/redis.conf --appendonly yes


命令解析:

--name redis1 为容器指定一个名字redis1
-d 后台运行容器,并返回容器ID
-p 6379:6379 将主机(宿主)端口6379映射到容器端口6379
-v $PWD/conf/redis.conf:/etc/redis.conf 意思是把主机中当前目录下conf/redis.conf文件挂载到容器的/etc/redis.conf
-v $PWD/data:/data 意思是把主机中当前目录下data目录挂载到容器的/data目录
redis 就是镜像的名字
redis-server /etc/redis.conf --appendonly yes 这条命令就是redis的启动命令,加了--appendonly yes后redis才会数据持久化。

\color{Hotpink}{注意:宿主机映射的目录会覆盖容器的目录!比如宿主机映射的目录为空那么容器对应的目录也会被清空。}

显示当前正在运行的容器:

sudo docker ps

启动redis-cli客户端连接到docker的redis中:
因为我本机没有安装redis所以没有redis-cli,但是刚运行的redis1容器中有redis-cli,所以可以在容器中启动redis-cli:

sudo docker exec -it redis1 redis-cli

参数it 的意思:
-i :即使没有附加也保持STDIN 打开

-t :分配一个伪终端

停止运行的容器:

sudo docker stop redis1

强制停止容器:

docker kill redis1

启动容器:

sudo docker start redis1

重启容器:

sudo docker restart redis1

查看所有容器实例,包括停止的:

sudo docker ps -a

删除容器,正在运行的不能删除:

sudo docker rm redis1

删除镜像:

sudo docker rmi redis 

查看容器信息

sudo docker inspect redis1

进入容器命令行,并且查看容器的linux系统

sudo docker exec -it redis1 /bin/bash

查看linux内核版本,可以看到官方使用的是ubuntu做基础镜像:
cat /proc/version
uname -a

容器和宿主机互相复制文件

宿主机文件复制到容器:
sudo docker cp test.txt  redis1:test.txt

容器文件复制到宿主机:
sudo docker cp redis1:test.text test.txt

创建镜像Dockerfile


一开始一直没明白为什么要使用基础镜像,动手做了Dockerfile之后明白了。
使用基础镜像启动的容器可以直接当做是个虚拟机操作系统来使用,而没有使用基础镜像的容器那么里面就只有你的程序了。
所以使用系统基础镜像的容器可以当做一个虚拟操作系统进去做任何事情,比如安装go,安装gcc,git自己的代码然后编译。
甚至可以在这个容器里再安装docker,然后pull基础系统镜像,然后再进去......盗梦空间,无限循环,哈哈哈~~~

如果你的宿主机为ubuntu,但是你的程序需要centos环境,这时使用centos基础镜像一样可以跑。

写一个简单的go程序,名字叫test:

package main
import (
 "fmt"
 "os"
)
func main(){
  for i, args := range os.Args {
    fmt.Println(i, args)
  }
  fmt.Println("Hello world.", len(os.Args))
}

在目录下创建一个名字叫Dockerfile的文件:
依赖基础系统镜像:

FROM ubuntu
MAINTAINER wbt
RUN mkdir /work
COPY ./test /work
ENTRYPOINT ["/work/test", "wbttest"]

第一行如果改为FROM ubuntu:16.04则表示指定版本的ubuntu。否则都是ubuntu latest最新版本。
使用基础系统镜像的话做出来的Image镜像非常大,因为包含了基础镜像的内容。

不依赖基础镜像:因为go程序是纯静态没有依赖动态库可以直接添加

FROM scratch
MAINTAINER wbt
#RUN mkdir /work
COPY ./test /
CMD ["/test", "wbttest"]
#ENTRYPOINT ["/work/test", "wbttest"]

RUN mkdir /work这个需要注释掉是因为mkdir这条命令现在没有了,而上面使用基础系统镜像的方式可以使用是因为基础镜像里有这条命令。
不依赖基础镜像的Image很小,跟原生的go程序差不多大。

CMD与ENTRYPOINT指令的区别主要在启动容器时覆盖命令和参数有所不同,CMD的命令和参数可以在run时被覆盖,ENTRYPOINT不会被覆盖。

编译Dockerfile:

不带版本号,最后
sudo docker build -t test .

带版本号1.0:
sudo docker build -t test:1.0 .
这个是scratch方式的镜像测试:
后面的/test param1 param2 param3是覆盖了原来Dockerfile指定的命令和参数。
加上--rm之后当容器退出时自动删除容器。

sudo docker run -it --name tt --rm test /test param1 param2 param3
输出:
0 /test
1 param1
2 param2
3 param3
Hello world. 4

查看logs:

sudo docker logs tt

启动加上-a-i参数都可以回显输出:

sudo docker start -a tt

docker start 好像不能重写命令和参数。

如果要做镜像的程序是动态编译有依赖库那么需要把动态库在Dockerfile中指定打包进去。
下回写个c++程序再测试一下。

使用busybox做为基础镜像创建Dockerfile


因为scratch基础镜像是个空镜像,里面没有任何命令,如果需要做mkdir, wget等操作是没有办法的,这时可以选择busybox做为基础镜像,busybox包含了很多的unix基本工具:

Currently defined functions:
[, [[, acpid, add-shell, addgroup, adduser, adjtimex, ar, arch, arp,
arping, ash, awk, base64, basename, bc, beep, blkdiscard, blkid,
blockdev, bootchartd, brctl, bunzip2, bzcat, bzip2, cal, cat, chat,
chattr, chgrp, chmod, chown, chpasswd, chpst, chroot, chrt, chvt,
cksum, clear, cmp, comm, conspy, cp, cpio, crond, crontab, cryptpw,
cttyhack, cut, date, dc, dd, deallocvt, delgroup, deluser, depmod,
devmem, df, dhcprelay, diff, dirname, dmesg, dnsd, dnsdomainname,
dos2unix, dpkg, dpkg-deb, du, dumpkmap, dumpleases, echo, ed, egrep,
eject, env, envdir, envuidgid, ether-wake, expand, expr, factor,
fakeidentd, fallocate, false, fatattr, fbset, fbsplash, fdflush,
fdformat, fdisk, fgconsole, fgrep, find, findfs, flock, fold, free,
freeramdisk, fsck, fsck.minix, fsfreeze, fstrim, fsync, ftpd, ftpget,
ftpput, fuser, getopt, getty, grep, groups, gunzip, gzip, halt, hd,
hdparm, head, hexdump, hexedit, hostid, hostname, httpd, hush, hwclock,
i2cdetect, i2cdump, i2cget, i2cset, id, ifconfig, ifdown, ifenslave,
ifplugd, ifup, inetd, init, insmod, install, ionice, iostat, ip,
ipaddr, ipcalc, ipcrm, ipcs, iplink, ipneigh, iproute, iprule,
iptunnel, kbd_mode, kill, killall, killall5, klogd, last, less, link,
linux32, linux64, linuxrc, ln, loadfont, loadkmap, logger, login,
logname, logread, losetup, lpd, lpq, lpr, ls, lsattr, lsmod, lsof,
lspci, lsscsi, lsusb, lzcat, lzma, lzop, makedevs, makemime, man,
md5sum, mdev, mesg, microcom, mkdir, mkdosfs, mke2fs, mkfifo,
mkfs.ext2, mkfs.minix, mkfs.vfat, mknod, mkpasswd, mkswap, mktemp,
modinfo, modprobe, more, mount, mountpoint, mpstat, mt, mv, nameif,
nanddump, nandwrite, nbd-client, nc, netstat, nice, nl, nmeter, nohup,
nologin, nproc, nsenter, nslookup, ntpd, nuke, od, openvt, partprobe,
passwd, paste, patch, pgrep, pidof, ping, ping6, pipe_progress,
pivot_root, pkill, pmap, popmaildir, poweroff, powertop, printenv,
printf, ps, pscan, pstree, pwd, pwdx, raidautorun, rdate, rdev,
readahead, readlink, readprofile, realpath, reboot, reformime,
remove-shell, renice, reset, resize, resume, rev, rm, rmdir, rmmod,
route, rpm, rpm2cpio, rtcwake, run-init, run-parts, runlevel, runsv,
runsvdir, rx, script, scriptreplay, sed, sendmail, seq, setarch,
setconsole, setfattr, setfont, setkeycodes, setlogcons, setpriv,
setserial, setsid, setuidgid, sh, sha1sum, sha256sum, sha3sum,
sha512sum, showkey, shred, shuf, slattach, sleep, smemcap, softlimit,
sort, split, ssl_client, start-stop-daemon, stat, strings, stty, su,
sulogin, sum, sv, svc, svlogd, svok, swapoff, swapon, switch_root,
sync, sysctl, syslogd, tac, tail, tar, taskset, tc, tcpsvd, tee,
telnet, telnetd, test, tftp, tftpd, time, timeout, top, touch, tr,
traceroute, traceroute6, true, truncate, tty, ttysize, tunctl,
ubiattach, ubidetach, ubimkvol, ubirename, ubirmvol, ubirsvol,
ubiupdatevol, udhcpc, udhcpd, udpsvd, uevent, umount, uname, unexpand,
uniq, unix2dos, unlink, unlzma, unshare, unxz, unzip, uptime, users,
usleep, uudecode, uuencode, vconfig, vi, vlock, volname, w, wall,
watch, watchdog, wc, wget, which, who, whoami, whois, xargs, xxd, xz,
xzcat, yes, zcat, zcip

busybox镜像非常小,只有1.2M。我们可以基于这个基础镜像来写Dockerfile:

FROM busybox
MAINTAINER wbt
RUN mkdir /work
COPY ./test /work
CMD ["/work/test", "wbttest"]

然后编译(如果你没有预先pull busybox的话docker会自动pull busybox镜像):

sudo docker build -t test2 .

运行:

sudo docker run -it --name test2 --rm test2 /work/test test2 param1 param2 

甚至可以这样运行,返回busybox的命令提示:

sudo docker run -it --name test2 --rm test2 busybox

或者这样:

查看目录结构:
sudo docker run -it --name test2 --rm test2 ls
sudo docker run -it --name test2 --rm test2 ls /bin

执行这条可以看到我们自己的test程序:
sudo docker run -it --name test2 --rm test2 ls /work

修改容器启动时映射的端口


  1. 查看需要修改的容器,记住container id
sudo docker ps -a
  1. 停止容器
sudo docker stop xxx
  1. 修改容器的配置文件
    如果下面出现权限不够,比如:cannot open directory '/var/lib/docker': Permission denied,那先修改docker目录权限:sudo chmod -R 755 /var/lib/docker
sudo vim /var/lib/docker/containers/{container_id}/hostconfig.json

修改:

"PortBindings": {
     "4000/tcp": [
             {
             "HostIp": "",
             "HostPort": "4000"//宿主机ip
             }
         ]
     },
  1. 重启docker服务
sudo service docker restart
  1. 重启容器

参考文章:
docker建立最简单最小的helloworld镜像
Dockerfile创建自定义Docker镜像以及CMD与ENTRYPOINT指令的比较
基于Docker部署nodejs应用

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351