开机自动运行容器
文章目录
一、创建容器
假设我们已经创建好了一个容器,如下图所示,名字为centos7
二、创建服务
为了让容器能够开机自动运行,需要以服务的形式存在。 在/etc/systemd/system/目录,为centos7容器创建一个systemd单元配置文件:
1sudo vim /etc/systemd/system/centos7-container.service
文件内容如下:
1[Unit]
2Description=centos7 container
3After=firewalld.service ufw.service
4
5[Service]
6Restart=always
7ExecStart=/usr/bin/podman start -a centos7
8ExecStop=/usr/bin/podman stop centos7
9
10[Install]
11WantedBy=multi-user.target
需要注意的是ExecStart以及ExecStop命令中的容器名字一定要与要实际的容器名字完全一致
如果容器中有端口需要让外部访问,比如容器中的SSHD服务,需要按照 配置与管理Ubuntu 21.10一文中所述,修改podman网络模式,这样即使开启了防火墙也不会被防火墙屏蔽,同时要求容器服务在防火墙服务之后启动,否则不能访问容器中的端口。
如果是CentOS系统,防火墙服务默认是firewalld,ubuntu系统默认是ufw,笔者是在ubuntu中为了方便使用cockpit管理,同时安装了firewalld服务,所以需要在firewalld以及ufw服务之后。
还有一种更加方便的方式,直接使用podman来生成,我们使用podman generate –help查看用法,可以看到可以生成两种文件:一种是生成Kubernetes的YAML文件,另一种就是生成systemd的单元文件。
1witton@witton:~$ podman generate --help
2Generate structured data based on containers, pods or volumes.
3
4Description:
5 Generate structured data (e.g., Kubernetes YAML or systemd units) based on containers, pods or volumes.
6
7Usage:
8 podman generate [command]
9
10Available Commands:
11 kube Generate Kubernetes YAML from containers, pods or volumes.
12 systemd Generate systemd units.
生成systemd的单元文件,正是我们想要的。再输入podman generate systemd –help查看用法:
1witton@witton:~$ podman generate systemd --help
2Generate systemd units.
3
4Description:
5 Generate systemd units for a pod or container.
6 The generated units can later be controlled via systemctl(1).
7
8Usage:
9 podman generate systemd [options] {CONTAINER|POD}
10
11Examples:
12 podman generate systemd CTR
13 podman generate systemd --new --time 10 CTR
14 podman generate systemd --files --name POD
15
16Options:
17 --container-prefix string Systemd unit name prefix for containers (default "container")
18 -f, --files Generate .service files instead of printing to stdout
19 --format string Print the created units in specified format (json)
20 -n, --name Use container/pod names instead of IDs
21 --new Create a new container instead of starting an existing one
22 --no-header Skip header generation
23 --pod-prefix string Systemd unit name prefix for pods (default "pod")
24 --restart-policy string Systemd restart-policy (default "on-failure")
25 --separator string Systemd unit name separator between name/id and prefix (default "-")
26 -t, --time uint Stop timeout override (default 10)
使用此命令来生成centos7的systemd单元文件:
1sudo podman generate systemd -n centos7
这里只是输出到屏幕,输出内容如下:
1# container-centos7.service
2# autogenerated by Podman 3.2.1
3# Thu Nov 25 06:09:23 UTC 2021
4
5[Unit]
6Description=Podman container-centos7.service
7Documentation=man:podman-generate-systemd(1)
8Wants=network.target
9After=network-online.target
10RequiresMountsFor=/run/containers/storage
11
12[Service]
13Environment=PODMAN_SYSTEMD_UNIT=%n
14Restart=on-failure
15TimeoutStopSec=70
16ExecStart=/usr/bin/podman start centos7
17ExecStop=/usr/bin/podman stop -t 10 centos7
18ExecStopPost=/usr/bin/podman stop -t 10 centos7
19PIDFile=/run/containers/storage/overlay-containers/af476904e658613624d0aefb21e1bad8ae2123008100c7affdab98acec0f1233/userdata/conmon.pid
20Type=forking
21
22[Install]
23WantedBy=multi-user.target default.target
podman命令生成的文件更为全面,建议大家使用此种方式来生成。
三、设置开机自动启动
1sudo systemctl enable centos7-container.service
四、测试服务
1sudo systemctl start centos7-container.service
2sudo systemctl status centos7-container.service
3sudo systemctl stop centos7-container.service
五、开机测试
从图中可以看到开机正常地自动启动容器服务,测试连接容器中的SSH服务
完全正常。
六、测试容器运行中情况下,重启主机
在前文 设置ubuntu和CentOS的IP地址为静态地址中笔者有提到:
如果系统中有podman容器处于开启状态,则在重启ubuntu后会出现找不到网卡,找不到网卡也就没有IP地址,这里需要再次重启ubuntu才能正常。
通过查看日志发现是由于在重启前未能正常卸载/run/netns,在启动中systemd-networkd网络服务未能成功启动,所以找不到网络,无法建立网络连接。
现在将容器设置为服务了,测试一下这种情况还会不会有问题。 经过测试发现完全正常了,不会再出现此问题。
七、使用容器编排的方式作为服务
如果我们需要的容器比较多的情况下,一个一个的去做容器的开机启动服务,相对还是比较麻烦,而且之前创建容器的时候是使用了啥参数,挂载了哪些卷,到后面可能就忘记了或者很容易记错。所以比较好的方式是使用容器编排的方式来启动容器,然后一个服务全部搞定。
比如,编写如下docker-compose.yml文件:
1version: '3'
2services:
3 mysql5.7:
4 image: "192.168.1.8:5051/mysql:5.7"
5 container_name: mysql57
6 restart: always
7 ports:
8 - 3317:3306
9 environment:
10 - MYSQL_ROOT_PASSWORD=123
11
12 volumes:
13 - /home/mysql/5.7/mysql:/var/lib/mysql
14 - /home/mysql/5.7/conf:/etc/mysql
15
16 mysql8.0:
17 image: "192.168.1.8:5051/mysql:8.0"
18 container_name: mysql80
19 restart: always
20 ports:
21 - 3318:3306
22 environment:
23 - MYSQL_ROOT_PASSWORD=123
24
25 volumes:
26 - /home/mysql/8.0/mysql:/var/lib/mysql-files
27 - /home/mysql/8.0/conf:/etc/mysql
28
29 centos6:
30 image: "192.168.1.8:5051/centos6-ssh:v1"
31 container_name: centos6
32 stdin_open: true
33 tty: true
34 ports:
35 - "2022:22"
36
37 centos7:
38 image: "192.168.1.8:5051/centos7-ssh:v1"
39 container_name: centos7
40 stdin_open: true
41 tty: true
42 ports:
43 - "2122:22"
来创建mysql5.7,mysql8.0,centos6,centos7四个容器,我们可以在/etc/systemd/system/创建一个如下内容的containers-compose.service:
1[Unit]
2Description=containers-compose
3After=firewalld.service ufw.service
4
5[Service]
6RemainAfterExit=true
7ExecStart=/usr/local/bin/podman-compose -f /srv/podman-compose/docker-compose.yml up -d
8ExecStop=/usr/local/bin/podman-compose -f /srv/podman-compose/docker-compose.yml stop
9
10[Install]
11WantedBy=multi-user.target
然后使用命令:
1sudo systemctl enable containers-compose.service
设置为开机启动服务即可。
注意: 1、docker-compose.yml中如果要启动带交互的容器,比如Centos,就需要添加
1stdin_open: true
2tty: true
stdin_open相当于podman run中的-i参数,tty相当于-t参数 2、containers-compose.service中使用podman-compose或者docker-compose时,由于执行后会退出,所以需要添加
1RemainAfterExit=true
否则会出现反复启动与关闭或者启动后关闭的问题。
- 原文作者:Witton
- 原文链接:https://wittonbell.github.io/posts/2021/2021-11-25-开机自动运行容器/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。