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

K8s 增強版工作負載 OpenKruise 之運維增強功能

云計算 云原生 運維
SidecarSet 支持通過 Admission Webhook 來自動為集群中創建的符合條件的 Pod 注入 Sidecar 容器,除了在 Pod 創建時候注入外,SidecarSet 還提供了為 Pod 原地升級其中已經注入的 Sidecar 容器鏡像的能力。

前面我們和大家已經學習了 OpenKruise 的基本概念以及常用的幾個增強控制器,接下來我們來繼續了解其他高級功能。

SidecarSet

SidecarSet 支持通過 admission webhook 來自動為集群中創建的符合條件的 Pod 注入 sidecar 容器,除了在 Pod 創建時候注入外,SidecarSet 還提供了為 Pod 原地升級其中已經注入的 sidecar 容器鏡像的能力。SidecarSet 將 sidecar 容器的定義和生命周期與業務容器解耦,它主要用于管理無狀態的 sidecar 容器,比如監控、日志等 agent。

比如我們定義一個如下所示的 SidecarSet 資源對象:

# sidecarset-demo.yaml
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
name: scs-demo
spec:
selector:
matchLabels: # 非常重要的屬性,會去匹配具有 app=nginx Pod
app: nginx
updateStrategy:
type: RollingUpdate
maxUnavailable: 1
containers:
- name: sidecar1
image: busybox
command: ["sleep", "999d"]
volumeMounts:
- name: log-volume
mountPath: /var/log
volumes: # 該屬性會被合并到 pod.spec.volumes
- name: log-volume
emptyDir: {}

直接創建這個資源對象即可:

? kubectl get sidecarset
NAME MATCHED UPDATED READY AGE
scs-demo 0 0 0 6s

需要注意上面我們在定義 SidecarSet 對象的時候里面有一個非常重要的屬性就是 label selector,會去匹配具有 app=nginx? 的 Pod,然后向其中注入下面定義的 sidecar1? 這個容器,比如定義如下所示的一個 Pod,該 Pod 中包含 app=nginx 的標簽,這樣可以和上面的 SidecarSet 對象匹配:

apiVersion: v1
kind: Pod
metadata:
labels:
app: nginx # 匹配 SidecarSet 里面指定的標簽
name: test-pod
spec:
containers:
- name: app
image: nginx:1.7.9

直接創建上面的資源對象:

? kubectl get pod test-pod
NAME READY STATUS RESTARTS AGE
test-pod 2/2 Running 0 22s

可以看到該 Pod 中有 2 個容器,被自動注入了上面定義的 sidecar1 容器:

? kubectl get pod test-pod -o yaml
apiVersion: v1
kind: Pod
metadata:
labels:
app: nginx
name: test-pod
namespace: default
spec:
containers:
- command:
- sleep
- 999d
env:
- name: IS_INJECTED
value: "true"
image: busybox
imagePullPolicy: Always
name: sidecar1
resources: {}
volumeMounts:
- mountPath: /var/log
name: log-volume
- image: nginx:1.7.9
imagePullPolicy: IfNotPresent
name: app
# ......
volumes:
- emptyDir: {}
name: log-volume
# ......

現在我們去更新 SidecarSet 中的 sidecar 容器鏡像替換成 busybox:1.35.0:

? kubectl patch sidecarset scs-demo --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value": "busybox:1.35.0"}]'
sidecarset.apps.kruise.io/scs-demo patched

更新后再去查看 Pod 中的 sidecar 容器:

? kubectl get pod test-pod
NAME READY STATUS RESTARTS AGE
test-pod 2/2 Running 1 (67s ago) 28m
? kubectl describe pod test-pod
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
# ......
Normal Created 10m kubelet Created container app
Normal Started 10m kubelet Started container app
Normal Killing 114s kubelet Container sidecar1 definition changed, will be restarted
Normal Pulling 84s kubelet Pulling image "busybox:1.35.0"
Normal Created 77s (x2 over 11m) kubelet Created container sidecar1
Normal Started 77s (x2 over 11m) kubelet Started container sidecar1
Normal Pulled 77s kubelet Successfully pulled image "busybox:1.35.0" in 6.901558972s (6.901575894s including waiting)
? kubectl get pod test-pod -o yaml |grep busybox
kruise.io/sidecarset-inplace-update-state: '{"scs-demo":{"revision":"f78z4854d9855xd6478fzx9c84645z2548v24z26455db46bdfzw44v49v98f2cw","updateTimestamp":"2023-04-04T08:05:18Z","lastContainerStatuses":{"sidecar1":{"imageID":"docker.io/library/busybox@sha256:b5d6fe0712636ceb7430189de28819e195e8966372edfc2d9409d79402a0dc16"}}}}'
image: busybox:1.35.0
image: docker.io/library/busybox:1.35.0
imageID: docker.io/library/busybox@sha256:223ae047b1065bd069aac01ae3ac8088b3ca4a527827e283b85112f29385fb1b

可以看到 Pod 中的 sidecar 容器鏡像被原地升級成 busybox:1.35.0 了, 對主容器沒有產生任何影響。

基本特性

需要注意的是 sidecar 的注入只會發生在 Pod 創建階段,并且只有 Pod spec 會被更新,不會影響 Pod 所屬的工作負載 template 模板。 spec.containers 除了默認的 k8s container 字段,還擴展了如下一些字段,來方便注入:

apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
name: sidecarset
spec:
selector:
matchLabels:
app: sample
containers:
# 默認的 K8s 容器字段
- name: nginx
image: nginx:alpine
volumeMounts:
- mountPath: /nginx/conf
name: nginxconf
# 擴展的 sidecar 容器字段
podInjectPolicy: BeforeAppContainer
shareVolumePolicy: # 數據卷共享
type: disabled | enabled
transferEnv: # 環境變量共享
- sourceContainerName: main # 會把main容器中的PROXY_IP環境變量注入到當前定義的sidecar容器中
envName: PROXY_IP
volumes:
- Name: nginxconf
hostPath: /data/nginx/conf

  • podInjectPolicy? 定義了容器 注入到 pod.spec.containers 中的位置。
  • BeforeAppContainer:表示注入到 pod 原 containers 的前面(默認)。
  • AfterAppContainer: 表示注入到 pod 原 containers 的后面。
  • 數據卷共享。
  • 共享指定卷:通過 spec.volumes 來定義 sidecar 自身需要的 volume。
  • 共享所有卷:通過 spec.containers[i].shareVolumePolicy.type = enabled | disabled 來控制是否掛載 pod 應用容器的卷,常用于日志收集等 sidecar,配置為 enabled 后會把應用容器中所有掛載點注入 sidecar 同一路經下(sidecar 中本身就有聲明的數據卷和掛載點除外)。
  • 環境變量共享:可以通過 spec.containers[i].transferEnv 來從別的容器獲取環境變量,會把名為 sourceContainerName 容器中名為 envName 的環境變量拷貝到本容器。

SidecarSet 不僅支持 sidecar 容器的原地升級,而且提供了非常豐富的升級、灰度策略。同樣在 SidecarSet 對象中 updateStrategy? 屬性下面也可以配置 partition? 來定義保留舊版本 Pod 的數量或百分比,默認為 0;同樣還可以配置的有 maxUnavailable 屬性,表示在發布過程中的最大不可用數量。

  • 當 {matched pod}=100,partitinotallow=40,maxUnavailable=10,控制器會發布 100-40=60 個 Pod 到新版本,但是同一時間只會發布 10 個 Pod,每發布好一個 Pod 才會再找一個發布,直到 60 個發布完成。
  • 當 {matched pod}=100,partitinotallow=80,maxUnavailable=30,控制器會發布 20 個 Pod 到新版本,因為滿足 maxUnavailable 數量,所以這 20 個 Pod 會同時發布。

同樣也可以設置 paused: true 來暫停發布,此時對于新創建的、擴容的 pod 依舊會實現注入能力,已經更新的 pod 會保持更新后的版本不動,還沒有更新的 pod 會暫停更新。

apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
name: sidecarset
spec:
# ...
updateStrategy:
type: RollingUpdate
maxUnavailable: 20%
partition: 10
paused: true

金絲雀發布

對于有金絲雀發布需求的業務,可以通過 selector? 來實現,對于需要率先金絲雀灰度的 pod 打上固定的 [canary.release] = true? 的標簽,再通過 selector.matchLabels 來選中該 pod 即可。

比如現在我們有一個 3 副本的 Pod,也具有 app=nginx 的標簽,如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
spec:
replicas: 3
revisionHistoryLimit: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: ngx
image: nginx:1.7.9
ports:
- containerPort: 80

創建后現在就具有 4 個 app=nginx? 標簽的 Pod 了,由于都匹配上面創建的 SidecarSet 對象,所以都會被注入一個 sidecar1? 的容器,鏡像為 busybox:

? kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-6457955f7-7hnjw 2/2 Running 0 51s
nginx-6457955f7-prkgz 2/2 Running 0 51s
nginx-6457955f7-tbtxk 2/2 Running 0 51s
test-pod 2/2 Running 0 4m2s

現在如果我們想為 test-pod? 這個應用來執行灰度策略,將 sidecar 容器鏡像更新成 busybox:1.35.0?,則可以在 updateStrategy? 下面添加 selector.matchLabels? 屬性 canary.release: "true":

piVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
name: test-sidecarset
spec:
updateStrategy:
type: RollingUpdate
selector:
matchLabels:
canary.release: "true"
containers:
- name: sidecar1
image: busybox:1.35.0
# ......

然后同樣需要給 test-pod 添加上 canary.release=true 這個標簽:

apiVersion: v1
kind: Pod
metadata:
labels:
app: nginx
canary.release: "true"
name: test-pod
spec:
containers:
- name: app
image: nginx:1.7.9

更新后可以發現 test-pod 的 sidecar 鏡像更新了,其他 Pod 沒有變化,這樣就實現了 sidecar 的灰度功能:

? kubectl describe pod test-pod
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Killing 7m53s kubelet Container sidecar1 definition changed, will be restarted
Normal Created 7m23s (x2 over 8m17s) kubelet Created container sidecar1
Normal Started 7m23s (x2 over 8m17s) kubelet Started container sidecar1
Normal Pulling 7m23s kubelet Pulling image "busybox"
Normal Pulled 7m23s kubelet Successfully pulled image "busybox" in 603.928658ms

熱升級

SidecarSet 原地升級會先停止舊版本的容器,然后創建新版本的容器,這種方式適合不影響 Pod 服務可用性的 sidecar 容器,比如說日志收集的 Agent。

但是對于很多代理或運行時的 sidecar 容器,例如 Istio Envoy,這種升級方法就有問題了,Envoy 作為 Pod 中的一個代理容器,代理了所有的流量,如果直接重啟,Pod 服務的可用性會受到影響,如果需要單獨升級 envoy sidecar,就需要復雜的優雅終止和協調機制,所以我們為這種 sidecar 容器的升級提供了一種新的解決方案。

# hotupgrade-sidecarset.yaml
apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
name: hotupgrade-sidecarset
spec:
selector:
matchLabels:
app: hotupgrade
containers:
- name: sidecar
image: openkruise/hotupgrade-sample:sidecarv1
imagePullPolicy: Always
lifecycle:
postStart:
exec:
command:
- /bin/sh
- /migrate.sh
upgradeStrategy:
upgradeType: HotUpgrade
hotUpgradeEmptyImage: openkruise/hotupgrade-sample:empty

  • upgradeType?: HotUpgrade 代表該 sidecar 容器的類型是熱升級方案。
  • hotUpgradeEmptyImage?: 當熱升級 sidecar 容器時,業務必須要提供一個 empty 容器用于熱升級過程中的容器切換,empty 容器同 sidecar 容器具有相同的配置(除了鏡像地址),例如:command?、lifecycle?、probe 等,但是它不做任何工作。
  • lifecycle.postStart: 在 postStart 這個 hook 中完成熱升級過程中的狀態遷移,該腳本需要由業務根據自身的特點自行實現,例如:nginx 熱升級需要完成 Listen FD 共享以及流量排水(reload)操作。

整體來說熱升級特性總共包含以下兩個過程:

  • Pod 創建時,注入熱升級容器。
  • 原地升級時,完成熱升級流程。

注入熱升級容器

Pod 創建時,SidecarSet Webhook 將會注入兩個容器:

  • {sidecarContainer.name}-1?: 如下圖所示 envoy-1?,這個容器代表正在實際工作的 sidecar 容器,例如:envoy:1.16.0。
  • {sidecarContainer.name}-2?: 如下圖所示 envoy-2?,這個容器是業務配置的 hotUpgradeEmptyImage? 容器,例如:empty:1.0,用于后面的熱升級機制。

圖片

注入熱升級容器

熱升級流程

熱升級流程主要分為三個步驟:

  • Upgrade: 將 empty 容器升級為當前最新的 sidecar 容器,例如:envoy-2.Image = envoy:1.17.0
  • Migration?: lifecycle.postStart 完成熱升級流程中的狀態遷移,當遷移完成后退出
  • Reset: 狀態遷移完成后,熱升級流程將設置 envoy-1 容器為 empty 鏡像,例如:envoy-1.Image = empty:1.0

上述三個步驟完成了熱升級中的全部流程,當對 Pod 執行多次熱升級時,將重復性的執行上述三個步驟。

圖片

熱升級流程

這里我們以 OpenKruise 的官方示例來進行說明,首先創建上面的 hotupgrade-sidecarset 這個 SidecarSet。然后創建一個如下所示的 CloneSet 對象:

# hotupgrade-cloneset.yaml
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
name: busybox
labels:
app: hotupgrade
spec:
replicas: 1
selector:
matchLabels:
app: hotupgrade
template:
metadata:
labels:
app: hotupgrade
spec:
containers:
- name: busybox
image: openkruise/hotupgrade-sample:busybox

創建完成后,CloneSet 管理的 Pod 已經注入 sidecar-1? 和 sidecar-2 兩個容器:

? kubectl get sidecarset hotupgrade-sidecarset
NAME MATCHED UPDATED READY AGE
hotupgrade-sidecarset 1 1 0 58s
? kubectl get pods -l app=hotupgrade
NAME READY STATUS RESTARTS AGE
busybox-nd5bp 3/3 Running 0 31s
? kubectl describe pod busybox-nd5bp
Name: busybox-nd5bp
Namespace: default
Node: node2/10.206.16.10
# ......
Controlled By: CloneSet/busybox
Containers:
sidecar-1:
Container ID: containerd://511aa4b60d36483177e92805653c1b618495e47d8d5de331008259f78b3be89e
Image: openkruise/hotupgrade-sample:sidecarv1
Image ID: docker.io/openkruise/hotupgrade-sample@sha256:3d677ca19712b67d2c264374736d71089d21e100eff341f6b4bb0f5288ec6f34
Environment:
IS_INJECTED: true
SIDECARSET_VERSION: (v1:metadata.annotations['version.sidecarset.kruise.io/sidecar-1'])
SIDECARSET_VERSION_ALT: (v1:metadata.annotations['versionalt.sidecarset.kruise.io/sidecar-1'])
# ......
sidecar-2:
Container ID: containerd://6b0678695ccb977695248e41108606b409ad0c7e3e4fe1ba9b48e839e3c235ef
Image: openkruise/hotupgrade-sample:empty
Image ID: docker.io/openkruise/hotupgrade-sample@sha256:606be602967c9f91c47e4149af4336c053e26225b717a1b5453ac8fa9a401cc5
Environment:
IS_INJECTED: true
SIDECARSET_VERSION: (v1:metadata.annotations['version.sidecarset.kruise.io/sidecar-2'])
SIDECARSET_VERSION_ALT: (v1:metadata.annotations['versionalt.sidecarset.kruise.io/sidecar-2'])
# ......
busybox:
Container ID: containerd://da7eebb0161bab37f7de75635e68c5284a973a21f6d3f095bb5e8212ac8ce908
Image: openkruise/hotupgrade-sample:busybox
Image ID: docker.io/openkruise/hotupgrade-sample@sha256:08f9ede05850686e1200240e5e376fc76245dd2eb56299060120b8c3dba46dc9
# ......
# ......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 50s default-scheduler Successfully assigned default/busybox-nd5bp to node2
Normal Pulling 49s kubelet Pulling image "openkruise/hotupgrade-sample:sidecarv1"
Normal Pulled 41s kubelet Successfully pulled image "openkruise/hotupgrade-sample:sidecarv1" in 7.929984849s (7.929998445s including waiting)
Normal Created 41s kubelet Created container sidecar-1
Normal Started 41s kubelet Started container sidecar-1
Normal Pulling 36s kubelet Pulling image "openkruise/hotupgrade-sample:empty"
Normal Pulled 29s kubelet Successfully pulled image "openkruise/hotupgrade-sample:empty" in 7.434180553s (7.434189239s including waiting)
Normal Created 29s kubelet Created container sidecar-2
Normal Started 29s kubelet Started container sidecar-2
Normal Pulling 29s kubelet Pulling image "openkruise/hotupgrade-sample:busybox"
Normal Pulled 22s kubelet Successfully pulled image "openkruise/hotupgrade-sample:busybox" in 6.583450981s (6.583456512s including waiting)
Normal Created 22s kubelet Created container busybox
Normal Started 22s kubelet Started container busybox
......

busybox 主容器每 100 毫秒會請求一次 sidecar(versinotallow=v1)服務:

? kubectl logs -f busybox-nd5bp -c busybox
I0404 09:12:26.513128 1 main.go:39] request sidecar server success, and response(body=This is version(v1) sidecar)
I0404 09:12:26.623496 1 main.go:39] request sidecar server success, and response(body=This is version(v1) sidecar)
I0404 09:12:26.733958 1 main.go:39] request sidecar server success, and response(body=This is version(v1) sidecar)
......

現在我們去升級 sidecar 容器,將鏡像修改為 openkruise/hotupgrade-sample:sidecarv2:

? kubectl patch sidecarset hotupgrade-sidecarset --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value": "openkruise/hotupgrade-sample:sidecarv2"}]'

更新后再去觀察 pod 的狀態,可以看到 sidecar-2 鏡像正常更新了:

? kubectl get pods -l app=hotupgrade
NAME READY STATUS RESTARTS AGE
busybox-nd5bp 3/3 Running 2 (45s ago) 23m
? kubectl describe pods busybox-nd5bp
......
Events:
......
Normal Pulling 33s kubelet Pulling image "openkruise/hotupgrade-sample:sidecarv2"
Normal Killing 33s kubelet Container sidecar-2 definition changed, will be restarted
Normal Started 25s (x2 over 22m) kubelet Started container sidecar-2
Normal Created 25s (x2 over 22m) kubelet Created container sidecar-2
Normal Pulled 25s kubelet Successfully pulled image "openkruise/hotupgrade-sample:sidecarv2" in 8.169453753s (8.16946743s including waiting)
Normal Killing 14s kubelet Container sidecar-1 definition changed, will be restarted
Normal ResetContainerSucceed 14s sidecarset-controller reset sidecar container image empty successfully
Normal Pulling 14s kubelet Pulling image "openkruise/hotupgrade-sample:empty"
Normal Created 12s (x2 over 22m) kubelet Created container sidecar-1
Normal Started 12s (x2 over 22m) kubelet Started container sidecar-1
Normal Pulled 12s kubelet Successfully pulled image "openkruise/hotupgrade-sample:empty" in 1.766097364s (1.766109087s including waiting)

并且在更新過程中觀察 busybox 容器仍然會不斷請求 sidecar 服務,但是并沒有失敗的請求出現:

? kubectl logs -f busybox-nd5bp -c busybox
I0306 11:08:47.587727 1 main.go:39] request sidecar server success, and response(body=This is version(v1) sidecar)
I0404 09:14:28.588973 1 main.go:39] request sidecar server success, and response(body=This is version(v2) sidecar)
# ......

整個熱升級示例代碼可以參考倉庫的實現:https://github.com/openkruise/samples/tree/master/hotupgrade。

Container Restart

ContainerRecreateRequest? 控制器可以幫助用戶重啟/重建存量 Pod 中一個或多個容器。和 Kruise 提供的原地升級類似,當一個容器重建的時候,Pod 中的其他容器還保持正常運行,重建完成后,Pod 中除了該容器的 restartCount 增加以外不會有什么其他變化。

不過需要注意之前臨時寫到舊容器 rootfs? 中的文件會丟失,但是 volume mount 掛載卷中的數據都還存在。這個功能依賴于 kruise-daemon 組件來停止 Pod 容器。

為要重建容器的 Pod 提交一個 ContainerRecreateRequest 自定義資源(縮寫 CRR):

# crr-demo.yaml
apiVersion: apps.kruise.io/v1alpha1
kind: ContainerRecreateRequest
metadata:
name: crr-dmo
spec:
podName: pod-name
containers: # 要重建的容器名字列表,至少要有 1 個
- name: app
- name: sidecar
strategy:
failurePolicy: Fail # 'Fail' 或 'Ignore',表示一旦有某個容器停止或重建失敗, CRR 立即結束
orderedRecreate: false # 'true' 表示要等前一個容器重建完成了,再開始重建下一個
terminationGracePeriodSeconds: 30 # 等待容器優雅退出的時間,不填默認用 Pod 中定義的
unreadyGracePeriodSeconds: 3 # 在重建之前先把 Pod 設為 not ready,并等待這段時間后再開始執行重建
minStartedSeconds: 10 # 重建后新容器至少保持運行這段時間,才認為該容器重建成功
activeDeadlineSeconds: 300 # 如果 CRR 執行超過這個時間,則直接標記為結束(未結束的容器標記為失敗)
ttlSecondsAfterFinished: 1800 # CRR 結束后,過了這段時間自動被刪除掉

一般來說,列表中的容器會一個個被停止,但可能同時在被重建和啟動,除非 orderedRecreate? 被設置為 true。unreadyGracePeriodSeconds? 功能依賴于 KruisePodReadinessGate? 這個 feature-gate,后者會在每個 Pod 創建的時候注入一個 readinessGate?,否則,默認只會給 Kruise 工作負載創建的 Pod 注入 readinessGate,也就是說只有這些 Pod 才能在 CRR 重建時使用 unreadyGracePeriodSeconds。

當用戶創建了一個 CRR,Kruise webhook 會把當時容器的 containerID/restartCount 記錄到 spec.containers[x].statusContext? 之中。 在 kruise-daemon 執行的過程中,如果它發現實際容器當前的 containerID? 與 statusContext? 不一致或 restartCount 已經變大,則認為容器已經被重建成功了(比如可能發生了一次原地升級)。

圖片

容器重啟請求

一般情況下,kruise-daemon 會執行 preStop hook 后把容器停掉,然后 kubelet 感知到容器退出,則會新建一個容器并啟動。最后 kruise-daemon 看到新容器已經啟動成功超過 minStartedSeconds 時間后,會上報這個容器的 phase 狀態為 Succeeded。

如果容器重建和原地升級操作同時觸發了:

  • 如果 kubelet 根據原地升級要求已經停止或重建了容器,kruise-daemon 會判斷容器重建已經完成。
  • 如果 kruise-daemon 先停了容器,Kubelet 會繼續執行原地升級,即創建一個新版本容器并啟動。
  • 如果針對一個 Pod 提交了多個 ContainerRecreateRequest 資源,會按時間先后一個個執行。

ImagePullJob

NodeImage? 和 ImagePullJob 是從 Kruise v0.8.0 版本開始提供的 CRD。Kruise 會自動為每個節點創建一個 NodeImage,它包含了哪些鏡像需要在這個 Node 上做預熱,比如我們這里 3 個節點,則會自動創建 3 個 NodeImage 對象:

? kubectl get nodeimage
NAME DESIRED PULLING SUCCEED FAILED AGE
master1 0 0 0 0 5d
node1 0 0 0 0 5d
node2 0 0 0 0 5d

比如我們查看 node1 節點上的 NodeImage 對象:

? kubectl get nodeimage node1 -o yaml
apiVersion: apps.kruise.io/v1alpha1
kind: NodeImage
metadata:
name: node1
# ......
spec: {}
status:
desired: 0
failed: 0
pulling: 0
succeeded: 0

比如我們希望在這個節點上拉去一個 ubuntu:latest 鏡像,則可以按照如下所示的去修改 spec:

......
spec:
images:
ubuntu: # 鏡像 name
tags:
- tag: latest # 鏡像 tag
pullPolicy:
ttlSecondsAfterFinished: 300 # [required] 拉取完成(成功或失敗)超過 300s 后,將這個任務從 NodeImage 中清除
timeoutSeconds: 600 # [optional] 每一次拉取的超時時間, 默認為 600
backoffLimit: 3 # [optional] 拉取的重試次數,默認為 3
activeDeadlineSeconds: 1200 # [optional] 整個任務的超時時間,無默認值

更新后我們可以從 status 中看到拉取進度以及結果,并且你會發現拉取完成 600s 后任務會被清除。

? kubectl describe nodeimage node1
Name: node1
Namespace:
# ......
Spec:
Images:
Ubuntu:
Tags:
Created At: 2023-04-04T09:29:18Z
Pull Policy:
Active Deadline Seconds: 1200
Backoff Limit: 3
Timeout Seconds: 600
Ttl Seconds After Finished: 300
Tag: latest
Status:
Desired: 1
Failed: 0
Image Statuses:
Ubuntu:
Tags:
Completion Time: 2023-04-04T09:29:28Z
Phase: Succeeded
Progress: 100
Start Time: 2023-04-04T09:29:18Z
Tag: latest
Pulling: 0
Succeeded: 1
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal PullImageSucceed 11s kruise-daemon-imagepuller Image ubuntu:latest, ecalpsedTime 10.066193581s

我們可以在 node1 節點上查看到這個鏡像已經被拉取下來了:

ubuntu@node1:~$ sudo ctr -n k8s.io i ls  |grep ubuntu
docker.io/library/ubuntu:latest application/vnd.oci.image.index.v1+json sha256:67211c14fa74f070d27cc59d69a7fa9aeff8e28ea118ef3babc295a0428a6d21 28.2 MiB linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x io.cri-containerd.image=managed
docker.io/library/ubuntu@sha256:67211c14fa74f070d27cc59d69a7fa9aeff8e28ea118ef3babc295a0428a6d21 application/vnd.oci.image.index.v1+json sha256:67211c14fa74f070d27cc59d69a7fa9aeff8e28ea118ef3babc295a0428a6d21 28.2 MiB linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x io.cri-containerd.image=managed
ubuntu@node1:~$

此外用戶可以創建 ImagePullJob 對象,來指定一個鏡像要在哪些節點上做預熱。

圖片

比如創建如下所示的 ImagePullJob 資源對象:

apiVersion: apps.kruise.io/v1alpha1
kind: ImagePullJob
metadata:
name: job-with-always
spec:
image: nginx:1.9.1 # [required] 完整的鏡像名 name:tag
parallelism: 10 # [optional] 最大并發拉取的節點梳理, 默認為 1
selector: # [optional] 指定節點的 名字列表 或 標簽選擇器 (只能設置其中一種)
names:
- node1
- node2
matchLabels:
node-type: xxx
# podSelector: # [optional] pod label 選擇器來在這些 pod 所在節點上拉取鏡像, 與 selector 不能同時設置.
# pod-label: xxx
completionPolicy:
type: Always # [optional] 默認為 Always
activeDeadlineSeconds: 1200 # [optional] 無默認值, 只對 Alway 類型生效
ttlSecondsAfterFinished: 300 # [optional] 無默認值, 只對 Alway 類型生效
pullPolicy: # [optional] 默認 backoffLimit=3, timeoutSecnotallow=600
backoffLimit: 3
timeoutSeconds: 300
pullSecrets:
- secret-name1
- secret-name2

我們可以在 selector? 字段中指定節點的名字列表或標簽選擇器 (只能設置其中一種),如果沒有設置 selector 則會選擇所有節點做預熱。或者可以配置 podSelector 來在這些 pod 所在節點上拉取鏡像,podSelector 與 selector 不能同時設置。

同時,ImagePullJob 有兩種 completionPolicy 類型:

  • Always:表示這個 job 是一次性預熱,不管成功、失敗都會結束。
  • activeDeadlineSeconds:整個 job 的 deadline 結束時間。
  • ttlSecondsAfterFinished:結束后超過這個時間,自動清理刪除 job。
  • Never:表示這個 job 是長期運行、不會結束,并且會每天都會在匹配的節點上重新預熱一次指定的鏡像。

同樣如果你要預熱的鏡像來自私有倉庫,則可以通過 pullSecrets 來指定倉庫的 Secret 信息。

如果這個鏡像來自一個私有倉庫,則可以通過 pullSecrets 來指定倉庫的 Secret 信息。

# ...
spec:
pullSecrets:
- secret-name1
- secret-name2

因為 ImagePullJob? 是一種 namespaced-scope 資源,所以這些 Secret 必須存在 ImagePullJob 所在的 namespace 中。然后你只需要在 pullSecrets 字段中寫上這些 secret 的名字即可。

容器啟動順序

Container Launch Priority 提供了控制一個 Pod 中容器啟動順序的方法。通常來說 Pod 容器的啟動和退出順序是由 Kubelet 管理的,Kubernetes 曾經有一個 KEP 計劃在 container 中增加一個 type 字段來標識不同類型容器的啟停優先級,但是由于sig-node 考慮到對現有代碼架構的改動太大,所以將該提案拒絕了。

這個功能作用在 Pod 對象上,不管它的 owner 是什么類型的,因此可以適用于 Deployment、CloneSet 以及其他的工作負載。

比如我們可以設置按照容器順序啟動,只需要在 Pod 中定義一個 apps.kruise.io/container-launch-priority 的注解即可:

apiVersion: v1
kind: Pod
annotations:
apps.kruise.io/container-launch-priority: Ordered
spec:
containers:
- name: sidecar
# ...
- name: main
# ...

Kruise 會保證前面的容器(sidecar)會在后面容器(main)之前啟動。

此外我們還可以按自定義順序啟動,但是需要在 Pod 容器中添加 KRUISE_CONTAINER_PRIORITY 這個環境變量:

apiVersion: v1
kind: Pod
spec:
containers:
- name: main
# ...
- name: sidecar
env:
- name: KRUISE_CONTAINER_PRIORITY
value: "1"
# ...

該環境變量值的范圍在 [-2147483647, 2147483647],不寫默認是 0,權重高的容器,會保證在權重低的容器之前啟動,但是需要注意相同權重的容器不保證啟動順序。

資源分發

在對 Secret、ConfigMap 等命名空間級別資源進行跨 namespace 分發及同步的場景中,原生 Kubernetes 目前只支持用戶手動分發與同步,十分地不方便。比如:

  • 當用戶需要使用 SidecarSet 的 imagePullSecrets 能力時,要先重復地在相關 namespaces 中創建對應的 Secret,并且需要確保這些 Secret 配置的正確性和一致性。
  • 當用戶想要采用 ConfigMap 來配置一些通用的環境變量時,往往需要在多個 namespaces 做 ConfigMap 的下發,并且后續的修改往往也要求多 namespaces 之間保持同步。
  • 在多個命名空間中的 Ingress 對象需要使用同一個 Secret 對象

面對這些需要跨命名空間進行資源分發和多次同步的場景,OpenKruise 設計了一個新的 CRD - ResourceDistribution,可以更便捷的自動化分發和同步這些資源。

ResourceDistribution? 目前支持 Secret? 和 ConfigMap 兩類資源的分發和同步。

ResourceDistribution? 是全局的 CRD,其主要由 resource? 和 targets? 兩個字段構成,其中 resource? 字段用于描述用戶所要分發的資源,targets 字段用于描述用戶所要分發的目標命名空間。

apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
metadata:
name: sample
spec:
resource: ... ...
targets: ... ...

其中 resource 字段必須是一個完整、正確的資源描述,如下所示:

apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
metadata:
name: sample
spec:
resource:
apiVersion: v1
kind: ConfigMap
metadata:
name: game-demo
data:
game.properties: |
enemy.types=aliens,monsters
player.maximum-lives=5
player_initial_lives: "3"
ui_properties_file_name: user-interface.properties
user-interface.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
targets: ... ...

用戶可以先在本地某個命名空間中創建相應資源并進行測試,確認資源配置正確后再拷貝過來。

targets? 字段目前支持四種規則來描述用戶所要分發的目標命名空間,包括 allNamespaces?、includedNamespaces?、namespaceLabelSelector? 以及 excludedNamespaces:

  • allNamespaces: bool 值,如果為 true,則分發至所有命名空間。
  • includedNamespaces: 通過 Name 來匹配目標命名空間。
  • namespaceLabelSelector:通過 LabelSelector 來匹配目標命名空間。
  • excludedNamespaces: 通過 Name 來排除某些不想分發的命名空間。

allNamespaces?、includedNamespaces?、namespaceLabelSelector? 之間是**或(OR)**的關系,而 excludedNamespaces? 一旦被配置,則會顯式地排除掉這些命名空間。另外,targets? 還將自動忽略 kube-system? 和 kube-public 兩個命名空間。

一個配置正確的 targets 字段如下所示:

apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
metadata:
name: sample
spec:
resource: ... ...
targets:
includedNamespaces:
list:
- name: ns-1
- name: ns-4
namespaceLabelSelector:
matchLabels:
group: test
excludedNamespaces:
list:
- name: ns-3

該配置表示該 ResourceDistribution? 的目標命名空間一定會包含 ns-1? 和 ns-4?,并且 Labels 滿足 namespaceLabelSelector? 的命名空間也會被包含進目標命名空間,但是,即使 ns-3? 即使滿足 namespaceLabelSelector? 也不會被包含,因為它已經在 excludedNamespaces 中被顯式地排除了。

如果同步的資源需要更新則可以去更新 resource? 字段,更新后會自動地對所有目標命名空間中的資源進行同步更新。每一次更新資源時,ResourceDistribution? 都會計算新版本資源的哈希值,并記錄到資源的 Annotations 之中,當 ResourceDistribution 發現新版本的資源與目前資源的哈希值不同時,才會對資源進行更新。

apiVersion: v1
kind: ConfigMap
metadata:
name: demo
annotations:
kruise.io/resourcedistribution.resource.from: sample
kruise.io/resourcedistribution.resource.distributed.timestamp: 2021-09-06 08:44:52.7861421 +0000 UTC m=+12896.810364601
kruise.io/resourcedistribution.resource.hashcode: 0821a13321b2c76b5bd63341a0d97fb46bfdbb2f914e2ad6b613d10632fa4b63
... ...

當然非常不建議用戶繞過 ResourceDistribution 直接對資源進行修改,除非用戶知道自己在做什么。

  • 因為直接修改資源后,資源的哈希值不會被自動計算,因此,下次 resource 字段被修改后,ResourceDistribution 可能將用戶對這些資源的直接修改覆蓋掉。
  • ResourceDistribution? 通過 kruise.io/resourcedistribution.resource.from? 來判斷資源是否由該 ResourceDistribution? 分發,如果該 Annotation 被修改或刪除,則被修改的資源會被 ResourceDistribution? 當成沖突資源,并且無法通過 ResourceDistribution 進行同步更新。

除了這些增強控制器之外 OpenKruise 還有很多高級的特性,可以前往官網 https://openkruise.io 了解更多信息。

責任編輯:姜華 來源: k8s技術圈
相關推薦

2023-04-04 07:25:46

KubernetesOpenKruise

2023-09-03 19:43:46

htmxJavaScript網絡

2011-01-05 11:12:34

C++

2013-05-15 09:14:01

2021-01-27 10:01:46

MySQL數據庫SQLX

2022-09-21 10:50:43

pickledillPython

2011-09-15 14:00:52

IOS應用SpoolInstapaper

2011-05-26 17:55:08

2009-01-05 10:30:23

賽門鐵克Veritas數據中心

2020-06-30 08:08:25

k8s監控

2023-05-10 08:17:22

合并事件推送

2009-12-29 14:18:43

ADO.NET2.0

2022-04-22 13:32:01

K8s容器引擎架構

2015-09-23 11:27:20

Office 2016ISO鏡像微軟

2013-08-20 17:46:43

通達OA

2015-06-01 16:09:02

聯想

2012-08-28 13:37:30

2010-08-25 10:42:20

GroovyGroovy++

2013-10-09 14:57:41

通達oa
點贊
收藏

51CTO技術棧公眾號

蜜桃视频在线免费| 一区二区三区视频免费看| 亚洲伦理一区二区| 亚洲国产毛片aaaaa无费看 | 久久高清视频免费| 日批在线观看视频| 国产成人亚洲一区二区三区| 一区二区成人在线| 日韩啊v在线| 成人av手机在线| 久久精品主播| 欧美日韩xxx| 精品人伦一区二区| 中文字幕区一区二区三| 色激情天天射综合网| 992tv快乐视频| 免费在线超碰| 国产91露脸合集magnet| 国产精品久久网| 日本一级黄色录像| 欧美肥老太太性生活| 亚洲国产成人久久| www.国产福利| 二区三区不卡| 亚洲一二三四区| 亚洲欧洲精品一区二区| 日本国产在线| 国产麻豆视频精品| 国产精品嫩草视频| 麻豆久久久久久久久久| 欧美久久综合| 久久精品人人爽| 69视频在线观看免费| 国产精品115| 欧美一级黄色片| 超碰在线人人爱| 原纱央莉成人av片| 午夜精品一区二区三区电影天堂| 手机福利在线视频| 国产精品免费观看| 91免费国产在线| 国产精品一区二区欧美| 国产福利免费视频| 久久99精品国产麻豆婷婷洗澡| 热99在线视频| 国产高潮久久久| 亚洲性图久久| 欧美激情欧美激情在线五月| 国产一二三区精品| 99精品视频精品精品视频| 中文在线不卡视频| 免费看日本黄色片| 日本大胆欧美| 正在播放亚洲1区| 国产在线综合视频| 欧美一区二区三区激情视频| 一本色道久久88综合日韩精品| 四虎永久免费影院| 免费看av成人| 一道本无吗dⅴd在线播放一区| 中文字幕免费视频| 欧美午夜精品一区二区三区电影| 亚洲香蕉伊综合在人在线视看| 国产男男chinese网站| 婷婷综合成人| 国产亚洲精品91在线| 2019男人天堂| 四虎成人精品永久免费av九九| 尤物99国产成人精品视频| 国产三级短视频| 激情无码人妻又粗又大| 国产欧美日韩一区| 永久免费看mv网站入口亚洲| 色一情一乱一伦一区二区三区| 欧美伦理影视网| 久久久精品中文字幕麻豆发布| 免费成人av网站| 成人午夜电影在线观看| 国产精品理伦片| 亚洲精品偷拍视频| 黄色小说在线播放| 欧美日韩国产丝袜另类| 波多野结衣作品集| 日韩电影免费观看高清完整版在线观看 | 成人h在线播放| 凸凹人妻人人澡人人添| 国产亚洲福利社区一区| 桥本有菜av在线| 丰乳肥臀在线| 日本道精品一区二区三区| 五月激情婷婷在线| 在线日韩成人| 国产性色av一区二区| 欧美激情图片小说| 午夜在线一区二区| 成人性生交大片免费看小说| 成人爽a毛片一区二区| 91蝌蚪porny| 一区二区精品免费视频| av软件在线观看| 精品国产成人在线| 99九九99九九九99九他书对| 国产精品对白久久久久粗| 亚洲石原莉奈一区二区在线观看| 午夜国产福利视频| 国产精品色网| 亚洲综合中文字幕68页| 国产最新视频在线观看| 夜夜精品浪潮av一区二区三区| 国产日韩一区二区在线| 日本精品在线观看| 国产一区二区欧美日韩| 国产精品a成v人在线播放| 日韩av一级电影| 国产视频一区二区不卡| 成人在线观看亚洲| 欧美性猛片xxxx免费看久爱| 日本人添下边视频免费| 国产精品99久久精品| 国产成人黄色av| 狠狠综合久久av一区二区| 最新日韩在线视频| 亚洲 欧美 日韩系列| 视频福利一区| 久久人人爽人人爽人人片av高请| 97超碰人人草| 国产精品系列在线| 干日本少妇首页| 国产精品视屏| 另类图片亚洲另类| 中文字字幕在线观看| 久久先锋资源网| 欧美日韩成人免费视频| 99re8这里有精品热视频8在线| 伊人精品在线观看| 久久久久久久久久成人| 91性感美女视频| 少妇人妻无码专区视频| 91综合精品国产丝袜长腿久久| 久久视频中文字幕| 国产一区二区在线播放视频| 国产精品蜜臀在线观看| 亚洲第一狼人区| 国产欧美日韩在线一区二区| 欧美一性一乱一交一视频| 天天操天天射天天| 婷婷久久综合九色国产成人| 久久久高清视频| 日韩天堂av| 九九热久久66| 免费日韩电影| 亚洲欧美三级在线| 国产一区免费看| 国产欧美精品一区aⅴ影院 | 日韩欧美一二区| 美国黄色小视频| 国产精品18久久久久久vr| 日本男女交配视频| 成人高潮视频| 5252色成人免费视频| 全色精品综合影院| 91黄视频在线| 中文国语毛片高清视频| 黄网站免费久久| 国产日韩第一页| 日韩在线精品强乱中文字幕| 欧美精品18videos性欧| 香蕉视频国产在线| 91福利视频久久久久| 免费黄色三级网站| 爽好多水快深点欧美视频| 亚洲图片欧洲图片日韩av| 亚洲日本中文| 久久久久久久香蕉网| 男人天堂资源在线| 精品视频色一区| 激情视频在线播放| 99精品欧美一区二区三区综合在线| 97xxxxx| 偷拍欧美精品| 国产精品乱码一区二区三区| 免费观看一级欧美片| 日韩中文字幕久久| 高h调教冰块play男男双性文| 黑人极品videos精品欧美裸| 日韩精品电影一区二区三区| 国产一区免费电影| 男人揉女人奶房视频60分| 欧美aaaa视频| 国偷自产av一区二区三区小尤奈| 少妇精品视频一区二区免费看| 久久久av免费| 日本午夜在线| 3atv一区二区三区| 九九热在线免费观看| 亚洲天堂网中文字| 波多野结衣 在线| 国产一区二区三区美女| 人妻熟女一二三区夜夜爱| 91蜜臀精品国产自偷在线| 国产精品一区二| 日本免费成人| 欧美性受xxxx黑人猛交| 欧美精品hd| 亚洲精品自拍第一页| 国产又粗又大又黄| 日韩欧美在线视频日韩欧美在线视频| 亚洲综合图片一区| 久久久久青草大香线综合精品| 欧美在线视频你懂得| 在线播放av中文字幕| 国产亚洲精品v| 99热这里只有精品7| 免费视频亚洲| 国产精品香蕉视屏| 99er精品视频| 国产精品成人aaaaa网站| aaa在线播放视频| 久久精品国产成人| 春暖花开成人亚洲区| 日韩一级片在线观看| 亚洲天堂手机在线| 日韩人在线观看| 国产成人一区二区三区影院在线 | 91精品免费在线| 波多野结衣mp4| 福利视频导航一区| xxxxxx国产| 亚洲精品久久久久久国产精华液| 国产探花视频在线播放| 久久久久亚洲综合| 黄色国产在线观看| 97精品久久久久中文字幕| 国产又粗又猛又爽又黄| 国产在线精品不卡| 在线观看岛国av| 乱馆动漫1~6集在线观看| 国产一区二区观看| 国产乱国产乱300精品| 亚洲国产精品视频在线观看| 在线观看欧美激情| 男人天堂视频网| а√中文在线天堂精品| 欧美国产一区二区在线观看| 91麻豆精品国产综合久久久久久| 久久91精品国产91久久跳| 国产69精品久久久久9999apgf| 亚洲午夜精品久久| 欧美成人国产精品一区二区| 午夜在线视频免费| 日韩毛片免费看| 亚洲国产免费看| 91视频99| 精品视频一区二区三区在线观看 | 高清免费日韩| 成人线上播放| 国内外成人免费视频| 天堂av一区二区三区在线播放 | 57pao成人永久免费视频| 蜜桃视频在线观看播放| 欧美亚洲在线观看| 二吊插入一穴一区二区| 国产精品情侣自拍| 亚洲欧美综合久久久久久v动漫| 成人性生交大片免费看视频直播 | 性8sex亚洲区入口| 国产麻花豆剧传媒精品mv在线| 久久福利精品| 午夜视频你懂的| 精品一区二区在线免费观看| 女王人厕视频2ⅴk| 99久久久无码国产精品| 四虎国产精品成人免费入口| 国产精品毛片a∨一区二区三区| 日韩欧美123区| 黄色91在线观看| 欧美 亚洲 另类 激情 另类| 在线不卡一区二区| 成人毛片在线免费观看| 国产一区二区黑人欧美xxxx| 1769免费视频在线观看| 亚洲91av视频| 亚洲第一会所| 国产精品视频福利| 国产在线日韩精品| 亚洲五码在线观看视频| 国产精品毛片在线看| 一区二区三区 欧美| 大桥未久av一区二区三区中文| 短视频在线观看| 亚洲欧美一区二区三区孕妇| 亚洲日本韩国在线| 欧美精品久久久久久久久老牛影院| 亚洲精品久久久蜜桃动漫 | 欧美三级视频在线观看| 朝桐光av在线一区二区三区| 亚洲乱码国产乱码精品精天堂| 欧美激情免费| 日本在线观看天堂男亚洲| 精品视频一区二区三区| 日韩国产精品一区二区| 亚洲视频日本| 日韩大片一区二区| av电影在线观看不卡| 天天色天天综合| 日韩欧美国产高清91| 精品久久久久成人码免费动漫| 亚洲美女视频网| 欧美人与禽性xxxxx杂性| 国产精品久久久久久久久久 | 亚洲国产成人久久综合一区| av在线天堂| 秋霞av国产精品一区| 成人涩涩网站| ijzzijzzij亚洲大全| 日韩高清一区在线| 男人的天堂影院| 亚洲日本电影在线| 亚洲天堂手机版| 亚洲色图15p| 理论片午夜视频在线观看| 成人h视频在线观看| 亚洲精品小说| 91高清国产视频| 国产亚洲女人久久久久毛片| 日本三级片在线观看| 欧美一卡2卡3卡4卡| 在线看黄色av| 国产精品第2页| 国产欧美亚洲精品a| 欧美成人xxxxx| 91看片淫黄大片一级| 国产第一页在线播放| 日韩欧美精品在线| 国产黄a三级三级三级av在线看| 国产欧美一区二区三区视频| 国内精品伊人久久久| 国产主播在线看| 成人高清视频在线| 日本黄色片视频| 亚洲黄色www网站| av在线视屏| 国产精品初高中精品久久| 欧美不卡在线| 秋霞午夜鲁丝一区二区| 亚洲精品欧美综合四区| 国产不卡av在线播放| 欧美大尺度激情区在线播放| 激情视频亚洲| 日韩激情视频一区二区| 成人国产在线观看| 日本一本高清视频| 亚洲女人天堂色在线7777| 手机在线观看av| 欧美日韩国产综合视频在线| 久久久久国产精品一区二区| 国产jk精品白丝av在线观看| 欧美三级电影一区| 久热国产在线| 成人免费在线一区二区三区| 欧美天天视频| av鲁丝一区鲁丝二区鲁丝三区| 午夜av一区二区| 你懂的在线免费观看| 国产精品美女www爽爽爽视频| 日韩午夜电影网| avtt中文字幕| 午夜视频久久久久久| 免费黄色在线视频网站| 国产精品日韩在线| 中文字幕免费一区二区| 污污污www精品国产网站| 色综合天天综合给合国产| 91se在线| 国产成人看片| 羞羞答答国产精品www一本| 五月婷婷六月香| 欧美一区二区在线观看| 欧美sm一区| 亚洲国产精品123| 国产成人免费视| 免费av网站在线| 俺去亚洲欧洲欧美日韩| 给我免费播放日韩视频| 国模杨依粉嫩蝴蝶150p| 亚洲欧洲av在线| 无码国产色欲xxxx视频| 国产精品久久久久久久久久久不卡| 一区二区蜜桃| 黄色aaa视频| 欧美一级高清片| 伊人久久高清| 久久艹国产精品| 国产欧美精品一区aⅴ影院| 亚洲奶汁xxxx哺乳期| 国产精品久在线观看| 国一区二区在线观看| 18精品爽国产三级网站| 精品99999| 亚洲免费看片|