ingress 실습 후 현재 상황
LB가 앞에 있고 ingress-controller가 nginx로 잡히어 있다. 이거 외에도 (kong, HAproxy, nginx, aws, gcp 등등 사용가능)
이거 이후에는 ingress가 rule이 정해져 있고 이때의 ingress 별로 svc가 정해져 있고 svc 아래에 pod까지 배치되어 있을것이다.
각 도메인별로 넘겨주는 서비스가 다르게 정해져 있다. 해당 서비스에서는 특정 포드로 연결되도록 되어 있다.
이렇게 해서 배포된 pod는 추가적으로 이러한 일을 할 수 있다.
위와같이 각 포드별로 backup이라는 디렉토리를 마운트해놓고 web, sql의 파일을 hostname.date.tar.gz 형태로 던져주면
외부에 연결되어 있는 스토리지로 백업한 데이터가 올라가게 될 것이다.
스토리지의 종류는 크게 3가지
1. File Storage(NFS)
2. Block Storage(iSCSI)
3. Object Storage(gdrive, s3, swift)
---
지금까지는 포드를 배포할 경우 전체 노드를 대상으로 포드가 배포되었다.
하지만 특정 포드를 특정 노드에 배포하고 싶은 경우가 있을 수 있다. 이 경우에는 특정 노드를 지정하기 위하여 라벨을 사용할 수 있다.
특정 노드에 배치할 수 있는 방법
1) Pod 배포시 spec에 배포될 Node 의 이름을 작성한다.
2) Node에 label을 부착하고 pod 배포시 해당 label을 지정한다. - 이렇게 하면 같은 라벨을 부착할 수도 있고 구지 노드별로 yaml을 만들어줄 필요도 없어진다. Pod를 확장해서 Deployment나 Replicaset으로 지정하면 Pod 별로 스케쥴링이 되어 배포된다.
노드에 라벨을 부착하고 Deployment, ReplicaSet 을 이용하여 포드의 숫자를 다수로 설정했을 경우에는 각 포드별로 스케줄링이 되므로 모든 포드가 하나의 노드에 배치되는 것이 아니라, 각 노드(동일한 라벨을 사용하는)에 분산 처리 배치 된다.
라벨을 선택할 때에는 두개이상의 라벨을 지정할 수 있다. 그래서 배포시에도 zone을 따라서 pod를 배포해줄 수 있다.
현재의 노드에 부착되어있는 라벨은 무엇인가?
```
kubectl get no --show-labels
```
직접 만든 사용자 라벨을 추가하고 싶다면?
```
kubectl label nodes node1 zone=seoul
kubectl label nodes node2 zone=seoul
kubectl label nodes node3 zone=busan
kubectl label nodes node1 level=low
kubectl label nodes node2 level=med
kubectl label nodes node3 level=med
* kubectl label nodes node1 region/zone=a (Key: region/zone, Value=a 이런 형식으로도 작성할 수 있다.)
* kubectl label nodes node2 region/zone=b
```
이 상황에서 Pod를 배포한다면 (spec 에 selector가 필요하다)
```
cd
cd k8s/
mkdir 0422 ; cd 0422
touch labeltestpod.yaml
vi labeltestpod.yaml
```
apiVersion: v1
kind: Pod
metadata:
name: testpod
spec:
nodeSelector:
zone: seoul
level: med
containers:
- name: testctn
image: nginx
node2에 배포된 것을 확인할 수 있다.
```
k get no --show-labels
```
```
k describe no node1
```
```
k describe pod testpod
k label node node1 zone-
k label node node2 zone-
k label node node3 zone-
k label node node1 level-
k label node node2 level-
k label node node3 level-
```
이제 했던것들을 모두 지워주자
---
Jenkins를 이용한 CI/CD
docker hub 에서 brain24에 있는 main, shop, blog 를 사용해보자
먼저 어제 만들었던 git 의 index.html 파일에서 내용을 조금만 수정해주자.
master 노드에서 jenkins가 github의 파일을 끌고와서 이미지로 만들고 docker-hub에 올리고 이걸 다른 노드들에서 다운로드 받아서 rolling update 해주면 된다.
사용자에게 무언가 요구하는 과정 없이 순차적으로 처리가 되도록 만들어야 한다. 안그러면 중간에 멈추기 때문에 자동화가 되지 않는다.
시작하기전에 먼저 jenkins그룹 안으로 들어간다.
```
usermod -aG docker jenkins
usermod -aG sudo jenkins
```
그리고 jenkins를 사용하기 위해서는 sudo를 사용해야 하는데 /etc/sudoers안에 jenkins를 넣어주자
이제 jenkins를 사용해보자
testcicd라는 이름의 Freestyle project를 만들자
소스 코드 관리 도구에 Git 부분에서 Repository URL 에 내가 push 했던 git을 넣어주자
그리고 branch는 나의 경우 main에 있어서 이걸 사용해주자
이제 Execute shell을 선택해서 빌드하게 되는데
sudo 로 이걸 실행해야한다.
이렇게 만들고 저장해주자
이제 왼쪽에 Build Now를 누르면 아래와같이 파란 막대기가 돌기시작한다.
작업공간에 들어가면 우리가 신청했던 파일들을 볼 수 있다.
우리의 요청이 성공했다면 위와같이 녹색 체크표시가 뜰텐데 저걸 눌러서 들어가보자
그리고 들어간 페이지의 Console Output으로 들어가면 우리가 어떤 부분에서 실패를 했는지 등등을 볼 수 있다.
docker hub에 가보면 testshop이라는 이미지가 newmain이라는 태그를 달고 온 것을 확인해볼 수 있다.
jenkins에서 Project 삭제를 우선해보자
그리고 Docker hub에 있는 이미지도 삭제해놓자
과제 :
앞서 실행한 freestyle 타입의 프로젝트를 활용하여
깃허브에 있는 Dockerfile, index.html 을 다운로드하고 이를 이용하여 id/testshop:newmain 이미지를 생성한 뒤, 이를 도커 허브에 올리고
kubectl 을 이용하여 현재 동작중이 pod-main의 이미지를 newmain으로 업데이트 하자.
프로젝트가 생성되면 해당 프로젝트를 진행하는 임시디렉토리가 생성되고 해당 디렉토리로 자동 이동한다.
sudo docker build -t brian24/testshop:newman .
sudo docker push brian24/testshop:newmain
sudo kauth
sudo kubectl set image deployment deploy-main ctn-main=brian24/testshop:newmain
jenkins는 kubernetes를 실행할 수 있는 권한이 존재하지 않는다.
kubesys 전체를 관리할 수 있는 kubesys-admin권한을 가지고 와야 한다. 그래야 k get node를 사용할 수 있다.
그래서 sudo kauth로 kubesys-admin권한을 가져오는 것이다.
이렇게하고 빌드하니 위의 페이지와 같이 페이지가 업데이트 된 것을 확인할 수 있다.
Quiz. 다음의 조건을 만족하는 yaml 파일을 작성하고 배포하라.
참고로 우리는 master 를 이용할 수 없다.
모든 작업은 jenkins를 통해 이루어져야 한다.
개발자는 로컬에서 Deployment, Service를 실행하기 위한 yaml 파일을 생성하고 배포하는데
- 이미지는 nginx를 사용한다.
- replicas는 3개를 배포한다.
- 서비스는 로드밸런서를 이용한다.
- 외부에서 공인주소를 통해 웹 접속이 가능해야 한다.(로그를 통해 정상적으로 배포되었는지 여부를 확인할 수 있어야 한다)
- 최종적으로 로드밸런서의 IP 주소도 master가 아닌 jenkins를 통해 확인할 수 있어야 한다.
---
1) 개발자는 로컬에서 yaml 파일을 만들고 이를 github에 push 한다.
cat nginx.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx-pods-label
template:
metadata:
name: nginx-pod
labels:
app: nginx-pods-label
spec:
containers:
- name: nginx
image: tonyhan18/testmain:newmain
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-lb
spec:
ports:
- name: nginx-port
targetPort: 80
port: 80
selector:
app: nginx-pods-label
type: LoadBalancer
이 상태에서 github에 업로드해버리자
jenkins의 Build 명령은 위와같이 넣어주었다.
---
ansible
선수학습
이런게 가능할 듯...
노드 자체를 관리하고 싶다면??
내가 직접 노드에 접속할수는 없으니 master에 들어가서 배포를 하는등의 작업이 이루어지게 된다.
결국 jenkins는 master만 관리하면 master는 그걸 전달받고 master가 각각의 노드에 전달하는 형태이다. 노드에서 svc, pod를 배포하는 형태가 된다.
그런데 우리는 노드자체를 관리하고 싶다. 우리가 과연 master로 노드 자체를 관리할 수 있을까? 할 수 있는 방법은 존재한다. SSH - Ansible을 쓰면 되는 거다.
[ 전체 관리자 역활 -> nfs: 211.183.3.99 (ansible) ] : CentOS
관리대상 : ubuntu
-> k8smaster : 211.183.3.100
-> k8snode : 211.183.3.101 ~ 103
nfs 에서
```
yum install -y epel-release && yum install -y ansible
vi /etc/ansible/hosts
```
들어가서 위와같이 master와 node의 ip를 등록해주자
그런데 master 에서 ubuntu로 ssh root 연결시 pass login이 허용되지 않는다. 무조건 key를 가지고 로그인하게 된다.
그런데 pem을 이용한 root로 작업은 안전하지 못하다. user1으로 접근해서 작업을 해주어야 한다.
```
su user1
ansible all -m ping
```
해주면 이렇게 뜨는데 여기에서 어렵다. yes를 끝날때까지 계속 처주어야 한다.
```
user1 home dir에서
cat .ssh/known_hosts
```
해주면 위와같이 호스트들이 등록된것을 볼 수 있다.
```
ansible all -m ping -k
```
하면 진짜로 ping을 보낸것은 아니지만 위와같이 출력된다.
```
ansible all -m shell -a "hostname" -k
ansible k8smaster -m shell -a "hostname" -k
ansible k8snode -m shell -a "sudo apt-get update -y" -k
ansible all -m shell -a "sudo touch /home/user1/test.txt" -k
```
실재로 파일이 생긴것을 볼 수 있다.
이제 나중에 node들 위에 pod가 centOS 기반으로 올라가게 될 것이다.
우리는 ansible을 이용해서 k8smaster와 k8snode에 원하는데로 업데이트가 될 수 있을것이다.
이걸 더 쉽게 하기 위해서 jenkins나 gitlab을 이용해서 ansible에 명령을 던져서 node들 각각에 명령을 보낼 수 있게 된다.
특히 gitlab은 github와 같은 호스팅 기술(SCM)이 포함되어 있다.
지금은 github 에 push 가 되어도 build가 자동으로 안되지만 gitlab은 자신이 git hosting 기술을 포함하고 있으므로 저장소에 commit이 발생하면 이를 즉시 인지하고 build가 자동으로 발생하도록 할 수 있다. 물론 이게 반드시 좋은것은 아닌게 실수를 한게 있다면 큰일이 난다.
---
jenkins의 설정을 파일을 옮기기 위해 pipeline이라는 방법을 사용하자
젠킨스도 고유 문법이 존재하고 yaml을 사용할 수 있다.
한번 만들어보자
이제 build trigger이라는 부분이 존재하는데
build after other projects as built는 다른 프로젝트가 끝난 이후에 빌드를 한다는 것이다.
build periodically schedule을 작성해야한다. 이건 cron 문법을 적용한다.
poll scm : 주기적으로(cron) github의 commit을 확인하여 기존 커밋과 비교했을 때 변경된 사항이 있으면 build 발생
만약, commit이 그대로라면 build는 발생하지 않는다.
빌드 안함 : 빌드하지 않음
Quiet period : push를 여러번하더라도 지연시간을 주겠다.
빌드를 원격으로 유발 : 원격에서 빌드를 시키는 것이다. 깃허브의 푸시 또는 메신저의 웹훅과 같이 주소를 이용해서 빌드를 시작할 수 있는 곳에서 사용. webhook을 사용하면 웹주소로 코드를 전달할 수 있다. 따라서 해당 서버가 공인주소로 설정되어 있어야 한다.(이게 문제인게 우리가 쓰는게 사설주소이기 때문이다 - 그게 아니면 좋은 방법이다)
gitlab은 클라우드 퍼블릭 공간에서도 서비스가 제공되지만 오픈소스를 활용하여 on-premise 환경에 직접 설치하여 운영하는 방법도 가능하다. 즉, 사설 주소를 이용할 수 있다. Cron이 아니라 즉시 전달하는 방법 가능하다.
마지막으로 Jsnkinsfile이라는 부분이 존재하여서 github에 jenkinsfile을 올리라는 것이다.
$ cat Jenkinsfile
pipeline {
agent any
stages {
stage('git scm update') {
steps {
git url: 'https://github.com/beomtaek78/testjenkins.git', branch: 'master'
}
}
stage('docker build and push') {
steps {
sh '''
sudo docker build -t brian24/myweb:1.0 .
sudo docker push brian24/myweb:1.0
'''
}
}
stage('deploy k8s') {
steps {
sh '''
sudo kubectl create deploy testpipeline --image=brian24/myweb:1.0
sudo kubectl expose deploy testpipeline --type=NodePort --port=8081 \
--target-port=80 --name=testpipeline-svc
'''
}
}
}
}
stages는 작업들을 정의한다.
stage는 작업이다.
이 내용을 Jenkinsfile에 복붙해주자
pipeline {
agent any
stages {
stage('git scm update') {
steps {
git url: 'https://github.com/tonyhan18/cicdtest.git', branch: 'main'
}
}
stage('docker build and push') {
steps {
sh '''
sudo docker build -t tonyhan18/testshop:newnewmain .
sudo docker push tonyhan18/testshop:newnewmain
'''
}
}
stage('deploy k8s') {
steps {
sh '''
sudo kauth
sudo kubectl set image deployment deploy-main ctn-main=tonyhan18/testshop:newnewmain
'''
}
}
}
}
그리고 이렇게 수정해주자
index.html 파일도 수정해서 올려버리자
이제 빌드해버리자
업데이트 된 것을 볼 수 있다.
'Development(Web, Server, Cloud) > 22) LINUX - Cloud' 카테고리의 다른 글
클라우드 68일차 (0) | 2022.04.29 |
---|---|
클라우드 67일차(PV,PVC,jenkins,gcp-정리중) (0) | 2022.04.28 |
클라우드 65일차(정리중, autoscale, jenkins) (0) | 2022.04.26 |
클라우드 64일차 (MSA, 다이나믹 pvc, 동적 pv, 정리중) (0) | 2022.04.25 |
클라우드 63일차(정리중, ingress, 정리중) (0) | 2022.04.22 |