[Kubernetes] 지워지지않는 Terminating 네임스페이스 삭제하기

반응형

다음과 같이 삭제되지 않는 네임스페이스를 강제로 삭제하는 방법입니다.

# kubectl get ns |grep Terminating
cf-org-d550a9c8-9bf1-49db-9887-310bc39261b1   Terminating   29m

 

방법1

kubectl 명령 옵션으로 삭제합니다.

# kubectl delete namespace cf-org-0ff8cc13-3a8e-47e2-839b-e68f5510583c --grace-period=0 --force

 

방법2

TARGET 변수에 삭제하고자하는 네임스페이스 이름을 넣고 실행합니다.

jq 명령어가 필요하므로 사전에 jq 패키지를 설치해주세요.

# apt -y install jq

# TARGET="cf-org-0ff8cc13-3a8e-47e2-839b-e68f5510583c"

# kubectl proxy & kubectl get namespace $TARGET -o json |jq '.spec = {"finalizers":[]}' > temp.json

[2] 375218
error: listen tcp 127.0.0.1:8001: bind: address already in use
[2]+  Exit 1                  kubectl proxy

 

위와 같이 에러가 출력되어도 괜찮습니다. 계속 진행합니다.

# kubectl replace --raw "/api/v1/namespaces/$TARGET/finalize" -f temp.json

 

[출처] https://mightytedkim.tistory.com/44

 

반응형

댓글()

Rocky Linux 9 에서 yt-dlp 설치하기 (youtube-dl 포크)

리눅스/OS 일반|2023. 10. 26. 14:09
반응형

yt-dlp 는 유튜의 영상 및 음원을 추출하는 도구 입니다.

 

 

1. yt-dlp 다운로드

 

yt-dlp 는 github 에서 다운로드 받을 수 있는데, 항상 최신버전을 받기 위해서 아래와 같이 진행합니다.

# wget https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -O /usr/local/bin/yt-dlp

# chmod +x /usr/local/bin/yt-dlp

 

 

2. FFMpeg 설치

 

yt-dlp 를 사용하기 위해서는 영상 및 오디오 파일 처리와 변환을 위한 오픈 소스 멀티미디어 프레임워크 및 도구인 FFMpeg 를 추가로 설치해야 합니다.

EPEL 저장소 및 CRB(PowerTools)를 활성화합니다.

# dnf -y install epel-release

# dnf config-manager --set-enabled crb

 

Rocky Linux 9 리포지토리를 추가합니다.

# dnf -y install --nogpgcheck https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-$(rpm -E %rhel).noarch.rpm

 

FFMpeg 를 설치합니다.

# dnf -y install ffmpeg ffmpeg-devel

 

 

3. 활용하기

 

yt-dlp --help 명령으로 사용방법을 확인 할 수 있기 때문에 여기에서는 mp3, mp4 를 추출하는 방법만 간단하게 알려드립니다.

 

1) Audio (MP3) 추출

# yt-dlp --extract-audio --audio-format mp3 --audio-quality 128K --output '%(title)s.%(ext)s' {유튜브 영상 URL}

 

2) Video (MP4) 추출

추출 가능한 형식을 확인합니다.

# yt-dlp -F {유튜브 영상 URL}

 

출력된 표에서 좌측의 ID 값을 이용하여 추출합니다.

동영상은 두가지 형태 (영상 + 오디오) 로 추출하여 합치는 작업이 필요합니다.

여기에서는 원하는 영상 사이즈와 포맷, 코덱 형식의 ID 값만 이용하고, 오디오 부분은 최상의 음질로 추출하도록 하였습니다.

# yt-dlp -f 136+bestaudio --output '%(title)s.%(ext)s' {유튜브 영상 URL}

 

반응형

댓글()

Kubernetes 1.28, Kind 에서 Korifi 설치 및 PHP 애플리케이션 배포하기

리눅스/PaaS|2023. 10. 24. 16:09
반응형

Kubernetes 및 MetalLB 가 구축되어 있다는 전제 하에 Korifi 설치하는 방법을 설명합니다.

준비되지 않으신 분은 아래 포스팅을 참고하세요.

- Kubernetes 설치 : https://sysdocu.tistory.com/1851

- MetalLB 설치 : https://sysdocu.tistory.com/1854

 

본 매뉴얼은 아래 URL 을 참고하여 재작성 하였습니다.

- CF 8 CLI 가이드 : https://cli.cloudfoundry.org/en-US/v8/

- Korifi 공식 문서 : https://github.com/cloudfoundry/korifi/

- 참고 : https://deep75.medium.com/korifi-api-cloud-foundry-v3-exp%C3%A9rimentale-dans-kubernetes-b759ddd38443

 

[환경]

Kubernetes 버전 : Kubernetes 1.28 (master 1대, worker3대)

OS : Ubuntu 22.04

 

[Korifi - 소개글 일부]

Korifi 는 빌드, 테스트, 배포 및 모니터링 단계를 지원하는 DevOps 툴체인에 통합되어 애플리케이션 개발자의 배포 환경을 단순화합니다. 또한 팀이 기존 CI/CD, 로깅 및 관찰 가능 도구를 확장할 수 있도록 하는 동시에 Provile, Kpack 과 같은 Kubernetes 네이티브 도구가 포함되어 있습니다. 소프트웨어 엔지니어링 팀은 Korifi 를 통해 포괄적인 Kubernetes 전략을 수립하고 개발, 테스트 및 배포 단계 전반에 걸쳐 모범 사례를 채택할 수 있습니다.

 

Korifi 는 단일 cf push 명령으로 모든 언어나 프레임워크로 작성된 앱을 배포할 수 있는 기존의 Cloud Foundry 경험을 그대로 유지하고 있습니다. Pak to build pack 을 사용하여 OCI 호환 컨테이너로 앱을 배포함으로써 앱 개발자 경험을 더욱 향상시킵니다. 앱 개발자들은 더 이상 Kubernetes 에 컨테이너화된 배포를 위해 복잡한 YAML 이나 Dockerfile 과 씨름할 필요가 없습니다.

 

 

1. Docker 설치

 

패키지 목록을 최신화하고 업데이트를 진행합니다.
# apt -y update

# apt -y upgrade
# apt -y install apt-transport-https ca-certificates curl gnupg lsb-release

Docker 공식 GPG 를 설치합니다.
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg |gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

Docker 공식 저장소를 추가합니다.
# echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" |tee /etc/apt/sources.list.d/docker.list > /dev/null

Docker 를 설치하고 확인합니다.

# apt -y update
# apt -y install docker-ce docker-ce-cli containerd.io
# docker --version

Docker version 24.0.7, build afdd53b

 

 

2. Kind 설치

 

Kind 는 도커 컨테이너 nodes 를 사용하여 로컬 Kubernetes Cluster 를 실행하기 위한 도구입니다.

# wget https://github.com/kubernetes-sigs/kind/releases/download/v0.20.0/kind-linux-amd64

# chmod +x kind-linux-amd64

# mv kind-linux-amd64 /usr/local/bin/kind

# kind version
kind v0.20.0 go1.20.4 linux/amd64

 

클러스터를 생성합니다.

# cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 80
    hostPort: 80
    protocol: TCP
  - containerPort: 443
    hostPort: 443
    protocol: TCP
EOF

Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.27.3) 🖼
 ✓ Preparing nodes 📦  
 ✓ Writing configuration 📜 
 ✓ Starting control-plane 🕹️ 
 ✓ Installing CNI 🔌 
 ✓ Installing StorageClass 💾 
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind

Thanks for using kind! 😊

 

* 참고 : 클러스터 생성 오류

클러스터 재설치 등의 작업으로 아래와 같은 에러가 출력된 경우 기존의 클러스터를 삭제해야 다시 생성이 가능합니다.

ERROR: failed to create cluster: node(s) already exist for a cluster with the name "kind"
클러스터 재설치 전에 'kind delete cluster --name kind' 명령으로 삭제를 먼저 한 뒤에 클러스터 생성 명령을 실행해 주세요.

 

클러스터가 잘 설치 되었는지 확인합니다.

# kubectl cluster-info --context kind-kind
Kubernetes control plane is running at https://127.0.0.1:40321
CoreDNS is running at https://127.0.0.1:40321/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

 

 

3. 환경 변수 설정

 

설치가 편리하도록 자주 사용하는 이름은 변수에 입력합니다.

# ROOT_NAMESPACE="cf"                             // CF 네임스페이스
# KORIFI_NAMESPACE="korifi-system"          // Korifi 네임스페이스
# ADMIN_USERNAME="kubernetes-admin"    // Admin 계정 아이디
# BASE_DOMAIN="az1.sysdocu.kr"                 // 기본 도메인

 

 

4. CF 설치

 

Cloud Foundry 는 개발자가 애플리케이션 코드를 작성하고 구축한 후 애플리케이션을 클라우드 환경에 배포하고 실행하는 데 도움이 되는 플랫폼입니다.

Ubuntu 계열이 아닐 경우 아래 공식 문서를 참고 하시기 바랍니다.

https://docs.cloudfoundry.org/cf-cli/install-go-cli.html

Korifi 에서는 CF 8.5 이상의 버전이 필요합니다. Ubuntu 계열에서 CF 설치 방법은 아래와 같습니다.

# wget -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add -

# echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list

# apt -y update

# apt -y install cf8-cli

 

설치된 CF 8 버전을 확인합니다.

# cf version
cf version 8.7.4+db5d612.2023-10-20

 

 

5. Helm 설치

 

Helm 은 Kubernetes Cluster 에서 Kubernetes 애플리케이션을 관리하기 위한 패키지 관리 도구입니다.

Helm 공식 웹사이트에서 운영 체제에 맞는 Helm 바이너리 파일을 다운로드하여 설치를 쉽게 진행할 수 있습니다.

다음 링크를 사용하면 최신 버전의 helm을 다운로드할 수 있습니다.

URL : https://github.com/helm/helm/releases

페이지 중간부에 Download 섹션이 있고, 64bit 리눅스 OS 를 사용하기 때문에 'Linux arm64' 항목의 주소를 복사하여 리눅스 쉘에서 다운로드 하였습니다.

# wget https://get.helm.sh/helm-v3.12.0-linux-amd64.tar.gz

# tar xvzf helm-v3.12.0-linux-amd64.tar.gz

 

실행파일을 PATH 경로에 포함된 디렉토리로 이동시킵니다.

# mv linux-amd64/helm /usr/local/bin/

 

버전을 확인합니다.

# helm version

version.BuildInfo{Version:"v3.12.0", GitCommit:"c9f554d75773799f72ceef38c51210f1842a1dea", GitTreeState:"clean", GoVersion:"go1.20.3"}

 

 

6. cert-manager 설치

 

cert-manager는 Kubernetes 클러스터에서 SSL/TLS 인증서를 관리하기 위한 오픈 소스 도구입니다. 이 도구는 Let's Encrypt 와 같은 인증 기관에서 인증서를 자동으로 발급하고 갱신하는 작업을 단순화합니다.

# kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.2/cert-manager.yaml

 

설치를 확인합니다.

# kubectl get pods -n cert-manager
NAME                                       READY   STATUS    RESTARTS   AGE
cert-manager-cainjector-65c7bff89d-kjwpr   1/1     Running   0          24s
cert-manager-cbcf9668d-7gd8w               1/1     Running   0          24s
cert-manager-webhook-594cb9799b-b48w2      1/1     Running   0          24s

 

 

7. Kpack 설치

 

Kpack 은 Cloud Foundry 컨테이너 빌드 도구로, Kubernetes 에서 컨테이너 이미지를 빌드하고 관리하는 오픈 소스 프로젝트입니다. Kpack 은 애플리케이션을 컨테이너 이미지로 변환하는 작업을 자동화하고 단순화하는 데 사용됩니다.
# kubectl apply -f https://github.com/buildpacks-community/kpack/releases/download/v0.12.2/release-0.12.2.yaml

 

설치를 확인합니다.

# kubectl get pods -n kpack
NAME                                READY   STATUS    RESTARTS   AGE
kpack-controller-7d544645c8-4h92h   1/1     Running   0          19s
kpack-webhook-77c465c879-lmkx6      1/1     Running   0          19s

 

 

8. Contour 설치

 

Contour 는 Ingress 컨트롤러입니다. Ingress 컨트롤러는 클러스터 외부에서 클러스터 내의 서비스로의 HTTP 및 HTTPS 트래픽을 관리하고 라우팅하는 역할을 합니다.

설치를 진행합니다.

# kubectl apply -f https://projectcontour.io/quickstart/contour.yaml

 

설치를 확인합니다.

# kubectl get pods -n projectcontour
NAME                            READY   STATUS      RESTARTS   AGE
contour-6775896b98-scqgb        1/1     Running     0          46s
contour-6775896b98-tt7v9        1/1     Running     0          46s
contour-certgen-v1-26-1-6jtws   0/1     Completed   0          46s
envoy-2zql9                     1/2     Running     0          46s
envoy-dqjbj                     1/2     Running     0          46s
envoy-xbrqw                     1/2     Running     0          46s

 

 

9. Metrics-server 설치

 

메트릭 서버는 Kubernetes 클러스터 내에서 리소스 사용 및 성능 메트릭을 수집, 저장 및 쿼리하는 데 사용되는 중요한 구성 요소입니다.

여기에서는 간단히 설치하고 넘어가므로, 자세한 내용응 아래 URL 을 참고하시기 바랍니다.

https://github.com/kubernetes-sigs/metrics-server

설치할 메트릭 서버 버전은 Kubernetes 의 버전에 따라 달라집니다.

Kubernetes 가 1.19 이상의 버전이라면 아래와 같이 실행하여 Metrics 를 설치하면 되고, 그 이하일 경우 또는 고가용성 (HA) 을 위한 이중화 구성은 위에 안내된 URL 에서 해당 버전을 확인하여 설치합니다.

# kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

 

설치를 확인합니다.

# kubectl get pods -A |grep metrics-server
kube-system        metrics-server-fbb469ccc-fwmsn             0/1     Running     0             73s

 

이상태로 사용해도 문제가 없으나 kubectl top nodes 등 Metrics 를 이용한 자원 사용량 등을 확인하고 싶은 경우 Running 중인 Pod 가 1개 이상 있어야 합니다. 아래 추가 포스팅을 참고하여 진행하시면 됩니다.

https://sysdocu.tistory.com/1890

 

 

10. Namespace 생성

 

root 및 korifi 네임스페이스를 생성합니다.

# cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: $ROOT_NAMESPACE
  labels:
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/enforce: restricted
EOF

# cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: $KORIFI_NAMESPACE
  labels:
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/enforce: restricted
EOF

 

 

11. Secret 생성

 

Korifi 와 Kpack 이 컨테이너 레지스트리에 연결할 수 있도록 secret 을 생성합니다.

Registry 서비스를 이용하지 않거나 새로 구축해야 하는 경우 별도 포스팅 (https://sysdocu.tistory.com/1855) 을 참고하고,

도커 허브를 사용하는 경우 --docker-server 는 생략하고 --docker-username 에 사용자 이름, --docker-password 에 암호 또는 개인 액세스 토큰을 입력합니다.

# kubectl --namespace "$ROOT_NAMESPACE" create secret docker-registry image-registry-credentials \
    --docker-username="sysdocu" \
    --docker-password="12345678" \
    --docker-server="https://registry.az1.sysdocu.kr:5000"

 

 

12. 네임서버 도메인 설정

 

Korifi API 및 Korifi 에서 실행할 앱에 대한 DNS 등록을 해야 합니다.

아래 내용을 참고하여 네임서버에 master node IP 로 설정해주세요.

- Korifi API 서버 : api.az1.sysdocu.kr / 115.68.142.120

- Apps : *.apps.az1.sysdocu.kr / 115.68.142.120

- 추후 서비스로 제공할 경우 {app_name}.apps.az1.sysdocu.kr 과 같은 개별 도메인은 배포되는 worker node IP 로 연결되도록 하는것도 방법입니다. (하지만 Cluster 구성이기 때문에 master node 에서도 응답은 합니다)

 

 

13. Korifi 설치

 

Korifi 는 빌드, 테스트, 배포 및 모니터링 단계를 지원하는 DevOps 툴체인입니다.

설치는 Helm 명령어로 합니다.

# helm install korifi https://github.com/cloudfoundry/korifi/releases/download/v0.5.0/korifi-0.5.0.tgz \
    --namespace="$KORIFI_NAMESPACE" \
    --set=global.generateIngressCertificates=true \
    --set=global.rootNamespace="$ROOT_NAMESPACE" \
    --set=adminUserName="$ADMIN_USERNAME" \
    --set=api.apiServer.url="api.$BASE_DOMAIN" \
    --set=global.defaultAppDomainName="apps.$BASE_DOMAIN" \
    --set=global.containerRepositoryPrefix=registry.az1.sysdocu.kr:5000 \
    --set=kpack-image-builder.builderRepository=registry.az1.sysdocu.kr:5000/kpack-builder

 

--set=global.containerRepositoryPrefix 옵션에는 업로드 할 수 있는 Repository 주소를 적어야 합니다.

--set=kpack-image-builder.builderRepository 옵션에도 동일한 Repository 주소를 적어주고 뒤에 kpack-builder 디렉토리 하나 더 추가해주세요.

여기에서 약간의 시간이 소요됩니다.

설치를 확인합니다.

# kubectl get pods -n korifi-system
NAME                                                           READY   STATUS    RESTARTS   AGE
korifi-api-deployment-5c747f489d-rc4dd                         1/1     Running   0          49s
korifi-controllers-controller-manager-6b7cdd98c-4h59q          1/1     Running   0          49s
korifi-job-task-runner-controller-manager-f799b99fc-d26vb      1/1     Running   0          49s
korifi-kpack-build-controller-manager-7cdc7fcc9-4r9rv          1/1     Running   0          49s
korifi-statefulset-runner-controller-manager-c49c9997d-ccfvk   1/1     Running   0          49s

 

참고로 helm 으로 설치된 Korifi 삭제는 helm uninstall korifi -n $KORIFI_NAMESPACE 입니다.

 

 

14. 조직 및 공간 생성

 

조직과 공간 생성 후 그 안에서 애플리케이션이 배포 됩니다.

아래와 같이 Cloud Foundry API 를 통해 조직과 공간을 생성하고 타겟 (작업공간으로 적용) 설정을 합니다.

 

Cloud Foundry API 인증 작업을 진행합니다.

# cf api https://api.$BASE_DOMAIN --skip-ssl-validation
# cf login
API endpoint: https://api.az1.sysdocu.kr

1. kind-kind
2. kubernetes-admin

Choose your Kubernetes authentication info (enter to skip): 1

Authenticating...
OK

Warning: The client certificate you provided for user authentication expires at 2024-12-07T02:35:20Z
which exceeds the recommended validity duration of 168h0m0s. Ask your platform provider to issue you a short-lived certificate credential or to configure your authentication to generate short-lived credentials automatically.
API endpoint:   https://api.az1.sysdocu.kr
API version:    3.117.0+cf-k8s
user:           kubernetes-admin
No org or space targeted, use 'cf target -o ORG -s SPACE'

 

위 명령은 'cf auth kind-kind' 로 대체할 수 있습니다.

조직과 공간을 생성하고 타겟 설정을 합니다.

# cf create-org org1
# cf create-space -o org1 space1
# cf target -o org1 -s space1

 

 

15. 빌드팩 추가

 

처음 cf 를 설치하고나서 기본적으로 제공되는 빌드팩은 아래와 같습니다.

# cf buildpacks
Getting buildpacks as kubernetes-admin...

position   name                         stack                        enabled   locked   filename
1          paketo-buildpacks/java       io.buildpacks.stacks.jammy   true      false    paketo-buildpacks/java@10.3.0
2          paketo-buildpacks/go         io.buildpacks.stacks.jammy   true      false    paketo-buildpacks/go@4.6.0
3          paketo-buildpacks/nodejs     io.buildpacks.stacks.jammy   true      false    paketo-buildpacks/nodejs@2.0.0
4          paketo-buildpacks/ruby       io.buildpacks.stacks.jammy   true      false    paketo-buildpacks/ruby@0.41.1
5          paketo-buildpacks/procfile   io.buildpacks.stacks.jammy   true      false    paketo-buildpacks/procfile@5.6.7

 

여기에 PHP Buildpack 을 추가해 보겠습니다. 아래 위치에 내용 추가 후 저장합니다.
# kubectl edit clusterstore cf-default-buildpacks

...

spec:
  sources:
  - image: gcr.io/paketo-buildpacks/java
  - image: gcr.io/paketo-buildpacks/nodejs
  - image: gcr.io/paketo-buildpacks/ruby
  - image: gcr.io/paketo-buildpacks/procfile
  - image: gcr.io/paketo-buildpacks/go
  - image: gcr.io/paketo-buildpacks/php

...

 

clusterbuilder 의 빌드팩 리스트를 갱신합니다.

여기에서도 PHP Buildpack 을 추가합니다. 추가 위치에 따라 빌드팩 순번이 결정됩니다.
# kubectl edit clusterbuilder cf-kpack-cluster-builder

...

spec:
  order:
  - group:
    - id: paketo-buildpacks/php
  - group:
    - id: paketo-buildpacks/java
  - group:
    - id: paketo-buildpacks/go
  - group:
    - id: paketo-buildpacks/nodejs
  - group:
    - id: paketo-buildpacks/ruby
  - group:
    - id: paketo-buildpacks/procfile

...

 

추가된 빌드팩을 확인합니다.

# cf buildpacks
Getting buildpacks as kubernetes-admin...

position   name                         stack                        enabled   locked   filename
1          paketo-buildpacks/php        io.buildpacks.stacks.jammy   true      false    paketo-buildpacks/php@2.11.1
2          paketo-buildpacks/java       io.buildpacks.stacks.jammy   true      false    paketo-buildpacks/java@10.3.0
3          paketo-buildpacks/go         io.buildpacks.stacks.jammy   true      false    paketo-buildpacks/go@4.6.0
4          paketo-buildpacks/nodejs     io.buildpacks.stacks.jammy   true      false    paketo-buildpacks/nodejs@2.0.0
5          paketo-buildpacks/ruby       io.buildpacks.stacks.jammy   true      false    paketo-buildpacks/ruby@0.41.1
6          paketo-buildpacks/procfile   io.buildpacks.stacks.jammy   true      false    paketo-buildpacks/procfile@5.6.7

 

 

16. 애플리케이션 배포

 

위에서 추가한 PHP Buildpack 을 이용해 애플리케이션을 배포해 보도록 하겠습니다.

간단한 소스를 만듭니다.

# mkdir php-source

# cd php-source
# vi index.php

<?php
echo "Hello, World!\n";
echo "PHP Version: " . phpversion() ."\n";
?>

 

PHP 소스를 배포 합니다.

# cf push php1

...

 

* 참고 (소스 디렉토리 지정)

소스를 배포할때는 해당 소스 디렉토리에서 cf push 명령을 실행해야 하지만, 디렉토리가 다를 경우 -p 옵션 (-p {소스 경로}) 을 추가하면 됩니다.

 

배포된 애플리케이션 정보는 아래 명령으로 확인됩니다.

# cf app php1

 

정상 동작하는지 curl 명령으로 접근해 봅니다.

# curl --insecure https://php1.apps.az1.sysdocu.kr
Hello, World!
PHP Version: 8.1.24

 

* Laravel 프로젝트 배포

Laravel 소스를 배포하기 위한 Composer 설치 및 Laravel 프로젝트 생성 방법은 아래 포스팅을 참고해 주세요.

https://sysdocu.tistory.com/1874

 

위 포스팅에서와 같이 Laravel 프로젝트 생성 준비가 되었다면, 다음과 같은 과정을 거쳐 배포가 가능합니다.

Laravel 프로젝트를 생성합니다. (예 : laravel-app)

# composer create-project laravel/laravel --prefer-dist laravel-app

 

생성된 Laravel 프로젝트 디렉토리로 이동 후, 배포를 위해 꼭 필요한 설정파일 2개를 생성합니다. (project.toml, extentions.ini)

# cd laravel-app

# vi project.toml

[ build ]
  [[ build.env ]]
    name='BP_PHP_SERVER'
    value='nginx'

  [[ build.env ]]
    name='BP_PHP_WEB_DIR'
    value="public"

  [[ build.env ]]
    name='BP_PHP_ENABLE_HTTPS_REDIRECT'
    value='false'

 

* 설명

- 웹서버를 httpd 로 사용하고 싶은 경우 nginx 대신 httpd 를 입력합니다.

- nginx 의 추가 설정이 필요한 경우 (예: DirectoryIndex) .nginx.conf.d/location-server.conf 파일을 생성하고 아래와 같이 필요한 설정을 넣으면 됩니다.

location / {

  try_files $uri $uri/index.html;

}

 

# mkdir .php.ini.d
# vi .php.ini.d/extentions.ini

extension = curl
extension = fileinfo
extension = openssl

 

* 참고

다른 PaaS 서비스를 제공하는 사이트에서는 소스코드가 어떤 모듈을 사용하는지 모르기 때문에, 모든 모듈을 추가하여 제공합니다. CF 환경에서 테스트 결과 아래 모듈이 사용 가능했습니다.

extentions.ini
0.00MB

 

Laravel 프로젝트를 배포합니다.

# cf push laravel-app

 

간단히 curl 명령으로 확인이 가능하며,

# curl --insecure https://laravel-app.apps.az1.sysdocu.kr

 

위에서 네임서버 설정을 미리 해두었으므로 웹브라우저에서도 출력된 도메인으로 접속하여 Laravel 초기 페이지 확인이 가능합니다.

> https://laravel-app.apps.az1.sysdocu.kr

 

 

* 참고

 

새로운 세션에서 API 연결은 되었지만, CloudFoundry 로그인 시도 할때 아래와 같이 인증 실패 메세지가 출력되었다면

 

# cf api https://api.az1.sysdocu.kr--skip-ssl-validation
Setting API endpoint to https://api.az1.sysdocu.kr...
OK

API endpoint:   https://api.az1.sysdocu.kr
API version:    3.117.0+cf-k8s

Not logged in. Use 'cf login' or 'cf login --sso' to log in.


root@master:~# cf login
API endpoint: https://api.az1.sysdocu.kr

API endpoint:   https://api.az1.sysdocu.kr 
API version:    3.117.0+cf-k8s
Not logged in. Use 'cf login' or 'cf login --sso' to log in.
Unable to authenticate.
FAILED

 

Kubernetes 환경 변수를 불러오지 않았을 경우가 있으므로 아래 명령을 통해 KUBECONFIG 환경 변수를 설정합니다.

# export KUBECONFIG=/etc/kubernetes/admin.conf

 

반응형

댓글()

Openstack 에서 운영중인 VM 용량 늘리기

리눅스/OpenStack|2023. 10. 19. 11:55
반응형

Flavor 를 변경하는 방법과 disk 파일의 크기를 직접 늘려주는 방법이 있는데, 여기에서는 disk 파일 크기를 바로 변경하는 더 쉬운 방법을 안내 드리겠습니다.

 

변경하고자 하는 master 라는 이름의 VM 이 어느 컴퓨트 노드에 있는지 확인합니다.

(Controller 서버에서)

# openstack server show master |grep hostname
| OS-EXT-SRV-ATTR:hypervisor_hostname | compute1                                                 |

 

(해당 컴퓨트 노드에서)

사용중인 VM 의 PID 값 확인 후 종료합니다.

# ps -ef|grep disk
root        1110       1  0 02:37 ?        00:00:00 /usr/libexec/udisks2/udisksd
libvirt+    2788       1 99 02:38 ?        00:00:08 /usr/bin/qemu-system-x86_64 -name guest=instance-00000006,debug-threads=on -S -object {"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain-1-instance-00000006/master-key.aes"} -machine pc-i440fx-6.2,usb=off,dump-guest-core=off,memory-backend=pc.ram -accel kvm -cpu Skylake-Client-IBRS,ss=on,vmx=on,pdcm=on,hypervisor=on,tsc-adjust=on,clflushopt=on,umip=on,md-clear=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,pdpe1gb=on,ibpb=on,ibrs=on,amd-stibp=on,amd-ssbd=on,rsba=on,skip-l1dfl-vmentry=on,pschange-mc-no=on,hle=off,rtm=off -m 8192 -object {"qom-type":"memory-backend-ram","id":"pc.ram","size":8589934592} -overcommit mem-lock=off -smp 4,sockets=4,dies=1,cores=1,threads=1 -uuid f6aa6879-0ea4-4be8-a610-d1abcd60c9ab -smbios type=1,manufacturer=OpenStack Foundation,product=OpenStack Nova,version=25.2.0,serial=f6aa6879-0ea4-4be8-a610-d1abcd60c9ab,uuid=f6aa6879-0ea4-4be8-a610-d1abcd60c9ab,family=Virtual Machine -no-user-config -nodefaults -chardev socket,id=charmonitor,fd=31,server=on,wait=off -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet -no-shutdown -boot strict=on -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -blockdev {"driver":"file","filename":"/var/lib/nova/instances/_base/bf15376deac35c8c707e130fb5d70882999b77d2","node-name":"libvirt-2-storage","cache":{"direct":true,"no-flush":false},"auto-read-only":true,"discard":"unmap"} -blockdev {"node-name":"libvirt-2-format","read-only":true,"cache":{"direct":true,"no-flush":false},"driver":"raw","file":"libvirt-2-storage"} -blockdev {"driver":"file","filename":"/var/lib/nova/instances/f6aa6879-0ea4-4be8-a610-d1abcd60c9ab/disk","node-name":"libvirt-1-storage","cache":{"direct":true,"no-flush":false},"auto-read-only":true,"discard":"unmap"} -blockdev {"node-name":"libvirt-1-format","read-only":false,"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":"libvirt-1-storage","backing":"libvirt-2-format"} -device virtio-blk-pci,bus=pci.0,addr=0x4,drive=libvirt-1-format,id=virtio-disk0,bootindex=1,write-cache=on -netdev tap,fd=34,id=hostnet0,vhost=on,vhostfd=36 -device virtio-net-pci,host_mtu=1450,netdev=hostnet0,id=net0,mac=fa:16:3e:cb:7e:47,bus=pci.0,addr=0x3 -add-fd set=3,fd=33 -chardev pty,id=charserial0,logfile=/dev/fdset/3,logappend=on -device isa-serial,chardev=charserial0,id=serial0 -device usb-tablet,id=input0,bus=usb.0,port=1 -device usb-kbd,id=input1,bus=usb.0,port=2 -audiodev {"id":"audio1","driver":"none"} -vnc 127.0.0.1:0,audiodev=audio1 -device virtio-vga,id=video0,max_outputs=1,bus=pci.0,addr=0x2 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5 -object {"qom-type":"rng-random","id":"objrng0","filename":"/dev/urandom"} -device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.0,addr=0x6 -device vmcoreinfo -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny -msg timestamp=on
root        2836    2649  0 02:38 pts/1    00:00:00 grep --color=auto disk

 

# kill -9 2788

 

인스턴스 디렉토리로 들어가 disk 파일의 사이즈를 20G 더 늘려줍니다.

# cd /var/lib/nova/instances/f6aa6879-0ea4-4be8-a610-d1abcd60c9ab

# qemu-img resize disk +20G

Image resized.

 

(Controller 서버에서)

중지되었던 VM 을 다시 가동합니다.

# openstack server start master

 

(VM 에서)

용량 확인 명령으로 초기 20GB 에서 20GB 더 늘린 40GB 사용이 확인되었습니다.

root@master:~# df -h
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           794M  1.7M  793M   1% /run
/dev/vda1        39G   19G   21G  48% /
tmpfs           3.9G     0  3.9G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
/dev/vda15      105M  6.1M   99M   6% /boot/efi
tmpfs           794M  4.0K  794M   1% /run/user/1000

 

반응형

댓글()

리눅스에서 현재 세션의 명령 히스토리만 삭제하기

리눅스/OS 일반|2023. 10. 17. 08:32
반응형

기존 history 는 남기고 현재 세션의 명령 history 만 삭제하는 방법은 아래와 같습니다.

 

- 목적 : 특별한 작업 로그를 남기지 않을 경우 사용

- 명령어 : # unset HISTFILE

 

반응형

댓글()

Ubuntu 22.04 에서 Ansible 2.10.8 설치 및 설정, 플레이북 활용

리눅스/OS 일반|2023. 10. 12. 11:34
반응형

Ansible 은 인프라스트럭처 관리와 소프트웨어 프로비저닝을 자동화하기 위한 오픈 소스 도구 및 프레임워크입니다. Ansible 은 다음 3가지의 핵심 구성 요소를 가지고 있습니다.
- 인벤토리 : 관리 대상 호스트 (서버, 가상 머신 등) 의 목록 및 그룹을 정의하는 INI 또는 YAML 파일
- 플레이북 : 작업 (task), 역할 (role), 변수, 조건문 등을 포함한 YAML 파일로, 여러 대상 호스트에서 작업을 수행
- 모듈 : 특정 작업을 수행하기 위한 실행 가능한 코드 블록

 

Ubuntu 22.04 기반에서 Ansible 을 설치, 설정하고 실제로 실행하는 방법을 알아보겠습니다.

 

[테스트를 위한 사전 준비]

- Ubuntu 22.04 기반 서버 3대 (Ansible 서버 1대, 대상 호스트 2대)

 

 

1. 설치

 

Ansible 설치는 굉장히 간단합니다.

Ansible 명령을 수행할 Ansible 서버에만 몇 개의 패키지를 설치하면 되며, 작업을 수행할 서버에 설치할 패키지 또는 Agent 는 없습니다.

(그렇기 때문에 본 매뉴얼의 모든 명령은 Ansible 서버에서만 실행합니다)

Ansible 는 SSH 기반으로 명령을 수행하기 때문에 sshpass 패키지까지 설치해줘야 합니다.

그리고 Ansible 은 Python 으로 제작되었기 때문에 Ansible 설치시 Python 도 같이 설치가 됩니다.

# apt -y update

# apt -y upgrade

# apt -y install ansible sshpass

# ansible --version
ansible 2.10.8
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0]

 

 

2. 인벤토리 설정

 

1) 인벤토리 파일 생성

관리하는 서버의 정보를 담은 파일을 아래와 같이 생성합니다.

섹션 이름은 서버를 그룹핑하기 위한 명칭으로 적절히 설정하면 되고,

대상 호스트는 IP 또는 도메인으로 입력할 수 있습니다.

섹션 내에 여러대의 호스트 추가가 가능합니다.

# vi servers.ini

[web]
10.101.0.23
[db]
10.101.0.34

 

2) SSH 공개키 복사

Ansible 은 ssh 를 이용하여 대상 호스트로 명령을 수행합니다.

ssh 공개키를 생성하고 대상 호스트에 설정하여두면 Ansible 명령 실행시마다 패스워드를 입력하는 번거로움을 줄일 수 있습니다.

# ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): (그냥 엔터)
Enter passphrase (empty for no passphrase): (그냥 엔터)
Enter same passphrase again: (그냥 엔터)
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:2bKuWWJfCBqiNnkCYgKZRmI6GEZDynqWbGM41/TsbAk root@kuru80-223962
The key's randomart image is:
+---[RSA 3072]----+
|=B               |
|X+.              |
|Oo  .            |
|++ + o   o       |
|B.@ E + S .      |
|=O.o * o +       |
|.= .. B + .      |
|. +  o * .       |
|      o.o        |
+----[SHA256]-----+

생성된 공개키를 대상 호스트로 복사합니다. 처음 호스트 접속시 패스워드가 필요하지만 키 복사가 완료된 후에는 패스워드가 필요 없게 됩니다.

# ssh-copy-id root@10.101.0.23

# ssh-copy-id root@10.101.0.34

 

3) 연결 테스트

Ansible 에서 주로 사용하는 옵션은 세가지가 있습니다. (help 에서는 더 많은 옵션이 출력됩니다)

-m : 모듈

-i : 인벤토리

-u : 유저명

유저명은 제외하고 아래와 같이 인벤토리 (servers.ini) 에 등록된 모든 호스트에 ping 테스트를 해봅니다.

참고로 all 말고 섹션명을 지정해주면 인벤토리 내의 특정 세션에 등록된 호스트로만 명령을 실행합니다.

# ansible -i servers.ini all -m ping
10.101.0.34 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
10.101.0.23 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}

 

 

3. 옵션

 

Ansible 은 기본적으로 작업을 병렬 처리 합니다.

기본 동시 처리되는 호스트 개수는 5개 입니다.

# ansible-config dump |grep -i forks
DEFAULT_FORKS(default) = 5

 

서버의 자원이 충분하여 동시에 처리되는 양을 늘리고자 할 경우 아래와 같이 설정파일을 수정하여 동시처리 개수를 늘릴 수 있습니다.

설정파일은 아래 여러 가지 방법중 한가지 방법을 이용하여 설정할 수 있으며, 우선 순위대로 검색되는 구성 파일으로 적용되어집니다.

- ANSIBLE_CONFIG (환경변수)
- ansible.cfg (현재 디렉토리)
- ~/.ansible.cfg (홈디렉토리)
- /etc/ansible/ansible.cfg

 

디렉토리가 바뀌어도 항상 적용이 가능하도록 세번째 방법으로 설정해보겠습니다.

# vi ~/.ansible.cfg

[defaults]
forks = 10

 

저장만 해도 변경된 것이 확인되었습니다.

# ansible-config dump |grep -i forks
DEFAULT_FORKS(/root/.ansible.cfg) = 10

 

아래는 중요하거나 자주 사용하는 옵션입니다. 모두 [default] 섹션에 넣어주면 됩니다.

- remote_user

: 원격 호스트에 연결할 때 사용할 SSH 사용자 이름을 지정합니다. 기본값은 현재 사용자의 이름입니다. 이 옵션을 설정하여 명시적으로 원격 사용자를 지정할 수 있습니다.
예) remote_user = myuser

 

- private_key_file

: SSH 키 파일의 경로를 지정합니다. 이 옵션을 사용하여 사용자 지정 SSH 키 파일을 사용할 수 있습니다.
예) private_key_file = /path/to/ssh/keyfile

 

- inventory

: 인벤토리 파일의 경로를 지정합니다. 기본적으로 ansible.cfg 파일이 있는 디렉토리에서 inventory 파일을 검색하며, 이 옵션을 사용하여 사용자 정의 인벤토리 파일을 지정할 수 있습니다. 인벤토리 파일의 경로를 지정하면 ansible 명령 실행시 -i 옵션을 이용해 인벤토리 파일을 일일이 명시하지 않아도 됩니다.
예) inventory = /root/servers.ini

 

- roles_path

: 역할 (roles) 디렉토리의 기본 경로를 지정합니다. 이 옵션을 사용하여 역할을 저장하는 디렉토리를 사용자 정의할 수 있습니다.
예) roles_path = /path/to/custom/roles

 

- forks

: 병렬로 실행될 작업 수를 지정합니다. 기본값은 5이며, 시스템 리소스에 따라 적절한 값을 설정할 수 있습니다.
예) forks = 10

 

- become

: 작업을 슈퍼 유저(루트) 권한으로 실행할지 여부를 지정합니다. yes로 설정하면 슈퍼 유저로 작업을 실행합니다.
예) become = yes

 

- become_user

: 슈퍼 유저(루트) 권한으로 작업을 실행할 때 사용할 사용자를 지정합니다.
예) become_user = root

 

- timeout

: SSH 연결 또는 명령 실행의 타임아웃을 지정합니다. 기본값은 10초입니다.
예) timeout = 30

 

 

4. 플레이북 설정

 

플레이북 (playbook) 을 활용한 다양한 예시를 준비했습니다.

 

1) 대상 서버로 파일 복사하기

아래와 같이 플레이북 파일을 작성합니다.

# vi copy.yaml

---
- name: Copy a file to a remote server
  hosts: web
  tasks:
    - name: Copy a file
      copy:
        src: /root/servers.ini
        dest: /root/

 

- 플레이북 파일의 시작은 --- 로 시작하고, 여러개의 작업이 있을 경우 작업 단위마다 - 으로 구분해줘야 합니다.

- hosts : 섹션을 지정합니다. hosts 를 web 섹션으로 하지 않고 all 로 입력 할 경우 인벤토리에 등록된 모든 호스트로 파일을 복사하게 됩니다.

- name : 작업을 구분하기 위한 명칭입니다. (위, 아래 둘다)

- copy : 복사하려는 로컬 파일과 붙여넣으려는 대상 호스트의 디렉토리를 지정합니다.

 

작성한 플레이북을 실행합니다.

# ansible-playbook -i servers.ini copy.yaml

 

2) 패스워드 변경하기

대상 호스트의 root 패스워드를 변경합니다.

# vi chpasswd.yaml

---
- name: Update Remote Server Password
  hosts: all
  tasks:
    - name: Update password
      user:
        name: root
        update_password: always
        password: "{{ '12345678' | password_hash('sha512') }}"

 

- name: 플레이북의 이름을 정의합니다. 이 이름은 플레이북을 식별하기 위해 사용됩니다.
- hosts: 플레이북이 실행될 호스트 그룹을 지정합니다. "all"은 모든 호스트를 대상으로 하는 것을 의미합니다.
- tasks: 플레이북에서 실행할 작업 목록을 정의합니다.
- name: 각 작업의 이름을 지정합니다. 이것은 작업을 식별하기 위한 레이블입니다.
- user 모듈: 이 모듈은 사용자 관리 작업을 수행합니다.
- name: root: user 모듈에 전달된 사용자 이름으로 "root" 사용자를 지정합니다. 이 플레이북은 "root" 사용자의 비밀번호를 변경합니다.
- update_password: always: 사용자 모듈의 update_password 옵션을 "always"로 설정하면 항상 비밀번호를 업데이트하도록 강제합니다.
- password: user 모듈에서 변경할 비밀번호를 정의합니다. 이 플레이북에서는 "12345678"을 password_hash 필터를 사용하여 SHA-512로 해싱한 값을 비밀번호로 설정합니다. 해싱된 비밀번호를 사용하면 보안성을 향상시킬 수 있습니다.

 

작성한 플레이북을 실행합니다.

# ansible-playbook -i servers.ini chpasswd.yaml

 

3) 패키지 설치하기

이 예시는 원격 서버의 APT 패키지 관리자를 사용하여 패키지를 설치합니다.
# vi apt.yaml

---
- name: Install a package on a remote server
  hosts: web
  tasks:
    - name: Install package
      apt:
        name: apache2
        state: present

 

- name: 플레이북의 이름을 정의합니다. 이 이름은 플레이북을 식별하기 위해 사용됩니다.
- hosts: 플레이북이 실행될 호스트 그룹을 지정합니다. "web"은 모든 호스트를 대상으로 하는 것을 의미합니다.
- tasks: 플레이북에서 실행할 작업 목록을 정의합니다.
- apt 모듈: 패키지 설치 작업을 수행합니다.

 

작성한 플레이북을 실행합니다.

# ansible-playbook -i servers.ini apt.yaml

 

4) 데몬 컨트롤 하기

이 예제에서는  Ubuntu 에서 Apache 웹 서버를 시작하는 플레이북을 사용합니다.
# vi apache2.yaml

---
- name: Start Apache Web Server
  hosts: web
  become: yes
  tasks:
    - name: Ensure Apache service is running
      service:
        name: apache2
        state: started


- name: 플레이북의 이름을 지정합니다.
- hosts: 플레이북을 실행할 호스트 그룹 또는 호스트 이름을 지정합니다.
- become: yes: become 키워드를 사용하여 플레이북을 실행할 때 슈퍼유저(루트) 권한으로 실행합니다. 이는 데몬 또는 서비스를 시작하거나 중지할 때 필요한 권한을 얻기 위해 사용됩니다.
- tasks: 수행할 작업 목록을 나열합니다.
- name: 작업의 이름을 지정합니다.
- service 모듈: 서비스 관리 작업을 수행하는 모듈입니다.
- name: apache2: 서비스의 이름을 지정합니다. Ubuntu 에서 Apache 웹 서버는 apache2 로 알려져 있습니다.
- state: started: 서비스를 시작하도록 지정합니다. 이 작업은 Apache 웹 서버가 이미 실행 중인 경우에는 아무 작업도 수행하지 않습니다.

 

작성한 플레이북을 실행합니다.

# ansible-playbook -i servers.ini apache2.yaml

 

5) 사용자 생성 및 그룹 할당
이 예시는 원격 서버에 사용자를 생성하고 그룹에 할당하는 플레이북입니다. user 및 group 모듈을 사용합니다.

# vi useradd.yaml

---
- name: Create a user and assign to a group
  hosts: web
  tasks:
    - name: Create a group
      group:
        name: developers
        state: present

    - name: Create a user
      user:
        name: sysdocu
        groups: developers
        state: present

 

* 설명

- name: 플레이북의 이름을 지정합니다.
- hosts: 플레이북을 실행할 호스트 그룹 또는 호스트 이름을 지정합니다.
- tasks: 수행할 작업 목록을 나열합니다.
- group 및 user 모듈: 그룹 및 사용자 생성 및 할당 작업을 수행합니다.

 

작성한 플레이북을 실행합니다.

# ansible-playbook -i servers.ini useradd.yaml

 

6) 보안 패치 적용
서버에 보안 패치를 적용합니다.
# vi update.yaml

---
- name: Apply security patches
  hosts: all
  tasks:
    - name: Update package cache
      apt:
        update_cache: yes
      become: yes

    - name: Upgrade all packages
      apt:
        upgrade: safe
      become: yes

 

작성한 플레이북을 실행합니다.

# ansible-playbook -i servers.ini update.yaml

 

7) MySQL 설치 및 설정
MySQL 데이터베이스를 설치하고 설정합니다.

DB 생성, 계정 생성 및 DB 권한 부여까지 진행합니다.
# vi mysql.yaml

---
- name: Install MySQL and Configure Database
  hosts: db
  become: yes
  tasks:
    - name: Install MySQL Server
      apt:
        name: mysql-server
        state: present

    - name: Start MySQL Service
      service:
        name: mysql
        state: started

    - name: Install python3-pymysql
      apt:
        name: python3-pymysql
        state: present

    - name: Change MySQL root password
      mysql_user:
        login_user: root
        login_password: ''
        name: root
        password: 12345678
        host: localhost
        login_unix_socket: /var/run/mysqld/mysqld.sock

    - name: Create a MySQL Database
      mysql_db:
        login_user: root
        login_password: 12345678
        name: sysdocudb
        state: present

    - name: Create a MySQL User
      mysql_user:
        name: sysdocu
        password: 12345678
        priv: sysdocudb.*:ALL

    - name: Flush MySQL Privileges
      mysql_user:
        login_user: root
        login_password: 12345678
        name: sysdocu
        host: localhost
        priv: "*.*:ALL,GRANT"
        append_privs: yes

 

작업을 설명하면, 아래와 같이 순차 처리됩니다.

- MySQL 설치

- MySQL 시작

- python3-pymysql 설치 (Ansible 에서 MySQL 관리하기 위해 필요)

- root 패스워드 변경 (null -> 12345678)

- DB 생성

- DB 계정 생성

- 계정에 DB 권한 부여

* 작업별로 MySQL 쿼리 실행을 위해 root 계정정보를 입력해 주었습니다.

 

작성한 플레이북을 실행합니다.

# ansible-playbook -i servers.ini mysql.yaml

 

8) Docker 컨테이너 배포 및 관리

Docker 컨테이너를 배포하고 관리합니다.

플레이북에서 대상 호스트에 Docker 패키지와 docker-py 설치 작업 후 컨테이너를 구동하는 절차로 작성하면 되지만, 여기에서는 Docker 및 docker-py 가 대상 호스트에 설치되었다고 가정하고 컨테이너 구동 방법만 설명드립니다.

 

* 참고 : Docker 및 docker-py 설치 (Ubuntu 22.04)

(대상 호스트에서)

# apt -y install apt-transport-https ca-certificates curl gnupg lsb-release
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg |gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# echo   "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" |tee /etc/apt/sources.list.d/docker.list > /dev/null
# apt -y update
# apt -y install docker-ce docker-ce-cli containerd.io

# apt -y install python3-pip

# pip3 install docker-py

 

플레이북을 작성합니다.

(Ansible 서버에서)

# vi docker.yaml

---
- name: Deploy Docker containers
  hosts: db
  tasks:
    - name: Pull Docker image
      docker_image:
        name: nginx:latest

    - name: Run a Docker container
      docker_container:
        name: my_nginx
        image: nginx:latest
        ports:
          - "80:80"

 

- name: 플레이북의 이름을 지정합니다. 이 이름은 플레이북을 식별하는 레이블입니다.
- hosts: 플레이북을 실행할 호스트 또는 호스트 그룹을 지정합니다. 이 예시에서는 "db" 호스트 그룹에 대한 작업을 수행합니다.
- tasks: 플레이북에서 실행할 작업 목록을 정의합니다.
- name: 각 작업의 이름을 지정합니다. 이것은 작업을 식별하는 레이블입니다.
- docker_image 모듈: 이 모듈은 Docker 이미지 관리 작업을 수행합니다. name 속성은 다운로드하려는 Docker 이미지의 이름을 지정합니다. 이 예시에서는 "nginx:latest" 이미지를 다운로드합니다.
- docker_container 모듈: 이 모듈은 Docker 컨테이너 관리 작업을 수행합니다. name 속성은 컨테이너의 이름을 지정하고, image 속성은 사용할 Docker 이미지를 지정합니다. ports 속성은 컨테이너와 호스트 간의 포트 매핑을 설정합니다. 이 예시에서는 "my_nginx"라는 이름의 컨테이너를 생성하고 "nginx:latest" 이미지를 사용하며, 호스트의 80번 포트와 컨테이너의 80번 포트를 연결합니다.

작성한 플레이북을 실행합니다.

# ansible-playbook -i servers.ini docker.yaml

 

반응형

댓글()

Windows 에서 Docker 사용하기 (Windows Container)

윈도우즈/OS 일반|2023. 10. 10. 14:50
반응형

윈도우즈에서 Docker 를 사용하는 방법입니다.

여기에서는 Docker 를 이용해 Windows Container 를 가동해 보겠습니다.

Windows Container 는 Windows 10, 11 또는 Windows Server 2016 이후의 버전을 기반으로 실행해야 합니다.

저는 Windows 2019 Server 기반에서 진행하였습니다.

 

 

1. Hyper-V 설치

 

윈도우즈 파워쉘을 열고 아래 명령을 실행하여 Hyper-V 구성요소를 설치합니다.

PS C:\Users\Administrator> Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
지금 컴퓨터를 다시 시작하여 이 작업을 완료하시겠습니까?
[Y] Yes  [N] No  [?] 도움말 (기본값은 "Y"): Y

 

'Y' 를 입력하여 리부팅을 합니다.

 

 

2. Docker Desktop for Windows 설치

 

부팅이 되었다면 아래 URL 에 접속하여 윈도우즈용 Docker 를 다운로드 받아 설치합니다.

https://docs.docker.com/desktop/install/windows-install 으로 접속하여 [Docker Desktop for Windows] 버튼을 클릭해 설치파일을 다운로드하고, 실행하여 설치합니다.

현재 날짜 기준으로 Docker Desktop 4.24.1 버전이 설치되었습니다.

설치 완료 후, 재부팅을 해야 합니다.

부팅되어 윈도우즈에 다시 로그인을 하면 Docker Desktop 에서 아래와 같은 메세지가 출력됩니다.

 

-----

Windows 17763 is deprecated

You can still use Docker Desktop but you are on Windows 17763.

You will not be able to install further major updates (3.6.0 and above).

We recommend upgrading to the latest version of Windows.

-----

Windows 17763은 더 이상 사용되지 않습니다.
Docker Desktop을 계속 사용할 수 있지만 Windows 17763을 사용하고 있습니다.
추가 주요 업데이트(3.6.0 이상)를 설치할 수 없습니다.
최신 버전의 Windows로 업그레이드하는 것이 좋습니다.

-----

 

[OK] 버튼을 누르고 사용 동의를 묻는 질문에 동의합니다.

그 다음 저는 로그인을 스킵하고 진행하였습니다. (맨 아래 밑줄 클릭)

직업을 묻는 창이 뜨는데 마찬가지로 스킵하고 진행하였습니다.

이제 Docker Desktop 사용준비가 완료되었습니다.

 

 

3. Windows Container 이미지 다운로드

 

Windows Container 는 latest TAG 를 지원하지 않으므로 아래 페이지에서 TAG 를 확인 후 정확하게 입력해줘야 합니다.

- Server Core : https://hub.docker.com/_/microsoft-windows-servercore

- Nano Server : https://hub.docker.com/_/microsoft-windows-nanoserver

- Windows : https://hub.docker.com/_/microsoft-windows

- Windows Server : https://hub.docker.com/_/microsoft-windows-server

 

nanoserver:ltsc2022 버전을 다운로드 하기위해 파워쉘을 실행해 아래와 같이 명령어를 입력합니다.

PS C:\Users\Administrator> docker pull mcr.microsoft.com/windows/nanoserver:2022-amd64
[2023-10-10T06:40:43.321895600Z][docker-credential-desktop.system][W] Windows version might not be up-to-date: The system cannot find the file specified.
2022-amd64: Pulling from windows/nanoserver
no matching manifest for linux/amd64 in the manifest list entries

 

위와 같은 메세지가 출력된다면 Linux 컨테이너를 실행하도록 되어 있는 것입니다. Windows 컨테이너로 실행하려면 플랫폼 옵션을 추가해 줍니다.

PS C:\Users\Administrator> docker pull --platform windows/amd64 mcr.microsoft.com/windows/nanoserver:2022-amd64

[2023-10-10T06:51:52.322714700Z][docker-credential-desktop.system][W] Windows version might not be up-to-date: The system cannot find the file specified.
2022-amd64: Pulling from windows/nanoserver
no matching manifest for windows/amd64 10.0.17763 in the manifest list entries

 

플랫폼은 변경되었으나, 에러가 발생했습니다. 에러는 아래에서 잡도록 하고 우선 플랫폼 옵션이 번거로우므로 기본 설정으로 변경하여 옵션을 생략하도록 합니다.

윈도우 하단 우측의 트레이에서 Docker 아이콘을 우클릭하면 'Switch to Windows containers...' 옵션이 보입니다. 이를 클릭하고 다시 명령을 실행해 보겠습니다.

PS C:\Users\Administrator> docker pull mcr.microsoft.com/windows/nanoserver:2022-amd64
[2023-10-10T07:23:17.806412500Z][docker-credential-desktop.system][W] Windows version might not be up-to-date: The system cannot find the file specified.
2022-amd64: Pulling from windows/nanoserver
no matching manifest for windows/amd64 10.0.17763 in the manifest list entries

 

옵션을 제외하고 Windows 컨테이너로 다운로드 시도한것이 보입니다. 하지만 에러가 해결되지는 않았습니다.

OS 버전을 확인합니다.

PS C:\Users\Administrator> docker info |findstr 'Operating System'
 Operating System: Microsoft Windows Server Version 1809 (OS Build 17763.107)

 

현재 OS 버전은 1809 이므로 1809 이후의 버전은 구동하지 못합니다.

원래 다운로드 받으려고 했던 2022-amd64 버전을 1809-amd64 로 변경하여 다운로드 합니다.

PS C:\Users\Administrator> docker pull mcr.microsoft.com/windows/nanoserver:1809-amd64
[2023-10-10T07:40:06.050064200Z][docker-credential-desktop.system][W] Windows version might not be up-to-date: The system cannot find the file specified.
1809-amd64: Pulling from windows/nanoserver
f10ae9b68062: Pull complete
Digest: sha256:1b377c168fe2aeef3acd02d3a654c1280b45e6151d66d71ca1d50292e1cce106
Status: Downloaded newer image for mcr.microsoft.com/windows/nanoserver:1809-amd64
mcr.microsoft.com/windows/nanoserver:1809-amd64

What's Next?
[2023-10-10T07:40:14.293630700Z][docker-credential-desktop.system][W] Windows version might not be up-to-date: The system cannot find the file specified.
[2023-10-10T07:40:14.369957100Z][docker-credential-desktop.system][W] Windows version might not be up-to-date: The system cannot find the file specified.
  View a summary of image vulnerabilities and recommendations → docker scout quickview mcr.microsoft.com/windows/nanoserver:1809-amd64

 

다운로드가 잘 되었습니다. 도커 이미지 목록에도 보이는지 확인합니다.

PS C:\Users\Administrator> docker images
REPOSITORY                             TAG          IMAGE ID       CREATED       SIZE
mcr.microsoft.com/windows/nanoserver   1809-amd64   bd7fe7d0dddd   5 weeks ago   252MB

 

참고로 배포되는 컨테이너 TAG 리스트는 아래에서 확인이 가능합니다.

- Server Core : https://mcr.microsoft.com/v2/windows/servercore/tags/list

- Nano Server : https://mcr.microsoft.com/v2/windows/nanoserver/tags/list

- Windows : https://mcr.microsoft.com/v2/windows/tags/list

- Windows Server : https://mcr.microsoft.com/v2/windows/server/tags/list

 

 

4. Windows Container 실행

 

아래와 같이 실행하면 컨테이너의 명령프롬프트 실행이 가능합니다.

PS C:\Users\Administrator> docker run -it mcr.microsoft.com/windows/nanoserver:1809-amd64 cmd.exe

 

cmd.exe 대신 ipconfig.exe 를 입력하면 명령 수행 후 컨테이너가 바로 종료됩니다.

그래서 추가작업이 필요한 경우 cmd.exe 를 실행하고 출력된 명령프롬프트에서 추가 명령을 진행하면 됩니다.

이제, 컨테이너 목적으로 사용하시려면 Dockerfile 을 작성해서 웹서버와 같은 서비스를 구동해 보시기 바랍니다.

 

 

* 참고 (Container 원격 접속)

 

아래 링크에서 확인된 바로는 윈도우즈 컨테이너에서는 RDP 나 GUI 를 제공하지 않는다고 나와 있습니다.

 

https://github.com/microsoft/Windows-Containers/issues/306#issuecomment-1376440627

"Windows 컨테이너 이미지에서 제거되었으므로 지원되지 않습니다. 조만간 RDP 나 GUI 를 사용할 계획이 없기 때문에 Windows 컨테이너 구현 방식을 대대적으로 재설계해야 합니다. 애플리케이션에 GUI 나 RDP 가 필요한 경우 VM 을 계속 사용하는 것이 좋습니다. Azure Virtual Desktop 이나 Azure VM 과 같은 서비스가 더 적합할 수 있습니다."

 

https://learn.microsoft.com/en-us/virtualization/windowscontainers/quick-start/lift-shift-to-containers#what-cant-be-moved-to-windows-containers

- 지원되지 않는 응용프로그램/기능 : 데스크톱이 필요한 애플리케이션

- 지원되지 않는 이유 : 컨테이너가 GUI (Graphic User Interface) 를 지원하지 않음

- 이 문제를 해결할 수 있습니까? : 애플리케이션에서 GUI 만 설치하면 되는 경우 자동 설치로 변경하는 것이 해결책이 될 수 있습니다.

- 지원되지 않는 응용프로그램/기능 : RDP(Remote Desktop Protocol)를 사용하는 응용프로그램

- 지원되지 않는 이유 : RDP는 대화형 세션을 위한 것이므로 위의 원칙이 여기서도 적용됩니다.

- 이 문제를 해결할 수 있습니까? : WAC(Windows Admin Center) 또는 Remote PowerShell을 원격 관리 대신 사용할 수 있습니다.

 

특정 버전에서 RDP 를 사용할 수 있는 방법이 있다고 하는데 이마저도 완벽히 동작하지는 않는듯 합니다.

https://withinrafael.com/2018/03/09/using-remote-desktop-services-in-containers/

 

마이크로소프트에서 공식적으로 컨테이너에서 RDP 는 제공하지 않는다고 하였고, 향후 계획도 없다고 하였으므로 컨테이너에 RDP 접속은 할 수 없는것으로 판단됩니다. 컨테이너 목적이 다르므로, 그래도 원격접속을 하고 싶을 경우 VM 을 이용하면 됩니다.

반응형

댓글()

개인 도커 레지스트리 (Docker Registry) 구축하기

반응형

Docker Registry 는 Docker 이미지를 업로드 하거나, 다운로드하여 컨테이너를 생성하는 등 이미지 저장소의 역할을 담당합니다. Docker Hub 와 같이 알려진 공개 Docker Registry 말고, 개인적으로 사용 가능한 Docker Registry 를 직접 만들어 보겠습니다.

보통은 Private Registry 라고 하며 Kubernetes 내에서 생성하고 사설 네트워크로 연결하도록 구성하지만, 여기에서는 별도의 단독 서버 1대 (공인IP) 로만 구성할 예정입니다. Registry 서버가 Kubernetes Cluster 와 동일한 스위치 내에 위치한다면 방화벽을 설치함으로써 Private Registry 과 같은 형태로 만들 수 있습니다. 이런 형태로 서비스에 적용할 예정이라면 스토리지 여러대로 GlusterFS 나 Ceph 를 구성하고 별도로 마운트하고 도커 서비스를 구동할 서버 1대로 구성하면 됩니다.

 

다시 말씀 드리면, 두가지 방식중 아래 방식으로 진행합니다.

- Kubernetes 설치, 스토리지 준비, PV 및 PVC 생성, Registry Pod 생성

- Docker 설치, Registry Container 생성

 

[환경 및 사전준비]

OS : Ubuntu 22.04

/data 디렉토리 생성 (로컬 호스트의 이미지 저장소)

 

 

1. SSL 인증서 생성

 

Registry 를 사용할때 파일을 업로드 하거나 다운로드 하게되는데, 이때 암호화 전송이 필요합니다.

(암호화 전송 없이 http 프로토콜을 사용하는 옵션도 있긴 합니다)

인증서가 없을 경우, Let's encrypt SSL 에서 무료 인증서를 발급받을 수 있습니다.

운영체제에 따라 인증서 발급 명령이 다르므로 아래 포스팅을 확인하여 자신의 운영체제에 맞는 명령을 참고하시기 바랍니다.

https://sysdocu.tistory.com/search/let's%20encrypt

 

발급 방법은 위 포스팅에 있으므로 여기에서는 생략하고 넘어가겠습니다.

이제 도메인 인증서를 생성하였고, 인증서를 master 서버의 /root/certs 디렉토리에 복사해 두었습니다.

- 도메인 : registry.az1.sysdocu.kr

- 인증서 파일 위치 : /opt/registry/certs/

 

 

2. Docker 설치

 

Registry 서비스는 Docker Registry 컨테이너를 이용할 것이기 때문에 Docker 패키지를 설치해야 합니다.

패키지 목록을 최신화하고 업그레이드 합니다.
# apt -y update

# apt -y upgrade
# apt -y install apt-transport-https ca-certificates curl gnupg lsb-release

Docker 공식 GPG 를 설치합니다.
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg |gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

Docker 공식 저장소를 추가합니다.
# echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" |tee /etc/apt/sources.list.d/docker.list > /dev/null

Docker 를 설치하고 확인합니다.

# apt -y update
# apt -y install docker-ce docker-ce-cli containerd.io
# docker --version

Docker version 24.0.6, build ed223bc

 

 

3. Registry 설치 및 가동

 

Docker Hub 에서 Docker Registry 최신버전 이미지를 다운로드 합니다.
# docker pull registry:latest
latest: Pulling from library/registry
7264a8db6415: Pull complete 
c4d48a809fc2: Pull complete 
88b450dec42e: Pull complete 
121f958bea53: Pull complete 
7417fa3c6d92: Pull complete 
Digest: sha256:d5f2fb0940fe9371b6b026b9b66ad08d8ab7b0d56b6ee8d5c71cb9b45a374307
Status: Downloaded newer image for registry:latest
docker.io/library/registry:latest

 

다운로드 된 이미지를 확인합니다.

# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
registry     latest    0030ba3d620c   3 weeks ago   24.1MB

 

Registry 에 접근할 사용자를 생성합니다.

사용자 생성 방식은 htpasswd 를 이용하였습니다.

# apt -y install apache2-utils

# mkdir -p /opt/registry/auth

# htpasswd -c -b -B /opt/registry/auth/htpasswd sysdocu 12345678
Adding password for user sysdocu

 
이제 Registry Docker 이미지, SSL 인증서, 사용자 계정이 준비되었습니다.

컨테이너를 다음과 같은 명령으로 가동합니다.
# docker run --name MyRegistry --restart=always -p 5000:5000 \
    -v /opt/registry/auth:/auth \
    -v /opt/registry/certs:/certs \
    -v /data:/var/lib/registry \
    -e "REGISTRY_AUTH=htpasswd" \
    -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
    -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
    -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/fullchain1.pem \
    -e REGISTRY_HTTP_TLS_KEY=/certs/privkey1.pem \
    -e REGISTRY_COMPATIBILITY_SCHEMA1_ENABLED=true \
    -d registry

* 참고

-v: command not found, -e: command not found 등의 에러 출력시 행 사이에 줄이 떨어져 있는 것이므로 메모장에 기입해 빈 행을 없애거나 역슬래시를 제거하여 한줄 명령으로 사용하면 됩니다.

 

* 설명

--name MyRegistry : 실행되는 컨테이너의 이름을 MyRegistry 로 설정합니다.
--restart=always : 컨테이너가 종료되거나 실패할 경우 자동으로 다시 시작하도록 설정합니다.

-p 5000:5000 : 호스트의 포트 5000 과 컨테이너의 포트 5000 을 연결하여 Registry 에 엑세스할 수 있게 합니다.

-v /opt/registry/auth:/auth : 호스트의 /opt/registry/auth 디렉토리와 컨테이너 내의 /auth 디렉토리를 볼륨 마운트합니다. 이 디렉토리는 사용자 인증 정보를 저장하기 위한 것으로, htpasswd 형식의 사용자 인증 파일이 여기에 저장됩니다.
-v /opt/registry/certs:/certs : 호스트의 /opt/registry/certs 디렉토리와 컨테이너 내의 /certs 디렉토리를 볼륨 마운트합니다. 이 디렉토리에는 TLS (SSL) 인증서 및 키 파일이 저장됩니다.
-v /data:/var/lib/registry : 호스트의 /data 디렉토리와 컨테이너 내의 /var/lib/registry 디렉토리를 볼륨 마운트합니다. 여기에는 레지스트리의 이미지 데이터가 저장됩니다.

-e "REGISTRY_AUTH=htpasswd" : 환경 변수를 설정하여 레지스트리가 htpasswd 형식의 사용자 인증을 사용하도록 합니다.
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" : htpasswd 형식의 사용자 인증을 위한 Realm 을 설정합니다.
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd : 사용자 인증 정보를 저장하는 htpasswd 파일의 경로를 지정합니다.
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/fullchain1.pem : TLS (SSL) 인증서 파일의 경로를 설정합니다.
-e REGISTRY_HTTP_TLS_KEY=/certs/privkey1.pem : TLS (SSL) 인증서의 개인 키 파일의 경로를 설정합니다.
-e REGISTRY_COMPATIBILITY_SCHEMA1_ENABLED=true : Docker Registry v2의 호환성을 유지하고 Docker v1/v1 API를 사용할 수 있도록 활성화합니다.
-d registry : 컨테이너를 백그라운드에서 실행하도록 설정하고, 다운로드 받아놓은 registry 라는 Docker Image 를 사용하여 컨테이너를 시작합니다.

 

구동된 컨테이너를 확인합니다.

# docker ps
CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS         PORTS                                       NAMES
f246853edd47   registry   "/entrypoint.sh /etc…"   6 seconds ago   Up 5 seconds   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   MyRegistry

 

포트도 5000 번으로 정상적으로 열린것이 확인되었습니다.

# netstat -nltp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      23260/systemd-resol 
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN      54372/docker-proxy  
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      18912/sshd: /usr/sb 
tcp6       0      0 :::5000                 :::*                    LISTEN      54379/docker-proxy  
tcp6       0      0 :::22                   :::*                    LISTEN      18912/sshd: /usr/sb 

 

만들어진 Registry 컨테이너로 로그인을 해봅니다.

계정은 위에서 htpasswd 로 생성했던 계정입니다.

# docker login -u sysdocu -p 12345678 https://registry.az1.sysdocu.kr:5000
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

 

로그인 성공하여 접근 허용이 되었으면, Registry 이미지 리스트를 확인합니다.

업로드한 이미지가 없기때문에 아직은 아무것도 출력되지 않습니다.

# curl -u sysdocu:12345678 https://registry.az1.sysdocu.kr:5000/v2/_catalog
{"repositories":[]}

 

여기까지 Registry 구축이 완료되었습니다.

아래는 다른 서버에서 Registry 를 사용하는 방법입니다.

 

 

4. 이미지 업로드 및 컨테이너 생성

 

두가지 방법이 있는데, 여기에서는 기본 컨테이너에서 내용을 변경해보는 아래 방식으로 진행합니다.

- Docker Hub 이미지 그대로 Registry 에 업로드

- Docker Hub 이미지를 받아서 수정하고 Registry 에 업로드

 

진행할 예제는 php:7.4-apache 기준으로 작성하였습니다.
우선 php:7.4-apache 이미지를 다운로드 합니다.

# docker pull docker.io/php:7.4-apache

 

테스트용으로 PHP 소스 파일을 만듭니다.

# mkdir ./source

# vi ./source/index.php

<?php
echo "Good job";
?>

 

Dockerfile 을 아래 내용으로 작성합니다.
# vi Dockerfile

FROM docker.io/php:7.4-apache
COPY ./source/ /var/www/html/
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf
CMD ["apache2-foreground"]

 

* 설명

FROM docker.io/php:7.4-apache : 기본 이미지를 지정하는 부분입니다. php2.4 와 apache 웹서버가 설치된 이미지 입니다.
COPY ./source/ /var/www/html/ : 호스트 시스템의 ./source/ 디렉토리의 내용을 컨테이너 내부의 /var/www/html/ 디렉토리로 복사하는 명령입니다. 

RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf : Apache 웹서버에 ServerName 옵션을 추가합니다.
CMD ["apache2-foreground"] : 컨테이너가 시작될 때 실행될 명령입니다. 여기에서는 Apache 웹 서버를 시작합니다.

 

만들어진 Dockerfile 을 사용하여 Docker 이미지를 새로 만듭니다.

형식) docker build --tag <새 이미지 이름> <Dockerfile 위치>

# docker build --tag php7.4-apache-update .

 

만들어진 새 이미지가 확인 되었습니다.

# docker images
REPOSITORY             TAG       IMAGE ID       CREATED          SIZE
php7.4-apache-update   latest    b36ddfe193e1   28 seconds ago   453MB
registry               latest    0030ba3d620c   3 weeks ago      24.1MB

 

이번에는 로컬에 만들어져 있는 php7.4-apache-update 이미지를 Registry 에 올려 보겠습니다.

업로드 권한이 필요하므로 생성했던 htpasswd 계정을 이용해 Registry 에 로그인을 합니다.

(아까 위에서 로그인 했을 경우 생략 가능)

# docker login -u sysdocu -p 12345678 https://registry.az1.sysdocu.kr:5000

 

태그 설정을 하고 업로드 합니다.

태그 이름은 로컬에 만들어놓은 이름 (php7.4-apache-update) 과 동일하게 하겠습니다.

그리고 sysdocu 라는 디렉토리로 이미지 용도를 구분 짓도록 하겠습니다.

# docker tag php7.4-apache-update registry.az1.sysdocu.kr:5000/sysdocu/php7.4-apache-update

# docker push registry.az1.sysdocu.kr:5000/sysdocu/php7.4-apache-update
Using default tag: latest
The push refers to repository [registry.az1.sysdocu.kr:5000/sysdocu/php7.4-apache-update]
61323a0752b4: Pushed 
3d4722dde23c: Pushed 
3d33242bf117: Pushed 
529016396883: Pushed 
5464bcc3f1c2: Pushed 
28192e867e79: Pushed 
d173e78df32e: Pushed 
0be1ec4fbfdc: Pushed 
30fa0c430434: Pushed 
a538c5a6e4e0: Pushed 
e5d40f64dcb4: Pushed 
44148371c697: Pushed 
797a7c0590e0: Pushed 
f60117696410: Pushed 
ec4a38999118: Pushed 
latest: digest: sha256:2a03e9c0ac98d726ec0f6707d4bd6265aec6de5b0aa3b982315b9eaae0b61123 size: 3449

 

Registry 컨테이너 가동시 지정했던 로컬 호스트 디렉토리 /data 에서 컨테이너에 올려진 데이터가 확인됩니다.

# ll /data/docker/registry/v2/repositories/sysdocu/php7.4-apache-update/
total 20
drwxr-xr-x 5 root root 4096 Sep  6 02:26 ./
drwxr-xr-x 3 root root 4096 Sep  6 02:26 ../
drwxr-xr-x 3 root root 4096 Sep  6 02:26 _layers/
drwxr-xr-x 4 root root 4096 Sep  6 02:26 _manifests/
drwxr-xr-x 2 root root 4096 Sep  6 02:26 _uploads/

 

이렇게도 확인이 됩니다.

아까는 빈 내용이였던 Registry 에 업로드한 이미지가 확인됩니다.

# curl -u sysdocu:12345678 https://registry.az1.sysdocu.kr:5000/v2/_catalog
{"repositories":["sysdocu/php7.4-apache-update"]}

 

이제 업로드 된 이미지를 활용하여 애플리케이션을 구동할 수 있습니다.

방법은 두가지 형식이 있으며 여기에서는 간단히 Docker 컨테이너로 생성해 보겠습니다.

- Kubernetes (Openshift, K-PaaS 등) 에서 Pod 생성, Service 생성

- Docker 에서 컨테이너 생성

# docker run -d -p 80:80 registry.az1.sysdocu.kr:5000/sysdocu/php7.4-apache-update

 

* 설명
-d : 컨테이너를 백그라운드에서 실행합니다.
-p 80:80 : 호스트의 포트 80 을 컨테이너의 포트 80 으로 매핑합니다. 즉, 웹 서버가 동작하는 포트에 접근할 수 있게 됩니다.
registry.az1.sysdocu.kr:5000/sysdocu/php7.4-apache-update : 실행할 Docker 이미지를 지정합니다.

 

컨테이너가 실행되면 웹 서버가 시작되어 호스트의 IP 또는 도메인과 80 번 포트로 웹서버에 접속할 수 있게 됩니다.

# curl http://registry.az1.sysdocu.kr

Good job

 

반응형

댓글()

Kubernetes 1.28 에서 MetalLB 설치하기

반응형

MetalLB 를 설치하면 LoadBalancer 를 사용할 수 있는데, 이는 외부에서 접근하는 공인 IP 를 Pod 에 부여함으로써 온전히 애플리케이션의 포트를 NodePort (30000~32767) 와 같이 임의 포트가 아닌 공식 표준 포트를 사용할 수 있게 됩니다.

아래 예제의 Kubernetes 환경은 1.28 버전이며, 모든 명령은 master (control-plane) 서버에서 진행하였습니다.

 

공식 홈페이지 Documents : https://metallb.universe.tf/installation/

 

 

1. kube-proxy 구성 편집

 

kube-proxy 를 사용하는 경우 ARP 모드를 사용해야 합니다.

아래 명령을 이용해 kube-proxy 구성을 편집합니다.

# kubectl edit configmap -n kube-system kube-proxy
configmap/kube-proxy edited

...
ipvs:
  strictARP: true
...

 

위 내용으로 저장합니다.

 

 

2. MetalLB 설치

 

MetalLB 컴포넌트 등을 하나의 파일로 설치합니다. 작성일 기준 최신 버전은 0.13.10 입니다.

# kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.10/config/manifests/metallb-native.yaml

 

MetalLB 관련 Pod 가 잘 생성되었는지 확인합니다.

Running 상태까지 되는데 시간이 소요될 수 있습니다. (모든 Pod 1/1)

# kubectl get pod -n metallb-system
NAME                          READY   STATUS    RESTARTS   AGE
controller-5c6b6c8447-4kzpl   1/1     Running   0          15m
speaker-6fxtx                 1/1     Running   0          15m
speaker-7gg7s                 1/1     Running   0          15m
speaker-z284z                 1/1     Running   0          15m

 

 

3. IP Pool 생성

 

라우팅 처리를 하기위해 보유하고 있는 IP 리스트를 등록합니다.

Pod 에서 IP 를 사용할 수 있도록 상단 스위치단에서 IP 설정이 이루어져 있어야 합니다.

아래는 28비트 대역 2개를 추가해 보았습니다.

실제로 Pod 에 할당하려는 IP 범위를 적어줍니다.

# vi ippool.yaml

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  - 115.68.142.130-115.68.142.140
  - 115.68.142.146-115.68.142.156

 

IP 를 추가할때는 서브넷 마스크를 별도로 지정하지 않아도 주소 범위 내의 모든 IP 주소를 사용할 수 있도록 인식합니다. MetalLB 는 주소 범위를 기반으로 자동으로 서브넷 마스크를 계산하기 때문입니다.

작성한 yaml 파일을 적용합니다.

# kubectl apply -f ippool.yaml

ipaddresspool.metallb.io/first-pool created

 

* 에러 발생시 ----------

여기에서 다음과 같은 에러가 발생했을때 조치방법 입니다.

Error from server (InternalError): error when creating "ippool.yaml": Internal error occurred: failed calling webhook "ipaddresspoolvalidationwebhook.metallb.io": failed to call webhook: Post "https://webhook-service.metallb-system.svc:443/validate-metallb-io-v1beta1-ipaddresspool?timeout=10s": dial tcp 10.102.110.54:443: connect: connection refused

 

이때는 아래와 같이 metallb-webhook-configuration 설정을 삭제하고 다시 실행해 보세요.

# kubectl delete validatingwebhookconfigurations metallb-webhook-configuration
validatingwebhookconfiguration.admissionregistration.k8s.io "metallb-webhook-configuration" deleted

----------------------------

 

L2 네트워크를 생성하고 적용합니다.

# vi l2.yaml

apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: my-l2
  namespace: metallb-system
spec:
  ipAddressPools:
  - first-pool

 

# kubectl apply -f l2.yaml

l2advertisement.metallb.io/my-l2 created

 

 

4. 테스트 (Pod 생성 및 IP 연결)

 

테스트를 위해 Nginx Pod 를 생성하고 공인 IP 를 할당하여 외부 통신이 되는지 확인합니다.

# kubectl create deploy nginx --image=nginx

deployment.apps/nginx created

 

# kubectl expose deploy nginx --port 80 --type LoadBalancer

service/nginx exposed

 

# kubectl get services
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1       <none>           443/TCP        3d
nginx        LoadBalancer   10.111.72.120   115.68.142.130   80:32088/TCP   20m

 

Kubernetes Cluster 외부의 네트워크에서 출력된 IP 로 접근하여 Nginx 가 열리는지 확인합니다.

# curl http://115.68.142.130

 

반응형

댓글()

Kubernetes 1.28 에서 worker 노드 제거 및 추가하기

반응형

1. 노드 제거하기

 

시스템 장애 또는 OS 재설치 등의 이유로 worker 노드 하나를 제거해야 할 수 있습니다.

제거하기 전의 Cluster 상태는 아래와 같습니다.

 

# kubectl get nodes
NAME      STATUS                     ROLES           AGE     VERSION
master    Ready                      control-plane   2d22h   v1.28.1
worker1   Ready                      <none>          2d22h   v1.28.1
worker2   Ready                      <none>          2d22h   v1.28.1

 

worker2 노드를 Kubernetes 클러스터에서 제거하고 다시 연결하는 프로세스는 다음과 같이 진행할 수 있습니다.
주의할 점이 하나 있는데, 노드를 클러스터에서 제거하면 해당 노드에서 실행 중인 모든 컨테이너와 Pod가 중지됩니다.

먼저 worker2 노드에서 실행 중인 Pod 를 다른 노드로 옮기거나 제거해야 합니다.

이 명령어는 worker2 노드에서 실행 중인 Pod 를 다른 노드로 옮기고, DaemonSet Pod 는 무시합니다.

# kubectl drain worker2 --ignore-daemonsets

node/worker2 cordoned
Warning: ignoring DaemonSet-managed Pods: kube-system/kube-proxy-8tqss
node/worker2 drained

 

이 상태로 node 리스트를 확인해보면, 해당 노드에 스케쥴링이 비활성화 된 것이 보입니다.

# kubectl get nodes
NAME      STATUS                     ROLES           AGE     VERSION
master    Ready                      control-plane   2d22h   v1.28.1
worker1   Ready                      <none>          2d22h   v1.28.1
worker2   Ready,SchedulingDisabled   <none>          2d22h   v1.28.1

 

worker2 노드를 클러스터 목록에서 제거합니다.
# kubectl delete node worker2

# kubectl get nodes
NAME      STATUS   ROLES           AGE     VERSION
master    Ready    control-plane   2d22h   v1.28.1
worker1   Ready    <none>          2d22h   v1.28.1

 

 

2. 노드 추가하기

 

worker2 노드를 다시 클러스터에 추가하려면 해당 노드를 다시 등록해야 합니다.

OS 를 재설치 한 경우 worker 노드의 환경 구성은 아래 URL 을 참고합니다.

https://sysdocu.tistory.com/1851

 

worker 노드 준비가 되었으면 master 서버에서 토큰 생성과 함께 join 명령을 출력합니다.

생성된 토큰의 유효 시간은 1일 (24시간) 이며, --ttl 1h 이런 옵션을 줄 경우 토큰 유효 시간을 지정할 수 있습니다.

(master 노드에서)

# kubeadm token create --print-join-command
kubeadm join 115.68.142.104:6443 --token pa3e56.88nw5c48vmbyr522 --discovery-token-ca-cert-hash sha256:82020f205bd07cd7b964a40227f33db5109adc523f042e742d7c6ec8443efbdc

 

(worker2 노드에서)

master 노드에서 출력된 명령줄을 실행합니다.

# kubeadm join 115.68.142.104:6443 --token pa3e56.88nw5c48vmbyr522 --discovery-token-ca-cert-hash sha256:82020f205bd07cd7b964a40227f33db5109adc523f042e742d7c6ec8443efbdc

 

추가된 worker2 노드를 확인합니다.

(master 노드에서)

# kubectl get nodes
NAME      STATUS   ROLES           AGE     VERSION
master    Ready    control-plane   2d23h   v1.28.1
worker1   Ready    <none>          2d23h   v1.28.1
worker2   Ready    <none>          3m44s   v1.28.1

 

* 에러 조치

master 서버에서 Pod 생성시 에러가 발생한다면 추가한 worker 노드에서 다음과 같이 조치 가능합니다.

 

[ 에러 ]

Events:
  Type     Reason                  Age                   From               Message
  ----     ------                  ----                  ----               -------
  Normal   Scheduled               37m                   default-scheduler  Successfully assigned ceph-csi-rbd/ceph-csi-rbd-nodeplugin-n9b2v to worker3
  Warning  FailedCreatePodSandBox  31m (x26 over 37m)    kubelet            Failed to create pod sandbox: rpc error: code = Unknown desc = cri-o configured with cgroupfs cgroup manager, but received systemd slice as parent: /kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-podd3fc3e78_f49c_4239_b271_55e406fd0b76.slice

 

[ 해결 ]

아래 kubelet 설정 파일에서 cgroup driver 를 바꿔줍니다.

(추가된 worker 노드에서)

# vi /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf

...

Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml --cgroup-driver=cgroupfs"
...

 

# systemctl daemon-reload
# systemctl restart kubelet

 

반응형

댓글()

Ubuntu 22.04 netplan 설정하기

리눅스/Network|2023. 9. 4. 13:50
반응형

Ubuntu 22.04 에서는 netplan 이 업데이트 되어 설정법이 약간 바뀌었습니다.

네트워크 설정 파일을 생성 합니다.

# vi /etc/netplan/50-cloud-init.yaml 

network:
  version: 2
  ethernets:
    eno1:
      addresses: [ 115.68.142.104/27 ]
      routes:
        - to: default
          via: 115.68.142.97
      nameservers:
        addresses: [ 8.8.8.8 ]

 

* 설명

eno1 : 네트워크 장치명입니다. 명칭을 모를경우 ip link 명령으로 확인이 가능합니다.

addresses : 비트수까지 기록해줘야 합니다. netmask 를 입력하는 곳이 없기 때문입니다.

routes: via : 게이트웨이 IP 를 입력합니다.

nameservers: addresses : 네임서버 IP 를 입력합니다.

 

설정을 적용합니다.

# netplan apply

 

 

 

 

 

 

 

반응형

댓글()