系统初始化
本次作为测试安装,我这里使用的是一台虚拟机,具体配置如下:
主机名 |
IP 地址 |
系统版本 |
内存(G) |
CPU(核) |
硬盘(G) |
node-01 |
192.168.200.101 |
CentOS Linux release 7.9.2009 |
4 |
4 |
20 |
- 关闭防火墙和 Selinux
1 2 3 4 5 6 7 8 9 10 11 12
| systemctl stop firewalld systemctl disable firewalld
sed -i "s#^SELINUX=.*#SELINUX=disabled#g" /etc/selinux/config setenforce 0
swapoff -a && sysctl -w vm.swappiness=0 sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab
|
- 配置 yum 源(云服务器不需要)
1 2 3 4 5 6 7
| cd /etc/yum.repos.d/ mkdir backup-$(date +%F) mv *repo backup-$(date +%F)
curl http://mirrors.aliyun.com/repo/Centos-7.repo -o ali.repo
|
- 安装基础依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| yum -y install epel-release yum clean all yum makecache
yum -y install gcc glibc gcc-c++ make cmake net-tools screen vim lrzsz tree dos2unix lsof \ tcpdump bash-completion wget ntp setuptool openssl openssl-devel bind-utils traceroute \ bash-completion bash-completion-extras glib2 glib2-devel unzip bzip2 bzip2-devel libevent libevent-devel \ ntp expect pcre pcre-devel zlib zlib-devel jq psmisc tcping yum-utils device-mapper-persistent-data \ lvm2 git device-mapper-persistent-data bridge-utils container-selinux binutils-devel \ ncurses ncurses-devel elfutils-libelf-devel
yum update
|
- 时间同步
1 2
| echo "# 互联网时间同步" >> /var/spool/cron/root echo "*/5 * * * * /usr/sbin/ntpdate time2.aliyun.com >/dev/null 2>&1" >> /var/spool/cron/root
|
- 打开文件数优化
1 2 3 4 5 6 7 8 9
| cat >> /etc/security/limits.conf << EOF # 打开文件优化配置 * soft nofile 655360 * hard nofile 131072 * soft nproc 655350 * hard nproc 655350 * soft memlock unlimited * hard memlock unlimited EOF
|
- 内核优化
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
| cat >> /etc/sysctl.d/user.conf << EOF # 内核调优 net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 fs.may_detach_mounts = 1 vm.overcommit_memory=1 vm.panic_on_oom=0 fs.inotify.max_user_watches=89100 fs.file-max=52706963 fs.nr_open=52706963 net.netfilter.nf_conntrack_max=2310720 net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_keepalive_probes = 3 net.ipv4.tcp_keepalive_intvl =15 net.ipv4.tcp_max_tw_buckets = 36000 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_max_orphans = 327680 net.ipv4.tcp_orphan_retries = 3 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_max_syn_backlog = 16384 net.ipv4.ip_conntrack_max = 65536 net.ipv4.tcp_max_syn_backlog = 16384 net.ipv4.tcp_timestamps = 0 net.core.somaxconn = 16384 EOF
|
- 内核升级
docker 对于 CentOS 的要求为内核版本不低于 3.10
,尽管 7.9 已经是 3.10 版本,但还是有升级的必要。
同时作为生产环境,一般不会选择安装最新版本。但官方仓库中提供的 rpm 一般只会有一个 lt 和一个 ml 版本,所以需要从第三方下载想要的版本,统一服务器的内核版本,可以避免出现未知 BUG。
http://193.49.22.109/elrepo/kernel/el7/x86_64/RPMS/
本次使用的是 4 版本最后一版:4.20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| cd /usr/local/src/ wget http://193.49.22.109/elrepo/kernel/el7/x86_64/RPMS/kernel-ml-4.20.13-1.el7.elrepo.x86_64.rpm wget http://193.49.22.109/elrepo/kernel/el7/x86_64/RPMS/kernel-ml-devel-4.20.13-1.el7.elrepo.x86_64.rpm
yum -y localinstall kernel-ml-*
awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
# 设置默认启动内核,上面的命令可以看到最新内核的序号是 0 grub2-set-default 0
# 重启系统 reboot
|
系统启动完成之后,查看内核情况:
到此,系统初始化完成!
安装包准备
docker 目前有三种版本可供选择:nightly(开发版)
,test(测试版)
,stable(稳定版)
。
对于生产环境,为了避免因为版本不同导致集群出现未知 BUG,建议手动下载 rpm 包安装。本次安装版本为 20.10.9
,下载地址:
https://download.docker.com/linux/centos/7/x86_64/stable/Packages/
如果觉得下载慢,可以使用国内的镜像地址:
http://mirrors.ustc.edu.cn/docker-ce/linux/centos/7/x86_64/stable/Packages/
需要下载的安装包如下:
- docker-ce-20.10.9-3.el7.x86_64.rpm(docker 引擎)
- docker-ce-cli-20.10.9-3.el7.x86_64.rpm(docker 引擎的命令行)
- containerd.io-1.6.6-3.1.el7.x86_64.rpm(守护进程,独立于 docker 工作,管理容器的生命周期)
- docker-ce-rootless-extras-20.10.9-3.el7.x86_64.rpm(ce 需要的依赖)
- docker-scan-plugin-0.9.0-3.el7.x86_64.rpm(cli 需要的依赖)
服务安装
事先使用 lrzsz 将下载的安装包上传到 /usr/local/src/
目录然后开始进行安装。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
cd /usr/local/src/ yum -y localinstall docker* containerd*
systemctl start docker systemctl enable docker systemctl status docker
|
查看 docker 信息:
结果如下:
服务优化
由于 docker 默认的 registry 是 docker hub,而 docker hub 又是外网的服务,可能因为网络原因访问,下载都会非常慢。所以需要将 registry 调整为国内的。
国内常用的 registry 有以下一些:
- 阿里云(需要注册用户):
https://<你的ID>.mirror.aliyuncs.com
- 网易:
http://hub-mirror.c.163.com
- 中科大:
https://docker.mirrors.ustc.edu.cn
通过增加配置来修改 docker 默认的 registry 地址:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| mkdir -p /ops/{data,service,log,backup,shell,package} mkdir -p /ops/data/docker/{run,lib}
cat > /etc/docker/daemon.json << EOF { "exec-opts": ["native.cgroupdriver=systemd"], "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"], "bip": "172.16.0.1/16", "exec-root": "/ops/data/docker/run", "data-root": "/ops/data/docker/lib" } EOF
systemctl stop docker systemctl start docker systemctl status docker
|
如果不清楚网段划分,可以使用工具查看:
http://tools.jb51.net/aideddesign/ip_net_calc/
重启完成后查看 docker 信息:
如图所示:
故障排查
docker 在停止的时候可能会出现提醒:
Warning: Stopping docker.service, but it can still be activated by: docker.socket
告警的意思为:如果你试图连接到 docker socket,而 docker 服务没有运行,系统将自动启动 docker。
该配置是在 /lib/systemd/system/docker.service
中配置的:
1
| ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
|
所以这个告警可以忽略掉。
重启失败,大概可能是 /etc/docker/daemon.json 存在报错,可以通过错误日志查看信息:
1
| tail -1000f /var/log/messages
|
unable to configure the Docker daemon with file /etc/docker/daemon.json: invalid character ‘Â’ looking for beginning of value
查看配置文件没有问题,但是一直这个错误,所以我怀疑里面的 tab 或者空格存在问题,通过执行命令:
1
| cat -A /etc/docker/daemon.json
|
发现文件中确实有很多特殊的字符,因为配置是网上复制的。通过将里面空格和 tab 替换成空格之后故障解决。
unable to configure the Docker daemon with file /etc/docker/daemon.json: invalid character ‘}’ looking for beginning of object key string
原因是我在 json 最后一个值后面也加了 , 符号的缘故,删除了就好了。
daemon.json
配置文件 daemon.json
参数详解:
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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| { "api-cors-header": "", "authorization-plugins": [], "bridge": "", "bip": "192.168.88.0/22", "cgroup-parent": "", "cluster-store": "", "cluster-store-opts": {}, "cluster-advertise": "", "debug": true, "default-gateway": "", "default-gateway-v6": "", "default-runtime": "runc", "default-ulimits": {}, "dns": ["192.168.1.1"], "dns-opts": [], "dns-search": [], "exec-opts": [], "exec-root": "", "fixed-cidr": "", "fixed-cidr-v6": "", "data-root": "/var/lib/docker", "group": "", "hosts": [], "icc": false, "ip": "0.0.0.0", "iptables": false, "ipv6": false, "ip-forward": false, "ip-masq": false, "insecure-registries": ["120.123.122.123:12312"], "labels": ["nodeName=node-101"], "live-restore": true, "log-driver": "", "log-level": "", "max-concurrent-downloads": 3, "max-concurrent-uploads": 5, "mtu": 0, "oom-score-adjust": -500, "pidfile": "", "raw-logs": false, "registry-mirrors": ["https://192.498.89.232:89"], "selinux-enabled": false, "storage-driver": "", "swarm-default-advertise-addr": "", "tls": true, "tlscacert": "", "tlscert": "", "tlskey": "", "tlsverify": true, "userland-proxy": false, "userns-remap": "", "storage-opts": ["overlay2.override_kernel_check=true", "overlay2.size=15G"], "log-opts": { "max-file": "3", "max-size": "10m" } }
|