docker

一、初步了解docker

1、什么是容器?

容器就是在隔离的环境中运行的一个进程。进程如果停止,容器就会销毁。隔离的环境拥有自己的系统文件(/根下的东西就叫系统文件),ip地址,主机名等,特别像虚拟机。

2、容器和虚拟化的区别(从启动流程分析)

linux开机启动流程: 当按下电源按钮时,系统会进行bios开机硬件自检,扫描计算机硬件,若硬件有问题就不会往下进行了,一旦开机自检通过,老式电脑会滴的一声。根据bios设置的优先启动项boot,网卡,硬盘,u盘,光驱,读取mbr信息,0柱面,0磁头,1扇区,mbr里有引导信息,引导信息会加载grub启动菜单(有每个操作系统的内核路径),根据内核路径加载内核,启动第一个进程/sbin/init(Centos
6) systemd(Centos 7),第一个进程会把其余的子进程拉起来,最终操作系统就启动完成了,运行服务。

容器启动流程: 容器共用宿主机的内核,第一个进程不是系统的第一个进程,容器的第一个进程直接就是跑的服务(nginx,httpd,mysql)。

总结:

容器共用宿主机内核,更加的轻量级,损耗少,启动快,性能高,只能运行linux系统
虚拟机:需要硬件的支持,需要模拟硬件,需要走开机启动流程,可以进行不同的操作系统

3、什么是docker?

docker是容器的管理工具,就相当于libvirt是kvm虚拟机的管理工具一样,docker是一种软件的打包技术,docker的主要目标是’build,ship and run any app,anywhere’构建,运输,处处运行。docker解决了软件和操作系统环境之间的依赖,使应用程序可以在几乎任何地方以相同的方式运行,开发人员在自己笔记本上创建并测试好的容器,无需任何修改就能够在生产系统的虚拟机,物理服务器或公有云主机上运行。

4、docker的主要组件

主要组件有:镜像,容器,仓库,网络,存储
启动容器必须要有一个镜像,仓库中只存储镜像
容器- - -镜像- - -仓库

二、docker的安装

1、系统要求

Docker 支持 64 位版本 CentOS 7/8,并且要求内核版本不低于 3.10,uname -r看内核版本

2、使用yum安装

yum install yum-utils  -y

鉴于国内网络问题,强烈建议使用国内源,执行下面的命令添加yum软件源

yum-config-manager --add-repo \ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

更新 yum 软件源缓存,并安装 docker-ce

yum install docker-ce docker-ce-cli containerd.io

启动 Docker

systemctl start docker
systemctl enable docker

3、验证docker是否安装成功
使用docker version有client和service两部分表示docker安装启动都成功了
在这里插入图片描述

三、启动第一个容器

1、docker info,可以查看容器状态,以及宿主机的版本及内存,如果要做监控可以用到
在这里插入图片描述
2、配置镜像加速文件

[root@docker ~]# cat /etc/docker/daemon.json
{
  "registry-mirrors": [
    "https://sopn42m9.mirror.aliyuncs.com",
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com"
  ]
}

再进行docker重启

[root@docker ~]# systemctl daemon-reload
[root@docker ~]# systemctl restart docker

启动第一个容器,现在用docker来安装nginx

[root@docker ~]# docker run -d -p 80:80 nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx

命令解释:

run 创建并运行一个容器
-d 放在后台
-p 端口映射
nginx docker镜像的名字

这时我们在浏览器访问就可以访问到nginx,我们查询进程时并没有这个进程,这就是docker的隔离环境运行的进程
在这里插入图片描述

[root@docker ~]# netstat -tupln|grep nginx
[root@docker ~]#

四、docker的镜像管理命令

1、搜索镜像

[root@docker ~]# docker search centos

也可以在仓库地址搜:hub.docker.com
2、从官方仓库下载镜像

[root@docker ~]# docker pull alpine
alpine是最小的linux镜像,只有5M

私有仓库就有镜像的域名,最后才有镜像的名称和版本,举例如下

[root@docker ~]# docker pull daoclound.io/huangzhichong/alpine-cn:latest

3、查看镜像列表

[root@docker ~]# docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
alpine       latest    6dbb9cc54074   3 weeks ago   5.61MB
nginx        latest    62d49f9bab67   3 weeks ago   133MB

4、删除镜像

[root@docker ~]# docker image rm  alpine
rm后可以加镜像名,也可以加id,正在使用的镜像无法删除哦

5、导出镜像

[root@docker ~]# docker image save -o /opt/docker_alpine.tar.gz alpine:latest
[root@docker ~]# ll -h /opt/docker_alpine.tar.gz
-rw------- 1 root root 5.7M 57 15:32 /opt/docker_alpine.tar.gz
#也可以直接重定向代替-o参数
[root@docker ~]# docker image save >/opt/docker_alpine.tar.gz alpine:latest

6、删除镜像,因为我们现在已经把它导出了,可以放心的删除

[root@docker ~]# docker image rm alpine:latest
Untagged: alpine:latest
Untagged: alpine@sha256:69e70a79f2d41ab5d637de98c1e0b055206ba40a8145e7bddb55ccc04e13cf8f
Deleted: sha256:6dbb9cc54074106d46d4ccb330f2a40a682d49dda5f4844962b7dce9fe44aaec
Deleted: sha256:b2d5eeeaba3a22b9b8aa97261957974a6bd65274ebd43e1d81d0a7b8b752b116
[root@docker ~]# docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nginx        latest    62d49f9bab67   3 weeks ago   133MB

7、导入镜像

[root@docker ~]# docker image load -i /opt/docker_alpine.tar.gz
b2d5eeeaba3a: Loading layer   5.88MB/5.88MB
Loaded image: alpine:latest
[root@docker ~]# docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
alpine       latest    6dbb9cc54074   3 weeks ago   5.61MB
nginx        latest    62d49f9bab67   3 weeks ago   133MB

五、docker的容器管理命令

1、创建并运行一个容器,-it表示进入到这个容器docker run=docker create + docker start

[root@docker ~]# docker run -it centos6.9

命令解释:

-i:以交互模式运行容器,通常与 -t 同时使用;
-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用
centos6.9 容器的名字

2、查看处于运行状态的容器,docker container ls=docker ps,加上-a参数列出所有状态的容器

[root@docker ~]# docker container  ls
CONTAINER ID   IMAGE     COMMAND                  CREATED             STATUS             PORTS                               NAMES
5b28872446ef   nginx     "/docker-entrypoint.…"   About an hour ago   Up About an hour   0.0.0.0:80->80/tcp, :::80->80/tcp   flamboyant_austin

3、停掉启动的容器

[root@docker ~]# docker stop 5b28872446ef
5b28872446ef
[root@docker ~]# docker ps  #再次进行查看,已经没有运行的容器
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

4、启动容器

[root@docker ~]# docker container start 5b28872446ef
5b28872446ef
[root@docker ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED             STATUS         PORTS                               NAMES
5b28872446ef   nginx     "/docker-entrypoint.…"   About an hour ago   Up 2 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   flamboyant_austin

5、进入容器(调试,排错)

进入到上面列表列出的容器
[root@docker ~]# docker container exec -it 5b28872446ef /bin/bash
root@5b28872446ef:/# 

在容器里进行的一系列操作都在宿主机里可以看到,首先我们要先在宿主机安装pstree

[root@docker ~]# yum install -y psmisc-22.20-17.el7.x86_64

然后在容器里执行sleep 1000,在宿主机里执行pstree就可以看到容器的活动了

在容器里执行
root@5b28872446ef:/# sleep 1000

在这里插入图片描述
6、删除容器

[root@docker ~]# docker rm 0d946eee236f
0d946eee236f
用docker ps -a 可以查到容器的ID号

批量删除容器

[root@docker ~]# docker ps -a -q    #-q静默输出id号
8506acb4b119
94b6c33b2211
5ecf5d5921db
5b28872446ef
[root@docker ~]# docker rm `docker ps -a -q`   #这样删除所有容器的Id号
8506acb4b119
94b6c33b2211
5ecf5d5921db
Error response from daemon: You cannot remove a running container 5b28872446efd01064b99e9f700d2a373ae4814f0172314624f56ced852abefc. Stop the container before attempting removal or force remove
#提示运行的容器无法删除,可以停止此容器或者强制删除,下面选取强制删除-f这种方式
[root@docker ~]# docker rm -f `docker ps -a -q`
5b28872446ef

六、docker容器的网络访问

1、单个容器使用80端口

进入到一个容器,查看它的IP地址

[root@docker ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED              STA                                           TUS              PORTS     NAMES
982c20052f66   nginx:latest   "/docker-entrypoint.…"   About a minute ago   Up                                            About a minute   80/tcp    gifted_montalcini
[root@docker ~]# docker exec -it 982c20052f66 /bin/bash
root@982c20052f66:/# hostname -i
172.17.0.2

此IP地址在宿主机可以访问,但是在浏览器上却不能访问。

[root@docker ~]# curl -I 172.17.0.2
HTTP/1.1 200 OK
Server: nginx/1.19.10
Date: Fri, 07 May 2021 09:03:12 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 13 Apr 2021 15:13:59 GMT
Connection: keep-alive
ETag: "6075b537-264"
Accept-Ranges: bytes

那么在生产中这样是不行的,要想通过浏览器访问就得做端口映射,用以下命令,-p 宿主机端口:容器端口

[root@docker ~]# docker run -d -p 80:80 nginx
c21acf6bbb1cdac6bbe37b14387837ef8c495c82eb9a709b5bdd6308a4f9a7

这时系统就自动修改了iptables规则

[root@docker ~]# iptables -t nat -L -n
...
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0
MASQUERADE  tcp  --  172.17.0.3           172.17.0.3           tcp dpt:80
从容器80端口出来的都模拟成宿主机的IP地址
Chain DOCKER (2 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 to:172.17                                        .0.3:80
做了地址转换,当访问宿主机的任何一个80端口都转到容器里面来

浏览器访问宿主机的IP就可以访问到nginx页面了。

2、多个容器同时使用80端口

设置两个网卡,ens33(192.168.119.166),ens34(192.168.119.168)
在运行容器时可以指定不用的IP地址

[root@docker ~]# docker run -d -p 192.168.119.166:80:80 nginx:latest
[root@docker ~]# docker run -d -p 192.168.119.168:80:80 nginx:latest

遇到的问题:

在创建容器时可能会出现以下错误,这是IPv4转发已禁用。网络将不起作用,所以我们开启ipv4转发就好了,具体命令如下

[root@docker ~]# docker run -d -p 192.168.119.168:80:80 nginx:latest
WARNING: IPv4 forwarding is disabled. Networking will not work.

解决办法如下再次创建容器就好了:

[root@docker ~]# echo "net.ipv4.ip_forward=1" >> /usr/lib/sysctl.d/00-system.conf
[root@docker ~]# tail -2 /usr/lib/sysctl.d/00-system.conf 
net.bridge.bridge-nf-call-arptables = 0
net.ipv4.ip_forward=1
[root@docker ~]# systemctl restart network
[root@docker ~]# systemctl restart docker

查看容器的运行列表,可以看到指向了两个不同的IP,同样的端口

[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                        NAMES
f6a773adddf8   nginx:latest   "/docker-entrypoint.…"   14 seconds ago   Up 12 seconds   192.168.119.168:80->80/tcp   eager_lamport
ad35963a76f3   nginx:latest   "/docker-entrypoint.…"   7 minutes ago    Up 7 minutes    192.168.119.166:80->80/tcp   sleepy_bardeen
a45542d91833   nginx:latest   "/docker-entrypoint.…"   6 minutes ago    Created                                      festive_khayyam
9dcf3223219d   nginx:latest   "/docker-entrypoint.…"   7 minutes ago    Created                                      beautiful_fermat

用netstat查看也是同样的结果

[root@docker ~]# netstat -tupln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 192.168.119.168:80      0.0.0.0:*               LISTEN      9464/docker-proxy
tcp        0      0 192.168.119.166:80      0.0.0.0:*               LISTEN      8419/docker-proxy

我们可以进入到容器里在/usr/share/nginx/html/index.html里设置不同的内容,在nginx页面访问就是不同的页面了

[root@docker ~]# docker exec -it aa7b710d2294  /bin/bash
root@aa7b710d2294:/# echo '166'> /usr/share/nginx/html/index.html

[root@docker ~]# docker exec -it 804b7502b4cf /bin/bash
root@804b7502b4cf:/# echo "168" > /usr/share/nginx/html/index.html

在这里插入图片描述
在这里插入图片描述

3、随机端口

[root@docker ~]# docker run -d -p 192.168.119.166::80 nginx:latest
15ec75d62312162316114c1259173c0cd869cc51104851d18524bb2dc4de0a5a

[root@docker ~]# netstat -tupln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 192.168.119.168:80      0.0.0.0:*               LISTEN      10487/docker-proxy
tcp        0      0 192.168.119.166:80      0.0.0.0:*               
tcp        0      0 192.168.119.166:49153   0.0.0.0:*               LISTEN      10682/docker-proxy
可以看到最后一个端口是随机分配的

随机端口可以应用在下列情况中
在这里插入图片描述
也可以选择下面的方法来随机指定端口

docker run -P nginx

4、指定udp协议

使用宿主机的192.168.119.166这个IP地址的随机端口的udp协议映射容器的udp53端口

docker eun -p 192.168.119.166::53:udp

七、docker的数据卷管理

1、-v 宿主机的目录:容器的目录
具体命令如下:

[root@docker opt]# cd /data/
[root@docker data]# cat index.html
weclome to docker
[root@docker data]# docker run -d -p 81:80 -v /data/:/usr/share/nginx/html ngin                                           x:latest
854843d96e7a882b264126fb0e62b34c27495c928f2912089ea8ab2fdcc43f4a

访问宿主机IP及端口号:
在这里插入图片描述
2、-v 数据卷名字:容器目录

[root@docker data]# docker run -d -p 82:80 -v test:/usr/share/nginx/html nginx:latest
32827ac1414acf3f4130badccb3ec91a2868face70f0f5ef95c4b2351a1a26a5

我们可以随便指定一个数据卷的名字,然后进行查看就可以看到数据卷的详细信息

[root@docker data]# docker volume ls
DRIVER    VOLUME NAME
local     test
[root@docker data]# docker volume inspect test
[
    {
        "CreatedAt": "2021-05-08T14:37:44+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/test/_data",
        "Name": "test",
        "Options": null,
        "Scope": "local"
    }
]
[root@docker data]# cd /var/lib/docker/volumes/test/_data
[root@docker _data]# ls
50x.html  index.html
这两个文件是容器里的文件

然后访问宿主机IP及端口
在这里插入图片描述

八、手动制作docker镜像

1、启动一个基础镜像,让镜像实现ssh功能,制作单服务镜像

[root@docker ~]# docker run -it centos:centos6.9
echo '192.168.119.166 mirrors.aliyun.com' >>/etc/hosts
curl -o /etc/yum.repos.d/Centos-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
yum install openssh-server -y
/etc/init.d/sshd restart

2、将容器提交成镜像

[root@docker ~]# docker container commit d3d79bbdf011 centos6.9_ssh:v1   最后为镜像的名称和版本
sha256:b0231e19e6842bb7f5b78d557ea617ff638761da753f6e16788ff3787f69bf36
[root@docker ~]# docker images
REPOSITORY      TAG         IMAGE ID       CREATED          SIZE
centos6.9_ssh   v1          b0231e19e684   12 seconds ago   218MB
可以看到创建的镜像

3、测试镜像的功能(即能启动服务,又能让服务一直在前台运行就加上最后一个参数)

docker run -d -p 1023:22 centos6.9_ssh:v1 /usr/sbin/sshd -D

九、dockerfile自动制作docker镜像

dockerfile常用格式

FROM 选择一个基础镜像,这个镜像的妈妈是谁
MAINTAINER 告诉别人,谁负责它(指定维护者信息,可以没有)
LABEL 描述,标签,也可以没有
RUN 安装软件,需要执行的命令(你想让它干啥)
ADD 给它点创业资金(会自动解压tar),制作docker基础的系统镜像
COPY 复制文件,不会解压tar包
WORKDIR 我是cd,今天化妆了(设置当前工作目录)
VOLUME 给它一个存放行李的地方(设置卷,挂载主机目录,将设置的目录持久化保存)
EXPOSE 它要打开的门是啥(指定对外的端口,-P 随机端口)
ENV 设置环境变量
CMD 指定容器启动后要干的事情

workdir的作用可以用下图解释,指定容器的初始目录
在这里插入图片描述
1、可以将上述的手动制作镜像搞成自动制作镜像

[root@docker ~]# cd  /data/dockerfile
[root@docker ~]# mkdir centos6.9_ssh
[root@docker ~]# cd  centos6.9_ssh
[root@docker ~]# cat  dockerfile
FROM centos:6.9
RUN  echo '192.168.119.166 mirrors.aliyun.com' >>/etc/hosts
RUN  curl -o /etc/yum.repos.d/Centos-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
RUN  yum install openssh-server -y
RUN  /etc/init.d/sshd restart
EXPOSE   22
CMD  ["/usr/sbin/sshd","-D"]

2、构建镜像

[root@docker ~]# docker build -t centos6.9_ssh:v2 .
.表示在当前目录读取dockerfile

3、运行容器

docker run -d -p 2022:22 centos6.9_ssh:v2

也可以用dockerfile做双服务的镜像,如ssh+nginx

[root@docker ~]# mkdir centos6.9_ssh_nginx
[root@docker ~]# cat  dockerfile
FROM centos:6.9
RUN  echo '192.168.119.166 mirrors.aliyun.com' >>/etc/hosts
RUN  curl -o /etc/yum.repos.d/Centos-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
RUN  curl -o /etc/yum.repos.d/epel.repo 
http://mirrors.aliyun.com/repo/epel-6.repo
RUN  yum install openssh-server nginx -y
RUN  /etc/init.d/sshd restart
ADD  init.sh  /init.sh 
EXPOSE   22 80
CMD  ["/bin/bash","/init.sh"]

然后在当前目录下创建init.sh文件

#!/bin/bash
service sshd restart
nginx -g 'daemon off;'

然后构建镜像

[root@docker ~]# docker build -t centos6.9_ssh_nginx:v1 .

运行容器

docker run -d -p 2023:22 -p 80:80  centos6.9_ssh_nginx:v1

再进行测试,发现ssh登录和nginx访问都没有问题
docker镜像的分层(kvm链接克隆,写时复制的特性),优点:复用,节省磁盘空间,相同的内容只需加载一份到内存。

dockerfile的优化:

1、尽可能合并RUN指令,清理无用的文件(yum缓存,源码包)
2、尽可能选择体积小的linux,如alpine
3、把变化的内容放在dockerfile的结尾,前面的就用缓存

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值