skills_docker

skills_docker

1 Docker容器暴露多个端口方法

  1. 创建容器时指定
    docker run -p [HOST_IP]:[HOST_PORT]:CONTAINER_PORT -p [HOST_IP]:[HOST_PORT]:CONTAINER_PORT
    多写几个 -p参数即可。
  2. 修改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

  1. 如果还没有 docker group 就添加一个:
    sudo groupadd docker

  2. 将用户加入该 group 内。然后退出并重新登录就生效啦。
    sudo gpasswd -a ${USER} docker

  3. 重启 docker 服务
    sudo service docker restart 或 sudo systemctl restart docker

  4. 切换当前会话到新 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账户登录。

16

17

18

posted @ 2021-08-16 02:33  mediocrep  阅读(145)  评论(0编辑  收藏  举报
既然选择了远方,便只顾风雨兼程!