NCP

NKS-Linuxer-Blog-trouble-shooting-lifecycle-not-working

블로그를 이전한지 얼마안됬기 때문에 집중모니터링 기간이다.
먼저 자원부터 본다.

k top node
NAME                  CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
nks-pool-1119-w-gzi   223m         5%     1265Mi          16%       
nks-pool-1119-w-kvi   172m         4%     1540Mi          20%       

k top pod
NAME                                             CPU(cores)   MEMORY(bytes)   
php-fpm-nginx-deployment-6bc7b6df77-fbdx9        9m           138Mi           
storage-nfs-client-provisioner-5b88c7c55-dvtlj   2m           8Mi             

자원은 얼마안쓰지만..혹시나 사용량이 늘어날까봐 scale을 늘렸다.

k scale deployment php-fpm-nginx-deployment --replicas=3
deployment.apps/php-fpm-nginx-deployment scaled

그리고 pod 를 확인했는데...

k get pod
NAME                                             READY   STATUS              RESTARTS   AGE
php-fpm-nginx-deployment-6bc7b6df77-bpf2g        2/2     Running             0          19s
php-fpm-nginx-deployment-6bc7b6df77-fbdx9        2/2     Running             3          32h
php-fpm-nginx-deployment-6bc7b6df77-rfpb2        0/2     ContainerCreating   0          19s
storage-nfs-client-provisioner-5b88c7c55-dvtlj   1/1     Running             0          10h

생성단계에서 멈춘 pod 가 있었다. 상태를 확인해보니

Events:
  Type     Reason               Age        From                          Message
  ----     ------               ----       ----                          -------
  Normal   Scheduled            <unknown>  default-scheduler             Successfully assigned default/php-fpm-nginx-deployment-6bc7b6df77-rfpb2 to nks-pool-1119-w-gzi
  Normal   Pulled               28s        kubelet, nks-pool-1119-w-gzi  Container image "linuxer-regi.kr.ncr.ntruss.com/php-fpm:12" already present on machine
  Normal   Created              28s        kubelet, nks-pool-1119-w-gzi  Created container php-fpm
  Normal   Started              28s        kubelet, nks-pool-1119-w-gzi  Started container php-fpm
  Normal   Pulled               28s        kubelet, nks-pool-1119-w-gzi  Container image "nginx:1.21" already present on machine
  Normal   Created              28s        kubelet, nks-pool-1119-w-gzi  Created container nginx
  Normal   Started              28s        kubelet, nks-pool-1119-w-gzi  Started container nginx
  Warning  FailedPostStartHook  28s        kubelet, nks-pool-1119-w-gzi  Exec lifecycle hook ([/bin/sh -c chmod 777 /run/php-fpm.sock]) for Container "nginx" in Pod "php-fpm-nginx-deployment-6bc7b6df77-rfpb2_default(6978da29-8045-49a0-9745-6be3cc48c364)" failed - error: command '/bin/sh -c chmod 777 /run/php-fpm.sock' exited with 1: chmod: cannot access '/run/php-fpm.sock': No such file or directory

Exec lifecycle hook ([/bin/sh -c chmod 777 /run/php-fpm.sock]) for Container "nginx" in Pod "php-fpm-nginx-deployment-6bc7b6df77-rfpb2_default(6978da29-8045-49a0-9745-6be3cc48c364)" failed - error: command '/bin/sh -c chmod 777 /run/php-fpm.sock' exited with 1: chmod: cannot access '/run/php-fpm.sock': No such file or directory

lifecycle hook 이 정상동작하지 않았다. 음...이벤트상으론 컨테이너가 생성전에 hook이 동작한건데 이건좀 확인해봐야겠다.

조금있다가 컨테이너가 자동으로 재시작되며 Runing 상태로 변경됬다.

k logs php-fpm-nginx-deployment-6bc7b6df77-rfpb2 -c nginx 
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: can not modify /etc/nginx/conf.d/default.conf (read-only file system?)
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/09/02 00:30:55 [notice] 1#1: using the "epoll" event method
2021/09/02 00:30:55 [notice] 1#1: nginx/1.21.1
2021/09/02 00:30:55 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6) 
2021/09/02 00:30:55 [notice] 1#1: OS: Linux 5.4.8-050408-generic
2021/09/02 00:30:55 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2021/09/02 00:30:55 [notice] 1#1: start worker processes
2021/09/02 00:30:55 [notice] 1#1: start worker process 22
2021/09/02 00:30:55 [notice] 1#1: start worker process 23
2021/09/02 00:30:55 [notice] 1#1: start worker process 24
2021/09/02 00:30:55 [notice] 1#1: start worker process 25

logs 도 정상...음...일단 로깅을 모아보고 생각해야겠다.

NKS-Linuxer-Blog-Rebuilding

블로그를 새로 만들기로 했다.

https://linuxer.name/2020/02/aws-linuxer의-블로그-톺아보기

2020년 2월에 완성된 블로그의 구조이니..이걸 우려먹은지도 벌써 1년이 훌쩍넘어다는 이야기다. 블로그를 좀더 가볍고 편한구조로 변경하려고 고민했으나..나는 실패했다.ㅠㅠ

능력이나 뭐 그런 이야기가 아니라..게으름에 진거다. 게으름에 이기기 위해서 글을 시작했다.

목적은 K8S 에 새로 만들기고, K8S의 특성을 가져가고 싶었다.

제일먼저 작업한것은 Wordpess 의 근간이 되는 PHP 다.

PHP는 도커파일을 먼저 작성했다.

FROM php:7.4-fpm

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
                           libpng-dev \
                           libzip-dev \
                           libicu-dev \
                           libzip4 \
        && pecl install xdebug \
        && docker-php-ext-install opcache \
    && docker-php-ext-enable xdebug \
        && docker-php-ext-install pdo_mysql \
        && docker-php-ext-install exif \
        && docker-php-ext-install zip \
        && docker-php-ext-install gd \
        && docker-php-ext-install intl \
        && docker-php-ext-install mysqli

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

WORKDIR /srv/app
RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini
RUN echo "date.timezone=Asia/Seoul" >> /usr/local/etc/php/php.ini
RUN sed -i --follow-symlinks 's|127.0.0.1:9000|/run/php-fpm.sock|g' /usr/local/etc/php-fpm.d/www.conf
RUN sed -i --follow-symlinks 's|short_open_tag = Off|short_open_tag = On|g' /usr/local/etc/php/php.ini
RUN sed -i --follow-symlinks 's|9000|/run/php-fpm.sock|g' /usr/local/etc/php-fpm.d/zz-docker.conf
CMD ["php-fpm"]

몇가지 수정사항이 있었는데 먼저 tcp socket를 사용하지 않고, unix socket을 사용했다. 흔하게 file socket이라고도 하는데 nginx <-> php-fpm 의 socket 통신의 속도가 상승한다. nginx와 php-fpm이 같은 서버내에 있을때 사용할수 있는 방법이다.
또 zz-docker.conf 는 php 이미지에서 ext를 설치할때 docker 패키지를 사용하면설치되는데 이 conf파일안에 unix 소켓을 사용할수 없도록 만드는 설정이 있다.

[global]
daemonize = no

[www]
listen = 9000

위설정이 바로 그 설정이다 listen = 9000 이 fix로 박히게 되는데 이걸 수정해주지 않으면 www.conf를 아무리 수정해도 unix socket을 사용할수 없다. 변경하고 빌드는 정상적으로 됬다.

빌드후 push는 NCP 의 Container Registry 서비스를 이용했다. docker login 할때 sub account 의 access key 와 secret key를 생성해서 사용했다.

docker build -t linuxer-cr/php-fpm:12 ./
docker push linuxer-cr/php-fpm:12

12번에 걸쳐서 빌드 테스트를 진행했다. centos 이미지였다면 쉬웠을껀데ㅠㅠ그냥 있는 이미지 써본다고 고생했다. 빌드가 완료된 php-fpm을 deployment 로 배포했다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: php-fpm-nginx-deployment
spec:
  selector:
    matchLabels:
      app: php-fpm-nginx
  template:
    metadata:
      labels:
        app: php-fpm-nginx
    spec:
      imagePullSecrets:
      - name: regcred
      containers:
      - name: php-fpm
        image: linuxer-rc/php-fpm:12
        volumeMounts:
        - name: vol-sock
          mountPath: /run
        - name: www
          mountPath: /usr/share/nginx/html
      - name: nginx
        image: nginx:1.21
        lifecycle:
          postStart:
            exec:
              command: ["/bin/sh", "-c", "chmod 777 /run/php-fpm.sock"]
        volumeMounts:
        - name: vol-sock
          mountPath: /run
        - name: nginx-config-volume
          mountPath: /etc/nginx/conf.d/default.conf
          subPath: default.conf
        - name: www
          mountPath: /usr/share/nginx/html

      volumes:
      - name: vol-sock
        emptyDir:
          medium: Memory
      - name: nginx-config-volume
        configMap:
          name: nginx-config
      - name: html
        emptyDir: {}
      - name: www
        persistentVolumeClaim:
          claimName: nfs-pvc

위의 manifest 는 완성된 버전이다. 특이한 부분을 말하자면 몇가지가 있는데,

첫번째로 nignx pod 와 php-fpm container의 unix socket 을 공유하는 부분이다.
emptyDir: medium:Memory 로 지정하면 메모리를 emptydir 로 사용한다 원래 컨셉은 shm 을 hostpath로 이용하여 마운트해서 사용하려했는데 편리한 방법으로 지원해서 사용해봤다. 일반 디스크에 unix socket를 사용하는것보다 속도가 빠를것이라 예상한다
벤치를 돌려보기엔 너무 귀찮았다.

두번째로 lifecycle: postStart다. nginx 프로세스가 시작하면서 소켓을 생성하기에 권한부족으로 정상적으로 php-fpm과 통신이 되지 않았다. 그래서 lifecycle hook을 이용하여 컨테이너가 모두 생성된 이후에 cmd 를 실행하도록 설정하였다.

세번째로 여러개의 파드에서 같은 데이터를 써야하므로 고민을 했다.
NFS-Server pod 를 생성하여 내부에서 NFS-Server를 이용한 데이터를 공유하느냐, 아니면 NAS서비스를 이용하여 NFS Client provisioner 를 이용할것인가. 고민은 금방 끝났다.
편한거 쓰자! NAS를 사용했다.

NAS 서비스를 확인하고,

#프로비저너 설치
helm --kubeconfig=$KUBE_CONFIG install storage stable/nfs-client-provisioner --set nfs.server=169.254.82.85 --set nfs.path=/n2638326_222222

#프로비저너 설치확인
k get pod storage-nfs-client-provisioner-5b88c7c55-dvtlj 
NAME                                             READY   STATUS    RESTARTS   AGE
storage-nfs-client-provisioner-5b88c7c55-dvtlj   1/1     Running   0          33m

#nfs-pvc 설치
cat << EOF | k apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: nfs-client
EOF

볼륨까지 프로비저닝했다.

그리고 네번째 nginx-config 다 configmap 으로 만들어져서 /etc/nginx/conf.d/default.conf 경로에 subpath 로 파일로 마운트된다.

cat << EOF | k apply -f -
kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-config
data:
  default.conf: |
    server {
    root   /usr/share/nginx/html;
    listen       80;
    server_name  _;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
    index index.php;
    try_files \$uri \$uri/ /index.php?\$args;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location ~ [^/]\.php(/|$) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        fastcgi_pass unix:/run/php-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param REQUEST_METHOD \$request_method;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
    }
    }
EOF

나는 대다수의 manifest를 shell 에서 그대로 적용해버리기때문에 $request_method 이런 변수가 있는 부분은 \$request_method 역슬러시를 넣어서 평문 처리를해줬다.

이 nginx conf configmaps 에서 특이점은 try_files \$uri \$uri/ /index.php?\$args; 부분이다. 이부분이 빠지면 wordpress 의 주소형식을 사용할수 없어 페이지 이동이 되지 않는다.

이제 이 모든과정이 php-fpm-nginx-deployment 를 정상적으로 동작하게 하기위한 과정이었다.

이제 데이터를 AWS 에 있는 EC2 에서 가져왔다.

그냥 귀찮아서 bastion host에서 rsync 로 sync 했다.

#NFS mount
mount -t nfs nasserverip/마운트정보 /mnt
#pod 가 마운트된 pvc로 다이렉트로 sync
rsync root@aws-ec2-ip:/wordpressdir /mnt/default-nfs-pvc-pvc-d04852d6-b138-40be-8fc3-150894a3daac

이렇게 하니 단순 expose 만으로도 1차적으로 사이트가 떴다.

NPLB(Network Proxy Load Balancer) -> nginx-php-fpm POD -> AWS RDS

이런구성으로 돌고있었기에 DB를 옮겨왔다.

#mysqldump
mysqldump -h rdsendpoint -u linxuer -p linuxer_blog > linuxerblog.sql
#sync
rsync root@aws-ec2-ip:/linuxerblog.sql /home/

테스트용도로 사용할 CDB

mysql -h cdb-endpoint -u -p linuxer_blog < linuxerblog.sql

디비 복구후 wp-config 에서 define('DB_HOST') 를 CDB로 변경했다. 기나긴 트러블 슈팅의 기간이 끝나가고 있었다.

잘될줄 알았는데, 그건 저 혼자만의 생각이었습니다.

처음부터 SSL은 절대 처리하지 않을것이라 생각했건만...이렇게 된거 Let's encrypt로 간다!

#certbot install
yum install certbot certbot-plagin-route53

#route53이용한 인증
certbot certonly \
  --dns-route53 \
  -d linuxer.name \
  -d *.linuxer.name

인증서에 root ca 가 포함되어있지 않기 때문에 root ca를 서버의 번들 인증서에서 삽입해 줘야한다.

openssl pkcs7 -inform der -in dstrootcax3.p7c -out dstrootcax3.pem -print_certs
cp fullchain.pem fullca.pem
cat dstrootcax3.pem >> fullca.pem
openssl verify -CAfile fullca.pem cert.pem
cert.pem: OK

이렇게 하면 이제 private key, public key, root ca chain 해서 Certificate Manager에 인증서가 등록이 가능하다. 여기에 잘 등록하면,

이렇게 인증서를 등록할수 있다. 인증서의 발급기관은 R3로 뜬다.

이제 드디어 ingress 를 만들 준비가 되었다. ingress 를 만들기 위해 먼저 svc가 필요하다.

k expose deployment php-fpm-nginx-deployment --type=NodePort --port=80 --target-port=80 --name=php-fpm-nginx-deployment

k get svc
NAME                           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
php-fpm-nginx-deployment-svc   NodePort    198.19.196.141   <none>        80:30051/TCP   24h

정상적으로 만들어 진게 확인되면,

cat << EOF | k apply -f -
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80},{"HTTPS":443}]'
    alb.ingress.kubernetes.io/ssl-certificate-no: "----"
    alb.ingress.kubernetes.io/actions.ssl-redirect: |
      {"type":"redirection","redirection":{"port": "443","protocol":"HTTPS","statusCode":301}}
  labels:
    linuxer: blog
  name: slinuxer-blog-ingress
spec:
  backend:
    serviceName: php-fpm-nginx-deployment-svc
    servicePort: 80
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: ssl-redirect
          servicePort: use-annotation
      - path: /*
        backend:
          serviceName: my-service
          servicePort: 80
EOF

대망의 ingress다. ALB 컨트롤러를 이용해 ingress를 생성하고 컨트롤한다.alb.ingress.kubernetes.io/ssl-certificate-no: "----" 이부분은 Resource Manager에서 NRN을 확인하자.

이후 내블로그를 NKS로 완벽하게 이전을 마치고 앞으로의 K8S의 테스트 환경이 될 모르모트로 완성되었다.

이이후 Route53에서 DNS를 돌리고 자원을 하나씩 중지했다.

입사후 긴시간 동안 마음만 먹었던 프로젝트를 끝내서 너무 속이 시원하다.

이제 NKS위에서 전보다 나은 퍼포먼스를 보여줄 LINUXER BLOG를 응원해 주시라!

즐거운 밤이 되시길 빈다.

terraform-provider-ncloud-review

오늘 하시코프x네이버클라우드 웨비나에서 terraform 과 Vault 에 대한 웨비나를 청취했습니다.

https://github.com/NaverCloudPlatform/terraform-provider-ncloud

이전에 방과후(?) meetup에서 네이버클라우드가 테라폼의 프로바이더로 있다는것을 알았습니다. 그 덕분에 네이버클라우드에서 terraform은 이미 경험이 있는 상태고, Vault도 경험이 있었습니다. 오늘의 주제 중 Secrets Engines이 궁금했습니다.

https://www.vaultproject.io/docs/secrets

Secrets engines are components which store, generate, or encrypt data.

시크릿엔진은 데이터를 저장또는 생성하고 암호화하는 구성요소.

AWS 의 Parameter Store / Secrets Manager 와 비슷한 기능을 한다고 생각이 들었습니다. 다른 벤더에서도 비슷한 서비스들이 있습니다.

https://hackernoon.com/aws-secrets-manager-vs-hashicorp-vault-vs-aws-parameter-store-bcbf60b0c0d1

https://www.cloudjourney.io/articles/security/aws_secrets_manager_vs_hashi_vault-su/

가장 일반적인 사용예라 생각되는것은, access key의 암호화라 생각됩니다. 일반적으로 aws-vault 같은 명령어로 지원합니다.

아직 ncp-vault 가 만들어진게 아니라, ncp 내에서 사용하기엔 좀 불편한 부분이 있으리라 생각됩니다. 현재 npc 는 provider로 등록된 상태고 cli 를 지원하므로 차차 지원하리라 생각됩니다.

https://www.44bits.io/ko/post/securing-aws-credentials-with-aws-vault#%ED%85%8C%EB%9D%BC%ED%8F%BCterraform%EC%97%90%EC%84%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0

aws 에서의 vault 사용예입니다.

https://www.vaultproject.io/docs/secrets/databases/mysql-maria

mysql-maria db의 user 암호화입니다.

이런 방법이 필요한 이유는 결국 어플리케이션 소스의 탈취로 문제를 방지하기 위함입니다. key의 자동로테이션이나, expire time 을가진 key 발급등을 할 수 있습니다.

Vault 는 근래에 들어서 굉장히 핫한 오픈소스라 테스트 해보시는게 좋을것 같습니다.

마무리를 하자면..

템플릿 소스들이 점점 쌓이고 사용예가 늘면 IaC는 점점 더 일반화 될것입니다.

미리미리 IaC를 준비하고 사용방법을 익히는것도 좋을것 같습니다.

조만간 Secrets Engines 사용하기 위해 자동화 스크립트를 적용하는 고민을 한번 해보려 합니다. 시간이 나면 한번 테스트 해봐야겠습니다.

읽어주셔서 감사합니다!

NCP-to-AWS-IPsec-multi-Cloud

NCP와 AWS 의 IPsec VPN을 연결해 보았습니다. Site to Site VPN을 연결하는 것입니다.

아직 NCP에서는 VPC 모드에서 IPsec VPN을 지원하지 않아서 Classic 모드에서 만 연결이 가능합니다.

NCP IPsec VPN Gateway 를 먼저 만들어야 AWS Customer Gateway 를 생성할수 있습니다.

NCP IPsec VPN Gateway 를 생성하기 위해선 Private Subnet 을 먼저 생성해야 합니다.
저는 192.168.1.0/24 로 생성했습니다.

Encryption : aes


D-H Group 은 NCP 에선 1/2/5만 지원합니다.

hash 는 sha 입니다.

확인 버튼을 누르면 생성됩니다.

확인된 IP는 49.236.139.115 입니다. 이 IP를 Customer Gateway에서 사용하시면 됩니다.

다음과 같이 CGW를 만들어 줍니다. 그다음 VGW를 생성해 줘야 합니다.
Virtual Private Gateway 는 VPC 에 붙이는 가상의 게이트 웨이로 CGW- tunnel -VGW 구성으로 통신하게 됩니다.

VGW는 생성하면 VPC에 Attach 해야 합니다.

VPN으로 사용하려는 VPC에 연결해 주세요.

이제 터널을 생성해야 합니다.

Site to Site VPN 메뉴에서 터널을 생성하면 됩니다.

미리 생성한 VPG와 CGW를 잘 넣어주시고 라우팅 옵션을 static 으로 설정합니다. BGP는 지원하지 않습니다.

정적라우팅 대역을 미리 추가해 주는게 편합니다.
Local IPv4 Network Cidr 는 NCP의 대역을 넣어주셔야 합니다.
Remote IPv4 Network Cidr cidr은 AWS 의 대역입니다.

Edit Tunnel 1 Options 을 체크해서 터널 옵션을 넣어줍니다.

Pre-Shared Key for Tunnel 1 에서 key 라고 표기하지만 VPN 인증시에 사용하는 값이라 패스워드처럼 취급되기도 하므로..저는 rkskekfk 로 설정했습니다.

위 옵션은 NCP IPsec VPN의 옵션에 맞춰서 체크한 옵션입니다. 모두 체크해도 문제는 없을듯합니다.

AWS는 DPD 옵션을 ikev2에서만 지원하므로 AWS VPN 자체에서 터널을 시작하는 기능은 NCP 와의 IPsec VPN 설정에선 사용할수 없는 설정입니다. 이유는 NCP의 IPsec VPN은 ikev1만 지원하기 때문입니다.

지금 설정에선 단일터널만 사용하려기에 tunnel 1만 설정해주려 합니다.

버튼눌러서 생성후엔 NCP의 IPsec VPN을 추가해야 합니다.

NCP 콘솔로 이동해서 AWS 의 터널 IP를 이용해서 터널링을 맺어줘야 합니다.

AWS 콘솔에서 VPN Tunnel Details 를 보면 Tunnel 1 의 IP를 확인할 수 있습니다.

이 아이피로 Peer IP로 사용해 연결할겁니다.

NCP 에서 Local Network 는 NCP의 Private Subnet Cidr입니다.

Remote Network 는 172.31.0.0/16 으로 AWS 의 네트워크 입니다.

위 이미지대로 선택해주세요.

사실 설명이 필요한 부분이 좀 있는데..과감히 생략합니다.
이유는 터널시작과 터널통신은 각각 인증방식을 사용하는데 이부분이 NCP는 나누어져서 설정하고 AWS 는 같이 설정합니다....그래서 그냥 따라서 해보시고 어려우면 댓글 남겨주세요.

생성하시면 굉장히 빠른속도로 생성됩니다. 아직 터널을 개시한 상태가 아니기 때문에 inactive 로 보일겁니다. 이때 터널의 상태를 확인할수 있는 방법이 있습니다.

메뉴에서

현재 상태를 확인할 수 있습니다.

인터페이스 / 라우팅 / IPsec VPN Tunnel 상태를 확인할수 있습니다.

There are no ipsec sas
There are no IKEv1 SAs

두줄의 메시지를 확인할수 있으며, 아직 터널이 UP상태가 아니기 때문입니다.

이제 인스턴스가 필요합니다.

네트워크 인터페이스에서 서버에 인터페이스를 붙이고 아이피를 부여해주세요.

다음과 같이 글로벌 비공인 IP와 추가한 Private Subnet IP가 보입니다.

인스턴스 내부에서 인터페이스를 설정해주세요.

cat <<EOF > /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
BOOTPROTO=static
ONBOOT=yes
#Private Subnet IP로 변경해주세요.
IPADDR=192.168.1.13
EOF
ifup eth1

이제 라우팅을 추가해야 합니다.

ip route add 172.31.0.0/16 via 192.168.1.1 dev eth1

추가 명령어 입니다.

 ip route del 172.31.0.0/16 via 192.168.1.1

라우팅을 잘못 넣게 되면 ip route del 명령어로 라우팅을 삭제할수 있습니다.
라우팅이 정상적으로 잘 연결되면 이제 AWS 에도 라우팅 테이블을 추가해야 합니다.

맨아랫 줄에 추가된 라우팅 테이블은 제일 먼저 만들었던 VGW 입니다.
이제 양방향으로 통신할 라우팅이 모두 만들어 졌고, 서로 통신할수 있도록 NCP 의 ASG와 AWS 의 SG를 열어주세요.

그리고 NCP의 인스턴스에서 ping 을 날려줍니다. AWS ikev1 은 DPD를 이용할수 없기 때문에 상태방에서 터널을 개시해야 합니다.

[root@s17596a9a6e6 ~]# ifconfig | grep inet
        inet 10.41.151.70  netmask 255.255.254.0  broadcast 10.41.151.255
        inet 192.168.1.13  netmask 255.255.255.0  broadcast 192.168.1.255
        inet 127.0.0.1  netmask 255.0.0.0
[root@s17596a9a6e6 ~]# ping 172.31.36.10
PING 172.31.36.10 (172.31.36.10) 56(84) bytes of data.
64 bytes from 172.31.36.10: icmp_seq=1 ttl=62 time=3.93 ms
64 bytes from 172.31.36.10: icmp_seq=2 ttl=62 time=3.45 ms
64 bytes from 172.31.36.10: icmp_seq=3 ttl=62 time=3.33 ms
64 bytes from 172.31.36.10: icmp_seq=4 ttl=62 time=3.44 ms

정상적으로 Site to Site VPN이 연결된것을 확인할수 있습니다.

이렇게 정상적으로 VPN이 연결 되면 AWS 콘솔에선 터널이 UP 상태가 되고,
NCP 콘솔에선 active 로 표시됩니다. 그리고 마지막으로 정상적으로 터널링이 맺어져서 통신이 되면 NCP 콘솔에서 아래와 같이 확인할수 있습니다.

KEv1 SAs:

Active SA: 1
Rekey SA: 0 (A tunnel will report 1 Active and 1 Rekey SA during rekey)
Total IKE SA: 1

1 IKE Peer: 3.34.211.29
Type : L2L Role : initiator
Rekey : no State : MM_ACTIVE
interface: outside
Crypto map tag: outside_map, seq num: 1, local addr: 49.236.139.115

access-list outside_cryptomap_1 extended permit ip 192.168.1.0 255.255.255.0 172.31.0.0 255.255.0.0
local ident (addr/mask/prot/port): (192.168.1.0/255.255.255.0/0/0)
remote ident (addr/mask/prot/port): (172.31.0.0/255.255.0.0/0/0)
current_peer: 3.34.211.29


#pkts encaps: 827, #pkts encrypt: 827, #pkts digest: 827
#pkts decaps: 764, #pkts decrypt: 764, #pkts verify: 764
#pkts compressed: 0, #pkts decompressed: 0
#pkts not compressed: 827, #pkts comp failed: 0, #pkts decomp failed: 0
#pre-frag successes: 0, #pre-frag failures: 0, #fragments created: 0
#PMTUs sent: 0, #PMTUs rcvd: 0, #decapsulated frgs needing reassembly: 0
#TFC rcvd: 0, #TFC sent: 0
#Valid ICMP Errors rcvd: 0, #Invalid ICMP Errors rcvd: 0
#send errors: 0, #recv errors: 0

local crypto endpt.: 49.236.139.115/0, remote crypto endpt.: 3.34.211.29/0
path mtu 1500, ipsec overhead 74(44), media mtu 1500
PMTU time remaining (sec): 0, DF policy: copy-df
ICMP error validation: disabled, TFC packets: disabled
current outbound spi: C7CCEEBF
current inbound spi : E2B83FD5

inbound esp sas:
spi: 0xE2B83FD5 (3803725781)
SA State: active
transform: esp-aes esp-sha-hmac no compression
in use settings ={L2L, Tunnel, PFS Group 2, IKEv1, }
slot: 0, conn_id: 264200192, crypto-map: outside_map
sa timing: remaining key lifetime (sec): 108
IV size: 16 bytes
replay detection support: Y
Anti replay bitmap:
0x00000000 0x00000001
spi: 0xEED2584F (4006762575)
SA State: active
transform: esp-aes esp-sha-hmac no compression
in use settings ={L2L, Tunnel, PFS Group 2, IKEv1, Rekeyed}
slot: 0, conn_id: 264200192, crypto-map: outside_map
sa timing: remaining key lifetime (sec): 0
IV size: 16 bytes
replay detection support: Y
Anti replay bitmap:
0x00000000 0x00000001
outbound esp sas:
spi: 0xC7CCEEBF (3352096447)
SA State: active
transform: esp-aes esp-sha-hmac no compression
in use settings ={L2L, Tunnel, PFS Group 2, IKEv1, }
slot: 0, conn_id: 264200192, crypto-map: outside_map
sa timing: remaining key lifetime (sec): 108
IV size: 16 bytes
replay detection support: Y
Anti replay bitmap:
0x00000000 0x00000001
spi: 0xC47BC9E1 (3296446945)
SA State: active
transform: esp-aes esp-sha-hmac no compression
in use settings ={L2L, Tunnel, PFS Group 2, IKEv1, Rekeyed}
slot: 0, conn_id: 264200192, crypto-map: outside_map
sa timing: remaining key lifetime (sec): 0
IV size: 16 bytes
replay detection support: Y
Anti replay bitmap:
0x00000000 0x00000001

이 포스팅은 과정 자체만 설명하고 자세한 프로토콜이나, 인증방식은 설명하지 않았습니다.

사용자의 레벨에서 따라만 해도 VPN 터널링이 가능한 수준의 포스팅을 하려했으나, VPN이 조금 난이도가 있는거 같습니다.

진행하다가 궁금하신 부분은 댓글남겨주세요.

읽어주셔서 감사합니다.

NCP-VPC-Update

드디어 NCP 에도 VPC가 업데이트 되었습니다.

VPC 모드로 전환하면 파란색으로 인터페이스가 전환됩니다.

금융존은 주황색

TMI는 여기 까지고 VPC를 생성해 보겠습니다.

아직 none-rfc-1918은 지원하지 않습니다. 다른 벤더에서도 rfc1918을 쓰는것을 권장하지만, none-rfc-1918의 필요성이 가끔 있으므로 차차 업데이트 되지 않을까 생각됩니다.

VPC 이름에는 대문자를 사용할 수 없습니다.

생성할떄 public / privite 으로 지정해서 만들게 됩니다. 인스턴스를 생성할때 public 으로 생성하면 인스턴스 용도로만 사용할수있고, private 으로 생성하면 로드벨런서 용도와 일반용도를 나누어서 생성할수 있습니다.

AWS 에서 계층화 된 서브넷의 구성에서 자유도를 빼놓은 구성같습니다.

사용자가 선택할수 있는 pub/pri 구분은 서브넷을 생성할 때 만 결정할 수 있는 것 입니다.

라우팅 테이블의 메뉴가 있긴 하나, 이 라우팅 테이블은 서브넷간 통신과 VPN 통신등을 컨트롤하는거고 public / privite 은 한번 설정하면 수정할 수 없습니다.

일단 VPC 와 Subnet을 생성했으니, 한번 classic 모드와 VPC 모드 전환시도를 간단하게 진행해 보겠습니다.

classic 모드에서 인스턴스를 생성하고, 이생성한 인스턴스를 이미지로 만든후 vpc에서 이미지로 인스턴스를 생성해보겠습니다.

생성된 서버이미지를 이제 VPC 모드에서 보겠습니다.

안보입니다.

여긴어디 나는누구........그럼 어쩌지...vpc mode 로 전환 어쩌지..

짤봇!

아직 전환할수 있는 지원은 안나온거 같고..서로 풀을 공유하지 않는것으로 보입니다.

이후 3월 4일 패치내용입니다.

서버이미지 공유와 Classic 에서 VPC로 이미지 복제기능이 런칭되었습니다.

아주 칭찬해!

옮길수있는 이미지리스트는 정해져있지만 아주 수월하게 이동이 가능합니다.

https://manvscloud.com/?p=516

manvscloud 님의 블로그를 링크하며 글을 마칩니다.