初次接触Calico从部署开始!

手工安装

前置工作

  • 安装CRD

    CRD文件可以下载每个版本的Helm Chart从crds/calico/kdd路径获取

  • 安装calicoctl

    1
    2
    
    curl -o /usr/local/bin/calicoctl https://s3.lqingcloud.cn/soft/calico/v3.17.6/calicoctl
    chmod +x /usr/local/bin/calicoctl
    
  • 创建默认的IPPool

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
kubectl apply -f - <<EOF
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: pool1
spec:
  cidr: 30.233.0.0/24
  ipipMode: Never
  natOutgoing: true
  disabled: false
  nodeSelector: all()
EOF

配置CNI

CNI 插件在创建 pod 时与 Kubernetes API 服务器交互,以获取附加信息并使用有关 pod 的信息更新数据存储。 由于CNI并非运行咋Pod中,无法使用ServiceAccount的信息通过Kube-Apiserver的认证,因此需要而外为其创建kubeconfig文件。

创建TLS证书,用于后续填充到kubeconfig文件中

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 生成签发请求
openssl req -newkey rsa:4096 \
  -keyout cni.key \
  -nodes \
  -out cni.csr \
  -subj "/CN=calico-cni"
# 使用Kubernetes集群的根证书签发cni.crt
sudo openssl x509 -req -in cni.csr \
  -CA /etc/kubernetes/pki/ca.crt \
  -CAkey /etc/kubernetes/pki/ca.key \
  -CAcreateserial \
  -out cni.crt \
  -days 365
# 修改权限
sudo chown $(id -u):$(id -g) cni.crt

使用生成的证书创建一个kubeconfig文件,文件中对应的USER信息为calico-cni和生成的TLS一致

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
APISERVER=$(kubectl config view -o jsonpath='{.clusters[0].cluster.server}')
kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/pki/ca.crt \
  --embed-certs=true \
  --server=$APISERVER \
  --kubeconfig=cni.kubeconfig
kubectl config set-credentials calico-cni \
  --client-certificate=cni.crt \
  --client-key=cni.key \
  --embed-certs=true \
  --kubeconfig=cni.kubeconfig
kubectl config set-context default \
  --cluster=kubernetes \
  --user=calico-cni \
  --kubeconfig=cni.kubeconfig
kubectl config use-context default --kubeconfig=cni.kubeconfig

创建ClusterRole和clusterrolebinding为calico-cni账户提供范围权限

参考:https://docs.projectcalico.org/getting-started/kubernetes/hardway/install-cni-plugin

拷贝cni.kubeconfig文件到/etc/cni/net.d/

1
  cp cni.kubeconfig /etc/cni/net.d/cni.kubeconfig

下载calico和calico-ipam插件到/opt/cni/bin/目录

1
2
3
4
  curl -L -o /opt/cni/bin/calico https://s3.lqingcloud.cn/soft/calico/v3.17.6/cni/calico
  chmod 755 /opt/cni/bin/calico
  curl -L -o /opt/cni/bin/calico-ipam https://s3.lqingcloud.cn/soft/calico/v3.17.6/cni/calico-ipam
  chmod 755 /opt/cni/bin/calico-ipam

并且生成CNI配置

 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
cat > /etc/cni/net.d/10-calico.conflist <<EOF
{
  "name": "k8s-pod-network",
  "cniVersion": "0.3.1",
  "plugins": [
    {
      "type": "calico",
      "log_level": "info",
      "datastore_type": "kubernetes",
      "mtu": 1500,
      "ipam": {
        "type": "calico-ipam"
      },
      "policy": {
        "type": "k8s"
      },
      "kubernetes": {
        "kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
      }
    },
    {
      "type": "portmap",
      "snat": true,
      "capabilities": {"portMappings": true}
    }
  ]
}
EOF

安装服务

calico的服务主要包括Typha和Calico/Node:

  • Typha:Datastore和网络服务之间的中间层。Typha运行时Watch当前资源的变换,并将这些信息推送(fan-out)到所有Node上的Daemon服务(比如Calico/Node)中。
  • Calico/Node:运行在每一个Kubernetes节点上

Typha

Typha和其他服务之间使用TLS加密通信,因此部署时需要生成双向验证的TLS证书。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 生成根证书
openssl req -x509 -newkey rsa:4096 \
  -keyout typhaca.key \
  -nodes \
  -out typhaca.crt \
  -subj "/CN=Calico Typha CA" \
  -days 365
# 将CA证书保存在Config中,方便其他服务读取
kubectl create configmap -n kube-system calico-typha-ca --from-file=typhaca.crt
# 生成Typha的服务端证书,PS:服务端证书中的用户名是 calico-typha
openssl req -newkey rsa:4096 \
  -keyout typha.key \
  -nodes \
  -out typha.csr \
  -subj "/CN=calico-typha"
openssl x509 -req -in typha.csr \
  -CA typhaca.crt \
  -CAkey typhaca.key \
  -CAcreateserial \
  -out typha.crt \
  -days 365
# 将服务端证书保存到Secret中
kubectl create secret generic -n kube-system calico-typha-certs --from-file=typha.key --from-file=typha.crt

生成服务使用的 ServiceAccount、RBAC 以及部署对应的 Deployment。

参考:https://docs.projectcalico.org/getting-started/kubernetes/hardway/install-typha

Calico/Node

Calico/Node服务中运行了一下三个进程:

  • Felix:Calico 每节点守护进程
  • BIRD:一个守护进程,它使用 BGP 协议将路由信息分发到其他节点
  • Confd:监视 Calico 数据存储以获取配置更改和更新 BIRD 配置文件的守护进程

Calico/Node可以参考下面的操作生成证书:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 生成证书的签发请求,User为calico-node
openssl req -newkey rsa:4096 \
  -keyout calico-node.key \
  -nodes \
  -out calico-node.csr \
  -subj "/CN=calico-node"
# 使用typhaca的根证书签发
openssl x509 -req -in calico-node.csr \
  -CA typhaca.crt \
  -CAkey typhaca.key \
  -CAcreateserial \
  -out calico-node.crt \
  -days 365
# 保存到Secret
kubectl create secret generic -n kube-system calico-node-certs --from-file=calico-node.key --from-file=calico-node.crt

生成服务使用的 ServiceAccount、RBAC 以及部署对应的 Daemon。

参考:https://docs.projectcalico.org/getting-started/kubernetes/hardway/install-node

BGP Peer 配置

参考:https://docs.projectcalico.org/getting-started/kubernetes/hardway/configure-bgp-peering

Tigera-Operator 安装

使用上述手工方式,可以比较细致的了解每一步的安装流程,但是无法安装最新版本的Calico(鄙人没有找到各个版本最新的Yaml文件)。

通过以下方式部署Tigera-Operator:

1
2
  helm repo add projectcalico https://docs.projectcalico.org/charts
  helm pull projectcalico/tigera-operator --version v3.20.0

为了在内网环境中安装,指定一下values.yaml文件,并且将installation.enabled设置为false,阻止自动安装calico服务:

1
2
3
4
5
6
7
8
9
installation:
  enabled: false
tigeraOperator:
  image: calico/tigera-operator
  version: v1.20.0
  registry: registry.hci.io
calicoctl:
  image: registry.hci.io/calico/ctl
  tag: v3.20.0

由于Helm包中安装的命名空间写死为tigera-operator,因此Helm指定Namespace为kube-system,但是实际安装出来的Pod运行在tigera-operator:

1
helm install tigera-operator tigera-operator-v3.21.0-0.tgz -f values.yaml -n kube-system

Calico镜像

在离线环境安装时,tigera-operator允许用户创建ImageSet对象,该对象中可以指定Operator使用的镜像地址:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
kubectl apply -f - <<EOF
kind: ImageSet
apiVersion: operator.tigera.io/v1
metadata:
  name: calico-v3.20.0
spec:
  images:
    - image: "calico/cni"
      digest: "sha256:7c43c152cdf589ed789528c4055503d2f2b0ee943d7815c820fd8e99793f36b3"
    - image: "calico/kube-controllers"
      digest: "sha256:b206ed8a5dd2384d11172c0244a94bea2d0d191208926fd6970484c3692641df"
    - image: "calico/node"
      digest: "sha256:913955a36179a53d36a0df7f26319a5278991eea2514eab339cce15df24c220c"
    - image: "calico/typha"
      digest: "sha256:b68dfbf6ea1fed47d709addfa803257e49f0bbb72d8d84832560727872f6108d"
    - image: "calico/pod2daemon-flexvol"
      digest: "sha256:1cf3c28a3d384bb89d3fb3a73f6c8242eb4a40bd0a7c6c828692ded8aa3ea072"
    - image: "calico/apiserver"
      digest: "sha256:09565b70a7c8421f3a091c3c760abb53e9675f2b0c54ebc7e464936ca9190bb2"
EOF

以下命令获取tigera/operator镜像中指定的默认镜像:

1
docker run --rm registry.hci.io/calico/tigera-operator:v1.20.0 --print-images=list

说明:ImageSet强制使用digest而不使用镜像tag

上述命令会返回社区版本和企业版本的镜像,社区版通常只需要docker.io/calico打头的以下镜像

  • docker.io/calico/cni:v3.20.0
  • docker.io/calico/kube-controllers:v3.20.0
  • docker.io/calico/node:v3.20.0
  • docker.io/calico/typha:v3.20.0
  • docker.io/calico/pod2daemon-flexvol:v3.20.0
  • docker.io/calico/apiserver:v3.20.0

创建Installation

Installation表示K8S集群中Calico的部署实例全局只能部署一个,并且名称必须为Default

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
kubectl apply -f - <<EOF
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
  name: default
spec:
  # variant 指定安装社区版还是企业版
  variant: Calico
  # 镜像路径的格式为 <registry>/<imagePath>/<imagePrefix><imageName>:<image-tag>
  # 其中 <imageName>:<image-tag> 指定在ImageSet中
  registry: registry.hci.io
  imagePath: ""
  imagePrefix: ""
EOF

创建Installation后,Calico服务会被自动安装,并且自动匹配集群中ImageSet,执行以下命令验证Calico状态以及使用的ImageSet

1
2
kubectl get tigerastatus
kubectl get installation default -o yaml | grep imageSet

installation中字段的定义,可以参考:https://docs.projectcalico.org/reference/installation/api

代码仓库

Calico项目的源码在Github中,被分布在不同的代码仓库中:

仓库名称 说明
projectcalico/calico calico是Calico官网静态页面的源码,能够获取到每个Release版本的二进制文件,以及tigera-operator的helm包
projectcalico/cni-plugin CNI插件的源码仓库
projectcalico/calicotl calicotl的源码仓库
projectcalico/typha typha服务的源码仓库
projectcalico/node 用于Calico/Node服务镜像构建的仓库,Felix等实际二进制程序的源码在各自同名仓库中
tigera/operator 安装工具对应的源码仓库