calico目前最新版3.1,但是只支持k8s、openstack、OpenShift。只有在2版本才支持docker、mesos等架构,不过calico打算在以后的V3版本中继续支持mesos、docker等架构,所以目前我们就只能使用最新的V2版本了,是2.6版本,一下下载的软件都是适配2.6版本的
需要依赖etcd,支持docker1.9及以上,calico要以plugin的模式在docker上运行,需要修改docker的配置,cluster-store,在docker 1.10以上可以修改daemon.json来实现
下载calicoctl:
wget 'https://github.com/projectcalico/calicoctl/releases/download/v1.6.4/calicoctl'
配置calicoctl使用etcdv2版本的数据存储,calicoctl默认使用/etc/calico/calicoctl.cfg配置文件,不过也可以使用--config来覆盖。配置也可以使用环境变量,不过为了方便管理,我们使用配置文件。样例:
apiVersion: v1
kind: calicoApiConfig
metadata:
spec:
datastoreType: "etcdv2"
etcdEndpoints: "http://etcd1:2379,http://etcd2:2379"
更多参数参考:https://docs.projectcalico.org/v2.6/reference/calicoctl/setup/etcdv2
启动一个calico/node
calicoctl node run --node-image=quay.io/calico/node:v2.6.10
calicoctl node status
使用docker run可以查看calico在启动node的时候底层运行的docker命令:
calicoctl node run --init-system --dryrun --node-image=quay.io/calico/node:v2.6.10
docker run --net=host --privileged --name=calico-node --rm -e ETCD_AUTHORITY=127.0.0.1:2379 -e ETCD_SCHEME=http -e ETCD_ENDPOINTS= -e NODENAME=calico -e CALICO_NETWORKING_BACKEND=bird -e NO_DEFAULT_POOLS= -e CALICO_LIBNETWORK_ENABLED=true -e CALICO_LIBNETWORK_IFPREFIX=cali -v /var/run/calico:/var/run/calico -v /lib/modules:/lib/modules -v /var/log/calico:/var/log/calico -v /run/docker/plugins:/run/docker/plugins -v /var/run/docker.sock:/var/run/docker.sock quay.io/calico/node:v2.6.10
IPAM:
在docker1.10以后,calico网络允许用户在创建容器时选择特定的IP地址。为了使用此功能,Docker在运行docker network create时需要指定--subnet参数。
1 Create a Calico IP pool
cat << EOF | calicoctl create -f -
- apiVersion: v1
kind: ipPool
metadata:
cidr: 192.0.2.0/24
EOF
2 Create a Docker network using the IP pool
docker network create --driver calico --ipam-driver calico-ipam --subnet=192.0.2.0/24 my_net
3 Create a container using a specific IP address from the pool
docker run --net my_net --name my_workload --ip 192.0.2.100 -tid busybox
4 Verify that the IP address was assigned to the container
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my_workload
Calico and Systemd:
calico node以service运行,方便管理
calico.env:配置文件
ETCD_ENDPOINTS=http://localhost:2379
ETCD_CA_FILE=""
ETCD_CERT_FILE=""
ETCD_KEY_FILE=""
CALICO_NODENAME=""
CALICO_NO_DEFAULT_POOLS=""
CALICO_IP=""
CALICO_IP6=""
CALICO_AS=""
CALICO_LIBNETWORK_ENABLED=true
CALICO_NETWORKING_BACKEND=bird
Configuring BGP Peers
calico-node.service:配置Systemd service
[Unit]
Description=calico-node
After=docker.service
Requires=docker.service
[Service]
EnvironmentFile=/etc/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 /var/log/calico:/var/log/calico \
-v /run/docker/plugins:/run/docker/plugins \
-v /lib/modules:/lib/modules \
-v /var/run/calico:/var/run/calico \
quay.io/calico/node:v2.6.10
ExecStop=-/usr/bin/docker stop calico-node
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
Configuring BGP Peers:忽略
Route Reflector:
Configuring BIRD
The calico/routereflector container
IPv6 Support:不需要
External Connectivity:
Calico创建了一个路由网络,您的容器看起来就像普通的IP服务。 您可以从其他IP地址连接到它们。讨论了Calico端点与群集外部主机之间的连接。
Outbound connectivity
出站连接是指从Calico端点到群集外的目标的连接。获得出站连接的最简单方法是在您希望能够访问互联网的所有Calico池上打开NAT Outgoing。
cat << EOF | calicoctl apply -f -
- apiVersion: v1
kind: ipPool
metadata:
cidr: 192.168.0.0/16
spec:
nat-outgoing: true
EOF
Inbound connectivity
入站连接是指源自群集外部的Calico端点的连接有两种主要方法:BGP与网络基础架构对等,或使用orchestrator特定选项(k8s、openstack)。
BGP与基础网络对等--这需要访问Calico群集前面的支持BGP的交换机或路由器。通常,这将涉及使用支持BGP的交换机对Calico集群中的节点进行对等,这些交换机充当从外部到达集群中的Calico端点的网关。常见的情况是您的容器主机位于其自己的隔离的第2层网络上,例如服务器机房中的机架或整个数据中心。 通过路由器访问该网络,该路由器也是所有容器主机的默认路由器。
如果您拥有少量主机,则可以在路由器和每个启用Calico的主机之间配置BGP会话。 对于许多主机,您可能希望使用路由反射器(route reflector)或设置第3层拓扑。
Configuring IP-in-IP:
如果你的网络拓扑执行检查源地址目的地址的网络流量,并且在无法识别这些地址会丢弃流量时,你就需要开启IP-in-IP封装,尤其是在公有云环境,你无法在calico节点和网络路由器之间设置BGP对等的情况下,你可以在ip资源池上启用ipip选项,启用后,calico将在将数据包路由到属于ip池范围的节点时使用IP-in-IP封装。mode字段有两种情况:
Configuring IP-in-IP for all inter-workload traffic:
如果设置mode为always,calico则会使用ip-in-ip路由所有来自calico主机的流量到calico网络的容器和vm上
$ calicoctl apply -f - << EOF
apiVersion: v1
kind: ipPool
metadata:
cidr: 192.168.0.0/16
spec:
ipip:
enabled: true
mode: always
nat-outgoing: true
EOF
Configuring cross-subnet IP-in-IP:
也可以选择路由的流量
$ calicoctl apply -f - << EOF
apiVersion: v1
kind: ipPool
metadata:
cidr: 192.168.0.0/16
spec:
ipip:
enabled: true
mode: cross-subnet
nat-outgoing: true
EOF
Configuring a Node IP Address and Subnet:
Configure the IP and subnet through environment variables calicoctl node run --ip=10.0.2.10/24
Autodetect the IP and subnet calicoctl node run --ip=autodetect --ip-autodetection-method=can-reach=8.8.8.8
Manually configure the node resource: 下面
# Start by querying the current node configuration
$ calicoctl get node node2 -o yaml
- apiVersion: v1
kind: node
metadata:
name: node2
spec:
bgp:
ipv4Address: 10.0.2.10/32
ipv6Address: fd80:24e2:f998:72d6::/128
# Now reconfigure the node with updated ipv4Address to include the correct
# subnet.
$ calicoctl apply -f - << EOF
- apiVersion: v1
kind: node
metadata:
name: node2
spec:
bgp:
ipv4Address: 10.0.2.10/24
ipv6Address: fd80:24e2:f998:72d6::/120
EOF
=========================================================================
calico:
Calico在每个主机上通过一个自己的container与其他主机或者网络通讯,即calico-node的container,这个container里面包含了Bird路由管理、Felix协议等。在两台主机上分别运行,后面的ip是主机ip。calicoctl node --ip=10.11.150.72 运行后在两个主机用docker ps可以看到正在运行calico-node的container
下面为我们的calico网络添加可用的ip pool(在72或者74一台主机上运行即可):
calicoctl pool add 172.1.0.0/16 --nat-outgoing
calicoctl pool show
calicoctl pool remove 192.168.0.0/16
这里由于我的两个主机72和74本身就在同一个子网下,主机相互之间不需要L2 switch。如果是跨子网、跨机房、跨公网就需要加上--ipip选项,或者你有权限直接修改路由器的BGP协议,将两个不同子网的主机连接为BGP peer。
container启动后,给容器注册独立ip
docker run --net=none --name worker-1 -tid iperf
docker run --net=none --name worker-2 -tid iperf
calicoctl container add worker-1 172.1.0.1
calicoctl container add worker-2 172.1.0.2
Calico通过profile的形式来控制ACL,也以此来完成安全策略。
添加两个profile(72或者74均可):
./calicoctl profile add PROF_1
./calicoctl profile add PROF_2
calicoctl profile show
为container添加策略:
./calicoctl container worker-1 profile append PROF_1
./calicoctl container worker-2 profile append PROF_1
./calicoctl container worker-3 profile append PROF_1
./calicoctl container worker-4 profile append PROF_2
Cluster Store模式和docker swarm模式冲突
====================================================================
2 查看网络docker network ls
net1 是我们创建的网络,docker_gwbridge是docker自动创建的网络,他允许容器和他当前运行在的主机进行通讯,ingress也是docker自动创建的网络,docker swarm使用该网络暴露service到其他网络或者提供routeing mesh
3 启动容器,使用net1 y2hqtjir3i3u
docker service create --replicas 2 --name redis3 --network net1 172.31.68.241/library/redis
4 在/var/run下创建docker nets的软连接
ln -s /var/run/docker/netns netns
ip netns
只有把该软连接做好,ip netns才会显示
5 在容器里面执行查看
ip link
6 在node节点上执行查看
ip netns exec 1-y2hqtjir3i ip link