标签 docker 下的文章

问题
工作中经常发现一些第三方写的docker容器运行有问题,这时我们会通过docker logs命令观察容器的运行日志。很可惜,有时容器中运行的程序仅从日志很难查明问题。这时我们会通过docker exec在目标容器中执行某些命令以探查问题,有时却发现一些镜像很精简,连基本的sh、bash、netstat等命令都没包含。这时就很尴尬了,诊断问题很困难。

docker-debug工具,这个工具的使用方法也很简单,参考以下命令:

# Suppose the container below is a container which should be checked
docker run -d --name dev -p 8000:80 nginx:latest
# Enter a shell where we can access the above container's namespaces (ipc, pid, network, etc, filesystem)
docker-debug dev bash -l

docker-debug的实现原理
简单说执行docker-debug命令也会使用一个包含了常用诊断命令的镜像启动一个诊断容器,该诊断容器将在目标容器相关的命名空间中运行,这样在这个容器中就可以访问目标容器的ipc, pid, network, etc, filesystem,然后使用docker exec命令在诊断容器运行命令,并将docker exec运行命令的输入输出pipe到docker-debug命令的输入输出上。

另外,还发现类似的工具kube-debug,以后诊断pod中的问题方便多了。

前言
为了获得最佳的性能和可移植性,应该避免将重要数据直接写入容器的可写层,而应使用数据卷或绑定挂载。

可以为集群中的服务创建两种类型的挂载,数据卷挂载(volume mounts)或绑定挂载(bind mounts)。

无论使用哪种类型的挂载,在创建服务时使用 --mount 标志进行配置,或者在更新服务时使用 --mount-add 或 --mount-rm 标志。如果不指定一个类型,默认类型是数据卷挂载。

注:tmpfs mount 仅可用于独立容器,不能在 Docker Swarm Service 中使用,故此处不介绍。

一、数据卷挂载
数据卷是在主机上的持久化存储,即使容器删除,也不会影响数据卷。

使用 docker volume create 命令创建一个volume:

docker volume create --name cwxvolume

使用 docker volume ls 命令查看volume列表:

docker volume ls

创建服务时使用创建好的volume挂载目录:

#参数src写成source也可以;dst表示容器内的路径,也可以写成destination
docker service create --name masl -e TZ="Asia/Shanghai" --network mrp_net --mount type=volume,src=cwxvolume,dst=/home/mppay/logs/masl --replicas 2 -p 8081:8080 172.16.99.2:40305/masl:dev-yc-34

使用 docker service ps 命令查看服务情况:

docker service ps masl

发现分别在 manager-node 和 node1 节点上都创建了 masl 任务。

登陆 manager-node 服务器,使用 docker ps -a 命令查看容器运行情况:

docker ps -a

再使用 docker exec 进入容器:

docker exec -ti f820be6cf958 /bin/bash

发现,在容器内部的 /home/mppay/logs/masl 目录下有一个 masl.log文件,然后输入exit命令退出容器。

使用 docker volume inspect 命令查看挂载详细信息

docker volume inspect cwxvolume

进入上面指定的目录:

cd /var/lib/docker/volumes/cwxvolume/_data
ls

发现宿主机上也有这个文件。

二、绑定挂载
绑定挂载是调度程序为该任务部署容器时主机的文件系统路径,Docker 将路径挂载到容器中。在 Swarm 为任务初始化容器之前,该文件系统路径必须存在。

使用以下命令创建服务:

docker service create --name masl -e TZ="Asia/Shanghai" --network mrp_net --mount type=bind,source=/usr/local/tomcal_masl/logs,destination=/home/mppay/logs/masl --replicas 2 -p 8081:8080 172.16.99.2:40305/masl:dev-yc-34

其中,参数destination表示容器里面的路径,source表示本地硬盘路径

重要:虽然绑定挂载能用,但是也有可能导致一些问题:

1) 如果你挂载了一个主机路径到你的服务容器中,那么这个路径必须存在于 Swarm 集群中的每一个节点。Docker Swarm 调度器会把容器调度到任何满足资源可用性和满足你特定约束、位置偏好的节点上。

2) 如果运行中的容器变得不健康或者不可用,那么 Docker Swarm 调度器可能会随时重新安排它。

3) 主机绑定挂载是完全不可移植的。当你使用绑定挂载时,不能保证你的应用在开发中的运行方式与在生产中的运行方式相同。

总结
1) 挂载volume后,宿主机和容器之间就可以通过volume进行双向实时同步.

2) 如果replicas是多份,则每个节点宿主机上都会有一个volume路径,即每个节点宿主机的/var/lib/docker/volumes/cwxvolume/_data和分布到它上面的容器里的/home/mppay/logs/masl进行实时同步.

3)在容器里的同步目录下没有写权限,更新内容时只要放到宿主机的挂在目录下即可。

准备环境:
三台主机(centos7):docker version:12版本以上。

node01:172.16.1.30
node02:172.16.1.31
node03:172.16.1.32

(1)首先修改主机名:

[root@sqm-docker01 ~]# hostnamectl set-hostname node01
[root@sqm-docker01 ~]# hostnamectl set-hostname node02
[root@sqm-docker01 ~]# hostnamectl set-hostname node03

(2)三台主机分别配置域名解析:[root@node01 ~]# vim /etc/hosts
(3)设置免密登录://一直默认回车,生成密钥:
//将密钥拷贝给node02和node03:

[root@node01 ~]# ssh-copy-id  node02
[root@node01 ~]# ssh-copy-id  node03

//有了免密登录,将host域名解析文件拷贝给其他两个节点:

[root@node01 ~]# scp /etc/hosts  root@172.16.1.31:/etc/hosts
[root@node01 ~]# scp /etc/hosts  root@172.16.1.32:/etc/hosts

项目操作:
1)初始化集群:
指定当前主机为集群的创建者(leader)

2)既然在初始化集群时,已经提示加入集群的命令(将其复制),所以接下来将node02和node03主机加入到该集群:

//查看节点是否加入到集群中:提示:这步操作只有manager才有权限查看。

*####如果其他节点需要加入到该集群中,并且需要指定身份,当你忘掉初始化集群时生成的命令时,可以执行以下命进行查看命令:注意:只有manager端才有权限进行查看。

查看以worker端加入这个集群

[root@sqm-docker01 ~]# docker swarm join-token worker

查看以manager的身份加入这个集群

[root@sqm-docker01 ~]# docker swarm join-token manager

(3)配置web Ui界面:

拉取镜像:用的是本地的镜像包,所以直接导入:

[root@node01 ~]# docker load --input myvisualizer.tar

运行服务:

[root@node01 ~]# docker run -d -p 8000:8080 -e HOST=172.16.1.30 -e PORT=8080 -v /var/run/docker.sock:/var/run/docker.sock  --name visualizer  dockersamples/visualizer

HOST指定地址为本机地址

访问web网页界面:URL:http://172.16.1.30:8000/

可以看到集群中的三个节点。

(4)搭建swarm集群网络(overlay网络)
还记得在之前搭建overlay的博文中,在搭建overlay网络时需要先部署consul(数据中心),但现在是在swarm集群的环境中,默认自带consul服务的功能,所以可以在直接创建overlay网络。

创建overlay网络:

[root@node01 ~]# docker network  create -d overlay --attachable  docker

注意:在创建overlay网络时,如果没有加上--attachable,那么此网络不可以应用于容器上。

在node01和node02之上分别运行一个容器,测试是否能够正常通信:

[root@node01 ~]# docker run -itd --name test1 --network docker busybox
[root@node02 ~]# docker run -itd --name test2 --network docker busybox
[root@node01 ~]# docker exec testl ping test2

(5)搭建私有仓库(共享镜像)
搭建私有仓库的目的是为了能够在一个集群中大家共用私有仓库中的镜像,能够很方便的部署服务,并且在公司中为了安全考虑,大多都是部署自己的私有仓库。

//以官方的registry镜像进行部署:

[root@node01 ~]# docker run -d --name registry --restart=always -p 5000:5000 registry:latest

//修改docker配置文件:

[root@node01 ~]# vim /usr/lib/systemd/system/docker.service

修改内容如下:

ExecStart=/usr/bin/dockerd -H unix:// --insecure-registry 192.168.1.65:5000

//重启docker服务:

[root@sqm-docker01 ~]# systemctl daemon-reload
[root@sqm-docker01 ~]# systemctl restart docker.service

//直接将配置文件拷贝给node02和node03

[root@sqm-docker01 ~]# scp /usr/lib/systemd/system/docker.service  node02:/usr/lib/systemd/system/docker.service
[root@sqm-docker01 ~]# scp /usr/lib/systemd/system/docker.service  node03:/usr/lib/systemd/system/docker.service

拷贝过去后,需要在node02和node03重载进程并且重启docker服务。

部署完私有仓库,我们最好测试一下:

在node01上将apache镜像上传到私有仓库中:

[root@node01 ~]# docker tag httpd:latest  172.16.1.30:5000/myhttpd
[root@node01 ~]# docker push 172.16.1.30:5000/myhttpd

在其他节点上进行拉取:

[root@node02 ~]# docker pull 172.16.1.30:5000/myhttpd
[root@node03 ~]# docker pull 172.16.1.30:5000/myhttpd

(6)docker swarm集群配置service服务

发布任务,并且创建副本数量为2

[root@node01 ~]# docker service create  --replicas 2 --name web01 -p 80:80 172.16.1.30:5000/myhttpd:latest

--replicas:副本,可以基于该副本进行复制。--replicas 1表示只需要一个容器。
-p 可以写成以下形式,以使用mode=host模式,在每一个节点暴露端口给主机,不走swarm路由网络
--publish published=53,target=53,protocol=udp,mode=host \

//查看服务:

[root@node01 ~]# docker service  ls

查看服务运行在集群中的哪个节点之上:
除了通过命令行的方式进行查看service的各种信息,还可以通过web网页进行查看:

发布第二个服务:

[root@node01 ~]# docker service create --replicas 4 --name web02 -p 80 172.16.1.30:5000/myhttpd

#随机生成端口, 可以看到依然会均衡的分布在每个节点。

(7)service服务的扩容与缩容:
实现扩容和缩容的原因很明确,缩容是当某一个节点压力过大,或者是服务器配置不足以承受所运行的服务,需要减少容器,以保证稳定运行,扩容呢?是当 某个节点的服务器处于闲置的状态下,多给分配几个服务运行,也是不影响的。

1)扩容:

[root@node01 ~]# docker service  scale web01=6

在web网页进行查看:

2)缩容:

[root@node01 ~]# docker service  scale web02=1

在web网页上进行查看:

(8)设置manager不参加工作:
在一个集群中,最好的状态是指定manager节点不参加工作,让node节点进行工作,好比是在一个公司中,老板是不可能工作的是吧,一般会去让员工进行工作。

指定manager节点不参加工作:

[root@node01 ~]# docker node update  --availability drain  node01

从上图可以看到,manager已经不参加工作,所以运行的容器默认已经工作在node01和node02上。

(9)指定副本运行节点位置:
如果有需求,需要将发布的所以服务运行在同一台服务器上,该怎么实现呢?方法一:

1)定义标签:

[root@node01 ~]# docker node update  --label-add disk=max node03

##将标签定义到节点3上
2)发布服务:

[root@node01 ~]# docker service  create  --name test --replicas 5 -p 80 --constraint 'node.labels.disk==max'  172.16.1.30:5000/myhttpd

查看是否指定成功:

方法二:直接指定节点主机名。

[root@node01 ~]# docker service create --replicas 5 --name testname --constraint 'node.hostname==node02' -p 80 172.16.1.30:5000/myhttpd

service服务的更新&回滚:
1,服务的更新:
将以上服务(test)更新为2.0版本。

[root@node01 ~]# docker tag 172.16.1.30:5000/myhttpd:latest 172.16.1.30:5000/myhttpd:v2.0
[root@node01 ~]# docker push 172.16.1.30:5000/myhttpd:v2.0
[root@node01 ~]# docker service update --image 172.16.1.30:5000/myhttpd:v2.0 test

注意:当服务的版本升级了,它原来的版本依然会进行保留的。

2,服务自定义更新:
将以上服务进行更新为3.0版本。

[root@node01 ~]# docker tag 172.16.1.30:5000/myhttpd:v2.0 172.16.1.30:5000/myhttpd:v3.0
[root@node01 ~]# docker push 172.16.1.30:5000/myhttpd:v3.0
[root@node01 ~]# docker service update --image 172.16.1.30:5000/myhttpd:v3.0 --update-parallelism 2 --update-delay 1m test

参数解释:--update-parallelism 2 :设置并行(同时)更新的副本数。--update-delay 1m(m(分钟 s(秒) h (小时)d(天) w(星期)):指定滚动更新的时间间隔。

3,服务的回滚操作:
当我们执行回滚操作时,默认是回滚到上一次操作的版本,只能在前后两个版本之间进行回滚,不能连续回滚。

[root@node01 ~]# docker service update --rollback test

登陆web网页更直观的进行查看:

回滚成功。。。

测试再次回滚,它会回滚到哪个版本呢?

[root@node01 ~]# docker service  update --rollback test

可以看到它会回滚到第一次回滚前的一个版本。证明是不可以连续回滚的。

原文链接:https://www.huaweicloud.com/articles/f3a99702d06510a0135c41fc8ce7ef7f.html
docker registry 镜像删除:https://www.huaweicloud.com/articles/5e70b8948cadd126f84f88f5a9e6acc6.html

原文: https://www.dadclab.com/archives/7638.jiecao

1. 创建通过systemd配置docker服务的文件夹

mkdir /etc/systemd/system/docker.service.d

2. 创建服务配置文件

vim /etc/systemd/system/docker.service.d/http-proxy.conf

并将以下内容写入文件之中(根据你的实际情况,修改上述文件内容之中的代理信息)。

[Service]
 # NO_PROXY is optional and can be removed if not needed
 # Change proxy_url to your proxy IP or FQDN and proxy_port to your proxy port
 # For Proxy server which require username and password authentication, just add the proper username and password to the URL. (see example below)

 # Example without authentication
 Environment="HTTP_PROXY=http://proxy_url:proxy_port" "NO_PROXY=localhost,127.0.0.0/8"

 # Example with authentication
 Environment="HTTP_PROXY=http://username:password@proxy_url:proxy_port" "NO_PROXY=localhost,127.0.0.0/8"

3. 生效
使用如下命令重新加载systemctl, 验证服务环境变量并重启Docker服务。

# 重新加载systemctl 
systemctl daemon-reload
# 验证配置
systemctl show docker --property Environment
# 重启服务
system restart docker

怎么进入 docker 正在运行的容器
docker exec -it 775c7c9ee1e1 /bin/bash

说明:
-i 交互式
-t 打开一个TTY终端来显示交互的内容

775c7c9ee1e1 容器的ID 可以用 docker ps 来查看运行中的容器
/bin/bash 执行这个命令

怎么重命名docker容器名
docker rename old容器名 new容器名

怎么杀死所有正在运行的容器
docker kill $(docker ps -a -q)

怎么删除所有已经停止的容器
docker rm $(docker ps -a -q)

怎么删除所有未打 dangling 标签的镜像
docker rmi $(docker images -q -f dangling=true)

怎么删除所有镜像
docker rmi $(docker images -q)

怎么强制删除镜像名称中包含“doss-api”的镜像
docker rmi --force $(docker images | grep doss-api | awk '{print $3}')