쿠버네티스에서 블루/그린, 카나리 배포를 하는 방법은 아래와 같다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: version-blue
labels:
app: version
color: blue
spec:
replicas: 1
selector:
matchLabels:
app: version
color: blue
template:
metadata:
labels:
app: version
color: blue
spec:
containers:
- name: version
image: nginx:1.14.2
ports:
- containerPort: 8080
apiVersion: apps/v1
kind: Deployment
metadata:
name: version-green
labels:
app: version
color: green
spec:
replicas: 1
selector:
matchLabels:
app: version
color: green
template:
metadata:
labels:
app: version
color: green
spec:
containers:
- name: version
image: nginx:1.16.1
ports:
- containerPort: 8080
kubectl apply -f version-bule.yaml
kubectl apply -f version-green.yaml
apiVersion: v1
kind: Service
metadata:
name: version
labels:
app: version
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: version
color: blue
kubectl apply -f version-service.yaml
서비스의 설명을 보면 아래와 같다.
kubectl describe svc version
Name: version
Namespace: default
Labels: app=version
Annotations: <none>
Selector: app=version,color=blue
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.99.207.157
IPs: 10.99.207.157
Port: <unset> 80/TCP
TargetPort: 8080/TCP
Endpoints: 10.244.0.22:8080
Session Affinity: None
Events: <none>
kubectl patch service version -p '{"spec":{"selector":{"color":"green"}}}'
패치 후, 다시 서비스 정보를 보면 아래와 같이 그린 버전으로 변경된 것을 알 수 있다.
kubectl describe svc version
Name: version
Namespace: default
Labels: app=version
Annotations: <none>
Selector: app=version,color=green
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.99.207.157
IPs: 10.99.207.157
Port: <unset> 80/TCP
TargetPort: 8080/TCP
Endpoints: 10.244.0.23:8080
Session Affinity: None
Events: <none>
apiVersion: apps/v1
kind: Deployment
metadata:
name: application-deployment
labels:
app: application
version: stable
spec:
replicas: 4
selector:
matchLabels:
app: application
version: stable
template:
metadata:
labels:
app: application
version: stable
spec:
containers:
- name: application
image: nginx:1.14.2
ports:
- containerPort: 8080
apiVersion: apps/v1
kind: Deployment
metadata:
name: application-deployment-canary
labels:
app: application
version: canary
spec:
replicas: 1
selector:
matchLabels:
app: application
version: canary
template:
metadata:
labels:
app: application
version: canary
spec:
containers:
- name: application
image: nginx:1.16.1
ports:
- containerPort: 8080
kubectl apply -f canary-stable.yaml
kubectl apply -f canary-canary.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: application
name: app-service
namespace: default
spec:
ports:
- nodePort: 30880
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: application
type: NodePort
디플로이먼트를 만들 때, label을 이용해서 두 버전 모두 app: application
이지만 version: stable
, vesion: canary
의 차이를 뒀다.
서비스에서 app: application
으로 하여 두 버전 모두 실행되게 하고, 레플리카 수가 4개, 1개로 다르니 비율별로 실행되게 했다.
서비스 정보를 보면 아래와 같이 4개의 stable 버전과 1개의 canary 버전의 endpoint가 적혀있는 것을 볼 수 있다.
Name: app-service
Namespace: default
Labels: app=application
Annotations: <none>
Selector: app=application
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.111.214.240
IPs: 10.111.214.240
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 30880/TCP
Endpoints: 10.244.0.24:8080,10.244.0.25:8080,10.244.0.26:8080 + 2 more...
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>