Istio ServiceEntry 流量管理

324 阅读6分钟

istio serviceEntry

# 现有环境
kubectl get gw
#mygw 
kubectl get vs
#myvs ["mygw"] ["aa.yuan.cc"]
kubectl get dr
#mydr svc1 
kubectl get pods
#pod1
#pod2
​
kubectl exec -it pod1 -- bash
curl https://www.baidu.com   #可以访问到外网,代表所有的数据都是可以出去的
# serviceEntry 就可以解决这个问题

创建 ServiceEntry

mkdir chap4 && cd chap4
cp ../chap3/vs.yaml ../chap3/mygw1.yaml ./

# 编辑 serviceEntry yaml
vim se1.yaml

apiVersion: networking.istio.io/v1alpha3 
kind: ServiceEntry 
metadata: 
  name: myse
spec: 
  hosts: 
  - www.baidu.com #对此网址进行限制
  ports: 
  - number: 443  #通过443访问
    name: https  
    protocol: HTTPS #通过HTTPS的方式访问
  resolution: DNS  #解析通过DNS解析
  location: MESH_EXTERNAL  # MESH_EXTERNAL -- 网格外部;MESH_INTERNAL -- 网格内部
  
# 创建 serviceEntry
kubectl apply -f se1.yaml
# 进入pod测试
kubectl exec -it pod1 -- bash
curl https://www.baidu.com #并没有被拦截,代表通过DNS并不可行

# 相当于黑名单
# 修改 serviceEntry ,通过自定义指定不可访问
vim se1.yaml

apiVersion: networking.istio.io/v1alpha3 
kind: ServiceEntry 
metadata: 
  name: myse
spec: 
  hosts: 
  - www.baidu.com #对此网址进行限制
  ports: 
  - number: 443  #通过443访问
    name: https  
    protocol: HTTPS #通过HTTPS的方式访问
  #resolution: DNS  #解析通过DNS解析
  resolution: STATIC
  location: MESH_EXTERNAL
  endpoints: 
  - address: 192.168.26.3 #指定访问的 www.baidu.com 就是 192.168.26.3
  
# 重启 serviceEntry
kubectl apply -f se1.yaml
# 进入pod测试
kubectl exec -it pod1 -- bash
curl https://www.baidu.com  #访问被拦击

默认策略

# 修改策略
kubectl edit configmap istio -n istio-system -o yaml

data: 
  mesh: |-
    accessLogFile: /dev/stdout 
    defaultConfig: 
      discoveryAddress: istiod.istio-system.svc:15012 
      proxyMetadata: {} 
      tracing: 
        zipkin: 
          address: zipkin.istio-system:9411
    enablePrometheusMerge: true 
    outboundTrafficPolicy:        # 如果不加则默认是 ALLOW_ANY
      mode: REGISTRY_ONLY         # 只有注册的,才可以访问
    rootNamespace: istio-system
#此策略也可以在安装istio时进行设置:
istioctl install --set profile=demo -y --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
  
# 测试
kubectl exec -it pod1 -- bash
curl https://www.jd.com  #访问不通
curl svc1  #可以访问通,返回111

# 模拟环境 创建 podx
vim /root/podx.yaml

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: podx
  name: podx
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: podx
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

#启动 podx
kubectl apply -f /root/podx.yaml

#启动 svcx
kubectl expose --name=svcx pod podx --port=80

# 使用 pod1 测试
kubectl exec -it pod1 -- bash
curl svcx #可以访问到

# 更改 podx 的 namespace 再次测试 (default namespace 没有自动被 istio 注入)
kubectl apply -f podx.yaml -n default 
kubectl expose --name=svcx pod podx --port=80 -n default


------------
#pod1 还是可以访问通的,可能是集群内是可以访问的通的,只是限制出口的流量
kubectl get pods -n default
kubectl delete pod podx -n default
kubectl get svc svcx -n default
kubectl delete svc svcx -n default

# 相当于设置 se 白名单
# 修改 serviceEntry yaml
vim se1.yaml

apiVersion: networking.istio.io/v1alpha3 
kind: ServiceEntry 
metadata: 
  name: myse
spec: 
  hosts: 
  - www.baidu.com  #此处就相当于了放行
  - www.jd.com
  ports: 
  - number: 443  #通过443访问
    name: https  
    protocol: HTTPS #通过HTTPS的方式访问
  resolution: DNS  #解析通过DNS解析
  #resolution: STATIC
  location: MESH_EXTERNAL
# 启动 se ,进行测试
kubectl apply -f se1.yaml
# 使用 pod1 测试
kubectl exec -it pod1 -- bash
curl https://www.jd.com     #可以访问通
curl https://www.baidu.com  #可以访问通
curl https://www.qq.com     #访问不通

#如果想修改的所有放行,则修改回之前的策略
kubectl edit configmap istio -n istio-system -o yaml

    outboundTrafficPolicy:        # 如果不加则默认是 ALLOW_ANY
      mode: ALLOW_ANY  # 改为所有
#删除 se
kubectl delete -f se1.yaml
# pod 则默认都可以访问外网地址

workEntry

workEntry管理流程图.png

目的是把 其他主机/虚拟机/服务器 纳入到service mesh里

此处现将我们现有的测试环境做一套快照,不然环境弄乱了不好恢复.....

  • 启用主动注册的性能 (先不做)
istioctl install --set profile=demo --set 
​
values.pilot.env.PILOT_ENABLE_WORKLOAD_ENTRY_AUTOREGISTRATION=true
  • 启动 自动注册 和 智能DNS
istioctl install --set profile=demo --set values.pilot.env.PILOT_ENABLE_WORKLOAD_ENTRY_AUTOREGISTRATION=true --set meshConfig.defaultConfig.proxyMetadata.ISTIO_META_DNS_CAPTURE='"true"'#此处本地的测试环境启动智能DNS会失败,就启动自动注册就好
istioctl install --set profile=demo --set values.pilot.env.PILOT_ENABLE_WORKLOAD_ENTRY_AUTOREGISTRATION=true
​
kubectl get pods -n istio-system -o wide
#istiod  10.244.186.142
​
kubeadm config view
# podSubnet: 10.244.0.0/16

新创建虚拟机进行测试

#创建虚拟机 IP:192.168.26.23, ping k8s pod 的 ip 是 ping 不通的
ping 10.244.186.142  #不通#添加网关
route add -net 10.244.0.0 gw 192.168.26.82 netmask 255.255.0.0 #gw的ip是gw所在节点的IP,可以写进配置文件中永久生效
​
ping 10.244.186.142 #可以访问了## 下载 sidecar 安装包,根据系统来选择
https://storage.googleapis.com/istio-release/releases/1.10.3/deb/istio-sidecar.deb
dpkg -i istio-sidecar.deb
​
https://storage.googleapis.com/istio-release/releases/1.10.3/rpm/istio-sidecar.rpm
rpm -ivh istio-sidecar.rpm

创建 WorkloadGroup

cd chap4 && vim mywg.yaml

apiVersion: networking.istio.io/v1alpha3 
kind: WorkloadGroup 
metadata: 
  name: mywg 
  namespace: ns1 
spec: 
  metadata: 
    annotations: {} 
    labels: 
      app: test  #指定的标签
  template: 
    ports: {} 
    serviceAccount: sa1 #使用sa1来管理
    
# 创建 wg
kubectl get wg 
kubectl apply -f mygw.yaml && kubectl get wg 

# 创建 sa
kubectl get sa
# default 1 ##是在 default 的 namespace
kubens
# ns1 所在 ns1 的 namespace 上

#创建sa1
kubectl create sa sa1

# 生成虚拟机安装所需要的文件
mkdir 11
istioctl x workload entry configure -f mywg.yaml -o 11
ls 11
# cluster.env  hosts  istio-token  mesh.yaml  root-cert.pem
# 把11目录及里面的东西拷贝到虚拟机
scp -r 11/ 192.168.26.23:~

虚拟机的操作

# centos 7.6 
# 在虚拟机上安装根证书
mkdir -p /etc/certs
cp 11/root-cert.pem /etc/certs/root-cert.pem
​
# 安装令牌
mkdir -p /var/run/secrets/tokens
cp 11/istio-token /var/run/secrets/tokens/istio-token
cp 11/cluster.env /var/lib/istio/envoy/cluster.env  
cat /var/lib/istio/envoy/cluster.env   #可以看到集群生成的一些配置信息# 将网格配置安装到/etc/istio/config/mesh
cp 11/mesh.yaml /etc/istio/config/mesh
​
mkdir -p /etc/istio/proxy
chown -R istio-proxy /var/lib/istio /etc/certs /etc/istio/proxy /etc/istio/config /var/run/secrets /etc/certs/root-cert.pem  #安装完 sidecar 自动生成 istio-proxy 的用户# 修改/etc/hosts
#kubectl get pods -o wide -n istio-system 拿到 istiod 的 IP 地址
10.244.186.142 istiod.istio-system.svc
​
# 查看并启动 istio 的 sidecar
systemctl list-unit-files | grep istio
#disabled
systemctl start istio.service
systemctl enable istio.service #设置上开机自启动
systemctl is-active istio.service
#activating# 查看日志
tail -f /var/log/istio/istio.log
#报有 eroor 。。。 
#尝试换一个系统,用 ubuntu 试一下
# 使用 ubuntu 18.04 试一下,ip 改为 192.168.26.23 ,再做一遍上面的操作
https://storage.googleapis.com/istio-release/releases/1.10.3/deb/istio-sidecar.deb
dpkg -i istio-sidecar.deb
​
​
# 后把11目录及里面的东西拷贝到虚拟机
scp -r 11/ 192.168.26.23:~  #冲突那就是ssh的hosts有问题,删掉就可以了
vim ~/.ssh/known_hosts #删除192.168.26.23信息
scp -r 11/ 192.168.26.23:~
​
# 在虚拟机上安装根证书
mkdir -p /etc/certs
cp 11/root-cert.pem /etc/certs/root-cert.pem
​
# 安装令牌
mkdir -p /var/run/secrets/tokens
cp 11/istio-token /var/run/secrets/tokens/istio-token
cp 11/cluster.env /var/lib/istio/envoy/cluster.env  
cat /var/lib/istio/envoy/cluster.env   #可以看到集群生成的一些配置信息# 将网格配置安装到/etc/istio/config/mesh
cp 11/mesh.yaml /etc/istio/config/mesh
​
mkdir -p /etc/istio/proxy
chown -R istio-proxy /var/lib/istio /etc/certs /etc/istio/proxy /etc/istio/config /var/run/secrets /etc/certs/root-cert.pem  #安装完 sidecar 自动生成 istio-proxy 的用户# 修改/etc/hosts
#kubectl get pods -o wide -n istio-system 拿到 istiod 的 IP 地址
10.244.186.142 istiod.istio-system.svc
​
#添加路由
route add -net 10.244.0.0 gw 192.168.26.82 netmask 255.255.0.0
# 删除路由
route delete 10.244.0.0 dev ens32  #SIOCDELRT: No such process
route -n #查看路由
route delete gw 10.244.0.0 dev ens32  #gw: Host name lookup filure
route -n #查看路由
ping 10.244.186.142 #测试能否 ping 通,此时是 ping 通的# 查看并启动istio
systemctl is-active istio #inactive  还没有启动
systemctl start istio && systemctl enable istio 
systemctl is-active istio  #active 已经启动了起来# 查看日志
tail -f /var/log/istio/istio.log #已经启动了,日哦 可以了,看来centos没有ubuntu支持的好
kubectl get we #No resources found in ns1 namespace

# 为了防止目录太乱,在 chap 创建 xx 存放 we yaml
mkdir xx && cd xx
vim we.yaml

apiVersion: networking.istio.io/v1beta1 
kind: WorkloadEntry 
metadata: 
  name: mywe
  namespace: ns1 
spec: 
  serviceAccount: sa1   # 对应 WorkloadGroup 的 sa 
  address: 192.168.26.23  # 相当于把此虚拟机当成 pod 来用
  labels: 
    app: test 
    #instance-id: vm2
---
apiVersion: v1 
kind: Service 
metadata: 
  name: vm2-svc
  namespace: ns1 
  labels: 
    app: test 
spec: 
  ports: 
  - port: 80 
    name: http-vm 
    targetPort: 80 
  selector: 
    app: test

# 创建 we
kubectl apply -f we.yaml
kubectl get svc
#svc1
#svcx  #用不到了,删掉了 
#vm2-svc #创建了此 svc
kubectl delete svc svcx

# 测试连通
#vm23 启动80端口
python3 -m http.server 80

kubectl exec -it pod1 -- bash
curl vm2-svc  #可以看到返回内容

#vm23 
apt-get install nginx -y
echo "hello vm vm"
systemctl start nginx

kubectl exec -it pod1 -- bash
curl vm2-svc  #可以看到 nginx 页面内容
--------------------------------------------------------------
#此时代表 istio 网格内 pod 和 虚拟机vm23已经建立了通信
#清理一下环境
cd xx
kubectl delete -f we.yaml
cd ../ && kubectl delete -f mywg.yaml

外部服务器与网格内服务通信

cd chap4
kubectl apply -f mywg.yaml
cd xx && kubectl apply -f we.yaml
kubectl get gw
kubectl get vs
cp vs.yaml vs2.yaml

#编辑 vs2 yaml
vim vs2.yaml

apiVersion: networking.istio.io/v1alpha3 
kind: VirtualService
metadata: 
  name: myvs2
spec:
  hosts:
  - "bb.yuan.cc"
  gateways:
  - mygw
  http:
  - route:
    - destination:
        host: vm2-svc
        
# 启动 vs2
kubectl apply -f vs2.yaml

#创建一个虚拟机,在此虚拟机操作
vim /etc/hosts
192.168.26.230 bb.yuan.cc  bb
curl bb.yuan.cc
# 返回 vm23 nginx的信息:hello vm vm