精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

實戰(zhàn):如何優(yōu)雅的從 Skywalking 切換到 OpenTelemetry

開發(fā) 前端
OpenTelemetry 是可觀測系統(tǒng)的新標準,基于它可以兼容以前使用的 Prometheus、 victoriametrics、skywalking 等系統(tǒng),同時還可以靈活擴展,不用與任何但一生態(tài)或技術棧進行綁定。

背景

最近公司將我們之前使用的鏈路工具切換為了 OpenTelemetry。

我們的技術棧是:

OTLP                               
Client──────────?Collect────────?StartRocks
(Agent)                               ▲    
                                      │    
                                      │    
                                   Jaeger

其中客戶端使用 OpenTelemetry 提供的 Java Agent 進行埋點收集數(shù)據(jù),再由 Agent 通過 OTLP(OpenTelemetry Protocol) 協(xié)議將數(shù)據(jù)發(fā)往 Collector,在 Collector 中我們可以自行任意處理數(shù)據(jù),并決定將這些數(shù)據(jù)如何存儲(這點在以往的 SkyWalking 體系中是很難自定義的)

這里我們將數(shù)據(jù)寫入 StartRocks 中,供之后的 UI 層進行查看。

OpenTelemetry 是可觀測系統(tǒng)的新標準,基于它可以兼容以前使用的 Prometheus、 victoriametrics、skywalking 等系統(tǒng),同時還可以靈活擴展,不用與任何但一生態(tài)或技術棧進行綁定。更多關于 OTel 的內(nèi)容會在今后介紹。

難點

其中有一個關鍵問題就是:如何在線上進行無縫切換。

雖然我們內(nèi)部的發(fā)布系統(tǒng)已經(jīng)支持重新發(fā)布后就會切換到新的鏈路,也可以讓業(yè)務自行發(fā)布然后逐步的切換到新的系統(tǒng),這樣也是最保險的方式。

但這樣會有幾個問題:

  • 當存在調(diào)用依賴的系統(tǒng)沒有全部切換為新鏈路時,再查詢的時候就會出現(xiàn)斷層,整個鏈路無法全部串聯(lián)起來。
  • 業(yè)務團隊沒有足夠的動力去推動發(fā)布,可能切換的周期較長。

所以最好的方式還是由我們在后臺統(tǒng)一發(fā)布,對外沒有任何感知就可以一鍵全部切換為 OpenTelemetry。

仔細一看貌似也沒什么難的,無非就是模擬用戶點擊發(fā)布按鈕而已。

但這事由我們自動來做就不一樣了,用戶點擊發(fā)布的時候會選擇他們認為可以發(fā)布的分支進行發(fā)布,我們不能自作主張的比如選擇 main 分支,有可能只是合并了但還不具備發(fā)布條件。

所以保險的方式還是得用當前項目上一次發(fā)布時所使用的 git hash 值重新打包發(fā)布。

但這也有幾個問題:

  • 重復打包發(fā)布太慢了,線上幾十上百個項目,每打包發(fā)布一次就得幾分鐘,雖然可以并發(fā),但考慮到 kubernetes 的壓力也不能調(diào)的太高。
  • 保不準業(yè)務鏡像中有單獨加入一些環(huán)境變量,這樣打包可能會漏。

切換方案

所以思來想去最保險的方法還是將業(yè)務鏡像拉取下來,然后手動刪除鏡像中的 skywalking 包以及 JVM 參數(shù),全部替換為 OpenTelemetry 的包和 JVM 參數(shù)。

整體的方案如下:

  • 遍歷 namespace 的 pod >0 的 deployment。
  • 遍歷 deployment 中的所有 container,獲得業(yè)務鏡像。
  1. 跳過 istio 和日志采集 container,獲取到業(yè)務容器。
  2. 判斷該容器是否需要替換,其實就是判斷環(huán)境變量中是否有 skywalking ,如果有就需要替換。
  3. 獲取業(yè)務容器的鏡像。
  • 基于該 Image 重新構(gòu)建一個 OpenTelemetry 的鏡像 3.1 新的鏡像包含新的啟動腳本. 3.1.1 新的啟動腳本中會刪除原有的 skywalking agent 3.2 新鏡像會包含 OpenTelemetry 的 jar 包以及我們自定義的 OTel 擴展包 3.3 替換啟動命令為新的啟動腳本。
  • 修改 deployment 中的 JVM 啟動參數(shù)。
  • 修改 deployment 的鏡像后滾動更新。
  • 開啟一個 goroutine 定時檢測更新之后是否啟動成功。
  • 如果長時間 (比如五分鐘) 都沒有啟動成功,則執(zhí)行回滾流程。

具體代碼

因為需要涉及到操作 kubernetes,所以整體就使用 Golang 實現(xiàn)了。

遍歷 deployment 得到需要替換的容器鏡像

func ProcessDeployment(ctx context.Context, finish []string, deployment v1.Deployment, clientSet kubernetes.Interface) error {
 deploymentName := deployment.Name
 for _, s := range finish {
  if s == deploymentName {
   klog.Infof("Skip finish deployment:%s", deploymentName)
   return nil
  }
 }
 // Write finish deployment name to a file
 defer writeDeploymentName2File(deploymentName, fmt.Sprintf("finish-%s.log", deployment.Namespace))

 appName := deployment.GetObjectMeta().GetLabels()["appName"]
 klog.Infof("Begin to process deployment:%s, appName:%s", deploymentName, appName)

 upgrade, err := checkContainIstio(ctx, deployment, clientSet)
 if err != nil {
  return err
 }
 if upgrade == false {
  klog.Infof("Don't have istio, No need to upgrade deployment:%s appName:%s", deploymentName, appName)
  return nil
 }

 for i, container := range deployment.Spec.Template.Spec.Containers {
  if strings.HasPrefix(deploymentName, container.Name) {

   // Check if container has sw jvm
   for _, envVar := range container.Env {
    if envVar.Name == "CATALINA_OPTS" {
     if !strings.Contains(envVar.Value, "skywalking") {
      klog.Infof("Skip upgrade don't have sw jvm deployment:%s container:%s", deploymentName, container.Name)
      return nil
     }
    }
   }
   upgrade(container)

   // Check newDeployment status
   go checkNewDeploymentStatus(ctx, clientSet, newDeployment)

   // delete from image
   deleteImage(container.Image)

  }
 }

 return nil
}

這個函數(shù)需要傳入一個 deployment ,同時還有一個已經(jīng)完成了的列表進來。

已完成列表用于多次運行的時候可以快速跳過已經(jīng)執(zhí)行的 deployment。

checkContainIstio() 函數(shù)很簡單,判斷是否包含了 Istio 容器,如果沒有包含說明不是后端應用(可能是前端、大數(shù)據(jù)之類的任務),就可以直接跳過了。

而判斷是否需要替換的前提這事判斷環(huán)境變量 CATALINA_OPTS 中是否包含了 skywalking 的內(nèi)容,如果包含則說明需要進行替換。

Upgrade 核心函數(shù)

func upgrade(container Container){
 klog.Infof("Begin to upgrade deployment:%s container:%s", deploymentName, container.Name)
 newImageName := fmt.Sprintf("%s-otel-%s", container.Image, generateRandomString(4))
 err := BuildNewOtelImage(container.Image, newImageName)
 if err != nil {
  return err
 }

 // Update deployment jvm ENV
 for e, envVar := range container.Env {
  if envVar.Name == "CATALINA_OPTS" {
   otelJVM := replaceSWAgent2OTel(envVar.Value, appName)
   deployment.Spec.Template.Spec.Containers[i].Env[e].Value = otelJVM
  }
 }
 // Update deployment image
 deployment.Spec.Template.Spec.Containers[i].Image = newImageName

 newDeployment, err := clientSet.AppsV1().Deployments(deployment.Namespace).Update(ctx, &deployment, metav1.UpdateOptions{})
 if err != nil {
  return err
 }
 klog.Infof("Finish upgrade deployment:%s container:%s", deploymentName, container.Name)
}

這里一共分為以下幾部:

  • 基于老鏡像構(gòu)建新鏡像。
  • 更新原有的 CATALINA_OPTS 環(huán)境變量,也就是替換 skywalking 的參數(shù)。
  • 更新 deployment 鏡像,觸發(fā)滾動更新。

構(gòu)建新鏡像

dockerfile = fmt.Sprintf(`FROM %s
COPY %s /home/admin/%s
COPY otel.tar.gz /home/admin/otel.tar.gz
RUN tar -zxvf /home/admin/otel.tar.gz -C /home/admin
RUN rm -rf /home/admin/skywalking-agent
ENTRYPOINT ["/bin/sh", "/home/admin/start.sh"]
`, fromImage, script, script)

 idx := strings.LastIndex(newImageName, "/") + 1
 dockerFileName := newImageName[idx:]
 create, err := os.Create(fmt.Sprintf("Dockerfile-%s", dockerFileName))
 if err != nil {
  return err
 }
 defer func() {
  create.Close()
  os.Remove(create.Name())
 }()
 _, err = create.WriteString(dockerfile)
 if err != nil {
  return err
 }

 cmd := exec.Command("docker", "build", ".", "-f", create.Name(), "-t", newImageName)
 cmd.Stdin = strings.NewReader(dockerfile)
 if err := cmd.Run(); err != nil {
  return err
 }

其實這里的重點就是構(gòu)建這個新鏡像,從這個 dockerfile 中也能看出具體的邏輯,也就是上文提到的刪除原有的 skywalking 資源同時將新的 OpenTelemetry 資源打包進去。

最后再將這個鏡像上傳到私服。

其中的替換 JVM 參數(shù)也比較簡單,直接刪除 skywalking 的內(nèi)容,然后再追加上 OpenTelemetry 需要的參數(shù)即可。

定時檢測替換是否成功

func checkNewDeploymentStatus(ctx context.Context, clientSet kubernetes.Interface, newDeployment *v1.Deployment) error {
 ready := true
 tick := time.Tick(10 * time.Second)
 for i := 0; i < 30; i++ {
  <-tick
  originPodList, err := clientSet.CoreV1().Pods(newDeployment.Namespace).List(ctx, metav1.ListOptions{
   LabelSelector: metav1.FormatLabelSelector(&metav1.LabelSelector{
    MatchLabels: newDeployment.Spec.Selector.MatchLabels,
   }),
  })
  if err != nil {
   return err
  }

  // Check if there are any Pods
  if len(originPodList.Items) == 0 {
   klog.Infof("No Pod in deployment:%s, Skip", newDeployment.Name)
  }
  for _, item := range originPodList.Items {
   // Check Pod running
   for _, status := range item.Status.ContainerStatuses {
    if status.RestartCount > 0 {
     ready = false
     break
    }
   }
  }
  klog.Infof("Check deployment:%s namespace:%s status:%t", newDeployment.Name, newDeployment.Namespace, ready)
  if ready == false {
   break
  }
 }

 if ready == false {
  // rollback
  klog.Infof("=======Rollback deployment:%s namespace:%s", newDeployment.Name, newDeployment.Namespace)
  writeDeploymentName2File(newDeployment.Name, fmt.Sprintf("rollback-%s.log", newDeployment.Namespace))
 }

 return nil
}

這里會啟動一個 10s 執(zhí)行一次的定時任務,每次都會檢測是否有容器發(fā)生了重啟(正常情況下是不會出現(xiàn)重啟的)

如果檢測了 30 次都沒有重啟的容器,那就說明本次替換成功了,不然就記錄一個日志文件,然后人工處理。

這種通常是原有的鏡像與 OpenTelemetry 不兼容,比如里面寫死了一些 skywalking 的 API,導致啟動失敗。

所以替換任務跑完之后我還會檢測這個 rollback-$namespace 的日志文件,人工處理這些失敗的應用。

分批處理 deployment

最后講講如何單個調(diào)用剛才的 ProcessDeployment() 函數(shù)。

考慮到不能對 kubernetes 產(chǎn)生影響,所以我們需要限制并發(fā)處理 deployment 的數(shù)量(我這里的限制是 10 個)。

所以就得分批進行替換,每次替換 10 個,而且其中有一個執(zhí)行失敗就得暫停后續(xù)任務,由人工檢測失敗原因再決定是否繼續(xù)處理。

畢竟處理的是線上應用,需要小心謹慎。

所以觸發(fā)的代碼如下:

func ProcessDeploymentList(ctx context.Context, data []v1.Deployment, clientSet kubernetes.Interface) error {
 file, err := os.ReadFile(fmt.Sprintf("finish-%s.log", data[0].Namespace))
 if err != nil {
  return err
 }
 split := strings.Split(string(file), "\n")

 batchSize := 10
 start := 0

 for start < len(data) {

  end := start + batchSize
  if end > len(data) {
   end = len(data)
  }

  batch := data[start:end]

  //等待goroutine結(jié)束
  var wg sync.WaitGroup
  klog.Infof("Start process batch size %d", len(batch))

  errs := make(chan error, len(batch))

  wg.Add(len(batch))
  for _, item := range batch {
   d := item
   go func() {
    defer wg.Done()
    if err := ProcessDeployment(ctx, split, d, clientSet); err != nil {
     klog.Errorf("!!!Process deployment name:%s error: %v", d.Name, err)
     errs <- err
     return
    }
   }()
  }

  go func() {
   wg.Wait()
   close(errs)
  }()

  //任何一個失敗就返回
  for err := range errs {
   if err != nil {
    return err
   }
  }

  start = end
  klog.Infof("Deal next batch")
 }

 return nil

}

使用 WaitGroup 來控制一組任務,使用一個 chan 來傳遞異常;這類分批處理的代碼在一些批處理框架中還蠻常見的。

總結(jié)

最后只需要查詢某個 namespace 下的所有 deployment 列表傳入這個批處理函數(shù)即可。

不過整個過程中還是有幾個點需要注意:

  • 因為需要替換鏡像的前提是要把現(xiàn)有的鏡像拉取到本地,所以跑這個任務的客戶端需要有充足的磁盤,同時和鏡像服務器的網(wǎng)絡條件較好。
  • 不然執(zhí)行的過程會比較慢,同時磁盤占用滿了也會影響任務。

其實這個功能依然有提升空間,考慮到后續(xù)會升級 OpenTelemetry  agent 的版本,甚至也需要增減一些 JVM 參數(shù)。

所以最后有一個統(tǒng)一的工具,可以直接升級 Agent,而不是每次我都需要修改這里的代碼。

后來在網(wǎng)上看到了得物的相關分享,他們可以遠程加載配置來解決這個問題。

這也是一種解決方案,直到我們看到了 OpenTelemetry 社區(qū)提供了 Operator,其中也包含了注入 agent 的功能。

apiVersion: opentelemetry.io/v1alpha1  
kind: Instrumentation  
metadata:  
  name: my-instrumentation  
spec:  
  exporter:  
    endpoint: http://otel-collector:4317  
  propagators:  
    - tracecontext  
    - baggage  
    - b3  
  sampler:  
    type: parentbased_traceidratio  
    argument: "0.25"  
  java:  
    image: private/autoinstrumentation-java:1.32.0-1

我們可以使用他提供的 CRD 來配置我們 agent,只要維護好自己的鏡像就好了。

使用起來也很簡單,只要安裝好了 OpenTelemetry-operator ,然后再需要注入 Java Agent 的 Pod 中使用注解:

instrumentation.opentelemetry.io/inject-java: "true"

operator 就會自動從剛才我們配置的鏡像中讀取 agent,然后復制到我們的業(yè)務容器。

再配置上環(huán)境變量 $JAVA_TOOL_OPTIONS=/otel/javaagent.java, 這是一個 Java 內(nèi)置的環(huán)境變量,應用啟動的時候會自動識別,這樣就可以自動注入 agent 了。

envJavaToolsOptions   = "JAVA_TOOL_OPTIONS"

// set env value
idx := getIndexOfEnv(container.Env, envJavaToolsOptions)  
if idx == -1 {  
    container.Env = append(container.Env, corev1.EnvVar{  
       Name:  envJavaToolsOptions,  
       Value: javaJVMArgument,  
    })} else {  
    container.Env[idx].Value = container.Env[idx].Value + javaJVMArgument  
}

// copy javaagent.jar
pod.Spec.InitContainers = append(pod.Spec.InitContainers, corev1.Container{  
    Name:      javaInitContainerName,  
    Image:     javaSpec.Image,  
    Command:   []string{"cp", "/javaagent.jar", javaInstrMountPath + "/javaagent.jar"},  
    Resources: javaSpec.Resources,  
    VolumeMounts: []corev1.VolumeMount{{  
       Name:      javaVolumeName,  
       MountPath: javaInstrMountPath,  
    }},})

大致的運行原理是當有 Pod 的事件發(fā)生了變化(重啟、重新部署等),operator 就會檢測到變化,此時會判斷是否開啟了剛才的注解:

instrumentation.opentelemetry.io/inject-java: "true"

接著會寫入環(huán)境變量 JAVA_TOOL_OPTIONS,同時將 jar 包從 InitContainers 中復制到業(yè)務容器中。

這里使用到了 kubernetes 的初始化容器,該容器是用于做一些準備工作的,比如依賴安裝、配置檢測或者是等待其他一些組件啟動成功后再啟動業(yè)務容器。

目前這個 operator 還處于使用階段,同時部分功能還不滿足(比如支持自定義擴展),今后有時間也可以分析下它的運行原理。

參考鏈接:

  • https://xie.infoq.cn/article/e6def1e245e9d67735bd00dd5。
  • https://github.com/open-telemetry/opentelemetry-operator/#opentelemetry-auto-instrumentation-injection。
責任編輯:姜華 來源: crossoverJie
相關推薦

2020-02-11 15:50:51

WindowsLinux命令行

2020-04-17 14:37:19

WindowsLinux微軟

2022-09-29 09:58:30

Colima開源

2021-08-06 15:15:09

Windows 11Dev頻道Beta頻道

2024-08-28 08:09:13

contextmetrics類型

2023-02-08 13:01:20

Debian測試版

2025-11-18 07:52:13

2022-07-27 07:24:32

Debian系統(tǒng)

2023-04-20 16:48:22

PandasPolarsPython

2024-04-16 08:09:36

JavapulsarAPI

2020-06-28 16:07:03

HomebrewMacLinux

2009-12-03 10:05:26

Ubuntu超級用戶

2024-08-21 08:09:17

2024-09-04 08:09:51

2025-07-10 07:24:54

Spring支付策略類

2019-12-02 10:50:30

Python 2Python 3編程語言

2010-11-26 15:56:23

mysql環(huán)境變量

2009-06-23 18:19:54

NetBeans英文界面

2020-07-03 07:54:13

MacLinux操作系統(tǒng)

2010-05-24 09:41:31

點贊
收藏

51CTO技術棧公眾號

国产免费的av| 四虎影成人精品a片| 少女频道在线观看免费播放电视剧| 激情综合一区二区三区| 欧美国产亚洲精品久久久8v| 久久久久麻豆v国产精华液好用吗 在线观看国产免费视频 | 久99久在线| 中文在线字幕免费观| 欧美日一区二区三区在线观看国产免| 日韩经典第一页| 日本老熟妇毛茸茸| 国模雨婷捆绑高清在线| 国产丝袜欧美中文另类| 亚洲一区二区三区成人在线视频精品| 99久在线精品99re8热| 亚洲啊v在线观看| 日韩国产在线播放| 自拍一级黄色片| 福利精品一区| 欧美视频在线免费看| 一区二区三区在线观看www| 五月婷婷在线播放| 国产成人在线视频网址| 国产精品视频一区国模私拍| 久久这里只有精品国产| 91麻豆精品国产91久久久平台| 日韩精品电影网| 国产又黄又嫩又滑又白| 91精品福利观看| 在线视频国内自拍亚洲视频| 日韩欧美不卡在线| 尤物视频在线看| 最新热久久免费视频| 日韩电影天堂视频一区二区| 三级小视频在线观看| 国产成人在线视频网站| 国产日韩在线观看av| 黄色网址中文字幕| 小嫩嫩精品导航| 91精品国产色综合| 日韩av片在线播放| 精品成人一区| 欧美极品第一页| 免看一级a毛片一片成人不卡| 国产精品久久久久久麻豆一区软件| 国产亚洲人成a一在线v站| 稀缺小u女呦精品呦| 1769国产精品视频| 日韩一区二区三区三四区视频在线观看 | 色综合999| 一区二区视频在线看| 自拍偷拍视频在线| 麻豆视频网站在线观看| 亚洲日本在线a| 国产精品88久久久久久妇女 | 精品国产一区二区三区久久久蜜臀| 亚洲精品电影在线| 亚洲最大免费视频| 亚洲aaa级| 尤物yw午夜国产精品视频| 免费网站在线高清观看| 日韩国产一区| 欧美巨乳在线观看| 国产大片中文字幕在线观看| 亚洲毛片在线| 日本久久中文字幕| 中文av免费观看| 激情五月激情综合网| 亚洲已满18点击进入在线看片| 国产叼嘿视频在线观看| 国产成a人亚洲精| 精品亚洲第一| av在线电影播放| 亚洲人成网站精品片在线观看| av久久久久久| 中文字幕高清在线播放| 欧美亚洲国产一区二区三区va | 日韩中文字幕精品| a级片在线观看免费| 亚洲美女毛片| 国产精品极品在线| 99精品在线看| 91美女片黄在线观看91美女| 亚洲国产精品一区二区第四页av | 亚洲免费视频中文字幕| 日韩国产一级片| www.久久.com| 欧美精品一区二区三区久久久| 色欲av无码一区二区三区| 99久久久久国产精品| 久久免费成人精品视频| 最新中文字幕在线观看视频| 国产裸体歌舞团一区二区| 精品国产乱码久久久久久88av| www亚洲人| 亚洲自拍偷拍网站| 狠狠躁狠狠躁视频专区| 91成人入口| 日韩在线视频免费观看| 日本一区二区三区四区五区| 蜜臀久久久久久久| 国产一区二区三区免费不卡| av中文在线| 欧美日韩国产一区在线| 91在线第一页| 精品免费视频| 97人人爽人人喊人人模波多| 在线观看中文字幕av| kk眼镜猥琐国模调教系列一区二区| 亚洲精品久久久久久一区二区| caoprom在线| 欧美精品三级日韩久久| 亚洲久久久久久久| 黄色成人在线网址| 91久久精品国产91性色| 黄色片在线免费看| 欧美日韩国产区| 国产高潮失禁喷水爽到抽搐| 色男人天堂综合再现| 欧美有码在线视频| 老熟妇高潮一区二区高清视频| 国产精品私人影院| 欧美aⅴ在线观看| 国产成人一二片| 久久6免费高清热精品| 91久久久久国产一区二区| 久久久91精品国产一区二区三区| 五十路熟女丰满大屁股| 亚洲精品观看| 久久99精品国产99久久6尤物| 中文无码av一区二区三区| 91在线播放网址| 五十路熟女丰满大屁股| silk一区二区三区精品视频| 久久精品小视频| 又色又爽又黄无遮挡的免费视频| 国产网站一区二区| 黄色一级一级片| 亚洲精品国产动漫| 欧美伊久线香蕉线新在线| 老司机午夜福利视频| 亚洲国产一区在线观看| www.com日本| 亚洲福利免费| 精品久久久久久综合日本| 91破解版在线观看| 日韩电影中文 亚洲精品乱码| 日韩欧美高清在线观看| 97se亚洲国产综合自在线观| 天堂…中文在线最新版在线| 欧美电影免费网站| 91高潮精品免费porn| 三级黄视频在线观看| 欧美日韩视频在线| 扒开jk护士狂揉免费| 麻豆成人精品| 日韩偷拍一区二区| 欧美在线一级| 欧美黄色免费网站| 污视频网站免费观看| 日韩欧美在线第一页| 好吊视频在线观看| 麻豆精品精品国产自在97香蕉| 亚洲日本一区二区三区在线不卡| 成人精品在线| 欧美激情高清视频| 日韩国产福利| 欧美午夜精品一区二区蜜桃| 国产成人av免费在线观看| 国产精品亚洲午夜一区二区三区| 日b视频免费观看| 色综合www| 国产免费一区二区三区香蕉精| 麻豆视频在线免费观看| 欧美精品一区在线观看| 国产高清中文字幕| 国产精品国产自产拍高清av王其| 欧美一级小视频| 在线播放不卡| 色涩成人影视在线播放| 久久av网站| 欧美在线www| 黄网站免费在线播放| 亚洲第一区中文99精品| 午夜视频网站在线观看| 亚洲精品网站在线观看| 无码人妻aⅴ一区二区三区 | 色欧美片视频在线观看在线视频| 九一在线免费观看| 成人av在线看| 亚洲va综合va国产va中文| 国产综合久久| 一区二区三区观看| 香蕉视频一区| 999视频在线免费观看| 吞精囗交69激情欧美| 欧美日韩国产成人在线观看| 毛片在线播放网站| 欧美一级一区二区| 国产91av在线播放| 亚洲国产精品欧美一二99| 欧美人与性囗牲恔配| 成人午夜电影久久影院| 超碰人人草人人| 国产视频欧美| 日本大胆人体视频| 成人综合久久| 看高清中日韩色视频| 欧美成年网站| 国产欧美日韩中文字幕| 韩国美女久久| 91sao在线观看国产| 91极品在线| 综合网日日天干夜夜久久| 日本午夜在线| 亚洲电影成人av99爱色| 国产又大又长又粗| 欧美性做爰猛烈叫床潮| 久久国产精品免费看| 一区av在线播放| 国产美女久久久久久| 亚洲国产精品成人综合| 日本黄色特级片| 99久久久精品免费观看国产蜜| 波多野结衣在线免费观看| 免费观看一级特黄欧美大片| 久久精品一区二| 亚洲在线黄色| 噜噜噜久久亚洲精品国产品麻豆| 欧美午夜不卡| 中国老女人av| 久久久久久久久久久妇女 | 国产高清自拍一区| 日韩激情综合| 91免费观看| 欧美a级大片在线| 亚洲已满18点击进入在线看片| www.久久久久爱免| 91亚洲国产成人久久精品网站| 在线成人免费| 91在线精品视频| 成人在线精品| 电影午夜精品一区二区三区| 久久69av| 国产九色91| 红杏视频成人| 久久av一区二区三区亚洲| 欧美日韩夜夜| 欧美一区二区三区电影在线观看| 在线一级成人| 无码免费一区二区三区免费播放 | 国产91沈先生在线播放| 国产一区日韩欧美| 免费一级特黄毛片| 亚洲少妇一区| 欧美精品无码一区二区三区| 日韩激情av在线| www.久久久久久久久久久| 精品综合免费视频观看| 一本之道在线视频| 成人少妇影院yyyy| 无码h肉动漫在线观看| 欧美激情在线观看视频免费| 国精产品视频一二二区| 亚洲精品乱码久久久久久久久 | 日韩视频在线一区二区三区| 欧美日韩国产精品激情在线播放| 男人天堂欧美日韩| 国产九九在线视频| 国产成人在线色| 美女100%无挡| 亚洲婷婷在线视频| 国产精品自拍视频一区| 色哦色哦哦色天天综合| 亚洲图片在线播放| 欧美成人一区二区三区| 天天干,夜夜爽| 中文字幕在线观看亚洲| 亚洲无线看天堂av| 欧美重口另类videos人妖| 粉嫩av一区二区三区四区五区| 91亚色免费| 欧美限制电影| 国产精品久久久影院| 国产欧美日韩一级| 91福利免费观看| eeuss国产一区二区三区| 国产一二三四区在线| 一二三四区精品视频| 人人妻人人爽人人澡人人精品| 日韩一区二区三区电影| 欧美白人做受xxxx视频| 欧美大片va欧美在线播放| 亚洲淫成人影院| 亚洲xxxxx性| 欧州一区二区| 亚洲不卡中文字幕无码| 国产一区免费电影| 能免费看av的网站| 一区二区三区91| 中文字幕欧美在线观看| 亚洲韩国青草视频| 99在线播放| 国产欧美日韩综合精品| 秋霞影院一区二区三区| 国产在线拍揄自揄拍无码| 久久精品123| 一级黄色片毛片| 亚洲精品免费视频| 91麻豆一区二区| 亚洲一区二区久久久| 国产第一页在线视频| 国产欧美一区二区三区久久| 一本色道久久综合狠狠躁的番外| 丁香婷婷综合激情| 国产麻豆精品在线观看| 成人18视频免费69| 91国内精品野花午夜精品| 偷拍精品一区二区三区| 欧美精品激情在线观看| www欧美在线观看| 亚洲精品中文字幕在线| 日韩中文字幕亚洲一区二区va在线| 99精品一区二区三区无码吞精| 亚洲日本在线看| 国产农村妇女毛片精品| www.日韩系列| 日韩黄色在线| 在线综合视频网站| 美女脱光内衣内裤视频久久网站 | 可以免费观看的毛片| 欧美黑人巨大xxx极品| 日韩激情精品| 妺妺窝人体色www看人体| 国产精品一区二区x88av| 2018天天弄| 日韩精品中文字幕在线一区| 黄色视屏免费在线观看| 成人av在线亚洲| 亚洲国产精品日韩专区av有中文| 91亚洲免费视频| 亚洲视频在线一区二区| 国产手机视频在线| 欧美成人高清视频| 中文字幕一区二区三区四区久久| 四虎4hu永久免费入口| 国产一区二区电影| 青青草手机视频在线观看| 欧美一二三区精品| 美女尤物在线视频| 国产精品美女xx| 亚洲一区日本| 欧美大波大乳巨大乳| 欧美日韩综合一区| 成人日韩欧美| 国产精品乱码一区二区三区| 在线成人黄色| 性色av蜜臀av色欲av| 色成年激情久久综合| 尤物网址在线观看| 1卡2卡3卡精品视频| 亚洲性图久久| 波多野结衣a v在线| 欧美三级电影在线观看| 中文字幕伦理免费在线视频 | 国产九九精品视频| 在线中文字幕亚洲| av网页在线观看| 欧美中文字幕一区二区三区亚洲| 日本高清视频在线播放| 成人黄动漫网站免费| 免费日韩一区二区| 萌白酱视频在线| 精品人在线二区三区| 在线日韩影院| 伊人情人网综合| k8久久久一区二区三区| 国产情侣呻吟对白高潮| 欧美国产第二页| 国产精品欧美在线观看| 精品人妻一区二区三| 欧美性猛交xxxx偷拍洗澡| 久久久久久国产精品免费无遮挡| 国产精品免费一区二区三区四区 | missav|免费高清av在线看| 农村寡妇一区二区三区| 精品无码三级在线观看视频 | 国产精品最新自拍| 欧美特黄一级片| 日韩电影中文字幕在线观看| 久久精品超碰| 18禁免费观看网站| 亚洲视频一区二区在线观看| 外国精品视频在线观看| 国产精品成人v| 亚洲区欧美区| 欧美三级黄色大片| 亚洲性夜色噜噜噜7777| 国产色噜噜噜91在线精品| 日韩av片专区|