skills_docker
- skills_docker
- 1 Docker容器暴露多个端口方法
- 2 docker容器内的mysql使用
- 3 配置docker容器和宿主机在同一个局域网,并使用静态IP
- 4 容器的bridge网络 == vmware的NAT模式
- 5 Ubuntu上安装微信和qq
- 6 普通用户如何获取运行docker命令的权限
- 7 添加docker权限给当前用户,使docker命令免sudo
- 8 docker的ubuntu官方最新镜像版本为20.04.3
- 9 Dockerfile的 ENV 命令注意
- 10 Dockerfile的 VOLUME 命令注意
- 11 Dockerfile的 EXPOSE 命令注意
- 12 Dockerfile的 COPY & ADD 命令注意
- 13 Dockerfile的 RUN 命令注意
- 14 Dockerfile的 CMD & ENTRYPOINT 命令注意
- 15 如何使用root账户ssh到docker的linux镜像
- 16
- 17
- 18
skills_docker
1 Docker容器暴露多个端口方法
- 创建容器时指定
docker run -p [HOST_IP]:[HOST_PORT]:CONTAINER_PORT -p [HOST_IP]:[HOST_PORT]:CONTAINER_PORT
多写几个 -p参数即可。 - 修改Dockerfile expose所需要的端口,这样可以免去-p参数。
2 docker容器内的mysql使用
拉取mysql镜像:docker pull mysql:5.7
创建容器:docker run -d --name node7 -e MYSQL_ROOT_PASSWORD=root -p :33060:3306 --hostname node7 -v /usr/apps/:/usr/apps/ mysql:5.7
-d 标识是让 docker 容器在后台运行。
-p 标识通知 Docker 将容器内部使用的网络端口映射到我们使用的主机上。
–name 定义一个容器的名字,如果在执行docker run时没有指定Name,那么deamon会自动生成一个随机数字符串当做UUID。
-e 设置环境变量,或者覆盖已存在的环境变量
3306:3306 将容器的3306端口映射到本机的3306端口
查看运行的容器:docker ps -a
进入容器:docker exec -it 容器ID|容器NAME bash
如 docker exec -it node7 bash
连接:mysql -u root -p root
3 配置docker容器和宿主机在同一个局域网,并使用静态IP
背景:容器中无法像物理机或vmware虚拟机一样设置静态IP。
方法一、使用自定义网络
一开始想着在docker run中简单设置下参数network和ip,没想到报错
root@asus:~# docker run -dti --name node10 --hostname node10 --network bridge --ip 172.17.0.123 -p :9011:80 -v /usr/apps/:/usr/apps/ centos8-nginx-custom:v2.0 /sbin/init
48810a7b2c544dcee8168f15b9fe1d77e5a9966cd2026c505fab22859a21e213
docker: Error response from daemon: user specified IP address is supported on user defined networks only.
# 意思是,用户指定的IP地址仅仅被用户自定义的网络支持
而如果不加network参数,仅仅添加IP参数,能创建成功容器,但是没用,IP还是容器自动分配。
于是打算新建network,然后用自定义的network来创建容器,以下是我做的3个测试:
docker network create -d bridge --subnet=192.168.9.0/24 --gateway=192.168.9.1 -o parent=enp2s0 bridge2
docker run -dti --name node60 --hostname node60 --privileged=true --network bridge2 --ip 192.168.9.9 -v /usr/apps/:/usr/apps/ centos8-nginx-custom:v6.0 /sbin/init
ifconfig,确定其IP为192.168.9.9
ping 192.168.9.1 能ping通
ping 192.168.6.6 能ping通
ping baidul.com 能ping通
小结:该方法可行。
docker network create -d bridge --subnet=192.168.10.0/24 --gateway=192.168.10.1 bridge3
docker run -dti --name node61 --hostname node61 --privileged=true --network bridge3 --ip 192.168.10.9 -v /usr/apps/:/usr/apps/ centos8-nginx-custom:v6.0 /sbin/init
ifconfig,确定其IP为192.168.10.9
ping 192.168.10.1 能ping通
ping 192.168.6.6 能ping通
ping 192.168.6.16 能ping通
ping baidu.com 能ping通
小结:该方法可行,可以去掉-o参数(-o参数也是参照了网上的方法)。
docker network create -d bridge --subnet=192.168.6.0/24 --gateway=192.168.6.1 bridge4
docker run -dti --name node62 --hostname node62 --privileged=true --network bridge4 --ip 192.168.6.9 -v /usr/apps/:/usr/apps/ centos8-nginx-custom:v6.0 /sbin/init
ifconfig,确定其IP为192.168.6.9
ping 192.168.6.1 能ping通
ping 192.168.6.6 能ping通
ping 192.168.6.16 ping不通
ping baidu.com 能ping通
小结:该方法有缺陷,设置和宿主机同一个网段后,宿主机和容器无法ping通局域网的其他机器了,所以创建的网络,不要和宿主机同一个网段。
# 另外,要注意:如果创建network时,不添加 --subnet 参数,以后利用该网络创建容器时会报另一个错:
docker: Error response from daemon: user specified IP address is supported only when connecting to networks with user configured subnets.
# 意思是,利用自定义的网络创建容器时,如果要指定IP,则还需要自定义的网络中指定子网。
方法二、利用pipework
wget https://github.com/jpetazzo/pipework/archive/master.zip # 下载pipework
unzip pipework-master.zip
cp pipework-master/pipework /usr/local/bin/
chmod +x /usr/local/bin/pipework
docker run -dti --name test --net=none centos bash # 创建none模式的容器
pipework docker0 test 172.17.0.17/16@172.17.0.1 # 为其分配IP
注意:pipework分配IP后,容器重启后该IP消失,需要重新分配一次。
参考链接:https://www.jb51.net/article/113672.htm
该链接中的内容没有全部看完,因为感觉后半部分内容比较复杂,先放一放,还因为看完前半部分,我倒是有了新发现,并且结合前半部分内容能解决问题了。不一定非要将容器绑定到宿主机所在物理网段了。
方法三、设置网卡IP别名(网卡的副IP,一张网卡可以设置多个IP别名)
宿主机的docker0虚拟网卡可以和所有的容器直接通信!docker0相当于是所有容器的网关。
那么,可以在宿主机上设置IP别名(一个网卡有多个IP),实测下来,容器可以和主机以及外网通信。
# 设置开机自动创建IP别名
vim /etc/rc.local
# 在rc.local文件中添加以下2行语句,
ifconfig eth0:1 172.17.0.225 broadcast 172.17.255.255 netmask 255.255.0.0 up
route add -host 172.17.0.225 dev eth0:1
方法四、修改网卡IP(主IP)
修改网卡IP(ifconfig eth0 172.17.0.225)。
实测下来,如果将修改IP语句放到/etc/rc.local中,实现开机自动修改,则容器无法和主机以及外网通信; 登录容器后,手动修改ip,则可以和主机以及外网通信。
4 容器的bridge网络 == vmware的NAT模式
容器的bridge网络,可以访问到整个局域网的主机,和vmware的NAT模式基本相同。
eg. asus上的容器nfs客户端,能mount到lenovo实体机上的nfs服务端共享文件夹。
5 Ubuntu上安装微信和qq
1.1 主要用的是以下两个GitHub项目
https://github.com/bestwu/docker-wechat
https://github.com/bestwu/docker-qq
1.2 首先要允许所有用户访问X11服务,运行命令:
xhost +
1.3 下载微信镜像
docker pull bestwu/wechat
1.4 运行微信
docker run -d --name wechat --device /dev/snd --ipc=host \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v $HOME/WeChatFiles:/WeChatFiles \
-e DISPLAY=unix$DISPLAY \
-e XMODIFIERS=@im=ibus \
-e QT_IM_MODULE=ibus \
-e GTK_IM_MODULE=ibus \
-e AUDIO_GID=`getent group audio | cut -d: -f3` \
-e GID=`id -g` \
-e UID=`id -u` \
bestwu/wechat
运行这个wechat容器后,会跳出登录界面,扫描登录就行了
注:上面的多行代码也可以写到一个 wechat.sh 脚本,以便下次直接使用。
1.5 下载qq镜像
docker pull bestwu/qq
1.6 运行qq
docker run -d --name qq \
--device /dev/snd --ipc=host \
-v $HOME/TencentFiles:/TencentFiles \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e XMODIFIERS=@im=ibus \
-e QT_IM_MODULE=ibus \
-e GTK_IM_MODULE=ibus \
-e DISPLAY=unix$DISPLAY \
-e AUDIO_GID=`getent group audio | cut -d: -f3` \
-e VIDEO_GID=`getent group video | cut -d: -f3` \
-e GID=`id -g` \
-e UID=`id -u` \
bestwu/qq:latest
同样的运行这个qq容器后,会跳出登录界面,登录就行了
1.7 可能出现的问题
1.7.1 闪退问题
可能是因为你docker run的时候忘记加上 –ipc=host 了,官方给的运行代码是没有这个参数的,所以会出现闪退的情况,我也是被坑了很久。
我后来是看了这个issues才解决这个问题的。
1.7.2 微信无法输入中文问题
我看到有些人抱怨无法输入中文,这个其实是可以配置的,如果你ubuntu用的是ibus输入法,则直接用我上面的运行代码即可,如果是fcitx输入法,则把docker run时的代码里的ibus全部改成fcitx就行了。
1.7.3 保存聊天文件的问题
聊天文件实际上是保存在wechat容器中用户文件夹中,但是我们在docker run的时候已经把路径挂载出来了。所以你可以在 WeChatFiles 里面找到这个文件。不过我更推荐你另存为到指定目录,如在挂载目录WechatFiles中创建一个files文件夹,专门用来保存文件。
1.7.4 如何重新打开微信或qq
docker stop wechat
docker start wechat
docker stop qq
docker start qq
原文链接:https://blog.csdn.net/qq_43827595/article/details/109487664
6 普通用户如何获取运行docker命令的权限
# 加入docker组
# 添加用户到某一个组可以使用
usermod -G group_name user_name
# 这个命令可以添加一个用户到指定的组,但是以前添加的组就会清空掉。
# 所以想要添加一个用户到一个组,同时保留以前添加的组时,请使用 gpasswd 这个命令来添加操作用户
gpasswd -a user_name group_name
7 添加docker权限给当前用户,使docker命令免sudo
-
如果还没有 docker group 就添加一个:
sudo groupadd docker -
将用户加入该 group 内。然后退出并重新登录就生效啦。
sudo gpasswd -a ${USER} docker -
重启 docker 服务
sudo service docker restart 或 sudo systemctl restart docker -
切换当前会话到新 group 或者重启 X 会话
newgrp docker 或者 pkill X
注意,最后一步是必须的,否则因为 groups 命令获取到的是缓存的组信息,刚添加的组信息未能生效,所以 docker images 执行时同样有错。
来源:https://www.cnblogs.com/codeaaa/p/9041533.html
8 docker的ubuntu官方最新镜像版本为20.04.3
当前日期为2021-12-11日
root@692cf532ed29:/# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.3 LTS"
9 Dockerfile的 ENV 命令注意
# 用于设置环境变量
# 如果没有ENV,则需要这么写,很不优雅
RUN echo -e 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile \
&& source /etc/profile
# ENV command. we can use both whitespace and equal sign
ENV JAVA_HOME /develop/jdk1.8.0_291
ENV INVENTORYS_HOME=/develop/inventorys
ENV PATH $JAVA_HOME/bin:$INVENTORYS_HOME:$PATH
10 Dockerfile的 VOLUME 命令注意
# define the anonymous volume. 在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。
# 这样,如果在启动容器时忘记挂载数据卷,还可以自动挂载到匿名卷
# 匿名卷默认路径:/var/lib/docker/volumes/100336405af9040827d83e681fc0ae9770d3098b88bbee8fc27cf2110470147e/_data/
VOLUME $SENTINEL_HOME/logs/
11 Dockerfile的 EXPOSE 命令注意
作用:直接作用是配置目标端口。让docker维护人员一看就知道系统内部需要暴露的端口是什么,主要作用是为了规范。
其次,容器启动时,添加 -P 参数,则会随机分配一个端口映射到目标端口;如果添加 -p 参数,则分配一个指定端口映射到目标端口;但是如果不添加-p 和 -P参数,则容器将不会有端口映射到外部!
12 Dockerfile的 COPY & ADD 命令注意
# COPY命令用于复制外部的文件到镜像中,但不会自动解压缩
COPY application.properties $NACOS_HOME/conf
# COPY命令另外尤其要注意的一点是,它可以拷贝文件夹以及文件夹内部的所有内容,但是拷贝到的目标路径一定要是下面的写法
# 因为COPY拷贝的是 agent/文件夹下的所有内容,不包括agent文件夹本身,所有目标路径应该写为$ORDERS_HOME/agent/,
# 表示把agent/目录下的所有内容拷贝到 $ORDERS_HOME/agent/目录下,其中如果$ORDERS_HOME/agent/不存在,会自动创建
COPY agent/ $ORDERS_HOME/agent/
# ADD 命令 用于添加并自动解压缩 **压缩文件** 到 镜像中
ADD jdk-8u291-linux-x64.tar.gz /develop/
# 如果没有 ADD,则需要如下写法,不优雅,而且还报错了
RUN tar -zxvf /app/jdk-8u291-linux-x64.tar.gz -C /develop \ # error occurs: tar (child): /app/jdk-8u291-linux-x64.tar.gz: Cannot open: Not a directory
13 Dockerfile的 RUN 命令注意
# RUN 命令 用于在镜像构建(build)时执行命令,执行结果产生的文件或对虚拟机造成的变化,被永久保存到镜像中
RUN yum install iproute nginx && yum clean all
14 Dockerfile的 CMD & ENTRYPOINT 命令注意
# CMD 和 ENTRYPOINT 命令都是执行命令的
# 两者都类似于 RUN 指令,用于运行程序,但二者和 RUN 运行的时间点不同;CMD和ENTRYPOINT 在docker run 时运行,而非docker build
CMD "startup.sh -m standalone"
CMD ["startup.sh", "-m", "standalone"]
ENTRYPOINT ["startup.sh", "-m"]
CMD ["standalone"] # 指定ENTRYPOINT所运行的命令的参数
15 如何使用root账户ssh到docker的linux镜像
docker exec
中使用 -u
参数,例如:docker exec -u 0 -it container-nexus bash
。
-u 0
,表示用 ID=0
的账户登录,也就是root账户登录。