10

基于kubeadm搭建istio多集群

 3 years ago
source link: https://fredal.xin/multi-cluster-istio-based-on-kubeadm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

准备2台机器。

安装kubernetes

我们基于kubeadm安装。

安装kubeadm

允许 iptables 检查桥接流量

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system

安装runtime

选择安装docker,参考容器运行时

安装 kubeadm、kubelet 和 kubectl

  1. 更新 apt 包索引并安装使用 Kubernetes apt 仓库所需要的包:
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
  1. 添加apt仓库,这边可以选择添加阿里云的库!
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
  1. 更新 apt 包索引,安装 kubelet、kubeadm 和 kubectl,并锁定其版本
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

如果不成功,先通过一些方法下载:https://packages.cloud.google.com/apt/doc/apt-key.gpg, 保存到当前目录。再执行:cat apt-key.gpg | sudo apt-key add - 再执行更新apt-get update,成功。

使用 kubeadm 创建集群

初始化需要的镜像可以通过kubeadm config images list 来查看:

k8s.gcr.io/kube-apiserver:v1.21.1
k8s.gcr.io/kube-controller-manager:v1.21.1
k8s.gcr.io/kube-scheduler:v1.21.1
k8s.gcr.io/kube-proxy:v1.21.1
k8s.gcr.io/pause:3.4.1
k8s.gcr.io/etcd:3.4.13-0
k8s.gcr.io/coredns/coredns:v1.8.0

使用下面命令提前拉取镜像

kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers

拉取不到的,去docker hub上拉下一样的版本然后docker tag打成需要的样子。

初始化控制平面节点

kubeadm init

kubeadm 还会提示我们第一次使用 Kubernetes 集群所需要的配置命令:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

查看下node

NAME           STATUS   ROLES                  AGE    VERSION
n251-241-069   Ready    control-plane,master   164m   v1.21.1

由于我们只有单节点,如果希望能够在master节点上调度Pod,就可以运行如下的命令:

kubectl taint nodes --all node-role.kubernetes.io/master-

这样就删除主节点上的 node-role.kubernetes.io/master 污点,调度器就能将Pod调度到 master 节点上。

安装网络插件

这里我们选择weave

kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

部署完成后,我们可以通过 kubectl get 重新检查 Pod 的状态,可以看到codedns也起来了,在部署网络插件前,coredns是不会运行的!:

# kubectl get pods -n kube-system
NAME                               READY   STATUS    RESTARTS   AGE
coredns-74ff55c5b-f95sj            1/1     Running   0          131m
coredns-74ff55c5b-zvjdz            1/1     Running   0          131m
etcd-yxj-test                      1/1     Running   0          131m
kube-apiserver-yxj-test            1/1     Running   0          131m
kube-controller-manager-yxj-test   1/1     Running   0          131m
kube-proxy-nm4tt                   1/1     Running   0          131m
kube-scheduler-yxj-test            1/1     Running   0          131m
weave-net-pl4qp                    2/2     Running   1          126m

优化kubeconfig

用本地终端来操作集群会比较方便,可以把安装好的两个集群的kubeconfig都下载到本地。

可以使用kubecm 来merge多个kubeconfig,本地切换context即可连接到不同的集群。

安装多网络主从ISTIO集群

  • 我们的环境是多网络,podIP不互通。
  • 其次我们选择共享控制平面,即主从架构。

2021-06-10-F2jNPf

在此配置中,集群 cluster1 将监测两个集群 API Server 的服务端点。 以这种方式,控制平面就能为两个集群中的工作负载提供服务发现。

跨集群边界的服务负载,通过专用的东西向流量网关,以间接的方式通讯。 每个集群中的网关必须可以从其他集群访问。

cluster2 中的服务将通过相同的的东西向网关访问 cluster1 控制平面。

下载istio

  1. curl -L https://istio.io/downloadIstio | sh - 下载最新包
  2. 转到 Istio 包目录。例如,如果包是 istio-1.10.0
$ cd istio-1.10.0

安装目录包含:

  • samples/ 目录下的示例应用程序
  • bin/ 目录下的 [istioctl](https://istio.io/latest/zh/docs/reference/commands/istioctl) 客户端二进制文件 .
  1. istioctl 客户端加入搜索路径(Linux or macOS):
$ export PATH=$PWD/bin:$PATH

设置context环境变量

由于涉及到切换集群,我们先设置好环境变量:

$ export CTX_CLUSTER1=<your cluster1 context>
$ export CTX_CLUSTER2=<your cluster2 context>

插入ca证书

2021-06-10-pwsnbc

在 Istio 安装包的顶层目录下,创建一个目录来存放证书和密钥:

$ mkdir -p certs
$ pushd certs

生成根证书和密钥:

$ make -f ../tools/certs/Makefile.selfsigned.mk root-ca

将会生成以下文件:

  • root-cert.pem:生成的根证书
  • root-key.pem:生成的根密钥
  • root-ca.conf:生成根证书的 openssl 配置
  • root-cert.csr:为根证书生成的 CSR

对于每个集群,为 Istio CA 生成一个中间证书和密钥。 以下是集群 cluster1 的例子:

$ make -f ../tools/certs/Makefile.selfsigned.mk cluster1-cacerts

运行以上命令,将会在名为 cluster1 的目录下生成以下文件:

  • ca-cert.pem:生成的中间证书
  • ca-key.pem:生成的中间密钥
  • cert-chain.pem:istiod 使用的生成的证书链
  • root-cert.pem:根证书

您可以使用一个您选择的字符串来替换 cluster1。例如,使用 cluster2-cacerts 参数,您可以在一个名为 cluster2 的目录中创建证书和密钥。

如果您正在离线机器上进行此操作,请将生成的目录复制到可以访问集群的机器上。

在每个集群中,创建一个私密 cacerts,包括所有输入文件 ca-cert.pemca-key.pemroot-cert.pemcert-chain.pem。例如,在 cluster1 集群上:

$ kubectl create namespace istio-system
$ kubectl create secret generic cacerts -n istio-system \
      --from-file=cluster1/ca-cert.pem \
      --from-file=cluster1/ca-key.pem \
      --from-file=cluster1/root-cert.pem \
      --from-file=cluster1/cert-chain.pem
  1. 返回 Istio 安装的顶层目录:
$ popd

安装主从集群

为 cluster1设置缺省网络

创建命名空间 istio-system 之后,我们需要设置集群的网络:

$ kubectl --context="${CTX_CLUSTER1}" get namespace istio-system && \
  kubectl --context="${CTX_CLUSTER1}" label namespace istio-system topology.istio.io/network=network1

将cluster1设为主集群

cluster1 创建 Istio 配置文件:

$ cat <<EOF > cluster1.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  values:
    global:
      meshID: mesh1
      multiCluster:
        clusterName: cluster1
      network: network1
EOF

将配置文件应用到 cluster1

$ istioctl install --context="${CTX_CLUSTER1}" -f cluster1.yaml

在cluster1安装东西向网关

cluster1 安装专用的东西向流量网关。 默认情况下,此网关将被公开到互联网上。 生产系统可能需要额外的访问限制(即:通过防火墙规则)来防止外部攻击。 咨询你的云服务商,了解可用的选择。

$ samples/multicluster/gen-eastwest-gateway.sh \
    --mesh mesh1 --cluster cluster1 --network network1 | \
    istioctl --context="${CTX_CLUSTER1}" install -y -f -

等待东西向网关获取外部 IP 地址

$ kubectl --context="${CTX_CLUSTER1}" get svc istio-eastwestgateway -n istio-system
NAME                    TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)   AGE
istio-eastwestgateway   LoadBalancer   10.80.6.124   34.75.71.237   ...       51s

这时候如果没有云服务商提供LB的话,可以自己配置一个可访问的externalIPs到spec下,edit或者patch对应的svc:

clusterIP: 10.101.23.43
clusterIPs:
- 10.101.23.43
externalTrafficPolicy: Cluster
externalIPs:
- 10.x.x.x

开发cluster1控制面

安装 cluster2 之前,我们需要先开放 cluster1 的控制平面,以便 cluster2 中的服务能访问服务发现。

$ kubectl apply --context="${CTX_CLUSTER1}" -f \
    samples/multicluster/expose-istiod.yaml

开放cluster1的服务

因为集群位于不同的网络,我们需要开放两个集群的东西向网关上的所有用户服务(*.local)。 虽然此网关被公开到互联网,但它背后的服务只能被拥有可信 mTLS 证书和工作负载 ID 的服务访问, 就像它们处于同一个网络一样。

$ kubectl --context="${CTX_CLUSTER1}" apply -n istio-system -f \
    samples/multicluster/expose-services.yaml

为cluster2设置缺省网络

命名空间 istio-system 创建之后,我们需要设置集群的网络:

$ kubectl --context="${CTX_CLUSTER2}" get namespace istio-system && \
  kubectl --context="${CTX_CLUSTER2}" label namespace istio-system topology.istio.io/network=network2

启用API Server访问cluster2配置

为了能够访问 cluster2 API Server,我们要生成一个远程 Secret,并把它应用到 cluster1

$ istioctl x create-remote-secret \
    --context="${CTX_CLUSTER2}" \
    --name=cluster2 | \
    kubectl apply -f - --context="${CTX_CLUSTER1}"

将cluster2设置为从集群

保存 cluster1 东西向网关的地址。

$ export DISCOVERY_ADDRESS=$(kubectl \
    --context="${CTX_CLUSTER1}" \
    -n istio-system get svc istio-eastwestgateway \
    -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

现在,为 cluster2 创建一个从集群配置:

$ cat <<EOF > cluster2.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  profile: remote
  values:
    global:
      meshID: mesh1
      multiCluster:
        clusterName: cluster2
      network: network2
      remotePilotAddress: ${DISCOVERY_ADDRESS}
EOF

将此配置应用到 cluster2

$ istioctl install --context="${CTX_CLUSTER2}" -f cluster2.yaml

在cluster2安装东西向网关

仿照上面 cluster1 的操作,在 cluster2 中安装专用于东西向流量的网关,并且开放用户服务。

$ samples/multicluster/gen-eastwest-gateway.sh \
    --mesh mesh1 --cluster cluster2 --network network2 | \
    istioctl --context="${CTX_CLUSTER2}" install -y -f -

等待东西向网关获取外部 IP 地址:

$ kubectl --context="${CTX_CLUSTER2}" get svc istio-eastwestgateway -n istio-system
NAME                    TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)   AGE
istio-eastwestgateway   LoadBalancer   10.0.12.121   34.122.91.98   ...       51s

开放cluster2中的服务

仿照上面 cluster1 的操作,通过东西向网关开放服务。

$ kubectl --context="${CTX_CLUSTER2}" apply -n istio-system -f \
    samples/multicluster/expose-services.yaml

至此在跨网络、主-从架构的集群上,成功的安装了 Istio 网格。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK