![](/style/images/good.png)
![](/style/images/bad.png)
基于kubeadm搭建istio多集群
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
- 更新
apt
包索引并安装使用 Kubernetesapt
仓库所需要的包:
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
- 添加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
- 更新
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不互通。
- 其次我们选择共享控制平面,即主从架构。
在此配置中,集群 cluster1
将监测两个集群 API Server 的服务端点。 以这种方式,控制平面就能为两个集群中的工作负载提供服务发现。
跨集群边界的服务负载,通过专用的东西向流量网关,以间接的方式通讯。 每个集群中的网关必须可以从其他集群访问。
cluster2
中的服务将通过相同的的东西向网关访问 cluster1
控制平面。
下载istio
curl -L https://istio.io/downloadIstio | sh -
下载最新包- 转到 Istio 包目录。例如,如果包是
istio-1.10.0
:
$ cd istio-1.10.0
安装目录包含:
samples/
目录下的示例应用程序bin/
目录下的[istioctl](https://istio.io/latest/zh/docs/reference/commands/istioctl)
客户端二进制文件 .
- 将
istioctl
客户端加入搜索路径(Linux or macOS):
$ export PATH=$PWD/bin:$PATH
设置context环境变量
由于涉及到切换集群,我们先设置好环境变量:
$ export CTX_CLUSTER1=<your cluster1 context>
$ export CTX_CLUSTER2=<your cluster2 context>
插入ca证书
在 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.pem
,ca-key.pem
,root-cert.pem
和 cert-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
- 返回 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 网格。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK