# 虚拟机部署

## 先决条件

* 虚拟机两台

第一台作为k8s 部署istio,第二台作为vm,系统为centos8,centos 7要升级glibc 麻烦的很,第二台通过静态路由访问 k8s内部的pod,

本环境:

```
vm1: 192.168.8.131
vm1上k8s pod cird: 10.201.0.0/24
vm2: 192.168.8.170
vm2添加静态路由:
route add -net 10.201.0.0 gw 192.168.8.131 netmask 255.255.255.0
```

* 1.16以上k8s
* k8s apiserver 开启服务账户卷投影

```
    - --service-account-api-audiences=api,istio-ca
    - --service-account-issuer=kubernetes.default.svc
    - --service-account-signing-key-file=/etc/kubernetes/pki/sa.key
```

* 设置环境变量VM\_APP,WORK\_DIR,VM\_NAMESPACE,和SERVICE\_ACCOUNT

```
#VM_APP: 该虚拟机将运行的服务名称
#VM_NAMESPACE: 服务命名空间名称
#WORK_DIR:工作目录
#SERVICE_ACCOUNT 用于该虚拟机的k8s serviceaccount名称
cat vm.env
export VM_APP=test
export VM_NAMESPACE=test
export WORK_DIR=./test
export SERVICE_ACCOUNT=test

. vm.env
```

* 创建工作目录

```
mkdir -p "${WORK_DIR}"
```

## 安装Istio控制面板

* 安装Istio。

```
 istioctl install --set profile=demo  --set meshConfig.defaultConfig.proxyMetadata.ISTIO_META_DNS_CAPTURE='\"true\"'
```

> 在部署的时间有些问题,pod的pilot-agent不能正常的识别ISTIO\_META\_DNS\_CAPTURE导致没有开启dns解析,感觉是字符拼接的问题,也可能是姿势不对
>
> 手动导出 `istioctl manifest generate --set profile=demo --set meshConfig.defaultConfig.proxyMetadata.ISTIO_META_DNS_CAPTURE=\'true\' > config.yaml` 然后修改 `ISTIO_META_DNS_CAPTURE: "true"`

* 部署东西向网关

在本示例中将直接将虚拟机连接pod IP不需要部署

```
samples/multicluster/gen-eastwest-gateway.sh --single-cluster | istioctl install -y -f -
```

* 使用提供的示例配置暴露控制平面

```
kubectl apply -f samples/multicluster/expose-istiod.yaml
```

## 配置虚拟机名称空间

* 创建将托管虚拟机的名称空间:

```
kubectl create namespace "${VM_NAMESPACE}"
```

* 为虚拟机创建一个服务帐户:

```
kubectl create serviceaccount "${SERVICE_ACCOUNT}" -n "${VM_NAMESPACE}"
```

## 创建文件以传输到虚拟机

* 为vm创建WorkloadGroup模板

WorkloadGroup是1.8新加的CRD,用于描述工作负载实例的集合。它提供了一个规范,工作负载实例可用于引导其代理,包括元数据和身份。它仅旨在与非k8s工作负载(例如虚拟机)一起使用,并且旨在模仿现有的用于Kubernetes工作负载的Sidecar注入和部署规范模型,以引导Istio代理。

```
istioctl x workload group create --name "${VM_APP}" --namespace "${VM_NAMESPACE}" --labels app="${VM_APP}" --serviceAccount "${SERVICE_ACCOUNT}" > workloadgroup.yaml
```

* 使用`istioctl x workload entry`命令生成虚拟机安装所需要的文件:

```
istioctl x workload entry configure -f workloadgroup.yaml -o "${WORK_DIR}"

#cluster.env:包含标识哪些名称空间,服务帐户,网络CIDR和(可选)要捕获的入站端口的元数据。
#istio-token:用于从CA获取证书的Kubernetes令牌。
#mesh.yaml:提供其他Istio元数据,包括网络名称,信任域和其他值。
#root-cert.pem:用于认证的根证书。
#hosts:绑定istiod的host
```

## 配置虚拟机

在要添加到Istio网格的虚拟机上运行以下命令:

* 将workdir内容发送到虚拟机。在选择安全传输这些文件的方式时,应考虑您的信息安全策略。为了方便起见,将所有必需的文件传输到虚拟机中"${HOME}"目录。
* 在以下位置安装根证书/etc/certs:

```
sudo mkdir -p /etc/certs
sudo cp "${HOME}"/root-cert.pem /etc/certs/root-cert.pem
```

* 在/var/run/secrets/tokens以下位置安装令牌:

```
sudo  mkdir -p /var/run/secrets/tokens
sudo cp "${HOME}"/istio-token /var/run/secrets/tokens/istio-token
```

* 安装包含Istio虚拟机集成运行时的软件包:

```
curl -LO https://storage.googleapis.com/istio-release/releases/1.8.0/rpm/istio-sidecar.rpm
sudo yum install -y istio-sidecar.rpm
```

* 在/var/lib/istio/envoy/目录中安装cluster.env

```
sudo cp "${HOME}"/cluster.env /var/lib/istio/envoy/cluster.env
```

* 将网格配置安装到/etc/istio/config/mesh:

```
sudo cp "${HOME}"/mesh.yaml /etc/istio/config/mesh
```

* 将istiod主机添加到/etc/hosts:

> 这里我们没有外部lb不需要设置

```
sudo sh -c 'cat $(eval echo ~$SUDO_USER)/hosts >> /etc/hosts'
```

查看itiod的IP并绑定host

```
10.201.0.14 istiod.istio-system.svc
```

* 修改权限:

```
sudo mkdir -p /etc/istio/proxy
sudo chown -R istio-proxy /var/lib/istio /etc/certs /etc/istio/proxy /etc/istio/config /var/run/secrets /etc/certs/root-cert.pem
```

## 在虚拟机中启动Istio

启动Istio代理:

```
systemctl start istio
```

## 验证Istio是否成功工作

* 检查登录/var/log/istio/istio.log。您应该看到类似于以下内容的条目:

```
[root@worker ~]# tail -f  /var/log/istio/istio.log
2020-11-21T04:27:44.248846Z    info    sds    resource:default pushed key/cert pair to proxy
2020-11-21T04:33:30.756067Z    info    xdsproxy    disconnected from XDS server: istiod.istio-system.svc:15012
2020-11-21T04:33:31.285240Z    info    xdsproxy    Envoy ADS stream established
2020-11-21T04:33:31.285453Z    info    xdsproxy    connecting to upstream XDS server: istiod.istio-system.svc:15012
2020-11-21T04:38:48.670065Z    info    xdsproxy    disconnected from XDS server: istiod.istio-system.svc:15012
2020-11-21T04:38:49.105717Z    info    xdsproxy    Envoy ADS stream established
2020-11-21T04:38:49.105884Z    info    xdsproxy    connecting to upstream XDS server: istiod.istio-system.svc:15012
2020-11-21T04:54:00.782318Z    info    xdsproxy    disconnected from XDS server: istiod.istio-system.svc:15012
2020-11-21T04:54:01.037151Z    info    xdsproxy    Envoy ADS stream established
2020-11-21T04:54:01.037506Z    info    xdsproxy    connecting to upstream XDS server: istiod.istio-system.svc:15012
```

* 创建一个命名空间以部署基于Pod的服务:

```
kubectl create namespace sample
kubectl label namespace sample istio-injection=enabled
```

* 部署HelloWorld服务:

```
kubectl apply -f samples/helloworld/helloworld.yaml -n sample
```

将请求从您的虚拟机发送到服务:

```
[root@worker ~]# curl helloworld.sample.svc:5000/hello
Hello version: v2, instance: helloworld-v2-54df5f84b-tts2z
[root@worker ~]# curl helloworld.sample.svc:5000/hello
Hello version: v1, instance: helloworld-v1-776f57d5f6-f72k9
```

## 在k8s内部访问vm服务

创建workloadentry 和service

```
apiVersion: networking.istio.io/v1beta1
kind: WorkloadEntry
metadata:
  name: test-vm-2
  namespace: test
spec:
  serviceAccount: test
  address: 192.168.8.170
  labels:
    app: test
    instance-id: vm2

---

apiVersion: v1
kind: Service
metadata:
  name: test
  namespace: test
  labels:
    app: test
spec:
  ports:
  - port: 80
    name: http-vm
    targetPort: 80
  selector:
    app: test
```

### 在vm上启动一个http server

```
python3 -m http.server 80
```

### 测试

```
kubectl exec -it helloworld-v1-776f57d5f6-nhmbc -n sample -- curl test.test.svc.cluster.local
Defaulting container name to helloworld.
Use 'kubectl describe pod/helloworld-v1-776f57d5f6-nhmbc -n sample' to see all of the containers in this pod.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
<li><a href="cluster.env">cluster.env</a></li>
...
</ul>
<hr>
</body>
</html>
```

## 原理概述

从上面我们可以看到vm上已经可以方便的访问k8s内部的服务,首先我们开启了1.8中`ISTIO_META_DNS_CAPTURE`功能,实现pilot-agent实现dns解析的功能,pilot-agent监听15053 udp/tcp端口,iptables将53的dns请求重定向到pilot-agent,规则如下:

```
-A POSTROUTING -p udp -m udp --dport 15053 -j SNAT --to-source 127.0.0.1
-A POSTROUTING -p udp -m udp --dport 15053 -j SNAT --to-source 127.0.0.1
-A POSTROUTING -p udp -m udp --dport 15053 -j SNAT --to-source 127.0.0.1
-A OUTPUT -p udp -m udp --dport 53 -m owner --uid-owner 991 -j RETURN
-A OUTPUT -p udp -m udp --dport 53 -m owner --gid-owner 991 -j RETURN
-A OUTPUT -p udp -m udp --dport 53 -j DNAT --to-destination 127.0.0.1:15053
-A OUTPUT -p udp -m udp --dport 53 -m owner --uid-owner 991 -j RETURN
-A OUTPUT -p udp -m udp --dport 53 -m owner --gid-owner 991 -j RETURN
-A OUTPUT -p udp -m udp --dport 53 -j DNAT --to-destination 127.0.0.1:15053
-A OUTPUT -p udp -m udp --dport 53 -m owner --uid-owner 991 -j RETURN
-A OUTPUT -p udp -m udp --dport 53 -m owner --gid-owner 991 -j RETURN
-A OUTPUT -p udp -m udp --dport 53 -j DNAT --to-destination 127.0.0.1:15053
-A ISTIO_REDIRECT -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 15053
```

ISTIO\_META\_DNS\_CAPTURE正常只能影响k8s上管理的pod,但是在cluster.env中,通过`ISTIO_META_DNS_CAPTURE=true`开启了vm上pilot-agent的该功能。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://rocdu.gitbook.io/deep-understanding-of-istio/4/3.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
