https://codefol.io/posts/deployment-versus-provisioning-versus-orchestration/
What's Deployment versus Provisioning versus Orchestration?
Hey, Ruby web developers! Having trouble asking deployment questions? Not sure what Provisioning or Orchestration are? Getting bad results Googling your questions, but not sure why? Let’s go over some deployment vocabulary from your point of view — tha
codefol.io
읽어보고 정리하기
전날에 했던것과 같이 서비스 배포방법은 3가지가 존재한다.
1. ClusterIP(인터넷 불가, 클러스터 내에서만 접근 가능)
2. NodePort(인터넷 가능, 연결 불편)
targetPort(pod port) : 80
port(서비스의 포트=clusterIP) : 80
nodePort : 31008
3. LoadBalander(인터넷 가능, 이것만 쓰자)
서비스 환경에서 LB를 사용하는 방법
1. service type으로 lb를 사용하는 방법
- 일반적으로 퍼블릭 클라우드에서 널리 사용됨
type: LoadBalance -> 자동으로 로드밸런서를 호출하여 서비스에 부착된다.
로드밸런서를 배포할때는 MatchLabel을 이용하여 지정된 라벨이 부착된 "Pod"에 배포한다
- 로컬 환경에서 kubeadm으로 k8s 환경을 구축하였다면 기본적으로 lb 오브젝트가 존재하는 것은 아니다. 따라서 3rd party를 이용해야 하는데 대표적으로 metallb를 활용할 수 있다.
외부에서 들어오는 건 ingress 나가는건 egress
nodeport는 각 노드의 IP 주소와 Port를 이용한다. 외부에서 포드로 접속할때에는 아래와 같은 방법을 이용할 수 밖에 없다. 포트로만 구분해야한다.
만약 로드밸런서를 이용하게 되면 미리 지정된 범위에서 IP 주소자체를 제공하므로 아래와 같은 방법으로 서비스 제공이 가능하다.
samsung의 LB -> 211.183.3.201
lg의 LB -> 211.183.3.215
결국 각 고객사별로 서로 다른 IP 주소를 제공할 수 있으며 해당 주소가 공인 주소라면 도메인과의 즉시 매핑이 가능하게 된다.
2. 하드웨어적인 방법으로 제공하는 방법
클러스터 앞 단에 HAProxy를 프로비저닝한다.
문제는 이렇게 처리해버리면 로드밸런서가 두개가 된다. 그래서 좋은 방법이라고 할 수 없다.
frontend에 공인주소가 한개 할당되어 있다면 내부 네임스페이스별로 별도의 공인주소를 매핑할 수 없으므로 LB의 fe 인터페이스에 여러 공인주소를 등록하는 방법을 고민해야함.
[네트워크 정리 해야함]
서브인터페이스
이제 하나의 컴퓨터 안에서도 namespace로 구분되기 때문에 ingress로 들어오는 트래픽에 대해 vlan의 서브 인터페이스로 구분이 필요해짐. 이걸 위와같
????
---
기존에 lg, samsung을 deploy 했는데 이것들을 모두 지우기 위해서 구지 파일을 찾지 말고 그냥 namespace만 지워주어도 모두 삭제 된다.
```
k delete namespace samsung
k delete namespace lg
```
# namespace
# configmap
이미지를 작성하고 해당 이미지에서 배포된 포드는 이미지의 내용을 그대로 복사해서 사용하는 형식이므로 만약 각 포드의 내용을 달리하거나 포드에 적용되어 있는 환경 변수 등을 다르게 하고 싶다면 우리는 여러개의 이미지를 작성하여 배포하는 방법과 각 포드에 들어가서 수정하는 방법을 생각할 수 있다. 하지만 이는 매우 소모적인 방법이라 할 수 있다.
????
실습
```
kubectl create cm cmap1 --from-literal NAME=gildong --from-literal ADDR=youngin
k get cm
```
```
k describe cm cmap1
```
하면 위와같이 defualt namespace에 ADDR과 NAME이 들어간것을 확인할 수 있다.
이렇게 만든 cmap을 pod에게 배포해보자
apiVersion: v1
kind: Pod
metadata:
name: env-pod
spec:
containers:
- name: env-ctn
image: nginx
envFrom:
- configMapRef:
name: cmap1
```
k apply -f 00.env-cmap1.yaml
```
만들어진 놈으로부터 정보를 받아와보자
```
k exec env-pod -- env
```
env라는 명령어를 pod로 전달해주면 위와같이 ADDR, NAME 환경변수 값을 확인할 수 있다.
볼륨 마운트하기
```
vi 01.vol-cmap1.yaml
```
apiVersion: v1
kind: Pod
metadata:
name: vol-pod
spec:
containers:
- name: vol-ctn
image: nginx
volumeMounts:
- name: vol-cmap1
mountPath: /etc/test1
volumes:
- name: vol-cmap1
configMap:
name: cmap1
```
k apply -f 01.vol-cmap1.yaml
```
이제 pod의 etc/test1에 무언가가 생기었을 것이다.
```
k get pod
k exec -it vol-pod -- bash #pod 에 들어간다
ls -l /etc/test1
```
하니까 위와같이 무언가가 보인다.
조금더 자세하게 살피어보니 어딘가에 링크 걸리어 있다.
링크를 열어보니 youngin과 gildong이 출력되는 것을 확인할 수 있다.
즉 이렇게 하면 위의 결과는 key값이 파일로 저장된다는 것을 알 수 있었다.
위와 같이 /etc/test1 이라는 디렉토리가 생성되고 key로 선언했던 ADDR, NAME이라는 파일, 파일 내에는 value가 지정되어 있다.
단순한 스트링 형태가 아닌 파일 전체를 컨피그맵으로 작성할수도 있다.
회사별로 index.html 파일을 다르게 넣을 수도 있다. 이는 포드의 특정 파일을 대체할 수 있으므로 구성파일등을 볼륨형태로 마운트하여 사용하면 편리하다.
위와같이 index.html 파일이 있는 것을 확인할 수 있다.
[ 실습 ]
1. index.html 은 아래와 같은 방법으로 생성
root@master:~/k8s/0419# curl https://www.samsung.com/sec/ > index.html
가져온 파일을 configmap으로 만들고 nginx의 /usr/share/nginx/html/web에 마운트 해버려야 한다.
2. 해당 index.html 파일을 컨피그 맵으로 생성한 뒤, 이를 볼륨에 추가하라. 볼륨이름은 vol-samsung 이다.
```
k create ns samsung
k create cm index --from-file index.html -n samsung
vi 02.vol-cmap2.yaml
```
3. 해당 볼륨은 nginx 에 추가되어 웹서비스를 제공할 수 있어야한다. (nginx 의 기본 홈 디렉토리는??)
```
# k create cm index2 --from-file index.html -n samsung --dry-run=client -o yaml
# --dry-run을 했기 때문에 실재로 생성하지는 않는다.
# 위의 방식으로 배포를 해도 되지만 이렇게 하면 index.html이 그대로 데이터 형태로 들어가기 때문에 별로이다
```
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-ss
namespace: samsung
spec:
replicas: 3
selector:
matchLabels:
app: my-ss-pods-label
template:
metadata:
name: my-ss-pod
labels:
app: my-ss-pods-label
spec:
containers:
- name: ss
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: samsung-vol
mountPath: /usr/share/nginx/html/web
volumes:
- name: samsung-vol
configMap:
name: index
---
apiVersion: v1
kind: Service
metadata:
name: ss-lb
namespace: samsung
spec:
ports:
- name: ss-port
targetPort: 80
port: 80
selector:
app: my-ss-pods-label
type: LoadBalancer
/usr/share/nginx/html
4. 최종 접속 주소는 아래와 같아야 한다.
http://211.183.3.20X/web -> index.html 이 보인다.
정상 배포된것을 확인할 수 있다.
5. 모든 작업은 samsung 네임스페이스에서 제공되어야 한다.
---
쿠버네티스 문서
쿠버네티스는 컨테이너화된 애플리케이션의 배포, 확장 및 관리를 자동화하기 위한 오픈소스 컨테이너 오케스트레이션 엔진이다. 오픈소스 프로젝트는 Cloud Native Computing Foundation에서 주관한다.
kubernetes.io
지금까지 작성한것들은 모두 k8s 공식 사이트를 보고서 작성해야 한다.
이걸 안보고 짠다는 것은 사실 말이 안된다.
---
Secret
Secret은 ConfigMap과 거의 동일하다. 단, 보관된 데이터의 내용을 암호화 하느냐에 따라 갈린다. 보안적 요소가 추가되었기 때문에 보다 많은 옵션과 활용예가 뒷 따른다.
포드내에 있는 패스워드, ssh, 토큰, 인증서와 같이 보안적 요소가 필요한 것들을 저장할 때에는 일반 clear text로 저장되는 configmap을 이용해서는 안된다.
secret 도 방법이 나뉜다.
1. 평문 -> 암호화 generic
```
k create secret generic pwd1 --from-literal pwd=test123
k get secret
```
Opaque라는 TYPE으로 생성된 것을 확인해볼 수 있다.
default-token-6hgz2 라고 적힌것은 서비스 접속을 위한 토큰값이다.
```
k get secret pwd1 -o yaml
```
저기에 적힌 pwd를 base64 -d 로 출력해보니 매우 잘 우리의 pwd가 나온다. 이게 뭔 암호화인가....
그래서 이거 말고 다른 방법으로 암호화시키어야 한다.
```
k get secret default-token-6hgz2 -o yaml
```
k8s 를 이용하기 위한 암호화된 파일을 확인해보면 위와같이 나오는 것을 확인할 수 있다. 이건 계정 로그인시 나오는 token 값이다.
---
이번에는 파일로부터 불러오기를 해보자
```
echo test123 > pw1 ; echo test1234 > pw2
k create secret generic pwd2 --from-file pw1 --from-file pw2
```
데이터를 확인해보면 pw1, pw2 모두 있는 것을 볼 수 있다.
그래서 이렇게 만든것을 어떻게 사용할 수 있을까?
먼저 pod를 생성하는데 컨테이너 안에 envFrom 안에 secretRef 변수로 지정해준다.
configMap으로 그냥 지정해버리면 DB password로 지정할때 로컬 configMap을 사용하기 때문에 매우 위험해진다. 보안을 요구하는 것은 secret을 요구하자는 의미에서 secretRef라는 변수 안에 넣은 것이다.
volumes 부분도 확인해보면 svolume1, svolume2에 대해 secret 부분을 만들고 위쪽 volume 부분에 적용시키어 주었다.
실재 마운트된 곳에 가보니 pw2라는 것이 있는 것을 확인해볼 수 있다.
그리고 실재로 배포가 될때는 decrypt 되어서 내용을 확인할 수 있었다.
즉 신청할때의 패스워드만 안호화 해놓고 나중에 실재 사용할때는 그 패스워드가 보이도록 해주었다고 생각하면 된다.
가정
사용자가 서비스 신청 페이지에 들어와서 DB를 사용하고 싶어할경우
1. EC2를 사용해서 이 안에 OS, mysql을 설치해서 제공하기(요청시 제공 - 온디멘드)
2. RDS 사용해서 mysql 서비스 제공하기(완벽한 환경 제공 - 완전관리형 서비스)
3. DB 컨테이너 형태로 제공 -> volume만 연결해서 제공
그러면 k8s 환경에서는 ID를 받아 namespace를 만들고 DB를 위한 PW 값도 받아 환경을 구축 및 배포해주면 되는 것이다. 이때 암호들은 모두 Secret으로 지정해서 제공해주어야 한다.
```
k create secret generic user1 --from-literal MYSQL_ROOT_PASSWORD=test123
```
위와같이 패스워드를 우리가 지정해줄 수도 있지만 사용자로부터 이걸 받아올 수도 있다. 이게 namespace를 해주기 때문에 가능하다.
암튼 생성한 패스워드를 가지고 배포해보자
apiVersion: v1
kind: Pod
metadata:
name: user1
spec:
containers:
- name: user1-ctn
image: nginx
envFrom:
- secretRef:
name: user1
이게 배포가 되었는지를 확인해보자
```
k exec user1 -- env | grep ROOT
```
로 확인해보면 위와같이 MYSQL의 루트 패스워드를 볼 수 있다.
```
k get secret user1 -o yaml
```
이 방식을 이용해서 사용자별로 DB를 제공할 수 있을 것이다.
---
도커 허브로의 로그인을 위한 secret 생성하기와 지정된 저장소 주소로의 접속을 위한 secret 생성하기
```
k create secret generic dockerhub1 --from-file=.dockerconfigjson=/root/.docker/config.json --type=kubernetes.io/dockerconfigjson
1,2 번은 docker hub로 접속하는 secret key를 만드는 방법이고 3번째는 registry 로 부터 받아오는 방법이다.
```
k create secret docker-registry registry1 --docker-username=gildong --docker-password=test123 --docker-server=211.183.3.250
```
위와같이 registry1이라는 secret과 함께 kubernetes.io/dockerconfigjson이 생긴것을 볼 수 있다.
도커허브에 로그인을 위해서 만들어진 부분이다.
```
k delete deploy,pod,cm,secret --all
```
인그레스를 통한 서비스 요청처리
외부에서 나에게 접속할 수 있는 인그레스 네트워크를 구축해보자
L4, L7 두개가 존재한다. 앞에는 Load Balancer 라고 적혀있다. 일반적인 LB는 HAProxy가 LB의 기능을 구현한 것이다. LB의 기능을 구분해보면 크게 L4, L7의 기능을 하는 로드밸런서로 구분하 수 있다.
우리는 기존에 ip로 접속한것에 대해 동일한 페이지들로 연결되도록 만들어주었다. 그런데 이렇게 할 경우의 단점중 하나는 외부에서 웹서비스를 받으러 오는데 혹여나 동영상 서비스를 받기 위해 서버로 갔는데 각 서버가 모두 동일한 기능을 수행해준다. 즉 모든 서버에 기능이 몰려있다는 단점이 생긴다.
실재환경에서는 동영상과 DB, 사진과 DB를 위한 서버와 DB가 모두 분리되어 있다. 그래서 들어오는 주소에 따라서 트래픽을 분산하자는 것이다. 문제는 이게 L4에서는 불가능하다. L4에서는 포트만 보지 그 뒤의 내용을 보지 않기 때문이다. 그래서 우리 생각처럼 각 서버가 모든 역활을 수행하는 형태가 될 수 밖에 없었던 것이다.
그래서 실재로는 각 도메인별로 서버를 구분해두었다. domain을 바꾸게 되면 서버를 바꾸어주는 것이다. 그러다가 특정 서비스에 대한 수요가 넘쳐나면 그 서비스에 대한 pod만 늘려주는 것이다. 이렇게 봐서는 port에 대한 번호만 봐서는 안된다. 문자열을 보아야한다. 글자는 그럼 어디에서 볼 수 있을까?
그래서 도메인별을 보고 pod를 나누어서 autoscaling 해주는 경우가 대다수인 것이다.
그리고 k8s에서는 도메인을 보고 어디로 보낼지를 결정하는 서비스가 ingress라는 서비스이다.
ingress controller는 별도로 제공되는 ad-on을 사용해서 도메인을 보고 ingress로 전달해주어야 한다.
일반적인 환경에서 ingress controller는 아래에 보는 것과 같이 nginx로부터 다운받아와야 한다.
인그레스 :
내부에서 외부로 나가는 트래픽은 이그레스(egress), 외부에서 내부로 유입되는 트래픽은 인그레스(ingress)
ingress는 인그레스 컨트롤러를 이용하여 외부에서 유입되는 트래픽들의 도메인 주소등을 확인하고 어떠한 포드로 포워딩할지를 결정해주는 도구이며 포트를 넘어 주소의 컨텐츠를 확인하고 로드밸런싱을 구현해준다.
일반적으로 인그레스는 다음과 같은 AddOn을 사용한다.(k8s에서 사용하는 인그레스 컨트롤러)
퍼스트 파티 : 1. nginx 2. aws 3. gcp
서드 파티 : kong, HAProxy ingress ...
받아주는것은 ingress controller인데 그걸 또 어떤 pod로 전달할지 결정하는 것은 ingress이다.
실재 코드를 보면 gildong.test.pri 도메인으로 들어온것중 root path로 가는 트래픽에 대해 어떠한 서비스를 제공할지 경정한 것을 볼 수 있다. 그리고 나중에 가서 각 도메인 별로 pod나 자원(cpu 등)을 더 줄 수도 있게 될 것이다.
물론 우리는 지금당장 도메인이 없기 때문에 이거 그대로 만들 수 없기 때문에
```
echo -e "211.183.3.101\tgildong.test.pri" >> /etc/hosts
```
로 도메인을 모든 노드와 마스터들에 추가해 주자
```
vi ingress.yaml
```
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
spec:
rules:
- host: gildong.test.pri
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-svc
port:
number: 80
위에보이는 rules에 따라서 forwarding 해준다.
이렇게 적으면 80번으로 접속시 자동으로 루트 경로로 전달해준다. 루트 경로에 test-svc로 연계되고 test-svc는 또 정의해주어서 가게해주면 된다. 그러면 test-svc에서 관련 트래픽들을 처리해주게 된다.
이제 인그레서 컨트롤러를 여기 앞에다가 배포해주어야 한다.
```
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.2/deploy/static/provider/cloud/deploy.yaml
```
인그레스 컨트롤러의 주소는 위와같다.
이걸 그대로 복붙하면 ingress-controller가 적용된다.
그리고 ingress도 배포해보자
????
???
이제 서비스를 만들어서 사용자가 사용할 수 있게 해보자
```
k run testweb --image=nginx
k expose pod testweb --port=80 --name testsvc --type=NodePort
```
이 상태에서 giledong web으로 접속이 되는지 해보자
k get svc로 우리가 만든 서비스를 확인해보자
서비스가 배포된 ip로 curl을 띄워보니 정상 접속되는 것을 확인해볼 수 있다.
여기까지 확인이 되었다면 클러스터 내부에서 pod가 정상적으로 동작하고 있는 것까지는 확인이 된 것이다. 이제 외부에서 유입되는 트래픽들에 대하여 ingress controller -> ingress -> svc -> Pod 로 들어올 수 있게 해보자
이제 ingress.yaml 파일에 다음의 내용을 추가하자.
도메인 활용을 위한 설정(기존 ingress.yaml 파일에 annotations를 추가해주자)
이게 ingress 내트워크중 어떤걸로 처리할지 결정하는 건데 nginx로 처리해주겠다는 의미이다.
rewrite-target는 redirect를 의미한다.
만약에 없는 주소라면(gildong.test.com/test) 거기로 찾아갈 수 없다. -> 서비스 없다(오류 발생)
/$2
라고 하면 어떤 결과가 나오는가
gildong.test.com/photo -> gildong.test.com (여기까지는 $1)
gildong.test.com -> gildong.test.com
gildong.test.com/photo/0419 -> 정상페이지로 redirect 된다.
그래서 /$1 이라고 해놓으면
gildong.test.com/photo -> gildong.test.com/photo 로 갈 수 있다.
$2는 두개까지 확인하기 때문에 그게 아니라면 그냥 루트로 보내버린다.
gildong.test.com -> gildong.test.com
이 내용을 넣고 배포해보자
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: gildong.test.pri
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-svc
port:
number: 80
이때 두번쨰 줄의 kubernetes.io/ingress.class: nginx controller는 이미 만들어져 있으니 그냥 배포하면 된다는 의미이다.
curl http://gildong.test.pri:31189
배포가 잘 된것을 확인해볼 수 있다.
???
이렇게하면 우리가 설정한 내용은 '/'에 대한 것만 정의되어 있다.
그래서 만약에 필요하다면 추가적인 경로들을 확인해주면 된다. 그리고 이것에 맞게 백엔드와 서비스, 포트등을 정의해주면 된다.
그렇기에 지금 이 상태라면 http://gildong.test.pri 에 접속하는 다른 도메인도 만들어서 서비스와 매칭시키어주면 된다.
그리고 개발도 도메인별로 페이지를 개발하면 되는 것이다.
내부 vm에서도 접속이 되는 것을 확인해볼 수 있다.
퍼시스턴트 볼륨(PV)과 퍼시스턴트 볼륨 클레임(Persistent Volume Claim; pvc)
먼저 네임스페이스에 속하는지 확인해보면 PVC는 네임스페이스에 속하고 PV는 아니다.
PV -> 영구볼륨
PVC -> 영구볼륨요청
필요이유??
???
각 노드별로 포드를 배포하고 각 포드가 DB라고 하면 이 세게는 전부 동일 Deploy에서 배포가 된 것이다. 그래서 각 DB 별로 맡은 역활이 다르다. 사용자가 회원가입에 을 위한 pod에 들어간경우.
1. 다른 pod로 연결시 DB 동기화가 없음으로 회원가입을 다시해야한다.
+ pod는 휘발성이다. 그래서 버전업데이트를 위해 한번 pod를 껐다 켜야한다는 단점이 생긴다.
그래서 해결 방법 1. local DB를 pod의 특정 디렉토리에 마운트하는 방법 -> 이것도 다른 pod로 가면 재가입해야하는 문제가 생긴다.
두번째 방법으로 똑같은 볼륨을 쓸 수 있도록 외부 스토리지를 만들고 각각의 포드에 연결해주는 방법이다.
호스트의 볼륨이나 디렉토리를 마운트 하는 방법으로 사용할 경우 데이터의 영구적인 보관이나 LB에 의해 다른 포드로 옮겨졌을 경우 해당 데이터를 찾을 수 없는 등의 문제가 발생하는데 이를 해결하기 위하여 외부에 볼륨을 제공하는 스토리지를 준비하고 각 포드는 이 스토리지로부터 볼륨을 제공받는 형식으로 애플리케이션을 배포하게 되면 포드가 이동하거나 재 실행되는 경우 앞서 언급한 문제를 해결할 수 있다.
포드는 직접적으로 외부와 통신할 수 없으므로 호스트를 통해 접속해야한다. 만약 외부에 NFS 서버를 통해 스토리지를 제공받는다면 포드에 NFS 클라이언트를 설치하는 것이 아니라 node에 client를 설치해야 한다. 왜냐하면 노드에서 kube-proxy를 통해서 외부와 연결이 되기 때문에 클라이언트는 반드시 노드에 설치해야한다.
노드1에서부터 3번까지
```
apt-get update && apt-get install -y nfs-common
```
nfs 서버 : 211.183.3.99를 활용하자
```
yum install -u nfs-utils
```
root 홈 디렉토리에 `mkdir k8s` 로 폴더를 만들자
```
mkdir /k8s
chmod 777 /k8s
```
```
vi /etc/exports
```
를 열어서 위와같이 디렉토리와 ip 주소 그리고 옵션을 적어주자
???
포드의 데이터를 영구적으로 저장하기 위한 옵션이 필요한데 이를 PV라고 부른다.
각 노드의 디렉토리를 각 포드와 공유하는 게 아닌, 스토리지를 마운트하여 데이터를 연속적으로 저장할 수 있는 볼륨을 퍼시스턴트 볼륨이라고 함. 포드가 다른 노드로 이동하더라도 데이터를 계속 사용할 수 있음.
네트워크 퍼시스턴트 볼륨의 대표적인 예
NFS, aws의 EBS, Ceph, GlusterFS 등
nfs-pod 생성하기
NFS 볼륨의 마운트는 컨테이너 자체에서의 접근이 아닌 워커 노드에서 발생하므로 각 워커 노드에서 먼저 nfs-common을 설치한다음 pod를 생성해주어야 한다.
이 방식으로 제작을 진행하면 불편함이 많다. 일반적인 사람들은 이걸 어떻게 하는지 모르기 때문에 PVC를 사용해야 한다.
apiVersion: v1
kind: Pod
metadata:
name: nfs-pod
spec:
containers:
- name: nfs-ctn
image: nginx
volumeMounts:
- name: nfs-vol
mountPath: /mnt
volumes:
- name: nfs-vol
nfs:
path: /k8s
server: 211.183.3.99
만약 포드가 정상배포되었다면 mnt라는 디렉토리에 외부 nfs 서버의 k8s 디렉토리와 연결된다.
이제 nfs 서버의 k8s 디렉토리에 hello.txt를 만들어놓고 배포를 해보자
pod를 생성하고 mnt 폴더를 확인해보니 hello.txt 파일이 있는 것을 확인할 수 있었다.
'Development(Web, Server, Cloud) > 22) LINUX - Cloud' 카테고리의 다른 글
클라우드 65일차(정리중, autoscale, jenkins) (0) | 2022.04.26 |
---|---|
클라우드 64일차 (MSA, 다이나믹 pvc, 동적 pv, 정리중) (0) | 2022.04.25 |
클라우드 62일 (0) | 2022.04.22 |
클라우드 61일(kubernetes 개념, pod, Deployment, Metal LB, autoscaler, web-ui) (0) | 2022.04.15 |
클라우드 60일차 (0) | 2022.04.14 |