容器技术(Docker)

容器技术(Docker)

容器技术的核心就是通过对资源的限制隔离把进程运行在一个沙盒中。并且这个沙盒可以被打包成容器镜像(Image),移植到另一台机器上可以直接运行,不需要任何的多余配置。其中docker是容器技术的事实标准。

docker常见问题

使用容器部署有什么优势?

  1. 容器具有强一致性,由同一个镜像创建的容器不管在任何一台机器上都拥有一套相同的独立的文件系统。因此可以保证环境的统一,dev、sit、uat、prod环境可以使用同一套镜像,节省同步本地、测试、生产环境的时间和精力。避免发生【我电脑上能跑啊,为什么你跑起来就不行呢】、【明明本地测试没问题啊,为什么上线不行呢】等问题。
  2. 对CI/CD友好,开发者修改代码后直接在本地docker build、docker run,运行的效果和上线效果是高度一致的。
  3. 容器可以更细化CPU、内存、IO等硬件资源的分配。使资源的使用更加高效合理。
  4. 启动快,对比虚拟机的分钟级,容器的启动速度是秒级的。
  5. 系统资源的损耗远小于虚拟机。

如何开启docker的tcp接口?

最好只用于虚拟机或内网测试环境。如果机器有对外提供服务或以任何形式可以被互联网访问,请勿打开此端口,此端口会被利用从而导致容器被植入挖矿程序。

启动dockerd时添加参数

如果机器上的docker是使用二进制安装,启动dockerd的方式。可以直接在启动dockerd的时候

sudo dockerd  -H  unix:///var/run/docker.sock -H tcp://<addr>:<port>
#例如,我们想要可以从本机直接调用测试服务器上或虚拟机上的docker,可以设置
sudo dockerd  -H  unix:///var/run/docker.sock -H tcp://0.0.0.0:2375
# 不能不设置 -H  unix:///var/run/docker.sock 不然宿主机没法使用docker cli
使用systemd时修改docker.service

一般docker.service的位置在 /usr/lib/systemd/system 或 /lib/systemd/system/

  1. 修改docker.service,在ExecStart=xxxxxx 后面添加 -H tcp://:

    #例如
    ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375
    
  2. 然后执行命令

systemctl deamon-reload
systemctl restart docker

如何使用IDEA连接docker?

使用docker远程端口

确保已经开放了docker的TCP端口后,并且IDEA安装了docker插件(idea utimate版都是预装的)。

进入IDEA Setting 的 Build,Execution,Deployment/docker,配置如下

容器技术(Docker)_第1张图片

将IP和端口设为docker宿主机的IP和开放的端口。

使用SSH

确保docker宿主机有ssh服务。在IDEA中进入Setting/Tools/SSH Configuration,配置如下

容器技术(Docker)_第2张图片

然后再进入IDEA Setting 的 Build,Execution,Deployment/docker,选择On SSH machine, 然后选中刚配置的docker宿主机的ssh即可。

如何使用IDEA远程调试docker容器内JVM进程

  1. 首先IDEA上代码与容器内运行的代码版本一致。

  2. IDEA在run/debug Configuration 添加一个Remote JVM Debug配置,如下。端口可以随便指定为一个可使用的端口容器技术(Docker)_第3张图片

  3. 按提示将JVM添加到容器内进程的启动参数。

  4. 启动容器时添加debug端口到宿主机端口的映射。

docker技术原理

namespace

Docker主要使用了Namespace实现了对容器资源的隔离,包括了

  • PID(进程编号)

  • UTS(主机信息)

  • network(网络)

  • user(用户权限)

  • mount(挂载信息)

  • IPC(进程间通信)

  • cgroups

正因为这些隔离,docker容器内的进程只能使用同一个namespace下的资源,只能感知同一个namespace下的其他进程。

Cgroups

Linux Cgroups技术可以限制进程对CPU、内存、IO设备等资源的使用。通过使用cgroups技术,docker engine可以限制每个容器所能使用的系统资源的大小。

Image

用面向对象的思维可以把镜像(image)理解为,容器(container)理解为对象。换一种说法可以将镜像理解为程序,容器理解为进程

一个镜像可以在不同的宿主机(物理机或是虚拟机)上启动为容器,并且几乎不需要多余的配置。

镜像的本质是一个操作系统的文件系统(rootfs),而容器需要调用内核时实际上是使用了宿主机的内核。

docker image的rootfs是分层的,开发者可以在原有的image基础上添加需要的内容(即新的层)创建出新的image,这个步骤也可以简单的理解成面向对象中的继承。

容器技术和虚拟机的对比

容器技术(Docker)_第4张图片

容器技术和虚拟机的区别可见上图,主要差异在于虚拟机多了一整套由hypervisor虚拟化的硬件基础设施,并且包括完整的guest os(包括内核),而容器只包括rootfs。

因此不能认为容器是轻量级的虚拟机,容器的实质是宿主机的一个进程,只是通过了namespace、cgroups技术使这个进程和其他进程隔离并且拥有独立的文件系统。

所以理论上windows系统不能运行linux容器,因为windows没有linux内核,而容器需要共享宿主机内核。(实际上windows是可以使用WSL、Hyper-V来运行容器,但是WSL、Hyper-V运行linux容器的原理也是虚拟化了一套linux内核来运行linux容器)

docker基础操作

docker 容器指令

注意!!!下文中的 [] 只是为了凸显内容,使用指令时不需要带[]() 内的内容表示选择性内容。

只包括一些常用的docker指令,详细的用法可以登录 https://docs.docker.com/reference/ 查看docker官方参考手册或者使用指令时,docker [command] --help 查看指令的具体用法。

1、启动容器
docker run -p [宿主机端口]:[容器端口] --name [容器名] \
-e TZ="Asia/Shanghai" \
-v /mydata/nginx/html:/usr/share/nginx/html \
-d nginx:1.17.0 \
--network [networkName] \
--restart=always

启动容器的基本命令就是docker run 镜像。另外docker提供了一系列的参数可以个性化的定义容器的各个参数,这些参数可以放在docker run 和 [image-name]之间,没有固定顺序。

  • -p:将宿主机和容器端口进行映射,格式为:宿主机端口:容器端口;
  • –name:指定容器名称,之后可以通过容器名称来操作容器;
  • -e:设置容器的环境变量,包括容器内时区和一些容器定义的变量
  • -v:将宿主机上的文件或文件夹挂载到宿主机上,格式为:宿主机文件(文件夹):容器文件(文件夹)
  • -d:表示容器以后台方式运行
  • –network 指定容器的网络,如果不指定默认为birdge(默认的网桥模式网络)
2、docker容器启动、关闭、删除、重启、重命名
docker start [containerName] | [containerId]
docker stop [containerName] | [containerId]
docker rm [containerName] | [containerId]
docker restart [containerName] | [containerId]
docker rename [containerName] | [containerId] [newName]
3、docker 宿主机\容器文件复制
docker cp containerID:/usr/xxxx/xxxx/xxx.xml /usr/xxx/xxx

复制容器的/usr/xxxx/xxxx/xxx.xml 到外部的/usr/xxx/xxx

参数反过来就是复制容器外部的到容器里

4、docker 进入指定容器命令
docker exec -it --user [userName] [containerName] | [containerId] bin/bash
#可以根据指定容器的name或id进入对应容器 ,可以指定进入容器的用户,也可以不指定
docker exec -it --user [userName] [containerName] | [containerId] sh
#有的容器没有bin/bash,也许可以用sh
5、docker 查看容器日志
docker logs (-f) [containerName] | [containerId]
#加上-f的话可以查看容器动态产生的日志
6、检查容器的信息
docker inspect [containerName] | [containerId]
docker inspect --format '{{ .NetworkSettings.IPAddress }}' [containerName] | [containerId] #查看容器ip
docker inspect --format='{{range .NetworkSettings.Networks}}{{.MacAddress}}{{end}}' [containerName] | [containerId] #查看容器的MAC地址
docker inspect --format='{{.LogPath}}' [containerName] | [containerId] #查看容器日志路径

7、修改容器的重启策略
# 例如将容器的重启策略改为always
docker container update --restart=always [containerName] | [containerId]
8、查看容器的资源占用情况
docker stats [containerName] | [containerId]
9、查看容器内进程
docker top [containerName] | [containerId]
10、容器打包
docker export -o [fileName] [containerName] | [containerId]
#例如 docker export -o ubuntu.tar ubuntu 即为将名为ubuntu的容器打包到当前目录的ubuntu.tar文件中
#容器打包指令会将容器的整个文件系统打包到指令文件,可以使用docker import命令将文件导入成docker镜像

docker 镜像指令

1、查看所有镜像
docker image ls
docker images
2、下载镜像
docker pull [imageName]:[tag]
#不指定【tag】,默认为latest
3、删除镜像
docker image rm [imageName]
docker rmi [imageName]
4、导入镜像
docker load -i [fileName] #例如 docker load -o ubuntu.tar
docker import [fileName] [imageName]:[imageTag] #例如 docker import ubuntu.tar ubuntu:18
#区别在于docker load无法重命名,并且只能从文件导入。 docker import 可以重命名并且支持从url导入
5、镜像重命名
docker tag [imageName]:[imageTag] [newImageName]:[newImageTag]
6、镜像打包成文件
docker save -o [fileName]  [imageName] 
7、推送镜像到参考
docker push [imageName]
8、清理虚无镜像
docker image prune
#这个指令会删除 imagename或tag为空的镜像,使用时要谨慎。

docker 程序指令

1、查看docker程序的磁盘使用情况
docker system df
2、清理docker
docker system prune
#会清理关闭的容器、虚无镜像和未使用的网络。请谨慎使用!
3、登录docker仓库
docker login (-u [username]) (-p [passwd]) [server]
4、退出登录
docker logout [server]

Dockerfile

Docker使用定义Dockerfile文件的方式显示声明镜像,Dockerfile是由一行行指令组成的文件。声明Dockerfile后,使用docker指令 docker build 打包镜像。

docker build (-t) [imageName]:[imageTag] .
#注意最后有一个点 '.' ,代表以当前目录为上下文。当前目录必须是dockerfile所在的目录 
FROM

指定容器所依赖度的基础镜像

FROM xxxx
ADD

将当前目录下的文件复制到容器中,如果容量目录不存在则会创建该目录

ADD [文件、目录] [容器目录]
COPY

与ADD命令基本相同,如果容量目录不存在则会创建该目录

COPY [文件、目录] [容器目录]
RUN

RUN命令在构建镜像时执行,一般是下载一些程序到docker。

RUN 
ENTRYPOINT

ENTRYPOINT命令在容器启动时执行,一般用来指定启动应用的命令。可以在容器启动时被替换

ENTRYPOINT 
CMD

docker run 时执行的默认操作,可以在容器启动时被替换

CMD 
ENV

指定容器的默认环境变量,可以在容器启动时再添加别的环境变量也可以替换原有的环境变量的值

ENV [key]=[value]
ENV [key] [value]
EXPOSE

通知 Docker 容器在运行时侦听指定的网络端口,可以指定tcp或udp协议,如果不指定默认为tcp。

EXPOSE的意义主要在于声明,不添加EXPOSE依然可以建立容器与宿主机的端口映射。

最主要的区别在于如果声明了EXPOSE,并且运行时映射了该端口到宿主机的映射,可以从宿主机直接访问容器端口。

EXPOSE [port]/[protocol]
LABEL

声明镜像的元数据信息。可以用于声明此镜像维护者的信息

LABEL author="henry"

你可能感兴趣的:(docker)