Replies: 13 comments 28 replies
-
Pull-based GitOps Iter8 will support Pull-based GitOps using operators like Flux, ArgoCD and JenkinsX. This is illustrated in the picture below. |
Beta Was this translation helpful? Give feedback.
-
Common Aspects of Push-and-Pull-based GitOps
|
Beta Was this translation helpful? Give feedback.
-
Differences Between Push-and-Pull-based GitOps
|
Beta Was this translation helpful? Give feedback.
-
References:
|
Beta Was this translation helpful? Give feedback.
-
Kubecon EU just got over which means this GitOps work is now back on track and our next deliverable... Resuming the design discussion below. |
Beta Was this translation helpful? Give feedback.
-
Seperation between CD pipeline segment and Iter8Steps 0, 1 and 3
Step 2
|
Beta Was this translation helpful? Give feedback.
-
Reframing Iter8 quick start tutorial as per the above design.Note: The following discussion uses helm, but alternative templating mechanisms can be used in place of helm. Istio quick start exampleStep 1helm template bookinfo/product-page --set image={{ GITHUB.ACTIONS.INPUTS.IMAGE }},stable=false,repo={{ GITHUB.ENV.REPO }},folderPath=src/envrepo --generate-name
The above command is intended to generate the following artifacts (which can be written to Git env repo in GitOps mode and
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
gateways:
- mesh
- bookinfo-gateway
hosts:
- productpage
- "bookinfo.example.com"
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
subset: productpage-stable
weight: 100
- destination:
host: productpage
port:
number: 9080
subset: productpage-experimental
weight: 0
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: bookinfo
spec:
host: productpage
subsets:
- labels:
app: productpage
version: stable
name: productpage-stable
- labels:
app: productpage
version: v2
name: productpage-experimental apiVersion: iter8.tools/v2alpha2
kind: Experiment
metadata:
name: quickstart-exp-7392lasdhf
spec:
# target identifies the service under experimentation using its fully qualified name
target: bookinfo-iter8/productpage
strategy:
# this experiment will perform an A/B test
testingPattern: A/B
# this experiment will progressively shift traffic to the winning version
deploymentPattern: Progressive
actions:
# when the experiment completes, promote the winning version using kubectl apply
start:
- task: common/script
with: |
kubectl wait --for=condition=available --timeout=600s deployment/baseline -n bookinfo-iter8
kubectl wait --for=condition=available --timeout=600s deployment/candidate -n bookinfo-iter8
finish:
- task: gitops/init # drop this task for clusterops
with:
repo: github.com/bookinfo/productpage
folder: env/repo/folder/path # optional; without this field, root of the repo is the default folder
secret: ns/git-token
- task: gitops/apply # replace gitops with clusterops for clusterops
with:
cmd: helm template bookinfo/product-page --set image={{ .image }},stable=true --generate-name
criteria:
rewards:
# (business) reward metric to optimize in this experiment
- metric: iter8-istio/user-engagement
preferredDirection: High
objectives: # used for validating versions
- metric: iter8-istio/mean-latency
upperLimit: 300
- metric: iter8-istio/error-rate
upperLimit: "0.01"
requestCount: iter8-istio/request-count
duration: # product of fields determines length of the experiment
intervalSeconds: 10
iterationsPerLoop: 10
versionInfo:
# information about the app versions used in this experiment
baseline:
name: productpage-v1
variables:
- name: image
value: bookinfo/productpage:v1
weightObjRef:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
namespace: bookinfo-iter8
name: bookinfo
fieldPath: .spec.http[0].route[0].weight
candidates:
- name: productpage-v2
variables:
- name: image # used by final action if this version is the winner
value: bookinfo/productpage:v2
weightObjRef:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
namespace: bookinfo-iter8
name: bookinfo
fieldPath: .spec.http[0].route[1].weight Random string in the above experiment is generated by helm -- experiment template has name: quickstart-exp-{{ randAlphaNum 10 }} For Steps 2 and 3, refer to start and finish actions respectively in the experiment. |
Beta Was this translation helpful? Give feedback.
-
@huang195 You identified several potential problems with GitOps release automation in general in the Iter8 workgroup discussion. I am listing them below... so that we can discuss how the above proposal (and any alternative) fares with respect to those problems. Problem 1: Problem 1 is simply stating that without iter8 writing back to the Env repo, it will not maintain GitOps guarantee, as what runs in the cluster could deviate from that of Env repo. Problem 2: Problem 2 says when Iter8 writes back to the Env repo, we are now introducing a race condition as now both CI and iter8 need to write to the same repo / files, which could lead to corruption. In light of this problem, the design proposal described above provide the following three important invariants. Problem 3 is regarding failure of handler code that changes env repo. If such code crashes in the middle, this could lead to inconsistency in env repo state. Who's responsible for recover from such failures? a. What happens if one of the Problem 4 is regarding whether or not iter8 should support both i) allow users to test every commit, and ii) allow users to test only the latest commit. My finding is it might support the former, but doesn't support the latter. Do we want to support both modes or just the former? Problem 5 is regarding fine-grained sync. The use case you and Ang discussed about having iter8 sync'ing back intermediate state of an experiment has the advantage of faster recovery from a crashed experiment, but if each sync requires a separate PR, that could become a problem for human operators who need to manually merge each one. |
Beta Was this translation helpful? Give feedback.
-
@sriumcp Let me summarize these problems here, copied from our Slack discussion:
|
Beta Was this translation helpful? Give feedback.
-
A few additional comments...
|
Beta Was this translation helpful? Give feedback.
-
@sriumcp Can you flesh out the details for step 3 in the gitops scenario? What does iter8 need to do to "release stable version" as the finish handler action? |
Beta Was this translation helpful? Give feedback.
-
@sriumcp @kalantar @fabolive Problem 1: Regarding parameters related to env repo and directory path, it was decided that this is the best we can do at the moment, so no action needs to be taken. Problem 2: Regarding race condition, not completely discussed before the meeting ended. Problem 3: Regarding transaction-awareness of handler code, it was decided that it will be the responsibility of the handler to be atomic, e.g., two git commits in the same handler does not satisfy this requirement. Moreover as an action can have multiple tasks, all the tasks in the action need to act as an atomic operation. The action is to clearly document this constraint. Problem 4: Regarding whether or not we should support both i) test every commit and ii) test only the newest one, the decision is to only support the latter. The former is deferred for now. Problem 5: Regarding sync'ing intermediate states while an experiment is running, ran out of time and did not discuss. |
Beta Was this translation helpful? Give feedback.
-
Pre-emptive GitOps experiment (take 2)Productpage candidate deployment apiVersion: apps/v1
kind: Deployment
metadata:
name: productpage-candidate # note the -candidate suffix. This is required.
namespace: bookinfo-iter8
labels:
app: productpage
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: productpage
version: v2
template:
metadata:
annotations:
sidecar.istio.io/inject: "true"
labels:
app: productpage # same as baseline
version: v2 # your app version (can be v2, v3, v4, ... and so on as you upgrade)
iter8AppVersion: candidate # always candidate (for the stable version, `candidate` is replaced with `stable`)
spec:
serviceAccountName: bookinfo-productpage
containers:
- name: productpage
image: iter8/productpage:v2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
env:
- name: deployment
value: "productpage-v2"
- name: namespace
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: color
value: "green"
- name: reward_min
value: "10"
- name: reward_max
value: "20"
- name: port
value: "9080" VS and DR # This resource is updated by both CD pipeline segment and Iter8
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
namespace: bookinfo-iter8
annotations:
hash: 382ud18s # random hash to force git sync
spec:
gateways:
- mesh
- bookinfo-gateway
hosts:
- productpage
- "bookinfo.example.com"
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
subset: stable
weight: 100 # can go out of sync
- destination:
host: productpage
port:
number: 9080
subset: candidate
weight: 0 # can go out of sync
---
# This is resource is created once per application (not once per version)
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: bookinfo
namespace: bookinfo-iter8
spec:
host: productpage
subsets:
- labels:
app: productpage
iter8AppVersion: stable
name: stable
- labels:
app: productpage
iter8AppVersion: candidate
name: candidate apiVersion: iter8.tools/v2alpha2
kind: Experiment
metadata:
name: quickstart-exp-7392lasdhf
namespace: bookinfo-iter8
spec:
# target identifies the service under experimentation using its fully qualified name
target: bookinfo-iter8/productpage
strategy:
# this experiment will perform an A/B test
testingPattern: A/B
# this experiment will progressively shift traffic to the winning version
deploymentPattern: Progressive
actions:
# when the experiment completes, promote the winning version using kubectl apply
start:
- task: gitops/init # drop this task for clusterops
with:
repo: github.com/bookinfo/productpage
folder: env/repo/folder/path # optional; without this field, root of the repo is the default folder
secret: ns/git-token
- task: gitops/verify-readiness
with:
timeout: 1h
- task: istio/verify-readiness
with:
timeout: 1h
name: productpage
namespace: bookinfo-iter8
finish:
- task: gitops/init
with:
repo: github.com/bookinfo/productpage
folder: env/repo/folder/path # optional; without this field, root of the repo is the default folder
secret: ns/git-token
- task: gitops/update-istio-deployment
with:
name: productpage
namespace: bookinfo-iter8
criteria:
rewards:
# (business) reward metric to optimize in this experiment
- metric: iter8-istio/user-engagement
preferredDirection: High
objectives: # used for validating versions
- metric: iter8-istio/mean-latency
upperLimit: 300
- metric: iter8-istio/error-rate
upperLimit: "0.01"
requestCount: iter8-istio/request-count
duration: # product of fields determines length of the experiment
intervalSeconds: 10
iterationsPerLoop: 10
versionInfo:
# information about the app versions used in this experiment
baseline:
name: productpage
weightObjRef:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
namespace: bookinfo-iter8
name: bookinfo
fieldPath: .spec.http[0].route[0].weight
candidates:
- name: productpage-candidate
weightObjRef:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
namespace: bookinfo-iter8
name: bookinfo
fieldPath: .spec.http[0].route[1].weight |
Beta Was this translation helpful? Give feedback.
-
See updated discussion all the way below...
Beta Was this translation helpful? Give feedback.
All reactions