快速构建实验环境的基础服务 | Word Count: 2.7k | Reading Time: 12mins | Post Views:
在单机试验环境中,经常需要配置DNS解析、生成SSL证书、保存或者拉取配置脚本,这些操作往往散布到各个节点的实际操作中,较为繁琐且容易出错,所以创建一个虚机镜像来提供统一的服务就是有需求的。以下就是通过在VM上部署实现相关功能的操作实践。
类别
内容
功能
基础架构服务
主机名
infra.contoso.com
IP
192.168.10.254
配置
2core 2G mem 40GB disk
承载服务
DNS以及DNS缓存、时间服务、SSL证书生成和下载、git服务、导航页、Ansible控制台、主机管理
包管理安装 主机准备 基础环境准备 主机环境的准备执行准备:RockyLinux9的主机部署
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 # 系统更新 dnf makecache dnf update -y # 由于主机模板只给了20G硬盘,所以需要扩容 dnf install cloud-utils-growpart-0.33-1.el9.x86_64 growpart /dev/sda 2 lvextend -l +100%free /dev/rl/root xfs_growfs /dev/rl/root # 为后续Gitea修改本地SSH端口为2022端口 echo "127.0.0.1 infra infra.contoso.com" >> /etc/hosts sed -e 's|#Port 22|Port 2022|g' -i.bak /etc/ssh/sshd_config # 开启新的防火墙端口 firewall-cmd --permanent --add-port=2022/tcp firewall-cmd --reload systemctl restart sshd systemctl status sshd --no-pager # 为后续使用创建文件夹 mkdir -p /data/{public,registry} # 增加github的解析地址 sh -c 'sed -i "/# GitHub520 Host Start/Q" /etc/hosts && curl https://raw.hellogithub.com/hosts >> /etc/hosts'
时间服务器 部署 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # 安装时间同步服务器 dnf install -y chrony systemctl enable --now chronyd # 设置时区为亚洲/上海 timedatectl set-timezone Asia/Shanghai # 添加阿里云NTP服务器 cat >> /etc/chronyd.conf <<EOF pool time.pool.aliyun.com iburst pool cn.pool.ntp.org iburst allow 192.168.0.0/16 EOF # 重启服务 systemctl restart chronyd systemctl status chronyd --no-pager # 开启防火墙 firewall-cmd --permanent --add-service=ntp firewall-cmd --reload
校验 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [root@Infra ~]# timedatectl status Local time: Tue 2023-10-24 16:58:52 CST Universal time: Tue 2023-10-24 08:58:52 UTC RTC time: Tue 2023-10-24 08:58:53 Time zone: Asia/Shanghai (CST, +0800) System clock synchronized: yes NTP service: active RTC in local TZ: no [root@Infra ~]# chronyc sources MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^? tick.ntp.infomaniak.ch 1 6 3 2 -14ms[ -14ms] +/- 88ms ^? tock.ntp.infomaniak.ch 1 6 1 4 +41ms[ +41ms] +/- 144ms ^? time.neu.edu.cn 1 6 7 1 +209us[ +209us] +/- 9831us ^? ntp6.flashdance.cx 2 6 3 2 -37ms[ -37ms] +/- 143ms
管理面板 为方便管理,我们启用系统自带的cockpit管理界面来对系统进行维护。
部署 1 2 3 4 dnf install -y cockpit-session-recording cockpit-system dnf install -y cockpit-navigator cockpit-pcp dnf install -y cockpit-bridge cockpit-file-sharing systemctl enable cockpit.socket --now
使用
Ansible Cli控制节点 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 # 安装 dnf install -y ansible # 创建目录 mkdir -p ~/ansible/{palybook,files,tmp,log} # 配置文件 cat > ~/ansible/ansible.cfg <<EOF [defaults] inventory = ./inventory remote_tmp = ~/.ansible/tmp local_tmp = ~/.ansible/tmp log_path = ~/.ansible/log/ansible.log forks = 5 poll_interval = 15 transport = smart host_key_checking = False [privilege_escalation] become = True become_method = sudo become_user = root EOF # 创建主机文件,配置简略 cat > ~/ansible/inventory <<EOF [Hosts] infra [Base] [K3s] kmaster[1:2] node[1:2] [K8s] node1 node2 EOF # 校验 cd ~/ansible/ ansible --version
内外网解析DNS 为了在后续安装部署和Lab环境测试,这里安装部署bind9来作为内部环境的DNS解析服务。同时,后续部署还需要访问外部环境,为了环境隔离和加速DNS的解析服务,一并部署Dnsmasq作为外部环境的解析缓存。使用内部域名时,解析跳转到bind9,非内部域名则跳转阿里云的公共DNS。
Bind部署 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 # 安装 dnf install -y bind bind-utils systemctl enable --now named # 添加解析文件 cat > /var/named/contoso.com.hosts <<EOF $ ttl 3600 $ ORIGIN contoso.com. @ IN SOA Infra. sujx.live.cn. ( 2023102502 3600 600 1209600 3600 ) contoso.com. IN NS Infra. git IN A 192.168.10.254 home IN A 192.168.10.254 pub IN A 192.168.10.254 infra IN A 192.168.10.254 dev IN A 192.168.10.100 EOF # 添加相关zone配置 cat >> vim /etc/named.rfc1912.zones <<EOF zone "contoso.com" IN { type master; file "contoso.com.hosts"; }; EOF # 重新加载并校验结果 named-checkconf named-checkzone "contoso.com" /var/named/contoso.com.hosts rndc reload dig git.contoso.com @127.0.0.1 # 配置服务端口为本机10053 sed -e 's|port 53|port 10053|g' -i.bak /etc/named.conf systemctl restart named systemctl status --no-pager named
Dnsmasq部署 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 # 安装 dnf install -y dnsmasq # 配置转发上游的公共DNS以及contoso.com的解析为本地10053端口 cp /etc/dnsmasq.conf /etc/dnsmasq.conf.bak cat > /etc/dnsmasq.conf << EOF port=53 proxy-dnssec no-negcache dns-forward-max=2000 server=223.5.5.5 server=119.29.29.29 server=114.114.114.114 server=/contoso.com/127.0.0.1#10053 log-queries log-facility=/var/log/dnsmasq/dnsmasq.log log-async=50 cache-size=100000 EOF # 创建日志文件 mkdir /var/log/dnsmasq touch /var/log/dnsmasq/dnsmasq.log # 设置自动启动 systemctl enable --now dnsmasq systemctl status dnsmasq --no-pager # 开启防火墙 firewall-cmd --permanent --add-service=dns firewall-cmd --reload # 设置日志轮询 cat > /etc/logrotate.d/dnsmasq << EOF /var/log/dnsmasq/dnsmasq.log { notifempty daily dateext rotate 15 sharedscripts postrotate [ ! -f /var/run/dnsmasq.pid ] || kill -USR2 `cat /var/run/dnsmasq.pid` endscript } EOF # 执行测试 logrotate -vf /etc/logrotate.conf # 设置本地网络地址解析DNS服务器为localhost nmcli c m ens160 ipv4.dns 127.0.0.1 nmcli c d ens160 && nmcli c u ens160
代码库Gitea gitea 是一个轻量级的Git代码仓库,为是gogs开发停滞之后的分叉,相关使用帮助可参考文档
gitea默认使用3000端口作为web访问端口,22端口为SSH端口。
数据库准备 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 # 安装 dnf install -y mariadb mariadb-server mariadb-server # 指定客户端和服务端使用utf8来访问mariadb cat > /etc/my.cnf.d/charset.cnf <<EOF [mysqld] character-set-server = utf8mb4 [client] default-character-set = utf8mb4 EOF # 拉起服务 systemctl enable --now mariadb.service systemctl status --no-pager mariadb.service # 创建gitea数据库,用户名为gitea,密码为gitea,仅限本地localhost访问 mysql -uroot << EOF CREATE USER 'gitea' IDENTIFIED BY 'gitea'; CREATE DATABASE giteadb CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'; GRANT ALL PRIVILEGES ON giteadb.* TO 'gitea'; FLUSH PRIVILEGES; exit EOF # 访问测试 mysql -ugitea -pgitea -hlocalhost <<EOF show databases; exit EOF
Gitea的部署 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 # 下载二进制文件 wget -O gitea https://dl.gitea.com/gitea/1.21/gitea-1.21-linux-amd64 chmod +x gitea mv gitea /usr/local/bin/gitea # 创建执行用户 groupadd --system git adduser \ --system \ --shell /bin/bash \ --comment 'Git Version Control' \ --gid git \ --home-dir /home/git \ --create-home \ git # 创建工作路径 mkdir -p /data/gitea/{custom,data,log} chown -R git:git /data/gitea/ chmod -R 750 /data/gitea/ mkdir /etc/gitea chown root:git /etc/gitea chmod 770 /etc/gitea # 创建systemd管理文件 cat > /etc/systemd/system/gitea.service <<EOF [Unit] Description=Gitea (Git with a cup of tea) After=network.target After=mariadb.service [Service] RestartSec=2s Type=simple User=git Group=git WorkingDirectory=/data/gitea/ ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini Restart=always Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/data/gitea [Install] WantedBy=multi-user.target EOF # 拉起服务 systemctl daemon-reload systemctl enable --now gitea systemctl status --no-pager gitea # 临时开启防火墙 firewall-cmd --add-port=3000/tcp firewall-cmd --reload
页面配置
容器部署 为了保证操作兼容性,当前仍然使用docker来进行部署。参照以下文档:
RockyLinuxan安装容器服务
证书生成Cert Maker 使用 1 2 3 4 5 6 7 # 使用苏洋开源的nodejs版本自签证书生成器 docker pull soulteary/certs-maker # 生成10年期通配符证书,可用于k8s环境部署 docker run --rm -it -e CERT_DNS="contoso.com;*.contoso.com;*.data.contoso.com" -e CERT_C="CN" -e CERT_ST="TJ" -e CERT_L="NK" -e CERT_O="CONTOSO" -e CERT_OU="IT Support" -e FOR_K8S="ON" -e CERT_CN="SUJX LAB" -v /data/public/:/ssl soulteary/certs-maker # 导入证书 cp /data/files/contoso.com.crt /etc/pki/ca-trust/source/anchors/ update-ca-trust
参考
文件格式转换
只有 3MB 的自签名证书制作 Docker 工具镜像:Certs Maker
如何制作和使用自签名证书
文件下载服务HTTP 部署 为了传递脚本或者证书方便,需要部署一个静态的HTTP文件下载站点。这里使用Nginx容器来实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 # 创建Dockerfile mkdir -p ~/Dockerfile/nginx cat > ~/Dockerfile/nginx/Dockfile <<EOF FROM nginx:latest MAINTAINER sujx@live.cn RUN rm -f /etc/nginx/conf.d/default.conf COPY ./default.conf /etc/nginx/conf.d/ EOF # 创建Nginx配置文件 cat > ~/Dockerfile/nginx/default.conf <<EOF server { listen 80; server_name public; location / { root /public; autoindex on; sub_filter '<h1>Index of /</h1>' '<h1>Get Files</h1>'; sub_filter_once on; } } EOF # 生成镜像 docker pull nginx cd ~/Dockerfile/nginx docker build -f ./Dockfile -t webshare . # 部署站点 docker run -itd -p 8088:80 --restart always --name publicfile -v /data/files:/public webshare
内部站点导航页 为了可快速方便的查找各种web服务,使用一个站点导航页面来提供书签功能。来源为:个人导航书签
部署站点 1 2 3 4 5 6 # 拉取镜像 docker pull soulteary/flare # 创建配置目录 mkdir /data/homepage # 启动容器 docker run -itd -p 5005:5005 -v /data/homepage:/app -e "nologin=0" -e "FLARE_USER=flare" -e "FLARE_PASS=flare" --restart always --name homepage soulteary/flare
配置文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 [root@Infra ~]# tree /data/homepage/ /data/homepage/ ├── apps.yml ├── bookmarks.yml └── config.yml 0 directories, 3 files # 自定义站点,可以自定义图标、地址、名称和描述文字 [root@Infra ~]# cat /data/homepage/apps.yml links: - name: 示例链接 link: https://link.example.com icon: evernote desc: 链接描述文本 - name: 示例链接 link: https://link.example.com icon: FireHydrant desc: 链接描述文本 # 自定义书签,可以执行分类展示 [root@Infra ~]# cat /data/homepage/bookmarks.yml categories: - id: cate-id-0 title: 链接分类1 - id: cate-id-1 title: 链接分类2 - id: cate-id-2 title: 链接分类3 - id: cate-id-3 title: 链接分类4 links: - name: 示例链接 link: https://link.example.com icon: checkDecagram category: cate-id-0 - name: 示例链接 link: https://link.example.com icon: sofaOutline category: cate-id-1 - name: 示例链接 link: https://link.example.com icon: foodCroissant category: cate-id-2
参考
源站
收尾 站点发布 由于主机使用多个端口承载多个web服务,所以使用Nginx作为站点前端来实现对后端站点的反向代理。
Nginx的安装 1 2 3 4 5 6 7 8 9 10 # 部署 dnf install -y nginx systemctl enable --now nginx systemctl status --no-pager nginx firewall-cmd --permanent -add-service={http,https} firewall-cmd --reload # 放置证书 mkdir -pv /etc/ssl/contoso.com cp /data/public/contoso.com.* /etc/ssl/contoso.com/
站点配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 # 配置git.contoso.com cat > /etc/nginx/conf.d/gitea.conf <<EOF server { listen 80 ; listen [::]:80 ; return 301 https://$host$request_uri; server_name git.contoso.com; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name git.contoso.com; charset utf-8; ssl_certificate "/etc/ssl/contoso.com/contoso.com.crt"; ssl_certificate_key "/etc/ssl/contoso.com/contoso.com.key"; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_ciphers PROFILE=SYSTEM; ssl_prefer_server_ciphers on; location / { proxy_pass http://127.0.0.1:3000/; } } EOF nginx -t # 配置导航页home.contoso.com cat > /etc/nginx/conf.d/homepage.conf <<EOF server { listen 80 ; listen [::]:80 ; return 301 https://$host$request_uri; server_name home.contoso.com; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name home.contoso.com; charset utf-8; ssl_certificate "/etc/ssl/contoso.com/contoso.com.crt"; ssl_certificate_key "/etc/ssl/contoso.com/contoso.com.key"; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_ciphers PROFILE=SYSTEM; ssl_prefer_server_ciphers on; location / { proxy_pass http://127.0.0.1:5005/; } } EOF nginx -t # 配置公共文件下载,为简化使用,保持使用80端口,并限制访问来源 cat > /etc/nginx/conf.d/public.conf <<EOF server { listen 80; server_name pub.contoso.com; location / { autoindex on; autoindex_exact_size on; autoindex_localtime on; root /data/public/; allow 127.0.0.1; allow 192.168.10.0/24; } } EOF nginx -t # 重新读取配置文件 systemctl reload nginx
清理 1 2 3 4 5 6 7 8 9 # 加固gitea 配置文件权限 chmod 750 /etc/gitea chmod 640 /etc/gitea/app.ini # 检查防火墙 firewall-cmd --list-all # 重启并复查各个站点 systemctl reboot