calico+etcd+docker+docker-compose配置跨宿主机的应用配置
一,资源准备
1.1系统前置资源准备:
名称 | 版本 | 备注 |
centos | 7.4-x86_64 | 参考最小官方镜像 |
etcd | 3.5.4 | 3.5.4之后可能移除enable-v2 |
docker | 20.10.17 | 其实19.x也可以 |
系统内核 | 4.4.249-1.el7.elrepo.x86_64 | 其实升级的3.10.x版本也行,不过用指定内核升级也行 |
calico-node | 2.6.12 | 这是2.x最高版本了,目前20220623为止,v3版本官方均不支持。 |
calicoctl | 1.6.1-1.6.5 | 最高到1.6.5 |
1.2 calico服务的端口相关配置的要求(取自3.23.3版本的时候的官方数据)
Configuration | Host(s) | Connection type | Port/protocol |
---|---|---|---|
Calico networking (BGP) | All | Bidirectional | TCP 179 |
Calico networking with IP-in-IP enabled (default) | All | Bidirectional | IP-in-IP, often represented by its protocol number 4 |
Calico networking with VXLAN enabled | All | Bidirectional | UDP 4789 |
Calico networking with Typha enabled | Typha agent hosts | Incoming | TCP 5473 (default) |
flannel networking (VXLAN) | All | Bidirectional | UDP 4789 |
All | kube-apiserver host | Incoming | Often TCP 443 or 6443* |
etcd datastore | etcd hosts | Incoming | Officially TCP 2379 but can vary |
经检测后发现,当使用ipip协议的时候,没有端口限制,相关辅助资料如下:
1,[docker创建并运行一个 nginx 容器](https://blog.csdn.net/weixin_44907803/article/details/123492293)
2,[IP协议号和传输端口号](https://blog.csdn.net/woxiaozhi/article/details/7719025)
3,[tcpdump抓包命令详解大全](https://blog.csdn.net/ljbcharles/article/details/122256796)
1.3,系统参数配置:
#开启ipv4转发
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
#由于某些环境下会出现配置网络的权限被deny的情况,则可能是ipv6的问题。
#相关参考链接:https://blog.csdn.net/weixin_43266367/article/details/105973683
#永久禁用ipv6
echo " ">>/etc/sysctl.conf
echo "# made for disabled IPv6 in $(date +%F)">>/etc/sysctl.conf
echo 'net.ipv6.conf.all.disable_ipv6 = 1'>>/etc/sysctl.conf
echo 'net.ipv6.conf.default.disable_ipv6 = 1'>>/etc/sysctl.conf
echo 'net.ipv6.conf.lo.disable_ipv6 = 1'>>/etc/sysctl.conf
tail -6 /etc/sysctl.conf
sysctl -p
二,系统内核升级
2.1,yum资源准备
#我们就用阿里提供的资源站的资源
rm -rf /etc/yun.repos.d/*
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
#其他内核版本,可以通过如下链接去浏览器访问:
#http://mirrors.aliyun.com/elrepo/kernel/el7/x86_64/RPMS/
2.2,新的指定内核安装
#注意,一旦3.x版本的kernel-tool*被移除后就不要顺便重启,一定要把kernel升级完之后才能重启,不然可能会有各种错误。
yum remove -y kernel-tool*
#如果要离线其他系统,记得先改yum的cache配置,这样就能保留rpm包以及相关依赖包
yum -y install http://mirrors.aliyun.com/elrepo/kernel/el7/x86_64/RPMS/kernel-lt-devel-4.4.249-1.el7.elrepo.x86_64.rpm
yum -y install http://mirrors.aliyun.com/elrepo/kernel/el7/x86_64/RPMS/kernel-lt-doc-4.4.249-1.el7.elrepo.noarch.rpm
yum -y install http://mirrors.aliyun.com/elrepo/kernel/el7/x86_64/RPMS/kernel-lt-headers-4.4.249-1.el7.elrepo.x86_64.rpm
yum -y install http://mirrors.aliyun.com/elrepo/kernel/el7/x86_64/RPMS/kernel-lt-tools-4.4.249-1.el7.elrepo.x86_64.rpm
yum -y install http://mirrors.aliyun.com/elrepo/kernel/el7/x86_64/RPMS/kernel-lt-tools-libs-4.4.249-1.el7.elrepo.x86_64.rpm
yum -y install http://mirrors.aliyun.com/elrepo/kernel/el7/x86_64/RPMS/kernel-lt-tools-libs-devel-4.4.249-1.el7.elrepo.x86_64.rpm
yum -y install http://mirrors.aliyun.com/elrepo/kernel/el7/x86_64/RPMS/perf-4.4.249-1.el7.elrepo.x86_64.rpm
yum -y install http://mirrors.aliyun.com/elrepo/kernel/el7/x86_64/RPMS/python-perf-4.4.249-1.el7.elrepo.x86_64.rpm
2.3,设定重启后启用新内核
#先查看自己安装的内核的序号
sudo awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
#然后指定,我这边是0,那么:
grub2-set-default 0
#重新生成 grub 配置文件
grub2-mkconfig -o /boot/grub2/grub.cfg
2.4,重启系统
#重启
reboot
三,ssl配置准备
3.1,下载一个生成秘钥的两个linux执行的命令
#自己可以选择不同版本的cfssl,建议用最新的,如果受到科学上网的过滤,则可通过https://pkg.cfssl.org/或者通过https://gitee.com/lingxuyizhi/cfssl/releases获取相关版本资源
curl -o /tmp/cfssl https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssl_1.6.1_linux_amd64
curl -o /tmp/cfssljson https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssljson_1.6.1_linux_amd64
3.2,新增相关加密配置的文件
#0,创建一个仓库
mkdir /opt/ssl && cd /opt/ssl
#1,新增/opt/ssl/config.json文件
cat >> /opt/ssl/config.json <<EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "87600h"
},
"server": {
"expiry": "1000000h",
"usages": ["signing", "key encipherment", "server auth", "client auth"]
},
"client": {
"expiry": "1000000h",
"usages": ["signing", "key encipherment", "client auth"]
},
"peer": {
"expiry": "43800h",
"usages": ["signing", "key encipherment", "server auth", "client auth"]
}
}
}
}
EOF
#2,创建ca请求配置文件/opt/ssl/csr.json
cat >>/opt/ssl/csr.json<<EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Wuhan",
"L": "Hubei",
"O": "k8s",
"OU": "System"
}
]
}
EOF
#3,创建需要被签名的请求配置文件/opt/ssl/etcd-csr.json
cat >>/opt/ssl/etcd-csr.json<<EOF
{
"CN": "etcd",
"hosts": [
"127.0.0.1",
"172.29.150.202",
"172.29.150.203",
"172.29.150.204"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Shanghai",
"L": "Shanghai",
"O": "etcd",
"OU": "Etcd Security"
}
]
}
EOF
#这里特别注意,hosts里面一定要有安装etcd的虚机的ip地址,如果是etcd集群,后期增加节点,那么可以重新生成一个服务器使用的公私钥
3.3,利用3.1下载下来的命令生成ca公私钥,被签名的服务公私钥
cd /opt/ssl
#先生成ca的公私钥,依次分别为ca.pem,ca-key.pem
cfssl gencert -initca csr.json | cfssljson -bare ca
#然后生成被签名的server公私钥,依次分别为etcd.pem etcd-key.pem
cfssl gencert -ca=/opt/ssl/ca.pem \
-ca-key=/opt/ssl/ca-key.pem \
-config=/opt/ssl/config.json \
-profile=kubernetes etcd-csr.json | cfssljson -bare etcd
#可以通过查看
ls -l *.pem
3.4,分发证书
#凡是涉及到证书的服务器都要分发一遍
scp -rp /opt/ssl/{ca,etcd,etcd-key}.pem root@{相关服务器的ip}:/opt/ssl/
#提一下,在整个部署过程中我们就用了一个CA证书,一个服务器证书和一个服务器秘钥这三个文件去进行客户端访问、server认证或者需要的peer认证访问(在本文不加peer访问认证)。
#如果觉得这三个进行三种访问不安全,可以参考其他资源分别生成服务器证书秘钥,客户端访问证书秘钥以及peer访问证书秘钥。注意,这三组必须都是需要同一个CA证书签名。
3.5,分享网友相关资源
1,https://c7sky.com/category/building-etcd-cluster.html
2,ETCD 部署并启用证书认证
四,docker安装
4.1 docker安装前的yum准备
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
#查看docker-ce的所有版本
yum list docker-ce --showduplicates
4.2,利用yum去进行docker安装
yum install -y docker-ce
4.3,启动doker
systemctl start docker
systemctl enable docker
4.4,预先下载etcd的image和calico的image
docker pull bitnami/etcd:latest
#注意: 此处下载的etcd版本是3.x,且默认启用v3版本,该处的源码出处为:https://github.com/bitnami/bitnami-docker-etcd
docker pull calico/node:v2.6.12
#注意:此处下载的calico默认对接的是v2版本的etcd,后期如果升级3.x版本可能会默认对接v3则会无法访问etcd-v2,这个问题需要注意。
五,etcd单实例的集群安装配置-v2版本
5.1,etcd的docker命令编写
按照命令也可以形成一个docker-compose.yml文件
#
#假设新建集群主机有 etcd01,etcd02,etcd03,对应ip为10.0.0.1,10.0.0.2,10.0.0.3
#则有如下变量内容:
#NAME_1=etcd01
#NAME_2=etcd02
#NAME_3=etcd03
#HOST_1=10.0.0.1
#HOST_2=10.0.0.2
#HOST_3=10.0.0.3
#CLUSTER=${NAME_1}://${HOST_1}:2380,${NAME_2}://${HOST_2}:2380,${NAME_3}://${HOST_3}:2380
#当前你的集群的数据如下
NAME_1=etcd01
HOST_1=10.0.0.99
CLUSTER=${NAME_1}://${HOST_1}:2380
docker run -d --name ${NAME_1} \
--hostname ${NAME_1}\
--volume /opt/ssl:/opt/ssl\
--publish 2379:2379 \
--publish 2380:2380 \
--env ETCDCTL_API=2 \
--env ETCD_NAME=${NAME_1} \
--env ALLOW_NONE_AUTHENTICATION=yes \
--env ETCD_TRUSTED_CA_FILE="/opt/ssl/ca.pem"\
--env ETCD_CERT_FILE="/opt/ssl/etcd.pem"\
--env ETCD_KEY_FILE="/opt/ssl/etcd-key.pem"\
--env ETCD_CLIENT_CERT_AUTH="true"\
--env ETCD_AUTO_TLS="true"\
--env ETCD_ADVERTISE_CLIENT_URLS=https://${HOST_1}:2379 \
--env ETCD_LISTEN_CLIENT_URLS=https://0.0.0.0:2379 \
--env ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380 \
--env ETCD_INITIAL_ADVERTISE_PEER_URLS=http://${HOST_1}:2380 \
--env ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster \
--env ETCD_INITIAL_CLUSTER="${CLUSTER}"\
--env ETCD_INITIAL_CLUSTER_STATE=new\
--env ETCD_ENABLE_V2=true\
bitnami/etcd:latest
#注意: ETCD_ENABLE_V2:表示将etcd版本降低到v2版本,我当前lastest版本是3.5.4
#ETCDCTL_API将etcdctl的版本降低到v2版本
5.2,验证etcd是否启动成功
#进入etcd容器
docker exec -it etcd01 bash
#执行etcdctl相关命令
etcdctl --endpoint=https://127.0.0.1:2379 --cert-file=/opt/ssl/etcd.pem --key-file=/opt/ssl/etcd-key.pem --ca-file=/opt/ssl/ca.pem member list;
#返回信息如下,即为成功启动
#e80dfa1da3c89966: name=etcd01 peerURLs=http://10.0.0.99:2380 clientURLs=https://10.0.0.99:2379 isLeader=true
5.3,部分报错解释
1,如果执行etcdctl返回为一个404报错,则表示你执行的etcdctl和etcd两者版本不一致;
2,如果执行etcdctl之后返回一个证书异常,则表示你证书配置的有问题;
3,如果执行etcdctl之后反馈一个包含no host,则表示你的server签名里面的host上没有指定该etcd所在的主机的ip信息。
六,calico安装配置-对接etcd的v2的版本
6.0前言:
4.4的时候已经获取了docker包,我们直接使用即可
下载calicoctl来管理calico
#两种方法,一种是通过wget或者aria2c通过代理或者不通过代理下载:
aria2c -x 16 -c --all-proxy="http://0.0.0.0:1000" https://github.com/projectcalico/calicoctl/releases/download/v1.6.1/calicoctl
chmod 755 calicoctl && mv calicoctl /usr/local/bin/
#另一种是通过下载镜像取提取:
CALICO_CTL_IMAGE=quay.io/calico/ctl:v1.6.5
docker pull ${CALICO_CTL_IMAGE}
docker create --name calico-ctl-create ${CALICO_CTL_IMAGE}
sudo docker cp calico-ctl-create:/calicoctl /usr/local/bin/calicoctl
docker rm calico-ctl-create
#参考链接:http://t.zoukankan.com/cheyunhua-p-15703173.html
6.1 配置systemctl的service文件,让calico-node收到其管理
echo '
[Unit]
Description=calico-node
After=docker.service
Requires=docker.service
[Service]
EnvironmentFile=/opt/platform/calico/calico.env
ExecStartPre=-/usr/bin/docker rm -f calico-node
ExecStart=/usr/bin/docker run --net=host --privileged \
--name=calico-node \
-e NODENAME=${CALICO_NODENAME} \
-e IP=${CALICO_IP} \
-e IP6=${CALICO_IP6} \
-e CALICO_NETWORKING_BACKEND=${CALICO_NETWORKING_BACKEND} \
-e AS=${CALICO_AS} \
-e NO_DEFAULT_POOLS=${CALICO_NO_DEFAULT_POOLS} \
-e CALICO_LIBNETWORK_ENABLED=${CALICO_LIBNETWORK_ENABLED} \
-e ETCD_ENDPOINTS=${ETCD_ENDPOINTS} \
-e ETCD_CA_CERT_FILE=${ETCD_CA_CERT_FILE} \
-e ETCD_CERT_FILE=${ETCD_CERT_FILE} \
-e ETCD_KEY_FILE=${ETCD_KEY_FILE} \
-v /opt/platform/calico/certs:/etc/calico/certs \
-v /opt/platform/calico/log:/var/log/calico \
-v /run/docker/plugins:/run/docker/plugins \
-v /lib/modules:/lib/modules \
-v /var/run/calico:/var/run/calico \
-v /var/run/docker.sock:/var/run/docker.sock \
quay.io/calico/node:v2.6.12
#calico/node:
ExecStop=-/usr/bin/docker stop calico-node
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
' > /usr/lib/systemd/system/calico-node.service
#这里值得注意的是,官方没有在这里面增加秘钥目录的映射和docker.sock的映射
#因为不是和k8s相关,所以CALICO_NETWORKING_BACKEND参数必须要设置,这样docker才能通过相关标准链接到calico
6.2 新增/opt/platform/calico/calico.env文件
在6.1中存在/opt/platform/calico/calico.env文件需要引用
mkdir -p /opt/platform/calico/
cat >>/opt/platform/calico/calico.env<<EOF
ETCD_ENDPOINTS="https://10.0.0.98:2379"
ETCD_CA_CERT_FILE="/etc/calico/certs/ca.pem"
ETCD_CERT_FILE="/etc/calico/certs/etcd.pem"
ETCD_KEY_FILE="/etc/calico/certs/etcd-key.pem"
CALICO_NODENAME=""
CALICO_NO_DEFAULT_POOLS=""
CALICO_IP=""
CALICO_IP6=""
CALICO_AS=""
CALICO_LIBNETWORK_ENABLED=true
CALICO_NETWORKING_BACKEND=bird
EOF
#注意:
#ETCD_ENDPOINTS:就是etcd集群里面所有节点的访问地址集合,每个访问地址用逗号分隔;
#如果etcd用的是https,则访问地址必须是https开头,而不是http开头
#ETCD_CA_CERT_FILE,ETCD_CERT_FILE,ETCD_KEY_FILE,这三个文件的地址都是容器内部地址,所以只要能访问到容器内部这三个文件就是对的。
6.3 启动服务
systemctl start calico-node
#如果失败重启的话,systemctl会重新构建一个calico-node,不需要我们手动删除node
#查看calico启动日志
docker logs calico-node
#如果是successful或者类似语句结尾,就表示你成功启动,可以开始新建网络验证calico的网络是否能够使用
#反之就要排查相关问题,这个比较苦恼的问题就是和etcd没有对接上报出的错误不怎么能够理解。一般就是etcd集群不可用什么的
#主要看三个地方,
#第一个就是calico中的endpoints是否是对的;
#第二个是etcd是否真的启动成功;
#第三个就是calico版本是不是和etcd启动的版本一致;比如都是2.x或者都是3.x版本,因为etcd两个版本对接的语句差别很大。
#怎么看两者版本信息: etcd那个地方有解释;calico的话需要进入容器执行calico命令看版本。
6.4 检查node状态
calicoctl node status;
#这个命令会输出当前节点以外的其他节点的联通状态,如果都是正常,则calico部署成功。
七,调整docker的配置文件
7.1,给docker增加参数配置,用来接入etcd存储
cat >> /etc/docker/daemon.json <<EOF
{
"cluster-store":"etcd://10.0.0.99:2379",
"cluster-store-opts": {
"kv.cacertfile": "/opt/platform/calico/certs/ca.pem",
"kv.certfile": "/opt/platform/calico/certs/etcd.pem",
"kv.keyfile": "/opt/platform/calico/certs/etcd-key.pem"
},
"cluster-advertise":"10.0.0.98:2376"
}
EOF
#cluster-advertise 指代本地监控的iterface或者ip以及端口,此监控较为特殊,它是监控utp流量的。
#cluster-store 这个就是etcd集群的地址,如果是多个地址,中间以逗号分隔;
#cluster-store-opts 这个就是秘钥位置了,和cluster-store相关。
7.2,重启docker,并启动其下的两个容器;
systemctl restart docker
#因为没有设置容器自动重启的功能,所以需要手动重启;
docker start etcd01
docker start calico-node
注,7.x章节其实可以在docker如何搭建的时候就可以配置,但是一开始配置服务好像无法启动,放置在最后就是为了保证能够顺利。
八,测试calico网络是否可用。
8.1 给calico配置ip池
cat >>/root/2v-ipPool.yaml<<EOF
- apiVersion: v1
kind: ipPool
metadata:
cidr: 10.88.0.0/24
spec:
ipip:
enabled: true
mode: always
nat-outgoing: true
disabled: false
EOF
calicoctl apply -f /root/2v-ipPool.yaml
#再次强调calicoctl要在1.6.1-1.6.5之间的版本;
8.2,查看当前calico有的ip池
calicoctl get ipPool
#输出内容为:
#CIDR
#10.88.0.0/24
#192.168.0.0/16
#fd80:24e2:f998:72d6::/64
#上述后面两个地址段是默认自带的,在docker上没有指定ip的网段会使用它,但是不指定网段的网络会出现一些问题
#建议在创建网络的时候指定地址段,且地址段必须在calicoctl能查到,否则会报错
8.3,在docker上创建一个calico网络
docker network create --driver calico --ipam-driver calico-ipam --subnet=10.88.0.0/24 cmp
#创建成功后会有一串不可读的字符串输出
#查看创建的网络
docker network ls cmp
#查看创建的网络详情
docker network inspect cmp
#创建出来的cmp网络会存在在所有calico-node存在的虚机上,如果没有,请检查异常的虚机上的docker和etcd之间的链接是否正常
8.4,创建容器验证
要求:在两个成功部署了calico-node,etcd,docker的虚机上分别创建一个在同一个网络中的容器;
#虚机一上执行:
docker run --net cmp --name workload-A -tid busybox
docker inspect workload-A
#检查该容器是否使用了calico的网段
#虚机二上执行
docker run --net cmp --name workload-B -tid busybox
docker inspect workload-B
#检查该容器是否使用了calico的网段
#进入虚机一上的容器workload-A中并ping容器B的容器名
docker exec -it workload-A sh
ping workload-B
#若ping成功,则表示使用calico网络成功