Docker基本操作

一、基本命令

docker pull nginx 下载docker镜像

docker images 查看目前下载的所有镜像

docker rmi nginx 删除nginx镜像

docker save nginx > /tmp/nginx.tar 保存nginx镜像

docker load < /tmp/nginx.tar 手动载入nginx镜像

docker run -it nginx sh 启动nginx镜像,并进入交互命令(sh)模式 ,run=create + start , -it是你需要交互的时候才用,平时用-d

docker ps 查看正在运行的docker镜像

docker ps -a 查看所有已创建docker镜像(已停止+在正运行)

docker rm -f container_id 删除docker容器

docker container prune 清除所有终止状态的容器

docker inspect names 查看容器的所有信息

docker attach names/container_id 进入容器方式1,大家共用一个tty,会互相影响,不推荐

docker exec -it names/container_id sh 进入容器方式2,拿到不同的tty,推荐,exit退出

nsenter -t $pid -m -i -u -n -p 利用namespace进入容器,方式3,比较复杂,不推荐。

pid = `docker inspect --format "{{.State.Pid}}" $1`
nsenter -t $pid -m -u -i -n -p

docker run -d --name my_nginx nginx 后台方式运行nginx docker, -d

docker logs my_nginx 查看my_nginx的日志

docker logs -f my_nginx 不断刷新的查看my_nginx 日志

docker commit container_name image_name 从改变的容器创建一个新镜像

docker tag image_id docker.io/username/iamge_name 在本地对镜像打一个tag

docker push docker.io/username/image_name 上传本地的镜像到docker hub

docker login
docker images
docker tag image_id docker.io/username/image_name
docker push docker.io/username/image_name

二、网络命令:

1、端口映射:

docker run -d -P --name my_nginx nginx 将容器暴露的端口随机映射到宿主机的端口

docker run -d -p 80:80 --name my_nginx nginx 将docker容器的80端口映射到宿主机的80端口,-p

不做IP绑定,即0.0.0.0

dcoker run -d -p 127.0.0.1:80:80 --name my_nginx nginx 将docker容器的80端口映射到宿主机的80端口,并绑定127.0.0.1

2、docker网络类型:

docker network ls 查看docker可以设置的网络类型

root@langxiaowei-pc:~# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
1fabfe0002bb        bridge              bridge              local
f4400c8b1fe7        host                host                local
cb0a51a6c279        none                null                local

docker run -it --network=bridge alpine sh 指定网络方式为桥接,启动容器,拿到172网段地址

docker run -it --network=host alpine sh 指定网络方式为主机,启动容器,使用主机的所有网卡,没有自己的IP

docker run -it --network=none alpine sh 指定网络方式为none,启动主机,只有本地回环网卡。

3、网络互联:

跨容器网络互联:

旧版:

docker run -d --name web1 -p 80:80 lxwno1/lang_nginx nginx

docker run -d --name web2 --link web1 -p 81:80 lxwno1/lang_nginx nginx

– link 将容器web2 连接到容器web1,即在web2中可以使用ping web1 找到web1,本质是修改了web2的hosts文件,标识web1 在哪里:172.17.0.2 web1 ae63849bb54f。 单方向的连接。

新版:

docker network create -d bridge my-net

docker run -it --rm --name busybox1 --network my-net busybox  sh

docker run -it --rm --name busybox2 --network my-net busybox  sh

ping busybox2
ping busybox1

创建自定义网络连接 my-net(-d 指定网络类型)。

创建容器busybox1和busybox2并加入自定义网络。

再每个容器中,互ping对方,通了。

多容器互联:

推荐使用Docker Compose。

跨主机网络互联:

route add -net 192.168.1.0/24 -gw 10.0.0.157 实现两台不同宿主机的docker直接网络沟通,添加一个路由表就好,网关指向宿主机的网卡IP。

4、数据管理:

数据卷

旧版(-v):

docker run -it -d -v /opt:/opt --name centos2 centos bash

docker run -it -d -v /etc/hosts:/opt/hosts --name centos3 centos bash

docker run -it -d -v /etc/hosts:/opt/hosts:ro --name centos4 centos bash

用 -v 参数,挂在宿主机的目录到容器,完成共享,可以作代码动态加载,-v 宿主机目录:容器目录,

要写绝对路径,而且俩个目录都要写。

新版(–mount):

创建并查看数据卷信息:

docker volume create my-vol

docker volume ls

docker volume inspect my-vol

docker volume rm my-vol

启动一个挂载数据卷的容器:

docker run -it -d --mount source=my-vol,target=/opt --name centos2 centos  bash

挂载一个主机目录作为数据卷(只读):

docker run -it -d --mount type=bind,source=/etc/,target=/opt/,readonly --name centos3 centos bash

挂载一个本地主机文件作为数据卷:

docker run -it -d --mount type=bind,source=$HOME/.bash_history,target=$HOME/.bash_history --name centos4 centos bash

这样就可以将容器中的命令记录在本地。

数据卷容器

docker run -it -d --volumes-from centos3 --name centos6 centos bash

用 –volumes 参数,从另一个容器加载数据卷。

三、Dokcerfile编写

1、文件例子:

Dockerfile文件编写,以自制nginx镜像为例,如下:

#This is a dockerfile for nginx

#base mirror
FROM centos
#maintainer information
MAINTAINER lxw lxwno.1@163.com
# relate command
RUN rpm -ivh https://mirrors.aliyun.com/epel/7/x86_64/Packages/e/epel-release-7-11.noarch.rpm
RUN yum install nginx -y
#add files
ADD index.html /usr/share/nginx/html/index.html
#arguments
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
# expose port
EXPOSE 80
#exec command
CMD ["nginx"]

2、 制作镜像:

dcoekr build -t df_nginx:v1 . 从当前目录的Dockerfile制作镜像,并指定名字和tag。

3、验证并启动:

dcoker images 可以查看刚构建好的docker镜像。

docker -d --name my_nginx df_nginx 启动镜像,注意命令后面不要加command 比如bash,不然bash会取代Dockerfile中写好的CMD命令 nginx,切忌。

dcoker ps -a 查看docker镜像状态

docker exec -it my_nginx bash 进入my_nginx容器

docker inspect my_nginx 查看my_nginx 的IP

curl ip 验证Nginx 启动成功

4、指令详解:

  1. Dockerfile是一行命令创建一层,所以所有命令尽量写入一行 ,通过 &&。要有清除动作。
  2. 每一个 RUN 都是启动一个容器、执行命令、然后提交存储层文件变更。
  3. docker build 可以从Dockerfile、指定压缩包.tar、从标准输入中读取Dockerfile和压缩包,进行构建。
  4. COPY指令用于文件复制,ADD指令在需要自动解压的场合才使用。可配合 –chown=:
  5. 容器内的主进程要以前台方式运行,容器是进程不是虚拟机,没有后台服务的概念。容器的启动程序就是容器内的应用进程(CMD),容器就是为了主进程存在的,主进程退出,容器就没存在的意义了,从而退出。
  6. CMD指令是容器启动命令,推荐格式是列表,例如 CMD ["nginx", "-g", "daemon off;"],可以被docker run中的命令替换。
  7. ENTYRPOINT 入口点指令,其内容可以是脚本可以是命令,用于接收来自CMD的指令当做参数,CMD内容可以来自Dockerfile,也可以来自docker run 中的 cmd。也可以被覆盖,需docker run 的参数 –entrypoint。
  8. ENV设置环境变量,方便其他指令引用。也类似设置全局变量。容器运行的时候,就会有这些环境变量。
  9. ARG构建参数,也是设置环境变量的,但是不会带到容器中去。会被–build-arg 覆盖。类似springboot启动命令对配置文件的选择。
  10. VOLUME 定义匿名卷,容器运行时向此卷写入的数据都不会记录到容器的存储层,从而保证了这个容器的无状态化(就是容器的读写层,原则上也不要写入数据,如果要写,请将宿主机的目录挂载为卷)。VOLUME指令定义的是target目录,是容器内部的目录,source呢,是匿名的,自动生成的,在宿主机的Docker安装目录下,/var/lib/docker/volumes。
  11. EXPOSE 声明端口,仅仅是告诉你我这个进程的守护端口是什么,说明而已,方便你做端口映射有个参考。另外 docker run -P 随机端口映射,会将这个声明的端口映射出去,不然鬼知道他要映射哪个端口。
  12. WORKDIR指定工作目录,改变以后各层的工作目录,类似shell中的cd效果(命令都写在一行才一样)。
  13. USER指定当前用户,改变环境状态并影响以后的层。如果你是用root执行的脚本,但是需要使用某个用户来启动特定进程,用gosu,不要用su、sudo。比如 CMD [ "exec", "gosu", "redis", "redis-server]
  14. HEALTHCHECK 健康检查 ,HEALTHCHECK CMD 设置检查容器健康状况的命令。docker ps 里可以看到,或者 docker inspect 的Health状态。
  15. ONSUILD 为他人做嫁衣 ,后面跟其他指令:RUN COPY等,这些指令不会立即执行,只有在以当前镜像为基础镜像制作新的镜像的时候,才会执行。类似模版吧,方便修改后统一跟新。
  16. 多阶段构建。推荐使用多阶段构建,而不是都写在一个Dokcerfile文件里,或者分散到多个Dockerfile。
  17. 镜像迁移,应该使用Docker Registry ,而不推荐 docker save 和 docker load。SSH传输例子,带进度条: docker save <镜像名> | bzip2 | pv | ssh <用户名>@<主机名> 'cat | docker load'

四、私库搭建

1、准备工作:

docker pull registry 使用docker官方的仓库镜像来做私有仓库

mkdir auth 建立密码文件目录

docker run --entrypoint htpasswd registry:2 -Bbn langxiaowei 123456 > auth/htpasswd 使用registry自带的apache命令htpasswd 命令生成密码文件,以供认证使用。

2、启动Registry:

docker run -d -p 5000:5000 --restart=always --name my_registry \
-v `pwd`/auth:/auth \ 
-e "REGISTRY_AUTH=htpasswd" \ 
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ 
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
registry

registry 默认使用5000端口,挂在密码文件后,设置环境变量-e来启动。

3、登陆并使用:

docker login 10.0.0.157:5000 输入用户名密码登陆私库

dcoker tag container_id 10.0.0.157:5000/user/image 将本地镜像打tag(name:latest)

dcoker push container_id 10.0.0.157:5000/user/image 上传本地镜像到私库

docker pull 10.0.0.157:5000/user/image 从 私库拉取镜像到本地

注意:以上如果不写IP和port,默认拉取官方镜像docker.io

4、报错解决:

登陆的时候,有以下提示:

  1. Error response from daemon: login attempt to http://10.0.0.157:5000/v2/ failed with status: 400 Bad Request 密码文件路径错误,找不到。

  2. Error response from daemon: Get https://10.0.0.157:5000/v2/: http: server gave HTTP response to HTTPS client

    Docker自从1.3.X之后docker registry交互默认使用的是HTTPS,但是搭建私有镜像默认使用的是HTTP服务,所以与私有镜像交时出现以上错误。

    解决办法:

    /lib/systemd/system/docker.service中,ExecStar 后面加入 –insecure-registry ip:5000

    然后重启docker 服务:

    systemctl daemon-reload 
    
    systemctl restart docker
    

五、容器编排(单机)

容器的编排,即容器的依赖启动,这里使用docker-compose 来完成容器的依赖启动,单机情况下。

1、安装:

其是用python编写的,故用pip安装:

apt-get install python-pip
pip install docker-compose

2、使用:

依赖docker-compose.yml文件,故要先编写yml文件。

web1:
        image: nginx
        expose:
                - 80

web2:
        image: nginx
        expose:
                - 80

haproxy:
        image: haproxy
        volumes:
                - /opt/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
        links:
                - web1
                - web2
        ports:
                - "7777:1080"
                - "80:80"

dcoker-compose up 启动编排好的容器

六、配置容器DNS

方法一:

容器默认挂载了宿主机的三个文件/etc/hosts, /etc/hostname, /etc/resolv.conf 使用宿主机的DNS解析。

方法二:

修改docker守护进程的配置文件/etc/docker/daemon.json,加入

"dns": ["114.114.114.114","223.5.5.5"]

###方法三:

docker run 命令行加入参数 -h –dns


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 lxwno.1@163.com

×

喜欢就点赞,疼爱就打赏